はじめに
他のデバイスへのファイル転送の煩わしさを少しでも解消できたらと思い作りました
MacユーザーならAirDropでとすんなりいけるのですが、他のユーザーだと、Slack、LINEとかを使ってのファイル転送で、それもなければメールで... と面倒です
ターミナルと使ってると、他のブラウザなりGUIを立ち上げるの面倒なのです。なのでコマンドで送れるように考えました
加えて、新しくコマンドをインストールせずに、標準的なコマンドだけで送れる方法を考えました
特徴
- 標準的なコマンド
curl
かwget
があれば、ファイル送受信できる - アカウントを作る必要がない
- ブラウザからでも送受信できる
ファイルを送る
以下は./test.txt
を送る例です
cat ./test.txt | curl -T - https://trans-akka.herokuapp.com/
ファイルを受け取る
以下の方法でダウンロードできます。
cwm
はFile IDです。送信したときのレスポンスのランダムな文字列です(後述のオプションでセキュリティのレベルを向上させることができます)。
curl https://trans-akka.herokuapp.com/cwm > myfile
(上記のURLにアクセスすれば、ブラウザからでもダウンロードできます)
その他の使い方
詳しい説明は、下の方の「その他の特徴」をご覧ください。
GitHubリポジトリ
GitHub: nwtgck/trans-server-akka
公開サーバー
Dockerでサーバーを立てる
docker run
一発ですぐに立てれます。
docker run -it -p 8080:80 nwtgck/trans-server-akka:v1.19.6 --http-port=80
これで、http://localhost:8080 にサーバーが立ちます。
データの永続化 - Docker
/trans/db
内にファイルデータもデータベースのデータもあるので、以下のコマンドで永続化するようなサーバーが立てれます
docker run -d -p 8080:80 -v $PWD/trans-db:/trans/db --restart=always nwtgck/trans-server-akka:v1.19.6 --http-port=80
現在(ver 1.19.6)では、
- ファイルは圧縮され、暗号化されて保存されます
- データベースはファイルベースのH2 Databaseを使用しています
Let's encryptでHTTPS化 - Docker
ファイル送信は安全が重要なので、Let's encryptを使った、HTTPS化の方法の紹介です。
(Let's encryptに限らず使えるとは思いますが)
FULLCHAIN=/etc/letsencrypt/live/hogehoge.io/fullchain.pem
PRIVKEY=/etc/letsencrypt/live/hogehoge.io/privkey.pem
# pkcs.p12を生成する
sudo openssl pkcs12 -export -in $FULLCHAIN -inkey $PRIVKEY -out pkcs.p12 -name mytlskeyalias -passout pass:changeit
# trans.keystoreを生成する
keytool -importkeystore -srckeystore pkcs.p12 -srcstoretype PKCS12 -destkeystore trans.keystore -deststoretype JKS -srcstorepass changeit -deststorepass changeit
# transサーバーを起動
sudo docker run -it -p 80:80 -p 443:443 -v $PWD/trans.keystore:/trans/trans.keystore nwtgck/trans-server-akka:v1.19.6 --http-port=80 --https-port=443
(FULLCHAIN
とPRIVKEY
はご自身のドメインに合わせて変更してください)
その他の特徴
ヘルプ/ サーバーバージョン
wget
とかcurl
のオプションとかを忘れたときに使えそうな/help
です
curl https://trans-akka.herokuapp.com/help
curl https://trans-akka.herokuapp.com/version
(curl
を使うとデフォルトで標準出力にレスポンスが出るので、curl
があるときはこっちが便利です)
ファイル削除
curl -X DELETE https://trans-akka.herokuapp.com/cwm
ダウンロード回数制限付きで送信
以下の例だと1回ダウンロードされると、自動的にファイルが消滅するになります
curl 'https://trans-akka.herokuapp.com/?get-times=1' -T ./test.txt
File IDを長くして送信
覚えやすさ優先で、デフォルトが3文字なので、長くしてセキュアにしたいときは、長さが指定できます。
curl 'https://trans-akka.herokuapp.com/?id-length=16' -T ./test.txt
削除キー付きで送信
デフォルトだと削除するときにキーがないので、File IDを知っている人はだれでも削除できるので、以下で削除用のキーを設定できます
curl 'https://trans-akka.herokuapp.com/?delete-key=mykey1234' -T ./test.txt
誰も削除できないようにする
curl 'https://trans-akka.herokuapp.com/?deletable=false' -T ./test.txt
URLを送る
HTTPのPOST送信ボディー部を内容にしているだけなので、以下のようにファイルに保存されている内容でなくても送れます
echo "https://example.com" | curl -T - https://trans-akka.herokuapp.com
https://trans-akka.herokuapp.com/r/YOUR FILE_ID
のように /r/YOUR FILE_ID
を指定することでリダイレクトしてくれます。
この機能で、一定時間で消滅する短縮リンクみたいになってくれます。
zip
& curl
でディレクトリ送信
上のURL送信と同じように、zip
でも一度圧縮したファイルを生成しなくても送れます
zip -q -r - ./mydir | curl -T - https://trans-akka.herokuapp.com
tar
& curl
でディレクトリ送信
以下は.tar.gz
版です
tar zfcp - ./mydir/ | curl -T - https://trans-akka.herokuapp.com
Range access
高速でダウンロードできるツールを Go で実装した。で有名なpget
にも対応してます
(追記) 専用のCLI
Transのコンセプトは、標準的なコマンドで送ったり受け取ったりすることです。
ただし、専用のCLIがあったほうが便利なので、Go言語でCLIを作りました。
これでtrans
コマンドを使える人はtrans
で送って、持っていない人はwget
、curl
やブラウザから送受信ができるようになり便利です。
インストール
brew install nwtgck/homebrew-trans/trans
使用法
trans send test.txt
trans get cwm
trans delete cwm
どのサーバーを使うかは以下のコマンドで設定できます。
trans use https://trans-akka.herokuapp.com
詳しい使い方は https://github.com/nwtgck/trans-cli-go や、trans -h
をみてください。
サーバーサイド
サーバーサイドは、Akka HTTPデータベースは、Slickで書いています。
ストリームな感じがとてもよく、
以下のような処理が、
ファイルのバイト列 => 圧縮 => 暗号化
=> バイト数を数える(Content-Lengthで使うため)
思ったように以下のようなコードになります
RunnableGraph.fromGraph(GraphDSL.create(fileStoreSink, lengthSink)(_.zip(_)){implicit builder => (fileStoreSink, lengthSink) =>
import GraphDSL.Implicits._
val bcast = builder.add(Broadcast[ByteString](2))
// * compress ~> encrypt ~> store
// * calc length
byteSource ~> bcast ~> Compression.gzip ~> CipherFlow.flow(genEncryptCipher()) ~> fileStoreSink
bcast ~> lengthSink
ClosedShape
})
特に凝ったこともしていないですし、Akka HTTPのHigh-Levelなルーティングで、とても快適にルーティングできました。
最後に
少しでもファイルを送り合う煩わしさから開放されたら嬉しいです
あと、AkkaとかAkka StreamとかAkka HTTPとかの日本語の記事が増えてくれると嬉しいです