使用 Range 和 partNumber 標頭 - Amazon Simple Storage Service

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 Range 和 partNumber 標頭

使用 Amazon S3 物件 Lambda 中的大型物件時,您可以使用RangeHTTP標頭從物件下載指定的位元組範圍。若要從同一物件內擷取不同的位元組範圍,您可以對 Amazon S3 使用並行連線。您還可以指定 partNumber 參數 (1 到 10,000 之間的整數),其會針對物件的指定部分執行範圍請求。

因為您可能需要多種方法來處理包含 Range 或者 partNumber 參數的請求,而 S3 Object Lambda 不會將這些參數套用至轉換的物件。相反,您的 AWS Lambda 函數必須根據應用程序的需要實現此功能。

若要搭配 S3 Object Lambda 使用 RangepartNumber 參數,請執行下列動作:

  • 在 Object Lambda 存取點組態中啟用這些參數。

  • 撰寫一個 Lambda 函數,其可以處理包含這些參數的請求。

下列步驟說明如何完成這項操作。

步驟 1:設定 Object Lambda 存取點

依預設,物件 Lambda 存取點會在標頭GetObjectHeadObject查詢參數中回應任何包含RangepartNumber參數的HTTP狀態碼 501 (未實作) 錯誤。

若要啟用 Object Lambda 存取點以接受此類請求,您必須在 Object Lambda 存取點組態的 AllowedFeatures 區段中包括 GetObject-RangeGetObject-PartNumberHeadObject-Range 或 HeadObject-PartNumber。如需更新 Object Lambda 存取點組態的詳細資訊,請參閱 建立 Object Lambda 存取點

步驟 2:在 Lambda 函數中實作 RangepartNumber 處理

當 Object Lambda 存取點使用範圍 GetObjectHeadObject 請求叫用 Lambda 函數時,RangepartNumber 參數會包含在事件內容中。如下表所述,參數在事件內容中的位置,取決於使用的參數以及將其包含在對 Object Lambda 存取點的原始請求中的方式。

參數 事件內容位置

Range (標頭)

userRequest.headers.Range

Range (查詢參數)

userRequest.url (查詢參數 Range)

partNumber

userRequest.url (查詢參數 partNumber)

重要

URL為您的物件 Lambda 存取點提供的預先簽署不包含來自原始請求的RangepartNumber參數。請參閱以下有關如何在 AWS Lambda 函數中處理這些參數的選項。

在擷取 RangepartNumber 值後,您可以根據應用程式的需求採取下列其中一種方法:

  1. 將請求的 RangepartNumber 映射到轉換的物件 (建議)。

    處理 RangepartNumber 請求的最可靠方式是執行以下動作:

    • 從 Amazon S3 擷取完整物件。

    • 轉換物件。

    • 將請求的 RangepartNumber 參數套用至轉換的物件。

    若要這麼做,請使用提供的預先簽署URL從 Amazon S3 擷取整個物件,然後視需要處理物件。如需以這種方式處理Range參數的 Lambda 函數範例,請參閱範例 GitHub 儲存庫中 AWS 的此範例。

  2. Range將請求映射到預先簽名URL。

    在某些情況下,您的 Lambda 函數可以將請求Range直接對應到預先簽署,以URL便僅從 Amazon S3 擷取部分物件。只有當轉換符合以下兩個條件時,此方法才適用:

    1. 轉換函數可套用於部分物件範圍。

    2. 在轉換函數之前或之後套用 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頭新增至預先簽署URL,Lambda 可用來從 Amazon S3 擷取請求的範圍。

    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; }