v2
- CORSは不要と気がつきましたので、
httpd.conf
の設定は不要だと思います(不具合が出たらまた見直すかもしれませんが) - 理由は前回記事をご覧ください。
- 変更点はv2としています。
目的
- tusdは巨大ファイルを分割して送信し、中断してもレジュームが聞くオープンソース(MITライセンス)のサービスです。
- これまでhttpと、httpsでのXHR通信でうまくいった記事を書きました。
- tusdとtus-js-client, uppyを使ったファイルアップロードをapache2.4のCentOS7で構築する(http編)
- tusdとtus-js-client, uppyを使ったファイルアップロードをapache2.4のCentOS7で構築する(https編)
- 今回はtusdを起動するときに、cookieを受け取ってユーザ毎やセッション毎に必要な処理の仕組みを試しました。
- その備忘録です。
環境
- CentOS7
- apache 2.4.41
- browser Firefox77 (MacOS)など
- tusd v1.0
- tus-js-client v2
仕組み
- tusでファイルアップロードする仕組みはクライアント(ブラウザ)から
https://www.your-site.net/files/
にfileをuploadすると宣言して、apacheではリバースプロキシで/files/
へのアクセスをhttp://localhost:1080/
に変換し、サーバのデーモンtusd
がこのポートを監視して、クライアントからのfileを/files/に格納する動きをするものでした。詳しくは前回の記事をご覧ください。 - このとき
tusd
はファイルを生成するときとファイル処理の完了したときにコマンドを発行する、あるいはhttp
で処理することができます。これをhookと呼びます。git
と同じ仕組みだとか。といってもファイルフックはtusd
の処理タイミングで決まった名前のコマンド(シェルスクリプト)をキックするというだけです。 - 取説はこちら:github.com/tusd/.../docs/hooks.md
- LATS(Linux, Apache, Textfile and Shell-script)では
http hook
でなく当然file hook
(シェルコマンド)を選択します。
フックコマンド
- 日本語訳をgoogle翻訳ベースにポイントだけ載せておきます。
- pre-create:アップロード前にトリガーされ、ユーザー確認などができます。アップロードの拒否は終了コードを0以外にするだけです。
- post-create: アップロード作成後にトリガーされ、新しいアップロードを処理する必要があることをシステムの他の部分に通知します。
- pre-finish: アップロードが完全に終了した後、クライアントに応答が返される前にトリガーされ、これはブロッキングフックであり、アップロードされたファイルを検証または後処理するために使用できます。0以外の終了コードの場合400、HTTP 500エラーがクライアントに返されます。
- post-finish: アップロードが完全に終了した後にトリガーされ、すべてのチャンクが転送されストレージに保存されます。このファイルを使用してさらに処理するか、他のアプリケーションにこのアップロードの完了を通知できます。チャンクとはtus固有の用語で分割されアップロードファイルを意味します。参考
- post-terminate: アップロードが終了した後にトリガーされ、アップロードが完全に停止し、関連チャンクがストレージから完全に削除されています。アップロードのコンテンツを取得できなくなり、このアップロードが再開または終了しないことを他のアプリケーションに通知することができます。
- post-receive: 実行中のアップロードごとにトリガーされ、現在の進行状況を示します。これは、サーバーがクライアントからより多くのデータを受信するたびに、最大で毎秒発行されます。オフセットプロパティは、その時点でサーバーに転送された合計バイト数に設定されます。
インプリ
apaheでCORSでcookieがやり取りできように設定[v2]
http.confにCORSでのcookieの設定(Access-Control-Allow-Credentials)を追加します。- この設定はクロスオリジンが発生していないので不要だと思います。
{http.conf}
<Directory /var/www/files>
Header always set Access-Control-Allow-Origin "https://www.your-site.net"
Header always set Access-Control-Allow-Credentials "true"
</Directory>
htmlでCORSでcookieをやり取りできるようにする[v2]
tus-js-clientのデモのindex.htmlでtus.jsのoptionにwithCredential
を設定します。75行目あたりにあります。- この設定はクロスオリジンが発生していないので不要だと思います。[v2]
{tus-js-cilent/demos/browser/demo.js}
var options = {
//
// Cookie対応する
withCredentials : true,
...
クライアントのブラウザにクッキーを書き込む
- JavaScriptでクッキーを(例えばセッションID情報)を格納します。最終行に追加しておきます。
{tus-js-cilent/demos/browser/demo.js}
// クッキーのセット
document.cookie = 'ID_SESSION=c043fe31-cf1b-4c77-AAAA-7a49c49c14d5; path=/; secure;'
tusdでファイルフックできるようにする
- 処理の段階で
tusd
でhook
できるようにtusd
の起動を次のようにしました。
{run_tusd.bash}
$ cat $(which run_tusd.bash)
#!/bin/bash -vxeu
# tusdをオプション込みで起動する
# log file
exec &> /var/www/log/$(basename $0).$(date '+%y%m%d_%H%M%S').$$.bash
#
# https用コマンドライン
sudo -u apache /usr/local/bin/tusd -upload-dir /var/www/files/ -behind-proxy -hooks-dir /var/www/hooks -verbose &
- tusdのフックはオプション
-hooks-dir
でディレクトリを指定することでファイルフックが可能になります。このディレクトリにpre-create
とかの名前のshell scriptを書いておけばいいです。
tusdのファイルアップロード開始時にクッキーを取り出す
- ファイルアップロード開始時は
pre-create
をキックするので、これにクッキー処理を書いておきます。下記の例は設定したキッキーのセッションIDを読み出します。 - 実験用なのでどういった起動時の環境変数もモニターします。
$ cat pre-create
#!/bin/bash -xveu
exec 2> /var/www/log/$(basename $0).$(date '+%y%m%d_%H%M%S').$$.bash
CMD_SESSION=$( basename $0 )
___TUS___=$( cat - |jq )
___ENV___=$( printenv | sort )
- コード解説します。
-
tusd
は-hooks-dir /var/www/hooks
で指定したディレクトリのpre-create
という名前のコマンドを起動します。 - ここでは
bash
で起動します。 - logを取っておきます
- 起動されたコマンド名を変数
CMD_SESSION
に設定されます。 -
tusd
は起動するフックにstdin
として変数を格納します。そのため読み出しをcat -
で読み出し、jq
で可読性をあげ、変数___TUS___
に入れておきます - ついでにどんなSHELL環境変数だったのかを変数
___ENV___
に入れておきます。 -
tusd
からキックされたpre-create
のクッキーがどうだったのか、logファイルを確認しましょう。
-
確認(pre-createに渡された変数)
- それではlogを確認しましょう。全行のせます。セキュリティの観点で省略している部分やサイト名、IPは変更しています。
ログファイルです。
{/var/www/log/pre-create.200628_084337.14802.bash }
$ cat pre-create.200628_084337.14802.bash
CMD_SESSION=$( basename $0 )
++ basename /var/www/hooks/pre-create
+ CMD_SESSION=pre-create
___TUS___=$( cat - |jq )
++ cat -
++ jq
+ ___TUS___='{
"Upload": {
"ID": "",
"Size": 37091,
"SizeIsDeferred": false,
"Offset": 0,
"MetaData": {
"filename": "your-upload-music-file.mp3"
},
"IsPartial": false,
"IsFinal": false,
"PartialUploads": null,
"Storage": null
},
"HTTPRequest": {
"Method": "POST",
"URI": "/files/",
"RemoteAddr": "[::1]:57482",
"Header": {
"Accept": [
"*/*"
],
"Accept-Encoding": [
"gzip, deflate, br"
],
"Accept-Language": [
"ja,en-US;q=0.7,en;q=0.3"
],
"Connection": [
"Keep-Alive"
],
"Content-Length": [
"0"
],
"Cookie": [
"ID_SESSION=c043fe31-cf1b-4c77-AAAA-7a49c49c14d5"
],
"Origin": [
"https://www.your-site..net"
],
"Referer": [
"https://www.your-site.net/vendors/node_modules/tus-js-client/demos/browser/index.html"
],
"Tus-Resumable": [
"1.0.0"
],
"Upload-Length": [
"37091"
],
"Upload-Metadata": [
"filename My4xLjItaHR0cHPjgYvjgpnjgrvjgq3jg6Xjg6rjg4bjgqPjgabjgpnkv53orbfjgZXjgozjgZ/mjqXntprjgpLnorrnq4vjgabjgpnjgY3jgarjgYTjgajoqIDjgo/jgozjgZ/jgajjgY3jga7lr77lh6bms5UubWQ=,filetype"
],
"User-Agent": [
"Mozilla/5.0 (省略)
],
"X-Forwarded-For": [
"(省略)"
],
"X-Forwarded-Host": [
"www.your-site.net"
],
"X-Forwarded-Proto": [
"https"
],
"X-Forwarded-Server": [
"www.your-site.net"
]
}
}
}'
___env___=$( printenv | sort )
++ printenv
++ sort
+ ___env___='HISTSIZE=1000
HOME=/usr/share/httpd
HOSTNAME=(省略)
LANG=ja_JP.UTF-8
LOGNAME=apache
LS_COLORS=(省略)
MAIL=(省略)
PATH=(省略)
PWD=/var/www/hooks
SHELL=/sbin/nologin
SHLVL=1
SUDO_COMMAND=/usr/local/bin/tusd -upload-dir /var/www/files/ -behind-proxy -hooks-dir /var/www/hooks -verbose
SUDO_GID=0
SUDO_UID=0
SUDO_USER=root
TERM=xterm-256color
TUS_ID=
TUS_OFFSET=0
TUS_SIZE=37091
USER=apache
USERNAME=apache
XDG_SESSION_ID=355
_=/bin/printenv'
設定したcookie値を、きちんとpre-create
で読むことができていますね。これはstdin
からの情報にあります。このコマンドを起動した環境変数には(もちろん)cookie情報がないことも確認できました。これでセッション情報に基づいたユーザ毎の処理をLATSでもできそうです。uppyにもCredentialの設定はできますよ。[v2]
どなたかのお役に立てましたらとても嬉しいです。今回の記事は”動いたよ”という段階なので間違った設定や使い方があるかもしれません。その時はご指摘ください。