再開可能なアップロードを実行する

概要

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

Google Cloud CLI とクライアント ライブラリで再開可能なアップロードを使用する方法については、ツールと API で再開可能なアップロードがどのように使用されるかをご覧ください。

必要なロール

再開可能なアップロードの実行に必要な権限を取得するには、次のいずれかのロールを付与するよう管理者に依頼してください。

  • オブジェクト保持ロックを含むアップロードの場合は、バケットに対する Storage オブジェクト管理者(roles/storage.objectAdmin)IAM ロールの付与を管理者に依頼します。

  • それ以外の場合は、バケットに対するストレージ オブジェクト ユーザー(roles/storage.objectUser)の IAM ロールの付与を管理者に依頼します。

これらの事前定義ロールには、それぞれのケースでオブジェクトをバケットにアップロードするために必要な権限が含まれています。必要とされる正確な権限については、「必要な権限」セクションを開いてご確認ください。

必要な権限

  • storage.objects.create
  • storage.objects.delete
    • この権限は、既存のオブジェクトを上書きするアップロードにのみ必要です。
  • storage.objects.setRetention
    • この権限は、オブジェクト保持ロックを含むアップロードでのみ必要です。

これらの権限は、他の事前定義ロールカスタムロールを使用して取得することもできます。

バケットに対するロールの付与については、バケットで IAM を使用するをご覧ください。

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

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

JSON API

  1. gcloud CLI のインストールと初期化を行います。これにより、Authorization ヘッダーのアクセス トークンを生成できます。

  2. 必要に応じて、アップロードするオブジェクトに設定するメタデータを含む JSON ファイルを作成します。たとえば、次の JSON ファイルでは、image/png にアップロードするオブジェクトの contentType メタデータを設定します。

    {
        "contentType": "image/png"
    }
  3. cURL を使用して、POST Object リクエストで JSON API を呼び出します。

    curl -i -X POST --data-binary @METADATA_LOCATION \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "Content-Length: INITIAL_REQUEST_LENGTH" \
        "https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME"

    ここで

    • METADATA_LOCATION は、前の手順で指定したオプションのメタデータを含む JSON ファイルのローカルパスです。メタデータ ファイルを含めない場合は、--data-binary @ および Content-Type ヘッダーとともに除外します。
    • INITIAL_REQUEST_LENGTH は、最初のリクエストの本体のバイト数です(例: 79)。
    • BUCKET_NAME は、オブジェクトをアップロードするバケットの名前です。例: my-bucket
    • OBJECT_NAME は、オブジェクトに付ける URL エンコードの名前です。例: pets%2Fdog.png として URL エンコードされているpets/dog.png。手順 2 でオブジェクト メタデータ ファイルに name を含めた場合、この操作は必要ありません。

    クロスオリジン リソース シェアリングを有効にしている場合、このリクエストと後続のアップロード リクエストに Origin ヘッダーも含める必要があります。

    リクエストに追加できるオプションのヘッダーには、X-Upload-Content-TypeX-Upload-Content-Length があります。

    成功した場合、レスポンスには 200 ステータス コードが含まれます。

  4. レスポンスの Location ヘッダーで指定された再開可能なセッション URIPOST Object リクエストに保存します。

    この URI は、それ以降にオブジェクト データをアップロードするためのリクエストで使用されます。

XML API

  1. gcloud CLI のインストールと初期化を行います。これにより、Authorization ヘッダーのアクセス トークンを生成できます。

  2. cURL を使用して、空の本文を含む POST Object リクエストで XML API を呼び出します。

    curl -i -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Length: 0" \
        -H "Content-Type: OBJECT_CONTENT_TYPE" \
        -H "x-goog-resumable: start" \
        "https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME"

    ここで

    • OBJECT_CONTENT_TYPE は、オブジェクトのコンテンツ タイプです。例: image/pngコンテンツ タイプを指定しない場合、Cloud Storage システムはオブジェクトの Content-Type メタデータを application/octet-stream に設定します。
    • BUCKET_NAME は、オブジェクトをアップロードするバケットの名前です。例: my-bucket
    • OBJECT_NAME は、オブジェクトに付ける URL エンコードの名前です。例: pets%2Fdog.png として URL エンコードされているpets/dog.png

    クロスオリジン リソース シェアリングを有効にしている場合、このリクエストと後続のアップロード リクエストに Origin ヘッダーも含める必要があります。

    成功した場合、レスポンスには 201 ステータス メッセージが含まれます。

  3. レスポンスの Location ヘッダーで指定された再開可能なセッション URIPOST Object リクエストに保存します。

    この URI は、それ以降にオブジェクト データをアップロードするためのリクエストで使用されます。

