鳩舎

レースしない

ファイルアップローダを作ろう

How to じゃなくて、何かの言語を学ぶ、もしくはあるパラダイムにチャレンジするとき、に僕がよく使うサンプルアプリケーションとして、ファイルアップローダというのがあり、それの仕様をまとめておこうと思い至っただけです。

ちょっと研修資料っぽい感じになっちゃったけど、まぁいいか。

アプリケーションの概要

非ログイン型のファイルアップローダです。ファイルの保持先は S3 や Disk 、 DB への Blob などいくつかの選択肢が提供されます。

HTTP のフォームからファイルがアップロードされ、リストで表示されるだけの簡単なアプリケーションです。

ファイルには有効期限があり、それを過ぎるとダウンロードできなくなる、かつリストにも表示されなくなります(保存先の実ファイルも削除されていることが望ましいです)。

また、ファイルにはプライベートモードがあります。プライベートモードのファイルはリストに表示されませんが、ファイルの個別 URL に直接アクセスすることでダウンロードすることが出来ます。

ファイルにはパスワードが設定でき、そのパスワードを用いることで、有効期限をまたずにファイルのダウンロードを無効化することが出来ます。

URL 一覧

  • GET / : ファイルリスト + アップロードフォーム(text/html)
  • POST /files : ファイル作成(作成後は /files/:id へリダイレクト)
  • GET /files/:id : ファイル個別ページ + 無効化フォーム(text/html)
  • GET /download/:id : ダウンロード(application/octet-stream もしくは実ファイルの content-type)
  • DELETE /files/:id : ファイル無効化(成功なら / へ、失敗なら /files/:id へリダイレクト)

想定する挙動一覧(正常系のみ)

  • ファイルをアップロードする -> リストにファイルが追加されている -> 個別ページにアクセス出来る -> ファイルがダウンロードできる
  • ファイルをプライベートモードでアップロードする -> リストには追加されていない -> 個別ページにアクセス出来る -> ファイルがダウンロードできる
  • ファイルを有効期限1秒後の設定でアップロードする -> 1秒後に個別ページにアクセスできない(404) -> ファイルのダウンロードも出来ない(404)
  • ファイルをパスワード付きでアップロードする -> 個別ページからパスワードを入力して無効化を行う -> 個別ページにアクセス出来ない -> ファイルのダウンロードも出来ない

補足

保存先の設定はアップロード毎じゃなくてアプリの設定でよいです。データの永続化先は DB でもファイルでもなんでもいいですが、要件上 DB を使っておくのが懸命です。

パスワードを生で保存するのは賢くないのでやめておくべきです。どのように保存するかは考えましょう。

正常系のみでいいのでテストを書きましょう。テストが書きにくい、難しいと感じたら、どうやったらテストしやすくなるかを考えましょう。

もし、身の回りに先輩やウィザードがいる場合、この仕様と出来上がったコードをセットでレビューを受けましょう。もしくは、どこか適当な(自前の VPS など)でアプリケーションを動かして、なんらかの攻撃に成功した人にコーヒーをおごる、といって友人、先輩などに公開しましょう(くれぐれもパブリックなアプリケーションとしては運用しないこと!)

蛇足

僕がこの仕様を使ったのは

  • 目指せオブ厨な勢いで OOP に馴染もうとしたとき
  • HTTP なアプリのテストの書き方がわからない言語を初めて触るとき
  • DDD / DCI などにチャレンジするとき

てな具合です。物足りない時はユーザー登録機能を足したり、ファイルが画像の時だけプレビュー機能をつけたり、アップロード出来るファイルの容量制限をかけたりってな具合に仕様を足して複雑度を上げていくようにしていました。

何かの参考になれば。