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-Range
、GetObject-PartNumber
、HeadObject-Range
、または HeadObject-PartNumber
を含める必要があります。Object Lambda アクセスポイントの設定の更新の詳細については、「Object Lambda アクセスポイントの作成」を参照してください。
ステップ 2: Lambda 関数で Range
または partNumber
処理を実装する
Object Lambda アクセスポイントが範囲 GetObject
または HeadObject
のリクエストで Lambda 関数を呼び出すとき、Range
または partNumber
パラメータはイベントコンテキストに含まれます。イベントコンテキストでのパラメータの場所は、次の表で説明するように、使用されたパラメータと Object Lambda アクセスポイントへの元のリクエストにどのように Lambda 含まれていたかによって異なります。
パラメータ | イベントコンテキストの場所 |
---|---|
|
|
|
|
|
|
重要
指定された Object Lambda アクセスポイントの署名付き URL には、元のリクエストの Range
または partNumber
パラメータが含まれていません。AWS Lambda 関数でこれらのパラメータを処理する方法については、以下のオプションを参照してください。
Range
または partNumber
の値を抽出した後に、アプリケーションのニーズに基づいて、次のいずれかの方法を使用できます。
-
リクエストされた
Range
またはpartNumber
を変換されたオブジェクトにマッピングします (推奨)。Range
またはpartNumber
リクエストを処理する最も確実な方法は、以下を実行することです。-
Amazon S3 から完全なオブジェクトを取得します。
-
オブジェクトを変換します。
-
リクエストされた
Range
またはpartNumber
パラメータを変換後のオブジェクトに適用します。
これを行うには、指定された署名付き URL を使用して Amazon S3 からオブジェクト全体をフェッチし、必要に応じてオブジェクトを処理します。例の Lambda 関数では、この方法で
Range
パラメータを設定し、AWS サンプル GitHub リポジトリの「このサンプル」を参照してください。 -
-
リクエストされた
Range
を署名付き URL にマッピングします。場合によっては、Lambda 関数でリクエストされた
Range
を署名済み URL に直接マッピングして、Amazon S3 からオブジェクトの一部のみを取得できます。このアプローチは、変換が次の両方の条件を満たしている場合にのみ適切です。-
変換関数は、部分的なオブジェクト範囲に適用できます。
-
変換関数の前または後に
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; }
-