データをアップロードする

再開可能なアップロードを開始したら、次の 2 つの方法でオブジェクトのデータをアップロードできます。

  • 単一のチャンク: 通常はこの方法が最適です。リクエストの数が少なく、パフォーマンスが向上します。
  • 複数のチャンク: 1 つのリクエストで転送されるデータ量を削減する必要がある場合(個々のリクエストに固定された時間上限がある場合など)やアップロードの開始時に合計サイズがわからない場合は、この方法を使用します。

単一のチャンク アップロード

単一のチャンクでデータをアップロードするには:

JSON API

  1. cURL を使用して、PUT Object リクエストで JSON API を呼び出します。

    curl -i -X PUT --data-binary @OBJECT_LOCATION \
        -H "Content-Length: OBJECT_SIZE" \
        "SESSION_URI"

    ここで

    • OBJECT_LOCATION は、オブジェクトへのローカルパスです。例: Desktop/dog.png
    • OBJECT_SIZE は、オブジェクトのバイト数です。例: 20000000
    • SESSION_URI は、再開可能なアップロードを開始したときに Location ヘッダーで返された値です。

    必要に応じて、接頭辞 X-Goog-Meta- を付けて、このリクエストの一部としてオブジェクトのカスタム メタデータを追加できます。

XML API

  1. cURL を使用して、PUT Object リクエストで XML API を呼び出します。

    curl -i -X PUT --data-binary @OBJECT_LOCATION \
        -H "Content-Length: OBJECT_SIZE" \
        "SESSION_URI"

    ここで

    • OBJECT_LOCATION は、オブジェクトへのローカルパスです。例: Desktop/dog.png
    • OBJECT_SIZE は、オブジェクトのバイト数です。例: 20000000
    • SESSION_URI は、再開可能なアップロードを開始したときに Location ヘッダーで返された値です。

アップロードが完了すると、リソースに関連するメタデータとともに 200 OK または 201 Created レスポンスが返されます。

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

複数のチャンク アップロード

複数のチャンクでデータをアップロードするには:

JSON API

  1. アップロードするデータ全体からデータのチャンクを作成します。

    チャンクサイズは、256 KiB(256 x 1,024 バイト)の倍数にする必要があります。通常、チャンクサイズを大きくするとアップロードが速くなりますが、速度とメモリ使用量の間にトレードオフがあることに注意してください。チャンクサイズは 8 MiB 以上を使用することをおすすめします。

  2. cURL を使用して、PUT Object リクエストで JSON API を呼び出します。

    curl -i -X PUT --data-binary @CHUNK_LOCATION \
        -H "Content-Length: CHUNK_SIZE" \
        -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    ここで

    • CHUNK_LOCATION は、現在アップロードしているチャンクへのローカルパスです。
    • CHUNK_SIZE は、現在のリクエストでアップロードするバイト数です。例: 8388608
    • CHUNK_FIRST_BYTE は、アップロードするチャンクに含まれるオブジェクト全体の開始バイトです。
    • CHUNK_LAST_BYTE は、アップロードするチャンクに含まれるオブジェクト全体の終了バイトです。
    • TOTAL_OBJECT_SIZE は、アップロードするオブジェクトの合計サイズです。
    • SESSION_URI は、再開可能なアップロードを開始したときに Location ヘッダーで返された値です。

    Content-Range の例としては、Content-Range: bytes 0-8388607/20000000 が考えられます。このヘッダーの詳細については、Content-Range をご覧ください。

    リクエストが成功すると、サーバーは 308 Resume Incomplete で応答します。レスポンスには Range ヘッダーが含まれています。

  3. アップロードするデータチャンクごとに上記の手順を繰り返します。各レスポンスの Range ヘッダーに含まれる上限値を使用して、後続のチャンクの開始位置を決定します。リクエストで送信されたすべてのバイトがサーバーで受信されているとは限りません。

    必要に応じて、再開可能なアップロードの最後のリクエストに X-Goog-Meta- で始まるヘッダーを追加して、オブジェクトのカスタム メタデータを追加できます。

