Range および partNumber ヘッダーの操作 - Amazon Simple Storage Service

Range および partNumber ヘッダーの操作

Amazon S3 Object Lambda で大規模なオブジェクトを操作する場合は、Range HTTP ヘッダーを使用して、オブジェクトから指定されたバイト範囲をダウンロードできます。同じオブジェクトのさまざまなバイト範囲をフェッチするには、Amazon S3 への同時接続を使用できます。また、オブジェクトの指定されたパートに対して範囲リクエストを実行する partNumber パラメータ(1~10,000 の整数) を指定することもできます。

Range または partNumber のパラメータを含んだリクエストを処理するには、複数の方法があるため、S3 オブジェクト Lambda ではこれらのパラメータを変換されたオブジェクトに適用しません。代わりに、AWS Lambda 関数は、アプリケーションで必要に応じてこの機能を実装する必要があります。

S3 Object Lambda で Range および partNumber パラメータを使用するには、次の操作を行います。

  • Object Lambda アクセスポイントの設定でこれらのパラメータを有効にします。

  • これらのパラメータを含むリクエストを処理できる Lambda 関数を作成します。

次のステップでそのやり方を説明します。

ステップ 1: Object Lambda アクセスポイントの設定

デフォルトでは、オブジェクト Lambda アクセスポイントは、ヘッダーまたはクエリパラメータに Range または partNumber パラメータを含む GetObject または HeadObject リクエストに対して、HTTP ステータスコード 501 (未実装) エラーで応答します。

Object Lambda アクセスポイントがこのようなリクエストを有効にするには、Object Lambda アクセスポイント設定の AllowedFeatures セクションに GetObject-RangeGetObject-PartNumberHeadObject-Range、または HeadObject-PartNumber を含める必要があります。Object Lambda アクセスポイントの設定の更新の詳細については、「Object Lambda アクセスポイントの作成」を参照してください。

ステップ 2: Lambda 関数で Range または partNumber 処理を実装する

Object Lambda アクセスポイントが範囲 GetObject または HeadObject のリクエストで Lambda 関数を呼び出すとき、Range または partNumber パラメータはイベントコンテキストに含まれます。イベントコンテキストでのパラメータの場所は、次の表で説明するように、使用されたパラメータと Object Lambda アクセスポイントへの元のリクエストにどのように Lambda 含まれていたかによって異なります。

パラメータ イベントコンテキストの場所

Range (ヘッダー)

userRequest.headers.Range

Range (クエリパラメータ)

userRequest.url (クエリパラメータ Range)

partNumber

userRequest.url (クエリパラメータ partNumber)

重要

指定された Object Lambda アクセスポイントの署名付き URL には、元のリクエストの Range または partNumber パラメータが含まれていません。AWS Lambda 関数でこれらのパラメータを処理する方法については、以下のオプションを参照してください。

Range または partNumber の値を抽出した後に、アプリケーションのニーズに基づいて、次のいずれかの方法を使用できます。

  1. リクエストされた Range または partNumber を変換されたオブジェクトにマッピングします (推奨)。

    Range または partNumber リクエストを処理する最も確実な方法は、以下を実行することです。

    • Amazon S3 から完全なオブジェクトを取得します。

    • オブジェクトを変換します。

    • リクエストされた Range または partNumber パラメータを変換後のオブジェクトに適用します。

    これを行うには、指定された署名付き URL を使用して Amazon S3 からオブジェクト全体をフェッチし、必要に応じてオブジェクトを処理します。例の Lambda 関数では、この方法で Range パラメータを設定し、AWS サンプル GitHub リポジトリの「このサンプル」を参照してください。

  2. リクエストされた Range を署名付き URL にマッピングします。

    場合によっては、Lambda 関数でリクエストされた Range を署名済み URL に直接マッピングして、Amazon S3 からオブジェクトの一部のみを取得できます。このアプローチは、変換が次の両方の条件を満たしている場合にのみ適切です。

    1. 変換関数は、部分的なオブジェクト範囲に適用できます。

    2. 変換関数の前または後に Range パラメータを指定すると、同じ変換後のオブジェクトになります。

    たとえば、ASCII エンコードオブジェクト内のすべての文字を大文字に変換する変換関数は、上記の両方の条件を満たします。変換はオブジェクトの一部に適用でき、変換前に Range パラメータを適用すると、変換後にパラメータを適用するのと同じ結果が得られます。

    対照的に、ASCII エンコードされたオブジェクトの文字を反転する関数は、これらの条件を満たしていません。このような関数は、部分的なオブジェクト範囲に適用できるため、基準 1 を満たしています。ただし、基準 2 を満たしていません。なぜなら、Range パラメータを変換前に適用した場合と、変換後にパラメータを適用する場合とは結果が異なるためです。

    コンテンツ abcdefg を含むオブジェクトの最初の 3 文字に関数を適用するリクエストを考えてみましょう。変換前にの Range パラメータを適用すると abc のみが取得され、その後、データを逆にして戻すと cba が取得されます。しかし、変換後にパラメータが適用された場合、関数はオブジェクト全体を取得し、それを反転し、Range パラメータを適用して、gfe を返します。これらの結果は異なるため、この関数は Amazon S3 からオブジェクトを取得する際に、Range パラメータを適用すべきではありません。代わりに、オブジェクト全体を取得し、変換を実行してから、Range パラメータを適用する必要があります。

    警告

    多くの場合、Range パラメータを署名済み URL に適用すると、Lambda 関数またはリクエスト元のクライアントによる予期しない動作が発生します。Amazon S3 から部分的なオブジェクトのみを取得するときにアプリケーションが正常に動作することが確実でない限り、アプローチ A で前述したように、完全なオブジェクトを取得して変換することをお勧めします。

    アプリケーションがアプローチ B の基準を満たしていれば、要求されたオブジェクト範囲のみをフェッチし、その範囲で変換を実行することで、AWS Lambda 関数を単純化することができます。

    次の Java コードの例では、次の処理を実行する方法を示します。

    • GetObject リクエストから Range ヘッダーを取得します。

    • Lambda が Amazon S3 からリクエストされた範囲を取得するために使用できる署名付き URL に Range ヘッダーを追加します。

    private HttpRequest.Builder applyRangeHeader(ObjectLambdaEvent event, HttpRequest.Builder presignedRequest) { var header = event.getUserRequest().getHeaders().entrySet().stream() .filter(e -> e.getKey().toLowerCase(Locale.ROOT).equals("range")) .findFirst(); // Add check in the query string itself. header.ifPresent(entry -> presignedRequest.header(entry.getKey(), entry.getValue())); return presignedRequest; }