

# Range および partNumber ヘッダーの操作
<a name="range-get-olap"></a>

**注記**  
2025 年 11 月 7 日現在、S3 Object Lambda は、現在サービスを使用している既存のお客様、および一部の AWS パートナーネットワーク (APN) パートナーのみが利用できます。S3 Object Lambda と同様の機能の詳細については、「[Amazon S3 Object Lambda availability change](https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazons3-ol-change.html)」を参照してください。

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 アクセスポイントの設定
<a name="range-get-olap-step-1"></a>

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

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

## ステップ 2: Lambda 関数で `Range` または `partNumber` 処理を実装する
<a name="range-get-olap-step-2"></a>

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 リポジトリの[「このサンプル」](https://github.com/aws-samples/amazon-s3-object-lambda-default-configuration/blob/main/function/nodejs_20_x/src/response/range_mapper.ts)を参照してください。

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

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

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

   1. 変換関数の前または後に `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;
   }
   ```