XML API

  1. アップロードするデータ全体からデータのチャンクを作成します。

    チャンクサイズは、256 KiB(256 x 1,024 バイト)の倍数にする必要があります。通常、チャンクサイズを大きくするとアップロードが速くなりますが、速度とメモリ使用量の間にトレードオフがあることに注意してください。チャンクサイズは 8 MiB 以上を使用することをおすすめします。

  2. cURL を使用して、PUT Object リクエストで XML API を呼び出します。

    curl -i -X PUT --data-binary @CHUNK_LOCATION \
        -H "Content-Length: CHUNK_SIZE" \
        -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    ここで

    • CHUNK_LOCATION は、現在アップロードしているチャンクへのローカルパスです。
    • CHUNK_SIZE は、現在のリクエストでアップロードするバイト数です。例: 8388608
    • CHUNK_FIRST_BYTE は、アップロードするチャンクに含まれるオブジェクト全体の開始バイトです。
    • CHUNK_LAST_BYTE は、アップロードするチャンクに含まれるオブジェクト全体の終了バイトです。
    • TOTAL_OBJECT_SIZE は、アップロードするオブジェクトの合計サイズです。
    • SESSION_URI は、再開可能なアップロードを開始したときに Location ヘッダーで返された値です。

    Content-Range の例としては、Content-Range: bytes 0-8388607/20000000 が考えられます。このヘッダーの詳細については、Content-Range をご覧ください。

    リクエストが成功すると、サーバーは 308 Resume Incomplete で応答します。レスポンスには Range ヘッダーが含まれています。

  3. アップロードするデータチャンクごとに上記の手順を繰り返します。各レスポンスの Range ヘッダーに含まれる上限値を使用して、後続のチャンクの開始位置を決定します。リクエストで送信されたすべてのバイトがサーバーで受信されているとは限りません。

アップロードが完了すると、リソースに関連するメタデータとともに 200 OK または 201 Created レスポンスが返されます。

チャンク アップロードが中断された場合、または 5xx のレスポンスを受け取った場合は、中断されたチャンク全体を再送信するか、中断位置からアップロードを再開します。

再開可能なアップロードのステータスを確認する

再開可能なアップロードが中断された場合や、アップロードが完了しているかどうかわからない場合は、アップロードのステータスを確認できます。

JSON API

  1. cURL を使用して、PUT Object リクエストで JSON API を呼び出します。

    curl -i -X PUT \
        -H "Content-Length: 0" \
        -H "Content-Range: bytes */OBJECT_SIZE" \
        "SESSION_URI"

    ここで

    • OBJECT_SIZE は、オブジェクトに含まれる合計バイト数です。オブジェクトのフルサイズがわからない場合は、この値に * を使用します。
    • SESSION_URI は、再開可能なアップロードを開始したときに Location ヘッダーで返された値です。

XML API

  1. cURL を使用して、PUT Object リクエストで XML API を呼び出します。

    curl -i -X PUT \
        -H "Content-Length: 0" \
        -H "Content-Range: bytes */OBJECT_SIZE" \
        "SESSION_URI"

    ここで

    • OBJECT_SIZE は、オブジェクトに含まれる合計バイト数です。オブジェクトのフルサイズがわからない場合は、この値に * を使用します。
    • SESSION_URI は、再開可能なアップロードを開始したときに Location ヘッダーで返された値です。

200 OK または 201 Created が返された場合、アップロードは完了しています。これ以上の操作は必要ありません。

308 Resume Incomplete が返された場合、データのアップロードを続行する必要があります。

  • Cloud Storage がまだバイトを保持していない場合、308 レスポンスには Range ヘッダーがありません。この場合、アップロードを最初から開始する必要があります。
  • それ以外の場合、308 レスポンスには、Cloud Storage がこれまでに保持したバイト数を指定する Range ヘッダーが含まれます。中断されたアップロードを再開する場合は、この値を使用します。

中断されたアップロードを再開する

レスポンスを受信する前にアップロード リクエストが終了した場合や、503 または 500 レスポンスを受け取った場合は、中断位置から中断されたアップロードを再開します。中断されたアップロードを再開するには以下の処理を行います。

