再開可能なアップロードの実行

コンセプトに移動

このページでは、Cloud Storage JSON API と XML API で再開可能なアップロードのリクエストを送信する方法を説明します。このプロトコルを使用すると、通信障害でデータフローが中断した後にアップロード操作を再開できます。

再開可能なアップロードのセッションを開始する

再開可能なアップロードのセッションを開始するには:

JSON API

  1. URI https://storage.googleapis.com/upload/storage/v1/b/[BUCKET_NAME]/o に対する POST リクエストを作成します。
  2. クエリ パラメータ uploadType=resumable を追加します。たとえば、myBucket という名前のバケットの場合、次のようにします。

    POST https://storage.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable
  3. ファイルにメタデータがない場合には、name クエリ パラメータを追加して、アップロードに関連するリソースを指定します。たとえば、オブジェクト名が myObject であることを指定するには、次のように記述します。

    POST https://storage.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&name=myObject
  4. ファイルにメタデータがある場合には、リクエストの本文に JSON 形式でメタデータを追加します。それ以外の場合には、リクエストの本文は空にしておきます。

  5. 次の HTTP ヘッダーを追加します。

    • X-Upload-Content-Type。省略できます。ファイルデータの MIME タイプに設定します。これは、後続のリクエストで転送されます。メタデータで、またはこのヘッダーを介してデータの MIME タイプが指定されていない場合、オブジェクトは application/octet-stream として提供されます。
    • X-Upload-Content-Length。省略できます。後続のリクエストで転送されるファイルデータのバイト数を設定します。
    • Content-Type。ファイルにメタデータがある場合には必須です。application/json; charset=UTF-8 に設定します。
    • Content-Lengthチャンク転送エンコードを使用しない場合は、必須です。この開始リクエスト本文のバイト数を設定します。
    • Originクロスオリジン リソース シェアリングを有効にしている場合。このヘッダーは、後続のアップロード リクエストでも使用する必要があります。
  6. リクエストを送信します。

次の例は、myBucket という名前のバケットを使用して再開可能なセッションを開始する方法を示しています。OAuth 2.0 Playground から承認アクセス トークンを取得できます。

POST https://storage.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable HTTP/1.1
  Authorization: Bearer [YOUR_AUTH_TOKEN]
  Content-Length: 38
  Content-Type: application/json; charset=UTF-8
  X-Upload-Content-Type: image/jpeg
  X-Upload-Content-Length: 2000000
  {
    "name": "myObject"
  }

次に、レスポンスを処理する方法を説明します。

XML API

再開可能なアップロードを開始するには、POST Object リクエストを Cloud Storage に送信します。POST Object リクエストにはアップロードするファイルは含まれていません。これには、再開可能なアップロードを実行することを Cloud Storage システムに通知するいくつかのヘッダーが含まれています。具体的には、POST Object リクエストには次のものが必要です:

  • 空のエンティティ ボディ。
  • Content-Length リクエスト ヘッダー。0 に設定する必要があります。
  • x-goog-resumable ヘッダー。start に設定する必要があります。
  • クロスオリジン リソース シェアリングを有効にしている場合、アップロードするファイル用に後続のアップロード リクエストで使用する Origin ヘッダー。

次の例は、example という名前のバケットにアップロードされる music.mp3 という名前のファイルに対して再開可能なアップロードを開始する方法を示しています。

    POST /music.mp3 HTTP/1.1
    Host: example.storage.googleapis.com
    Date: Fri, 01 Oct 2010 21:56:18 GMT
    Content-Length: 0
    Content-Type: audio/mpeg
    x-goog-resumable: start
    Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg
    

再開可能なセッションの URI を保存する

後続のリクエストで使用できるように、再開可能なセッションの URI をコピーして保存します。

JSON API

セッション開始リクエストが成功すると、200 OK HTTP ステータス コードが返されます。また、再開可能なセッション URI を指定した Location ヘッダーも含まれます。再開可能なセッション URI を使用してファイルデータをアップロードし、アップロード ステータスを確認します。

次の例は、myBucket という名前のバケットに対する再開可能なセッション URI を含むレスポンスを示しています。

HTTP/1.1 200 OK
  Location: https://storage.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&upload_id=xa298sd_sdlkj2
  Content-Length: 0

XML API

POST Object リクエストで再開可能なアップロードを開始すると、Cloud Storage は 201 Created というステータス メッセージを返します。ステータス メッセージには、Location ヘッダーが含まれており、その値に再開可能なセッション URI が指定されています。このセッション ID は、アップロード操作中のすべてのリクエストで使用するため、保存する必要があります。

次の例では、「再開可能なアップロードを開始する」セクションに示されていた Post Object リクエストに対するレスポンスを示します。

  HTTP/1.1 201 Created
  Location: https://example.storage.googleapis.com/music.mp3?upload_id=tvA0ExBntDa...gAAEnB2Uowrot
  Date: Fri, 01 Oct 2010 21:56:18 GMT
  Content-Length: 0
  Content-Type: audio/mpeg
  

ファイルをアップロードする

