HTTPで再開可能なアップロードを可能にする提案仕様

HTTPでファイルをアップロードする時、ネットワークの寸断などによりアップロードが中途半端に終わってしまうことがあります。アップロードが途中まで成功したとしても、一度切断するとそこから再開する方法は標準化されていません。
(PUTリクエスト + Rangeヘッダによる再開をサポートしているシステムもありますが標準化されてはいません。 参考URL)

そこで、再開可能なアップロードの仕組みを定義した「Resumable Uploads Protocol」という仕様がIETFに提出されています。この仕様は、Transloadit Ltd, Apple Inc, Cloudflare などの方々の共著になっています。

Resumable Uploads Protocol の概要

Resumable Uploads Protocol」は、一度中断しても再開可能なアップロード方式を定義しています。

簡単な流れは次のとおりです

  • クライアントから、POSTやPUTでファイルのアップロードを開始する。この時、再開用トークンをupload-tokenヘッダで送る。
  • サーバは、Resumable Uploads Protocolに対応していれば、104 レスポンスを送る。
  • その後、アップロードが中断した場合は、クライアントは再開用のトークンでアップロードを再開する。

(100番台のレスポンスは、サーバからレスポンスを返しても通信は終わらない点に注意してください。通信を維持し、最終的に改めて正式なレスポンスコードを返します。)

Resumable Uploads Protocolの流れ

Resumable Uploads Protocolにおいて、アップロードの開始および再開の流れについて説明していきます
f:id:ASnoKaze:20220227230313p:plain

アップロードの開始

Resumable Uploads Protocolに対応したクライアントは、まずPOSTやPUTリクエストでファイルのアップロードを開始します。この時次のヘッダを付けます。

  • upload-token: 今回のファイルアップロードを識別するためのトークン。再開時にも利用する
  • upload-draft-interop-version: 準拠している仕様のバージョン。本仕様では1が指定される。
104レスポンス

HTTPの仕様として、100番台のレスポンスは、本来のレスポンスに先んじて返されます。その後正式なレスポンス (200~500番台)が返されます。ですので、100番台のレスポンスを返しても通信は終わりはしません。

Resumable Uploads Protocolでは、サーバがこの仕様に対応している場合は、104レスポンスを返します。104レスポンスは、ボディを受信仕切る前に返せるので、通信が途中で中断される前にクライアントに通知することが出来ます。

(なお、サーバがResumable Uploads Protocolに対応してない場合は、通常通りのPOSTリクエストとして処理されます)

通信の中断

ユーザのアクションや、ネットワークの切断、ソフトウェアの終了などの理由により、アップロードが中断される可能性があります。

アップロードの再開

ファイルのアップロードを再開するにあたって、サーバがどこまで受信したのかをまず確認します。upload-tokenのついたHEADリクエストを送り、サーバから upload-offset を取得します。これが、サーバが受信したデータです。

そのオフセットからファイルアップロードを再開します。POSTリクエストにはupload-tokenおよびupload-offsetを付け送信します。

その他

詳しく説明しませんが、仕様では次のケースについても書かれています

  • サーバ側で、受け取ったupload-tokenに紐づく途中ファイルがない場合の扱い
  • クライアント側から、途中ファイルを破棄するようにサーバに通知する方法
  • 予め長さが分かってないファイルのアップロード ( Upload-Incomplete )