JSON API

  1. 再開可能なアップロードのステータスを確認します。

  2. ステータス チェックに対するレスポンスに含まれる Range ヘッダーの上限値を保存します。レスポンスに Range ヘッダーがない場合、Cloud Storage はまだバイトを保持していないため、最初からアップロードする必要があります。

  3. アップロードしようとしているオブジェクト データが Range ヘッダーの上限値より大きいバイトから始まることを確認します。

  4. 中断されたリクエストに X-Goog-Meta- という接頭辞を持つヘッダーが含まれている場合は、これらのヘッダーをリクエストに追加してアップロードを再開できます。

  5. cURL を使用して、Range ヘッダーの値の後のバイトを取得する PUT Object リクエストで JSON API を呼び出します。

    curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \
        -H "Content-Length: UPLOAD_SIZE_REMAINING" \
        -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    ここで

    • PARTIAL_OBJECT_LOCATION は、アップロードするデータの残りの部分へのローカルパスです。
    • UPLOAD_SIZE_REMAINING は、現在のリクエストでアップロードするバイト数です。たとえば、0~42 バイトのアップロードが完了した後に、合計サイズが 20,000,000 の残りのオブジェクトをアップロードすると、UPLOAD_SIZE_REMAINING19999957 になります。
    • NEXT_BYTE は、手順 2 で保存した値の次の整数です。たとえば、手順 2 の値が 42 の場合、NEXT_BYTE の値は 43 になります。
    • LAST_BYTE は、この PUT リクエストに含まれる終了バイトです。たとえば、合計サイズが 20000000 のオブジェクトのアップロードを完了するには、LAST_BYTE の値は 19999999 となります。
    • TOTAL_OBJECT_SIZE は、アップロードするオブジェクトの合計サイズです。例: 20000000
    • SESSION_URI は、再開可能なアップロードを開始したときに Location ヘッダーで返された値です。

XML API

  1. 再開可能なアップロードのステータスを確認します。

  2. ステータス チェックに対するレスポンスに含まれる Range ヘッダーの上限値を保存します。レスポンスに Range ヘッダーがない場合、Cloud Storage はまだバイトを保持していないため、最初からアップロードする必要があります。

  3. アップロードしようとしているオブジェクト データが Range ヘッダーの上限値より大きいバイトから始まることを確認します。

  4. cURL を使用して、Range ヘッダーの値の後のバイトを取得する PUT オブジェクト リクエストで XML API を呼び出します。

    curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \
        -H "Content-Length: UPLOAD_SIZE_REMAINING" \
        -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    ここで

    • PARTIAL_OBJECT_LOCATION は、アップロードするデータの残りの部分へのローカルパスです。
    • UPLOAD_SIZE_REMAINING は、現在のリクエストでアップロードするバイト数です。たとえば、0~42 バイトのアップロードが完了した後に、合計サイズが 20,000,000 の残りのオブジェクトをアップロードすると、UPLOAD_SIZE_REMAINING19999957 になります。
    • NEXT_BYTE は、手順 2 で保存した値の次の整数です。たとえば、手順 2 の値が 42 の場合、NEXT_BYTE の値は 43 になります。
    • LAST_BYTE は、この PUT リクエストに含まれる終了バイトです。たとえば、合計サイズが 20000000 のオブジェクトのアップロードを完了するには、LAST_BYTE の値は 19999999 となります。
    • TOTAL_OBJECT_SIZE は、アップロードするオブジェクトの合計サイズです。例: 20000000
    • SESSION_URI は、再開可能なアップロードを開始したときに Location ヘッダーで返された値です。

セッション URI がアクティブな間は、必要に応じて何回でもアップロードを再開できます。セッション URI は 1 週間後に期限切れになります。データが正常にアップロードされると、Cloud Storage は 200 OK または 201 created というステータス コードを返します。

アップロードをキャンセルする

完了していない再開可能なアップロードをキャンセルして、それ以上の操作を防ぐには次の処理を行います。

JSON API

  1. cURL を使用して、DELETE リクエストで JSON API を呼び出します。

    curl -i -X DELETE -H "Content-Length: 0" \
      "SESSION_URI"

    ここで

成功すると、レスポンスに 499 ステータス コードが含まれます。今後、アップロードのクエリまたは再開を試行すると、4xx レスポンスが返されます。

XML API

  1. cURL を使用して、DELETE リクエストで XML API を呼び出します。

    curl -i -X DELETE -H "Content-Length: 0" \
      "SESSION_URI"

    ここで

成功した場合、レスポンスには 204 ステータス コードが含まれます。また、アップロードに対するクエリを試行または再開しようとすると、204 レスポンスが返されます。

失敗の処理

まれに、中断されたアップロードを再開するリクエストが失敗し、再取得できない「4xx」エラーが発生することがあります。これは、バケットの権限が変更されたか、最後にアップロードされたオブジェクトの完全性チェックで不一致が検出されたためです。この場合は、新しい再開可能なアップロード セッションを開始してアップロードを再試行します。

次のステップ