JSON API

再開可能なセッションでファイルをアップロードするには、2 つの方法があります。

  • 単一リクエスト。通常はこの方法が最適です。リクエストの数が少なく、パフォーマンスが向上します。
  • 複数のチャンク。 次の場合に使用します。

    • 1 つのリクエストで転送するデータの量を減らす必要がある。これは、App Engine リクエストの一部のクラスのように、リクエストごとに固定の時間制限がある場合に必要になることがあります。
    • アップロードの進行状況を表すカスタム インジケーターが必要である。

単一リクエスト

ファイルを単一リクエストでアップロードするには:

  1. 再開可能なセッションの URI に PUT リクエストを作成します。
  2. ファイルのデータをリクエストの本文に追加します。
  3. Content-Length HTTP ヘッダーを追加し、ファイルのバイト数に設定します。
  4. リクエストを送信します。

アップロード リクエストが中断するか、5xx レスポンスを受信したら、中断されたアップロードの再開の手順に従います。

リクエストが成功すると、200 OK または 201 Created レスポンスと、リソースに関連付けられたメタデータを受け取ります。

次の例は、以前に取得した再開可能なセッション URI を使用して、2,000,000 バイトの JPEG ファイル全体を myBucket にアップロードする再開可能なリクエストを示しています。

PUT https://storage.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
Content-Length: 2000000
Content-Type: image/jpeg
Content-Range: bytes 0-1999999

複数のチャンク

複数のチャンクでファイルをアップロードするには:

  1. 再開可能なセッションの URI に PUT リクエストを作成します。
  2. リクエストの本文にチャンクのデータを追加します。サイズが 256 KB(256 x 1,024 バイト)の倍数になるようにチャンクを作成します(アップロードを完了する最後のチャックは除く)。アップロードを効率的に行うため、チャンクサイズはできるだけ大きくしてください。
  3. 次の HTTP ヘッダーを追加します。
    • Content-Length。現在のチャンクのバイト数を設定します。
    • Content-Range: ファイルの何バイト目から何バイト目までをアップロードするかを設定します。たとえば、Content-Range: bytes 0-524287/2000000 は、2,000,000 バイトのファイルで先頭の 524,288 バイト(256 x 1,024 x 2)をアップロードすることを意味します。
  4. リクエストを送信してレスポンスを処理します。アップロード リクエストが中断するか、5xx レスポンスを受信したら、中断されたアップロードの再開の手順に従います。

  5. ファイルの残りのチャンクに手順 1~4 を繰り返します。レスポンスの Range ヘッダーを使用して、次のチャンクの開始位置を決定します。前のリクエストで送信したデータがすべてサーバーで受信されているとは限りません。

ファイル全体のアップロードが完了すると、200 OK または 201 Created レスポンスと、リソースに関連付けられたメタデータを受け取ります。

次の例は、以前に取得した再開可能なセッション URI を使用して、ファイルの最初の 524,288 バイト(512 KB)を myBucket に送信するリクエストを示しています。

PUT https://storage.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
      Content-Length: 524288
      Content-Type: image/jpeg
      Content-Range: bytes 0-524287/2000000 

リクエストが成功すると、サーバーは、その時点までに格納された合計バイト数を示す 308 Resume Incomplete' along with aRange` ヘッダーとともにレスポンスを返します。

HTTP/1.1 308 Resume Incomplete
    Content-Length: 0
    Content-Range: bytes=0-524287

Range ヘッダーで返された上限値を使用して、次のチャンクの開始位置を決定します。ファイル全体のアップロードが完了するまで、ファイルの各チャンクの PUT を続行します。

全体のアップロードが完了すると、200 OK または 201 Created レスポンスと、リソースに関連付けられたメタデータを受け取ります。

XML API

ファイル ブロックを Cloud Storage に送信する PUT Object リクエストを実装します。PUT リクエストのリクエスト URI として取得したセッション URI を使用します。リクエストにはさらに Content-Length ヘッダーが含まれ、これを使用して、アップロードするファイルのサイズを指定する必要があります。

POST Object リクエストと同様に、リクエスト内で標準の Cloud Storage ホスト名(storage.googleapis.com)を使用する必要があります。セッション URI が、事実上、認証トークンであるため、明示的な認証トークンを使用する必要はありません。

次の例は、開始された再開可能なアップロード用に music.mp3 ファイルをアップロードする方法を示しています。

  PUT https://example.storage.googleapis.com/music.mp3?upload_id=tvA0ExBntDa...gAAEnB2Uowrot HTTP/1.1
  Date: Fri, 01 Oct 2010 21:56:18 GMT
  Content-Length: 7351375
  

PUT Object リクエストが中断されることなく、ファイルが正常にアップロードされると、Cloud Storage は 200 OK というステータス コードを返します。アップロードが中断された場合は、アップロードを再開できます。

別の PUT Object リクエストを送信して、受信したバイト数を照会する必要があります。PUT Object リクエストには次のものが必要です。

  • 空のエンティティ ボディ。
  • Content-Length リクエスト ヘッダー。0 に設定する必要があります。
  • Content-Range リクエスト ヘッダー。ステータスを調べるバイトの範囲を指定します。
  • 再開可能なアップロードのセッション URI と同じリクエスト URI。

