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

## 目的
- 音の処理をするwebアプリ作っています。
- ユーザの音源をfile uploadしたいので、レジューム可能なMITライセンスのライブラリの`tus.io`を使いたいと思っていました。そのテストです。本当はhttpsとクッキーによるユーザ管理を前提にしているのですが、まずは慣れるためにhttpで動かしてみました。
- `tus.io`は日本語の情報が少ないのですが頑張ってChromeの日本語変換機能を活用しながら動かしてみました。
- Webアプリは[LATS](https://www.usptomo.com/PAGE=20120207AVB) (Linux, Apache, Textfile and ShellScript)で作っているので、tusのデーモンは`tusd`を使います。


## 環境

- CentOS7
- apache 2.4.41
- browser Firefox77 (MacOS)など

## 参考
1. [【tus】動画などの大容量ファイルアップロードに嬉しい「Resumable Upload」が簡単に実現できる。](https://qiita.com/Amtkxa/items/6a605209bcc6eb477ec0)
2. [tus.io](https://tus.io)
2. [CentoOS7にyumでGoを入れてHello Worldするまで - Qiita](https://qiita.com/nooboolean/items/11805928527aeb576c21)
3. [uppy](https://uppy.io)

## インストール

### goのインストール
- `tusd`はgo言語で書かれています。そのためgoコンパイラが必要です。これは参考サイトに書いてあるとおりにすればそのとおりにインストールできました。$GOPATHの設定も書いてあるとおりにしました。問題なし。

```
$ sudo yum install -y golang
$ go version
go version go1.13.11 linux/amd64
```

## tusdのインストール

- [tusdのサイトに書いてあるとおり](https://github.com/tus/tusd/blob/master/docs/installation.md)にインストールします。

```
$ git clone git@github.com:tus/tusd.git
$ cd tusd/
$ sudo go build -o tusd cmd/tusd/main.go
```

## tusdを動かしてみる
- 巣のままで動かしてみます。下記の様に動いています。

```
$ /usr/local/go/bin/tusd
[tusd] 2020/06/18 20:40:43 Using '/home/hoge/data' as directory storage.
[tusd] 2020/06/18 20:40:43 Using 0.00MB as maximum size.
[tusd] 2020/06/18 20:40:43 Using 0.0.0.0:1080 as address to listen.
[tusd] 2020/06/18 20:40:43 Using /files/ as the base path.
[tusd] 2020/06/18 20:40:43 Using /metrics as the metrics path.
[tusd] 2020/06/18 20:40:43 Supported tus extensions: creation,creation-with-upload,termination,concatenation,creation-defer-length
[tusd] 2020/06/18 20:40:43 You can now upload files to: http://0.0.0.0:1080/files/
```

- ログの意味ですが、tusdはhttpのドキュメントルートから見た/filesをデフォルトディレクトリとしてファイルを格納します。モニターしているオリジン（？）は`http://0.0.0.0:1080/files/`です。プロトコルがhttpでドメインの0.0.0.0は全てのネットワークインタフェースを意味するそうです（[参考：127.0.0.1とlocalhostと0.0.0.0の違い](https://qiita.com/1ain2/items/194a9372798eaef6c5ab)）。ポートは1080がデフォルトです。tusdはクライアントからのアップロードをこのURL（？）で受け付けると言っています。

## tus-js-clientのインストール
- ブラウザでファイルアップロードするためのJavaScriptとデモサンプルを試します。
- [こちらのサイト](https://github.com/tus/tus-js-client/blob/master/docs/installation.md)の通りにインストールします。

```
$ cd /tus-js-clientをインストールするディレクトリに.../
$ npm install --save tus-js-client
```


## サーバをhttpを受け付ける様に設定をする

- tusはhttpベースを基本にしているのでサーバもhttpで動く様にします。
- apacheの制御の指示は`/etc/httpd/conf/http.conf`でなされます。
- httpd.confをオリジナルに戻してサーバ名だけ変えます。

```
# diff httpd.conf.org httpd.conf
95c95
< #ServerName www.example.com:80
---
> ServerName your-site.net:80
```

- 他のモジュールは`httpd.conf`から`/etc/httpd/conf.d/*conf`を読むことでロードされる設定になっています。
- 今の設定はhttps用にopensslが動いているのですが、この設定を読まない様にしておきます。
 
```
# cd /etc/httpd/conf.d/
# mv ssl.conf _ssl.conf
# systemctl restart httpd
```

### サーバの設定に合わせてtusdを動かす。

- logも残しておきたいため、tusdを起動するためのスクリプトを書いきました。
- uploadのデータを書き込める様にApacheを動しているユーザ名`apache`で起動するようにしています。

```
$ cat /usr/local/bin/run_tusd.bash 
#!/bin/bash -vxeu
# tusdをオプション込みで起動する
# 2020-06-23; (C) @woodie2wopper

# logを残す
exec &> /var/www/log/$(basename $0).$(date '+%y%m%d_%H%M%S').$$.bash
sudo -u apache /usr/local/go/bin/tusd -upload-dir /var/www/files &

$ /usr/local/bin/run_tusd.bash &
passwordを入力
```

## インストールしたデモ用のサイトを試す
- デモのhtmlはインストールしたtus-js-clientのフォルダの中にあります。無編集でこれを立ち上げます。
- サイト　-> http://your-site.net/vendors/node_modules/tus-js-client/demos/browser/index.html
- ポイントはUploadのendpointを`http`にすることと、`1080`のポート番号を入れることです。
- サイトのドメインはテストサイト名で、画像ではURLを変えています。
- ファイルを選択しただけでuploadが始まります。こんな感じです。

<img width="1017" alt="スクリーンショット 2020-06-23 13.02.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178143/39398231-3b4d-53c2-94f8-fcde2eaf0b76.png">

- 成功しています。パチパチ。

## ドラッグアンドドロップできるuppyを動かす

- tusのクライアントでtus-js-clientのラッパーのuppyも試してみます。
- サーバサイドの設定は変えていません。
- uppyを試すhtmlはURLだけ変えています。httpであること、ポート番号が1080であること、URLがきちんと"/"で終わっていること、がポイントです。
- サンプルのソースコードは[ここ](https://uppy.io/docs/)に書いてあります。
- これを適切ななまえに変えて変更点は`endpoint:`だけです。

```{bash}
$ cat html/test_uppy.html
...
        .use(Uppy.Tus, {
			endpoint: 'http://your-site.net:1080/files/',
...
```

- 試すとD&Dでuploadできました。

<img width="785" alt="スクリーンショット 2020-06-23 12.54.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178143/f961a04b-7697-4dd9-6ff9-759f4fd0c3c5.png">

## サーバを確認する

- /files/に格納したファイルはユニークIDです。
- UUIDと拡張子がinfoのファイルがあり、infoのファイルをjqで整形するとこんな感じです。

```
$ cd ./files
$ ll
合計 15524
-rw-r--r-- 1 apache apache     363 2020-06-23 10:34:56 896a0eb08e3c24558c9e8c7022fa2144.info
-rw-r--r-- 1 apache apache 3653046 2020-06-23 10:35:00 896a0eb08e3c24558c9e8c7022fa2144
...
$ cat 896a0eb08e3c24558c9e8c7022fa2144.info |jq
{
  "ID": "896a0eb08e3c24558c9e8c7022fa2144",
  "Size": 3653046,
  "SizeIsDeferred": false,
  "Offset": 0,
  "MetaData": {
    "filename": "IMG_4579.jpeg",
    "filetype": "image/jpeg",
    "name": "IMG_4579.jpeg",
    "relativePath": "null",
    "type": "image/jpeg"
  },
  "IsPartial": false,
  "IsFinal": false,
  "PartialUploads": null,
  "Storage": {
    "Path": "/your-site-directory/files/896a0eb08e3c24558c9e8c7022fa2144",
    "Type": "filestore"
  }
}

```

- lockファイルもできます。処理中を意味するのでしょう。

どなたかのお役に立てれば嬉しいです。何か間違いやコメントいただけますと嬉しいです。