tusdとtus-js-client, uppyを使ったファイルアップロードをapache2.4のCentOS7で構築する（https編）

## この記事：v2
- 投稿してから気分を一新するため、歩いているとふと疑問に思いました。
- フォロントエンドから`https://www.your-site.net/files`にアクセスするのなら別にクロスオリジンになっていないではないか、なので、apaheの`httpd.conf`の`<Directory>...</Directory>`の設定は不要ではないか？
- tus.ioではポートを1080にして`http://www.your-site:1080/filse/`にアクセスしていたのでhttpsでアクセスするにはCORSの対応が必要だけど、ReverseProxyでポートまで変換してるならCORS対応不要と思ったわけです。
- それで試してみました。CORS対応不要でした。下記はオリジナルにv2として見せ消ししています。

----
## 目的

- でかくて一杯ある音データをユーザ毎にサーバにアップロードしたいので、MITライセンスの`tusd`を使いたい。
- 実運用にはhttpsが必須です。クッキーでセッション管理して大容量・複数ファイルの処理をユーザ毎に行いたいからです。
- [前回ではhttpで動くことを確認](https://qiita.com/Woodie/items/5eea441cad405c8c9437)しました。
- この記事はhttpsでのトライアルです。クッキーには対応していません。

## 環境

- CentOS7
- apache 2.4.41
- browser Firefox77 (MacOS)など
- tusd 1.0
- tus-js-client v2

## 参考

- [tus.io](https://tus.io)

## 注意（この方法はtus.ioで記載されている方法とは違います。参考程度にお願いします）
- apacheのconfはここに書いてあります。[tusd/examples/apache2.conf](https://github.com/tus/tusd/blob/master/examples/apache2.conf)
- tus-js-clientのサンプルはここにあります[tus-js-client/docs/usage.md](https://github.com/tus/tus-js-client/blob/master/docs/usage.md)


## インプリの概要
1. uppy/tus-js-clientはCORS(Cross Origin Resource Sharing)が解決しないとブラウザは動いてくれません。そのための`Header`にいつもの"このサイトは大丈夫だからね！`Header always set Access-Control-Allow-Origin "https://www.my-site.net"`"を記述をします。
2. tusdはhttpベースでhttp:0.0.0.0:1080を監視しているので、クライアントとサーバのやり取りをhttpsで行う場合、サーバでhttpsからhttpにスキーム変換させるためにリバースプロキシを立てます。このときうまくいったコードでは、リバースプロキシはクライアントからの`https:/www.your-site.net/files`への要求を`http://localhost:1080/files/`に渡すので、クライアントはポート番号を指定しないことでうまく行きました。
3. スキームの変換はapacheの`ssl.conf`に記載します。
4. tusdはproxyの後ろで動いているとオプションを渡して起動させます。

この５つの設定でうまく行きました。うまくいったapach2.4の`httpd.conf`、`ssl.conf`、`tus`の起動スクリプト、tus-js-clientの`html`の例を次に記します。セキュリティのため、適当に書き換えていますので、読み替えてください。記載は本質的なところに限りました。

### apache2.4の設定ファイル[v2]
- sslの設定はLet's encryptで動いていますので、そちらを参考にしてください。
- [v2]この`httpd.conf`の設定は不要です。
- [v2] 参考にした`apache2.conf`は[ここ](https://github.com/tus/tusd/blob/master/examples/apache2.conf)にあります

#### ~~httpd.conf（部分）~~
```{httpd.conf}
Listen 80
...
Include conf.modules.d/*.conf
ServerName www.my-site.net:80

IncludeOptional conf.d/*.conf
...
<Directory /var/www/files>
  Header always set Access-Control-Allow-Origin "https://www.your-site.net"
</Directory>	
```
この`/var/www/files`にupload fileが入ります。

#### ssl.conf（部分）
```{ssl.conf}
...
<VirtualHost _default_:443>
...
	ServerName www.your-site.net
...
	SSLEngine on
	SSLCertificateFile your-cert.pem
	SSLCertificateKeyFile your-privkey.pem
	Include your-options-ssl-apache.conf
	SSLCertificateChainFile your-chain.pem
	
	RequestHeader set X-Forwarded-Proto "https"
	ProxyPreserveHost on
	ProxyRequests off
	<LocationMatch "/files">
		ProxyPass http://localhost:1080/files
		ProxyPassReverse http://localhost:1080/files
	</LocationMatch>
</VirtualHost>

SSLProtocol             all -SSLv3
SSLCipherSuite          ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-$:HIGH:MEDIUM:!MD5:!RC4
SSLHonorCipherOrder     on
SSLCompression          off

# OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling          on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
```
セキュリティの設定(SSLCipherSuite、OCSPなど）は適当です。


### tusdの起動スクリプト
tusdを立ち上げる時のログとコマンドをスクリプト化しました。リバースプロキシに対応させるため引数(`-behind-proxy`)を加えています。

```{run_tusd.bash }
#!/bin/bash -vxeu
# tusdをオプション込みで起動する
exec &> /var/www/log/$(basename $0).$(date '+%y%m%d_%H%M%S').$$.bash
sudo -u apache /usr/local/bin/tusd -upload-dir /var/www/files -behind-proxy &
```

### クライアントサイド
これがtus.ioの方法と一番違います。tus.ioでは`tttps://www.my-site.net:1080/files/`とポート番号を指定してアクセスするように書いていますが、apache2.4ではどうもうまく行きません。サンプルはapache2.2のようなので振る舞いが違うようになったのかもしれませんが私にはわかりません。動いたコードは下記です。

```{tus-js-clientのindex.html}
41行目：オリジナル <input type="text" id="endpoint" name="endpoint" value="https://www.your-site.net:1080/files/">
41行目：変更後　　 <input type="text" id="endpoint" name="endpoint" value="https://www.your-site.net/files/">
```

同様にuppyもendpointをポート番号1080を消して`https:www.you-site.net/files/`に指定したらうまく行きました。

```{uppy.html}
var uppy = Uppy.Core() 
...
  .use(Uppy.Tus, { 
      endpoint: 'https://www.your-site.net/files/',
...
 })
```

#### 参考
apacheのデバックはとても大変です。LogLevelをdebugにしてもよくわかりません。そこで教えてもらったのが`curl`です。CORSでOPTIONSの反応が全然わからないのでしたがterminalでpreflightのテストができるようになってからかなり素早く試行することができました。それとサーバのconfファイルの編集はrootでデフォルトのviでなくvimを使うほうが断然早いですね。curlのOPTIONSの反応は下記で見えます。ブラウザからどんな要求が出ているのかは FireFoxの表示メニュー → 開発メニュー → ネットワーク でヘッダを確認できました。

```{bash}
$ curl --verbose https://www.your-site.net/files/ -X OPTIONS -H 'Host: www.your-site.net' -H 'Origin: https://your-site.net' 1> /dev/null
```

どなたの参考になれば嬉しいですが、これが正しい設定なのかわかりません。apacheの仕組みも正確にわかっておらず多分そうだろうと思って書きました。間違いの指摘などご意見いただけましたら幸いです。