Content-Range リクエスト ヘッダーの値は次の形式にする必要があります。

Content-Range: bytes */<content-length>

&lt;content-length&gt; は、元の PUT Object リクエストで指定した Content-Length ヘッダーの値です。

さらに、リクエスト内で標準の Cloud Storage ホスト名を使用する必要があります(storage.googleapis.com)。

次の例では、再開可能なアップロードが中断された後で Cloud Storage システムに照会を行う方法を示します。

  PUT https://example.storage.googleapis.com/music.mp3?upload_id=tvA0ExBntDa...gAAEnB2Uowrot HTTP/1.1
  Date: Fri, 01 Oct 2010 22:25:53 GMT
  Content-Range: bytes */7351375
  Content-Length: 0
  

中断されたアップロードの再開

レスポンスを受信する前にアップロード リクエストが終了した場合や、503 または 500 のサービス利用不可レスポンスが返された場合は、中断されたアップロードを再開する必要があります。中断したアップロードを再開するには:

JSON API

  1. アップロードのステータスを取得するため、再開可能なセッションの URI に空の PUT リクエストを作成します。
  2. ファイル内の現在の位置が不明であることを示す Content-Range ヘッダーを追加します。

    たとえば、ファイルの合計サイズが 2,000,000 バイトの場合、Content-Range*/2000000 に設定します。

    ファイル全体のサイズがわからない場合は、Content-Range*/* に設定します。

  3. リクエストを送信します。

  4. レスポンスを処理します。

    • 200 OK または 201 Created が返された場合、アップロードは完了しています。これ以上の操作は必要ありません。
    • 308 Resume Incomplete が返された場合、ファイルのアップロードを続行する必要があります。
  5. 308 Resume Incomplete が返された場合、レスポンスの Range ヘッダーを処理します。このヘッダーには、Cloud Storage がその時点までに受信したバイト数が設定されています。次のステップでこの数値を使用します。Cloud Storage がまだバイトを受信していない場合、レスポンスに Range ヘッダーはありません。

    たとえば、Range ヘッダーが bytes=0-42 の場合、ファイルの先頭から 43 バイトを受信したという意味になります。

  6. これで、アップロードを再開する場所が確認できました。残りのデータまたは次のチャンクを送信して、ファイルのアップロードを続行します。送信するファイルの部分を示す Content-Range ヘッダーを含めます。

    たとえば、Content-Range: bytes 43-1999999/2000000 は、43 バイト目から 1,999,999 バイト目までを送信することを示します。

XML API

PUT Object リクエストを送信することで、アップロード操作を再開できます。PUT Object リクエストには次のものが必要です。

  • アップロードする必要があるバイトの範囲を含むエンティティ ボディ。この範囲は、Content-Length から Range(以前に取得)を引いて決定します。
  • Content-Length リクエスト ヘッダー。これは、現在のリクエストでアップロードするバイト数を指定します。
  • Content-Range リクエスト ヘッダー。これは、リクエストでアップロードするバイトの範囲を指定します。
  • 再開可能なアップロードのセッション URI と同じリクエスト URI。

    リクエスト内で標準の Cloud Storage ホスト名を使用する必要があります(storage.googleapis.com)。

次の例は、example バケットへの music.mp3 ファイルのアップロードを再開する PUT Object リクエストを示しています。

PUT https://example.storage.googleapis.com/music.mp3?upload_id=tvA0ExBntDa...gAAEnB2Uowrot HTTP/1.1
Date: Fri, 01 Oct 2010 22:25:53 GMT
Content-Range: bytes 2359296-7351374/7351375
Content-Length: 4992079

アップロードの再開は必要に応じて何回でも実行できますが、リクエストを再試行するときは、切り捨てられた指数バックオフを使用してください。例については、このロジックの boto 実装をご覧ください。

ファイルが正常にアップロードされると、Cloud Storage は 200 OK というステータス コードを返します。

オプションの最適化について詳細を確認してください。

アップロードのキャンセル

アップロードをキャンセルして、それ以降の処理が行われないようにするには、一意のアップロード URI で DELETE リクエストを発行します。DELETE リクエストが成功した後、アップロードの再開やクエリを試行すると、4xx レスポンスが返されます。

JSON API

次の例は、再開可能なアップロードをキャンセルする方法を示しています。

DELETE https://storage.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
Content-Length: 0

XML API

アップロードをキャンセルして、それ以降の処理が行われないようにするには、一意のアップロード URI で DELETE リクエストを発行します。DELETE リクエストが成功した後、アップロードの再開やクエリを試行すると、4xx レスポンスが返されます。

次の例は、再開可能なアップロードをキャンセルする方法を示しています。

 DELETE https://example.storage.googleapis.com/myFile.zip?upload_id=tvA0ExBntDa...gAAEnB2Uowrot HTTP/1.1
    Content-Length: 0

次のステップ