使用 Range 以及 partNumber 標頭 - Amazon Simple Storage Service

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

使用 Range 以及 partNumber 標頭

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

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

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

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

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

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

步驟 1:設定 Object Lambda 存取點

根據預設,Object Lambda 存取點會以HTTP狀態碼 501 (未實作) 錯誤回應任何包含 RangepartNumber 參數的 GetObjectHeadObject請求,無論是在標頭或查詢參數中。

若要啟用 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 為 Object Lambda Access Point 提供的預先簽章不包含原始請求中的 RangepartNumber 參數。請參閱下列選項,了解如何在 AWS Lambda 函數中處理這些參數。

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

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

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

    • 從 Amazon S3 擷取完整物件。

    • 轉換物件。

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

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

  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標頭新增至 Lambda 可用來從 URL 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; }