为 Amazon S3 Object Lambda 访问点编写和调试 Amazon Lambda 函数 - Amazon Simple Storage Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

为 Amazon S3 Object Lambda 访问点编写和调试 Amazon Lambda 函数

本节详细介绍如何编写和调试与 S3 Object Lambda 访问点结合使用的 Lambda 函数。

使用 WriteGetObjectResponse

S3 Object Lambda 包括一项新的 Amazon S3 API 操作 WriteGetObjectResponse,它可以让 Lambda 函数向 GetObject 发起人提供自定义数据和响应标头。WriteGetObjectResponse 根据 Lambda 作者的处理需求,为他们提供对状态代码、响应标头和响应正文的广泛控制。您可以使用 WriteGetObjectResponse 来响应整个变换对象、变换对象的某些部分或其他基于应用程序上下文的响应。以下部分介绍了使用 WriteGetObjectResponse API 操作的独特示例。

  • 示例 1:使用 HTTP 状态代码 403(禁止)进行响应

  • 示例 2: 通过转换后的图像进行响应

  • 示例 3: 流式压缩内容

示例 1:

您可以使用 WriteGetObjectResponse 根据对象的内容使用 HTTP 状态代码 403(禁止)进行响应。

Java

package com.amazon.s3.objectlambda; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.WriteGetObjectResponseRequest; import java.io.ByteArrayInputStream; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class Example1 { public void handleRequest(S3ObjectLambdaEvent event, Context context) throws Exception { AmazonS3 s3Client = AmazonS3Client.builder().build(); // Check to see if the request contains all of the necessary information. // If it does not, send a 4XX response and a custom error code and message. // Otherwise, retrieve the object from S3 and stream it // to the client unchanged. var tokenIsNotPresent = !event.getUserRequest().getHeaders().containsKey("requiredToken"); if (tokenIsNotPresent) { s3Client.writeGetObjectResponse(new WriteGetObjectResponseRequest() .withRequestRoute(event.outputRoute()) .withRequestToken(event.outputToken()) .withStatusCode(403) .withContentLength(0L).withInputStream(new ByteArrayInputStream(new byte[0])) .withErrorCode("MissingRequiredToken") .withErrorMessage("The required token was not present in the request.")); return; } // Prepare the presigned URL for use and make the request to S3. HttpClient httpClient = HttpClient.newBuilder().build(); var presignedResponse = httpClient.send( HttpRequest.newBuilder(new URI(event.inputS3Url())).GET().build(), HttpResponse.BodyHandlers.ofInputStream()); // Stream the original bytes back to the caller. s3Client.writeGetObjectResponse(new WriteGetObjectResponseRequest() .withRequestRoute(event.outputRoute()) .withRequestToken(event.outputToken()) .withInputStream(presignedResponse.body())); } }
Python

import boto3 import requests def handler(event, context): s3 = boto3.client('s3') """ Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request should be delivered and contains a presigned URL in 'inputS3Url' where we can download the requested object from. The 'userRequest' object has information related to the user who made this 'GetObject' request to S3 Object Lambda. """ get_context = event["getObjectContext"] user_request_headers = event["userRequest"]["headers"] route = get_context["outputRoute"] token = get_context["outputToken"] s3_url = get_context["inputS3Url"] # Check for the presence of a 'CustomHeader' header and deny or allow based on that header. is_token_present = "SuperSecretToken" in user_request_headers if is_token_present: # If the user presented our custom 'SuperSecretToken' header, we send the requested object back to the user. response = requests.get(s3_url) s3.write_get_object_response(RequestRoute=route, RequestToken=token, Body=response.content) else: # If the token is not present, we send an error back to the user. s3.write_get_object_response(RequestRoute=route, RequestToken=token, StatusCode=403, ErrorCode="NoSuperSecretTokenFound", ErrorMessage="The request was not secret enough.") # Gracefully exit the Lambda function. return { 'status_code': 200 }
Node.js

const { S3 } = require('aws-sdk'); const axios = require('axios').default; exports.handler = async (event) => { const s3 = new S3(); // Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request // should be delivered and contains a presigned URL in 'inputS3Url' where we can download the requested object from. // The 'userRequest' object has information related to the user who made this 'GetObject' request to S3 Object Lambda. const { userRequest, getObjectContext } = event; const { outputRoute, outputToken, inputS3Url } = getObjectContext; // Check for the presence of a 'CustomHeader' header and deny or allow based on that header. const isTokenPresent = Object .keys(userRequest.headers) .includes("SuperSecretToken"); if (!isTokenPresent) { // If the token is not present, we send an error back to the user. The 'await' in front of the request // indicates that we want to wait for this request to finish sending before moving on. await s3.writeGetObjectResponse({ RequestRoute: outputRoute, RequestToken: outputToken, StatusCode: 403, ErrorCode: "NoSuperSecretTokenFound", ErrorMessage: "The request was not secret enough.", }).promise(); } else { // If the user presented our custom 'SuperSecretToken' header, we send the requested object back to the user. // Again, note the presence of 'await'. const presignedResponse = await axios.get(inputS3Url); await s3.writeGetObjectResponse({ RequestRoute: outputRoute, RequestToken: outputToken, Body: presignedResponse.data, }).promise(); } // Gracefully exit the Lambda function. return { statusCode: 200 }; }

示例 2:

执行图像转换时,您可能会发现需要源对象的所有字节,然后才能开始处理它们。在这种情况下,您的 WriteGetObjectResponse 请求会在一次调用中将整个对象返回给请求的应用程序。

Java

package com.amazon.s3.objectlambda; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.WriteGetObjectResponseRequest; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.awt.Image; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class Example2 { private static final int HEIGHT = 250; private static final int WIDTH = 250; public void handleRequest(S3ObjectLambdaEvent event, Context context) throws Exception { AmazonS3 s3Client = AmazonS3Client.builder().build(); HttpClient httpClient = HttpClient.newBuilder().build(); // Prepare the presigned URL for use and make the request to S3. var presignedResponse = httpClient.send( HttpRequest.newBuilder(new URI(event.inputS3Url())).GET().build(), HttpResponse.BodyHandlers.ofInputStream()); // The entire image is loaded into memory here so that we can resize it. // Once the resizing is completed, we write the bytes into the body // of the WriteGetObjectResponse. var originalImage = ImageIO.read(presignedResponse.body()); var resizingImage = originalImage.getScaledInstance(WIDTH, HEIGHT, Image.SCALE_DEFAULT); var resizedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); resizedImage.createGraphics().drawImage(resizingImage, 0, 0, WIDTH, HEIGHT, null); var baos = new ByteArrayOutputStream(); ImageIO.write(resizedImage, "png", baos); // Stream the bytes back to the caller. s3Client.writeGetObjectResponse(new WriteGetObjectResponseRequest() .withRequestRoute(event.outputRoute()) .withRequestToken(event.outputToken()) .withInputStream(new ByteArrayInputStream(baos.toByteArray()))); } }
Python

import boto3 import requests import io from PIL import Image def handler(event, context): """ Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request should be delivered and has a presigned URL in 'inputS3Url' where we can download the requested object from. The 'userRequest' object has information related to the user who made this 'GetObject' request to S3 Object Lambda. """ get_context = event["getObjectContext"] route = get_context["outputRoute"] token = get_context["outputToken"] s3_url = get_context["inputS3Url"] """ In this case, we're resizing '.png' images that are stored in S3 and are accessible through the presigned URL 'inputS3Url'. """ image_request = requests.get(s3_url) image = Image.open(io.BytesIO(image_request.content)) image.thumbnail((256,256), Image.ANTIALIAS) transformed = io.BytesIO() image.save(transformed, "png") # Send the resized image back to the client. s3 = boto3.client('s3') s3.write_get_object_response(Body=transformed.getvalue(), RequestRoute=route, RequestToken=token) # Gracefully exit the Lambda function. return { 'status_code': 200 }
Node.js

const { S3 } = require('aws-sdk'); const axios = require('axios').default; const sharp = require('sharp'); exports.handler = async (event) => { const s3 = new S3(); // Retrieve the operation context object from event. This object indicates where the WriteGetObjectResponse request // should be delivered and has a presigned URL in 'inputS3Url' where we can download the requested object from. const { getObjectContext } = event; const { outputRoute, outputToken, inputS3Url } = getObjectContext; // In this case, we're resizing '.png' images that are stored in S3 and are accessible through the presigned URL // 'inputS3Url'. const { data } = await axios.get(inputS3Url, { responseType: 'arraybuffer' }); // Resize the image. const resized = await sharp(data) .resize({ width: 256, height: 256 }) .toBuffer(); // Send the resized image back to the client. await s3.writeGetObjectResponse({ RequestRoute: outputRoute, RequestToken: outputToken, Body: resized, }).promise(); // Gracefully exit the Lambda function. return { statusCode: 200 }; }

示例 3:

压缩对象时,压缩数据是以增量方式生成的。因此,您可以使用您的 WriteGetObjectResponse 请求在压缩数据准备就绪后立即返回压缩的数据。如本示例所示,您不需要知道已完成转换的长度。

Java

package com.amazon.s3.objectlambda; import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.WriteGetObjectResponseRequest; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class Example3 { public void handleRequest(S3ObjectLambdaEvent event, Context context) throws Exception { AmazonS3 s3Client = AmazonS3Client.builder().build(); HttpClient httpClient = HttpClient.newBuilder().build(); // Request the original object from S3. var presignedResponse = httpClient.send( HttpRequest.newBuilder(new URI(event.inputS3Url())).GET().build(), HttpResponse.BodyHandlers.ofInputStream()); // Consume the incoming response body from the presigned request, // apply our transformation on that data, and emit the transformed bytes // into the body of the WriteGetObjectResponse request as soon as they're ready. // This example compresses the data from S3, but any processing pertinent // to your application can be performed here. var bodyStream = new GZIPCompressingInputStream(presignedResponse.body()); // Stream the bytes back to the caller. s3Client.writeGetObjectResponse(new WriteGetObjectResponseRequest() .withRequestRoute(event.outputRoute()) .withRequestToken(event.outputToken()) .withInputStream(bodyStream)); } }
Python

import boto3 import requests import zlib from botocore.config import Config """ A helper class to work with content iterators. Takes an interator and compresses the bytes that come from it. It implements 'read' and '__iter__' so that the SDK can stream the response. """ class Compress: def __init__(self, content_iter): self.content = content_iter self.compressed_obj = zlib.compressobj() def read(self, _size): for data in self.__iter__() return data def __iter__(self): while True: data = next(self.content) chunk = self.compressed_obj.compress(data) if not chunk: break yield chunk yield self.compressed_obj.flush() def handler(event, context): """ Setting the 'payload_signing_enabled' property to False allows us to send a streamed response back to the client. in this scenario, a streamed response means that the bytes are not buffered into memory as we're compressing them, but instead are sent straight to the user. """ my_config = Config( region_name='eu-west-1', signature_version='s3v4', s3={ "payload_signing_enabled": False } ) s3 = boto3.client('s3', config=my_config) """ Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request should be delivered and has a presigned URL in 'inputS3Url' where we can download the requested object from. The 'userRequest' object has information related to the user who made this 'GetObject' request to S3 Object Lambda. """ get_context = event["getObjectContext"] route = get_context["outputRoute"] token = get_context["outputToken"] s3_url = get_context["inputS3Url"] # Compress the 'get' request stream. with requests.get(s3_url, stream=True) as r: compressed = Compress(r.iter_content()) # Send the stream back to the client. s3.write_get_object_response(Body=compressed, RequestRoute=route, RequestToken=token, ContentType="text/plain", ContentEncoding="gzip") # Gracefully exit the Lambda function. return {'status_code': 200}
Node.js

const { S3 } = require('aws-sdk'); const axios = require('axios').default; const zlib = require('zlib'); exports.handler = async (event) => { const s3 = new S3(); // Retrieve the operation context object from the event. This object indicates where the WriteGetObjectResponse request // should be delivered and has a presigned URL in 'inputS3Url' where we can download the requested object from. const { getObjectContext } = event; const { outputRoute, outputToken, inputS3Url } = getObjectContext; // Download the object from S3 and process it as a stream, because it might be a huge object and we don't want to // buffer it in memory. Note the use of 'await' because we want to wait for 'writeGetObjectResponse' to finish // before we can exit the Lambda function. await axios({ method: 'GET', url: inputS3Url, responseType: 'stream', }).then( // Gzip the stream. response => response.data.pipe(zlib.createGzip()) ).then( // Finally send the gzip-ed stream back to the client. stream => s3.writeGetObjectResponse({ RequestRoute: outputRoute, RequestToken: outputToken, Body: stream, ContentType: "text/plain", ContentEncoding: "gzip", }).promise() ); // Gracefully exit the Lambda function. return { statusCode: 200 }; }
注意

虽然 S3 Object Lambda 允许使用长达 60 秒的时间通过 WriteGetObjectResponse 请求来将完整响应发送给发起人,但实际可用时间可能会减少。例如,您的 Lambda 函数超时可能少于 60 秒。在其他情况下,发起人可能会有更严格的超时。

要使原始发起人能够收到非 500(内部服务器错误)响应,必须完成 WriteGetObjectResponse 调用。如果 Lambda 函数在异常或其他情况下返回,在调用 WriteGetObjectResponse API 操作之前,原始发起人将收到 500 响应。在完成响应所需的时间内引发的异常将导致截断对发起人的响应。如果 Lambda 函数收到来自 WriteGetObjectResponse API 调用的 200 (OK) 响应,那么即表示原始发起人已经发送了完整的请求。S3 Object Lambda 会忽略 Lambda 函数的响应,无论是否抛出异常。

调用此 API 操作时,Amazon S3 需要事件上下文中的路由和请求令牌。有关更多信息,请参阅事件上下文格式和用法

WriteGetObjectResult 请求与原始发起人连接起来需要这些参数。尽管重试 500 响应始终是合理的,但请注意,由于请求令牌是一个单一用途令牌,后续尝试使用它可能会导致 400 (Bad Request) 响应。虽然使用路由和请求令牌调用 WriteGetObjectResponse 不需要从被调用的 Lambda 函数进行创建,但它必须由同一账户中的身份进行创建。还必须在 Lambda 函数完成执行之前完成调用。

调试 S3 Object Lambda

当 Lambda 函数调用或执行出现问题时,对 S3 Object Lambda 访问点的 GetObject 请求可能会导致新的错误响应。这些错误的格式与标准 Amazon S3 错误的格式相同。有关 S3 Object Lambda 错误的信息,请参阅 Amazon Simple Storage Service API 参考中的 S3 Object Lambda 错误代码列表

有关常规 Lambda 函数调试的更多信息,请参阅 Amazon Lambda 开发人员指南中的监控和排查 Lambda 应用程序故障

有关标准 Amazon S3 错误的信息,请参阅 Amazon Simple Storage Service API 参考中的错误响应

您可以在 Amazon CloudWatch 中为 Object Lambda 访问点启用请求指标。这些指标可用于监控访问点的运行性能。

要获取有关向 Object Lambda 访问点发出的请求的更精细的日志记录,您可以启用 Amazon CloudTrail 数据事件。有关更多信息,请参阅 Amazon CloudTrail 用户指南中的记录数据事件以便跟踪

使用 Range 和 partNumber 标头

使用大型对象时,您可以使用 Range HTTP 标头从对象中下载指定的字节范围。您可以使用到 Amazon S3 的并行连接,从相同对象中提取不同的字节范围。您还可以指定 partNumber 参数(1 到 10000 之间的整数),它能有效地执行对象中指定部分“范围内的”GET 请求。有关更多信息,请参阅 Amazon Simple Storage Service API 参考中的 GetObject 请求语法

由于您可能希望通过多种方法来处理包括 RangepartNumber 参数的请求,S3 Object Lambda 不会将这些参数应用于转换后的对象。相反,您的 Lambda 函数必须根据应用程序的需要实现此功能。

要将 RangepartNumber 参数与 S3 Object Lambda 结合使用,您可以为 Object Lambda 访问点启用这些参数,然后编写一个 Lambda 函数来处理包含这些参数的请求。以下步骤介绍了如何完成此操作。

步骤 1:配置 Object Lambda 访问点

默认情况下,Object Lambda 访问点会对标头或查询参数中包含 RangepartNumber 参数的任何 GetObject 请求响应 HTTP 501(未实施)错误。要使 Object Lambda 访问点能够接受此类请求,您必须通过使用 Amazon Web Services Management Console、Amazon Command Line Interface (Amazon CLI) 或 Amazon 软件开发工具包更新您的 Object Lambda 访问点配置。有关更新 Object Lambda 访问点配置的更多信息,请参阅 创建 Object Lambda 访问点

步骤 2:在 Lambda 函数中实施范围或 partNumber 处理

当您的 Object Lambda 访问点使用范围内的 GetObject 请求调用 Lambda 函数时,RangepartNumber 参数将包含在事件上下文中。如下表所述,参数在事件上下文中的位置取决于使用的参数以及如何将其包含在对 Object Lambda 访问点的原始请求中。

参数 事件上下文位置

Range(标头)

userRequest.headers.Range

Range(查询参数)

userRequest.url(查询参数 Range

partNumber

userRequest.url(查询参数 partNumber

重要

提供的预签名 URL 不包含来自原始请求的 RangepartNumber 参数。如果您只想从 Amazon S3 中检索指定的范围,则必须将参数添加到预签名 URL 中。

在您提取 RangepartNumber 值后,您可以根据应用程序的需求采取以下方法之一:

  1. 将请求的范围或 partNumber 映射到转换后的对象(建议)

    处理 RangepartNumber 请求的最可靠方法是从 S3 中检索完整对象、转换对象,然后将请求的 RangepartNumber 参数应用到转换后的对象。为此,请使用提供的预签名 URL 从 Amazon S3 获取整个对象,然后根据需要处理该对象。对于 Lambda 函数以此方式处理 Range 函数的示例,请参阅 Amazon Samples GitHub 存储库中的此示例

  2. 将请求的范围或 partNumber 映射到预签名的 URL

    在某些情况下,您的 Lambda 函数可以将请求的范围或 partNumber 直接映射到预签名 URL,以便仅从 Amazon S3 中检索部分对象。仅当您的转换符合以下两个条件时,此方法才适用:

    1. 您的转换函数可以应用于部分对象范围。

    2. RangepartNumber 参数对原始对象中的数据作用与转换后的对象中的数据相同。

    例如,将 ASCII 编码对象中的所有字符转换为大写的转换函数符合上述两个条件。转换可以应用于对象的一部分,在转换之前应用 RangepartNumber 参数达到的结果与在转换后应用参数相同。

    相比之下,反转 ASCII 编码对象中的字符的函数不符合这些条件。这样的函数符合标准 1,因为它可以应用于部分对象范围。但是,它不符合标准 2,因为在转换之前应用 Range 参数达到的结果与在转换后应用参数不同。

    例如,考虑请求将函数应用于包含内容 abcdefg 的对象的前三个字符。在转换前应用 Range 参数将仅检索 abc,然后反转数据,从而返回 cba。但是,如果在转换之后应用该参数,则函数将检索整个对象,将其反转,然后应用 Range 参数,以返回 gfe。由于这些结果不同,此函数在从 Amazon S3 中检索对象时不应应用 Range 参数。相反,它应该检索整个对象,执行转换,然后仅应用 Range 参数。

    警告

    在很多情况下,向预签名 URL 应用 RangepartNumber 参数将导致 Lambda 函数或请求客户端的意外行为。除非您确定应用程序在从 Amazon S3 中仅检索部分对象时能够正常工作,否则我们建议您按照前面的方法 A 中所述检索和转换完整对象。

    如果您的应用程序符合前面描述的标准,您可以简化您的 Amazon Lambda 函数,并通过仅获取请求的对象范围然后在该范围内运行转换,来最大限度地降低数据传输成本。

    以下 Java 代码示例演示了如何从 GetObject 请求中检索 Range 标头并将其添加到预签名 URL 中,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; }

事件上下文格式和用法

S3 Object Lambda 提供了在传递给 Lambda 函数的事件中发出的请求的上下文。下面显示了示例请求和字段描述。

{ "xAmzRequestId": "requestId", "getObjectContext": { "inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=<snip>", "outputRoute": "io-use1-001", "outputToken": "OutputToken" }, "configuration": { "accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap", "supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap", "payload": "{}" }, "userRequest": { "url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example", "headers": { "Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com", "Accept-Encoding": "identity", "X-Amz-Content-SHA256": "e3b0c44298fc1example" } }, "userIdentity": { "type": "AssumedRole", "principalId": "principalId", "arn": "arn:aws:sts::111122223333:assumed-role/Admin/example", "accountId": "111122223333", "accessKeyId": "accessKeyId", "sessionContext": { "attributes": { "mfaAuthenticated": "false", "creationDate": "Wed Mar 10 23:41:52 UTC 2021" }, "sessionIssuer": { "type": "Role", "principalId": "principalId", "arn": "arn:aws:iam::111122223333:role/Admin", "accountId": "111122223333", "userName": "Admin" } } }, "protocolVersion": "1.00" }
  • xAmzRequestId – 此请求的 Amazon S3 请求 ID。我们建议您记录此值以帮助调试。

  • getObjectContext – 连接到 Amazon S3 和 S3 Object Lambda 的输入和输出详细信息。

    • inputS3Url – 可用于从 Amazon S3 获取原始对象的预签名 URL。URL 是使用原始发起人的身份进行签名的,使用 URL 时它们的权限将适用。如果 URL 中有签名标头,则 Lambda 函数必须将这些标头包含在对 Amazon S3 的调用中,Host 标头除外。

    • outputRoute – 在 Lambda 函数调用 WriteGetObjectResponse 时添加到 S3 Object Lambda URL 的路由令牌。

    • outputToken – S3 Object Lambda 使用的不透明令牌,用于将 WriteGetObjectResponse 调用与原始发起人相匹配。

  • configuration – 有关 Object Lambda 访问点的配置信息。

    • accessPointArn – 收到此请求的 Object Lambda 访问点的 Amazon Resource Name (ARN)。

    • supportingAccessPointArn – Object Lambda 访问点配置中指定的支持访问点的 ARN。

    • payload – 应用于 Object Lambda 访问点配置的自定义数据。S3 Object Lambda 将此数据视为不透明字符串,因此在使用前可能需要对其进行解码。

  • userRequest – 有关对 S3 Object Lambda 的原始调用的信息。

    • url – S3 Object Lambda 接收的请求的解码 URL,不包括任何与授权相关的查询参数。

    • headers – 字符串到字符串的映射,包含原始调用中的 HTTP 标头及其值,不包括任何与授权相关的标头。如果同一个标头多次出现,会将相同标头的每个实例中的值组合成一个以逗号分隔的列表。此映射中会保留原始标头的大小写。

  • userIdentity – 有关对 S3 Object Lambda 发出调用的身份的详细信息。有关更多信息,请参阅 Amazon CloudTrail 用户指南中的记录数据事件以便跟踪

    • type – 身份的类型。

    • accountId – 身份所属的 Amazon Web Services 账户。

    • userName – 已发出调用的身份的友好名称。

    • principalId – 已发出调用的身份的唯一标识符。

    • arn – 已发出调用的委托人的 ARN。ARN 的最后一个部分包含已发出调用的用户或角色。

    • sessionContext – 如果已使用临时安全证书发出请求,此元素提供有关已为这些证书创建的会话的信息。

    • invokedBy – 发出请求的 Amazon Web Service 的名称,例如 Amazon EC2 Auto Scaling 或 Amazon Elastic Beanstalk。

    • sessionIssuer – 如果已使用临时安全证书发出请求,此元素提供有关证书获取方式的信息。

  • protocolVersion – 提供的上下文的版本 ID。此字段的格式为 {Major Version}.{Minor Version}。次要版本号始终是两位数字。对字段的语义进行任何删除或更改都将导致主要版本冲突,并且需要主动选择加入。Amazon S3 可以随时添加新字段,此时您可能会遇到次要版本冲突。由于软件部署的性质,您可能会同时看到多个次要版本处于使用状态。