本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 Range 和 partNumber 標頭
在 Amazon S3 Object Lambda 中使用大型物件時,您可以使用 Range
HTTP 標頭,從物件下載指定的位元組範圍。若要從同一物件內擷取不同的位元組範圍,您可以對 Amazon S3 使用並行連線。您還可以指定 partNumber
參數 (1 到 10,000 之間的整數),其會針對物件的指定部分執行範圍請求。
因為您可能需要多種方法來處理包含 Range
或者 partNumber
參數的請求,而 S3 Object Lambda 不會將這些參數套用至轉換的物件。相反,您的 AWS Lambda 函數必須根據應用程序的需要實現此功能。
若要搭配 S3 Object Lambda 使用 Range
和 partNumber
參數,請執行下列動作:
-
在 Object Lambda 存取點組態中啟用這些參數。
-
撰寫一個 Lambda 函數,其可以處理包含這些參數的請求。
下列步驟說明如何完成這項操作。
步驟 1:設定 Object Lambda 存取點
根據預設,Object Lambda 存取點會以 HTTP 狀態碼 501 (未實作) 錯誤回應任何 GetObject
或 HeadObject
請求,該請求包含在標頭或查詢參數中的 Range
或 partNumber
參數。
若要啟用 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 存取點的原始請求中的方式。
參數 | 事件內容位置 |
---|---|
|
|
|
|
|
|
重要
針對您的 Object Lambda 存取點所提供的預先簽章 URL 不包含來自原始請求的 Range
或 partNumber
參數。請參閱以下有關如何在 AWS Lambda 函數中處理這些參數的選項。
在擷取 Range
或 partNumber
值後,您可以根據應用程式的需求採取下列其中一種方法:
-
將請求的
Range
或partNumber
映射到轉換的物件 (建議)。處理
Range
或partNumber
請求的最可靠方式是執行以下動作:-
從 Amazon S3 擷取完整物件。
-
轉換物件。
-
將請求的
Range
或partNumber
參數套用至轉換的物件。
為此,請使用提供的預先簽章 URL 從 Amazon S3 擷取整個物件,然後根據需要處理物件。如需以這種方式處理
Range
參數的 Lambda 函數範例,請參閱範例 GitHub 儲存庫中 AWS 的此範例。 -
-
將請求的
Range
映射到預先簽署的 URL。在某些情況下,Lambda 函數可以將請求的
Range
直接映射到預先簽署的 URL,以便從 Amazon S3 中僅擷取部分物件。只有當轉換符合以下兩個條件時,此方法才適用:-
轉換函數可套用於部分物件範圍。
-
在轉換函數之前或之後套用
Range
參數,將會產生相同的轉換物件。
例如,將 ASCII 編碼物件中的所有字元轉換為大寫的轉換函數滿足上述兩個條件。轉換可套用至物件的一部分,而且在轉換前與轉換後套用
Range
參數的結果相同。相比之下,將 ASCII 編碼物件中的字元反轉的函數不符合這些條件。這類函數滿足標準 1,因為其可以套用於部分物件範圍。但不符合標準 2,因為在轉換前套用
Range
參數與轉換後套用參數的結果不同。請考慮以下請求:將函數套用至包含內容
abcdefg
之物件的前三個字元。在轉換前套用Range
參數會僅擷取abc
,接著反轉資料,傳回cba
。但是,如果在轉換之後套用參數,函數將擷取整個物件,將其反轉,然後套用Range
參數,最終傳回gfe
。因為這些結果都不同,所以此函數不應在從 Amazon S3 擷取物件時套用Range
參數。其反而應該擷取整個物件、執行轉換,然後才套用Range
參數。警告
在許多情況下,將
Range
參數套用至預先簽署的 URL,將導致 Lambda 函數或請求用戶端的發生意外行為。如前文方法 A 中所述,除非確定應用程式在從 Amazon S3 中僅擷取部分物件時能夠正常工作,否則建議您擷取和轉換完整物件。如果您的應用程式符合方法 B 先前所述的準則,您可以透過僅擷取要求的物件範圍,然後在該範圍上執行轉換,以簡化 AWS Lambda 函數。
下列 Java 程式碼範例會示範如何執行下列動作:
-
從
GetObject
請求中擷取Range
標頭。 -
將
Range
標頭新增至 Lambda 可以用來從 Amazon S3 擷取請求範圍的預先簽章 URL。
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; }
-