Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Menulis fungsi Lambda untuk Titik Akses S3 Lambda Objek
Bagian ini merinci cara menulis AWS Lambda fungsi untuk digunakan dengan Amazon S3 Object Lambda Access Points.
Untuk mempelajari tentang end-to-end prosedur lengkap untuk beberapa tugas Lambda Objek S3, lihat berikut ini:
Bekerja dengan GetObject
permintaan di Lambda
Bagian ini mengasumsikan bahwa Titik Akses Lambda Objek Anda telah dikonfigurasi untuk memanggil fungsi Lambda GetObject
. S3 Object Lambda mencakup operasi Amazon API S3WriteGetObjectResponse
, yang memungkinkan fungsi Lambda untuk menyediakan data yang disesuaikan dan header respons kepada pemanggil. GetObject
WriteGetObjectResponse
memberikan Anda kontrol ekstensif atas kode status, header respons, dan badan respons, berdasarkan kebutuhan pemrosesan Anda. Anda dapat menggunakan WriteGetObjectResponse
untuk menanggapi dengan seluruh objek yang berubah, bagian dari objek yang berubah, atau tanggapan lain berdasarkan konteks aplikasi Anda. Bagian berikut menunjukkan contoh unik penggunaan WriteGetObjectResponse
API operasi.
-
Contoh 1: Tanggapi dengan kode HTTP status 403 (Terlarang)
-
Contoh 2: Merespons dengan citra yang berubah
-
Contoh 3: Melakukan streaming konten terkompresi
Contoh 1: Tanggapi dengan kode HTTP status 403 (Terlarang)
Anda dapat menggunakan WriteGetObjectResponse
untuk merespons dengan kode HTTP status 403 (Terlarang) berdasarkan konten objek.
- 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 };
}
Contoh 2: Merespons dengan citra yang berubah
Saat melakukan transformasi citra, Anda mungkin memerlukan semua byte objek sumber sebelum Anda dapat mulai memprosesnya. Dalam kasus ini, permintaan WriteGetObjectResponse
Anda akan mengembalikan seluruh objek ke aplikasi permintaan dalam satu panggilan.
- 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 request.
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 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;
// 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 };
}
Contoh 3: Melakukan streaming konten terkompresi
Saat Anda mengompresi objek, data terkompresi dihasilkan secara bertahap. Akibatnya, Anda dapat menggunakan permintaan WriteGetObjectResponse
Anda untuk mengembalikan data terkompresi segera setelah semuanya siap. Seperti yang ditunjukkan dalam contoh ini, Anda tidak perlu mengetahui panjang transformasi yang telah selesai.
- 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 };
}
Meskipun S3 Lambda Objek mengizinkan hingga 60 detik untuk mengirim respons lengkap kepada pemanggil melalui permintaan WriteGetObjectResponse
, jumlah aktual waktu yang tersedia mungkin kurang. Misalnya, batas waktu fungsi Lambda Anda kemungkinan kurang dari 60 detik. Dalam kasus lain, pemanggil mungkin memiliki batas waktu yang lebih ketat.
Agar penelepon asli menerima respons selain kode HTTP status 500 (Kesalahan Server Internal), WriteGetObjectResponse
panggilan harus diselesaikan. Jika fungsi Lambda kembali, dengan pengecualian atau sebaliknya, sebelum WriteGetObjectResponse
API operasi dipanggil, pemanggil asli menerima respons 500 (Kesalahan Server Internal). Pengecualian yang diberikan selama waktu yang diperlukan untuk menyelesaikan respons akan mengakibatkan respons terpotong kepada pemanggil. Jika fungsi Lambda menerima respons kode HTTP status 200 (OK) dari WriteGetObjectResponse
API panggilan, maka pemanggil asli telah mengirim permintaan lengkap. Respon fungsi Lambda, terlepas dari pengecualian diberikan atau tidak, diabaikan oleh S3 Lambda Objek.
Saat memanggil WriteGetObjectResponse
API operasi, Amazon S3 memerlukan rute dan token permintaan dari konteks acara. Untuk informasi selengkapnya, lihat Format konteks peristiwa dan penggunaan.
Parameter rute dan token permintaan diperlukan untuk menghubungkan respons WriteGetObjectResult
dengan pemanggil asli. Meskipun selalu tepat untuk mencoba kembali 500 (Internal Server Error) tanggapan, karena token permintaan adalah token sekali pakai, upaya berikutnya untuk menggunakannya dapat menghasilkan kode HTTP status 400 (Permintaan Buruk) tanggapan. Meskipun panggilan ke WriteGetObjectResponse
dengan rute dan permintaan token tidak perlu dibuat dari fungsi Lambda yang dipanggil, itu harus dibuat oleh identitas di akun yang sama. Panggilan itu juga harus diselesaikan sebelum fungsi Lambda selesai dieksekusi.
Bekerja dengan permintaan HeadObject
di Lambda
Bagian ini mengasumsikan bahwa Titik Akses Lambda Objek Anda telah dikonfigurasi untuk memanggil fungsi Lambda HeadObject
. Lambda akan menerima JSON payload yang berisi kunci yang disebut. headObjectContext
Di dalam konteks, ada satu properti yang disebutinputS3Url
, yang merupakan presigned URL untuk titik akses pendukung untukHeadObject
.
Presigned URL akan mencakup properti berikut jika mereka ditentukan:
-
versionId
(di dalam parameter kueri)
-
requestPayer
(di dalam header x-amz-request-payer
)
-
expectedBucketOwner
(di dalam header x-amz-expected-bucket-owner
)
Properti lain tidak akan ditandatangani sebelumnya, dan karenanya tidak akan disertakan. Opsi yang tidak ditandatangani yang dikirim sebagai header dapat ditambahkan secara manual ke permintaan saat memanggil presigned URL yang ditemukan di header. userRequest
Opsi enkripsi di sisi server tidak didukung untuk HeadObject
.
Untuk URI parameter sintaks permintaan, lihat HeadObject
di APIReferensi Layanan Penyimpanan Sederhana Amazon.
Contoh berikut menunjukkan payload JSON input Lambda untuk. HeadObject
{
"xAmzRequestId": "requestId
",
"**headObjectContext**": {
"**inputS3Url**": "https://my-s3-ap-111122223333
.s3-accesspoint.us-east-1
.amazonaws.com/example?X-Amz-Security-Token=<snip>"
},
"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"
}
Fungsi Lambda Anda harus mengembalikan JSON objek yang berisi header dan nilai yang akan dikembalikan untuk panggilan. HeadObject
Contoh berikut menunjukkan struktur respons JSON Lambda untuk. HeadObject
{
"statusCode": <number>; // Required
"errorCode": <string>;
"errorMessage": <string>;
"headers": {
"Accept-Ranges": <string>,
"x-amz-archive-status": <string>,
"x-amz-server-side-encryption-bucket-key-enabled": <boolean>,
"Cache-Control": <string>,
"Content-Disposition": <string>,
"Content-Encoding": <string>,
"Content-Language": <string>,
"Content-Length": <number>, // Required
"Content-Type": <string>,
"x-amz-delete-marker": <boolean>,
"ETag": <string>,
"Expires": <string>,
"x-amz-expiration": <string>,
"Last-Modified": <string>,
"x-amz-missing-meta": <number>,
"x-amz-object-lock-mode": <string>,
"x-amz-object-lock-legal-hold": <string>,
"x-amz-object-lock-retain-until-date": <string>,
"x-amz-mp-parts-count": <number>,
"x-amz-replication-status": <string>,
"x-amz-request-charged": <string>,
"x-amz-restore": <string>,
"x-amz-server-side-encryption": <string>,
"x-amz-server-side-encryption-customer-algorithm": <string>,
"x-amz-server-side-encryption-aws-kms-key-id": <string>,
"x-amz-server-side-encryption-customer-key-MD5": <string>,
"x-amz-storage-class": <string>,
"x-amz-tagging-count": <number>,
"x-amz-version-id": <string>,
<x-amz-meta-headers>: <string>, // user-defined metadata
"x-amz-meta-meta1": <string>, // example of the user-defined metadata header, it will need the x-amz-meta prefix
"x-amz-meta-meta2": <string>
...
};
}
Contoh berikut menunjukkan cara menggunakan presigned URL untuk mengisi respons Anda dengan memodifikasi nilai header sesuai kebutuhan sebelum mengembalikan. JSON
- Python
-
import requests
def lambda_handler(event, context):
print(event)
# Extract the presigned URL from the input.
s3_url = event["headObjectContext"]["inputS3Url"]
# Get the head of the object from S3.
response = requests.head(s3_url)
# Return the error to S3 Object Lambda (if applicable).
if (response.status_code >= 400):
return {
"statusCode": response.status_code,
"errorCode": "RequestFailure",
"errorMessage": "Request to S3 failed"
}
# Store the headers in a dictionary.
response_headers = dict(response.headers)
# This obscures Content-Type in a transformation, it is optional to add
response_headers["Content-Type"] = ""
# Return the headers to S3 Object Lambda.
return {
"statusCode": response.status_code,
"headers": response_headers
}
Bekerja dengan permintaan ListObjects
di Lambda
Bagian ini mengasumsikan bahwa Titik Akses Lambda Objek Anda telah dikonfigurasi untuk memanggil fungsi Lambda ListObjects
. Lambda akan menerima JSON payload dengan objek baru bernama. listObjectsContext
listObjectsContext
berisi properti tunggal,inputS3Url
, yang merupakan presigned URL untuk jalur akses pendukung untukListObjects
.
Tidak seperti GetObject
danHeadObject
, presigned URL akan menyertakan properti berikut jika ditentukan:
Untuk URI parameter sintaks permintaan, lihat ListObjects
di APIReferensi Layanan Penyimpanan Sederhana Amazon.
Kami menyarankan Anda menggunakan versi yang lebih baru, ListObjectsV2, saat mengembangkan aplikasi. Untuk kompatibilitas mundur, Amazon S3 terus mendukung ListObjects
.
Contoh berikut menunjukkan payload JSON input Lambda untuk. ListObjects
{
"xAmzRequestId": "requestId
",
"**listObjectsContext**": {
"**inputS3Url**": "https://my-s3-ap-111122223333
.s3-accesspoint.us-east-1
.amazonaws.com/?X-Amz-Security-Token=<snip>",
},
"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"
}
Fungsi Lambda Anda harus mengembalikan JSON objek yang berisi kode status, XML hasil daftar, atau informasi kesalahan yang akan dikembalikan dari S3 Object Lambda.
S3 Lambda Objek tidak memproses atau memvalidasi listResultXml
, melainkan meneruskannya ke pemanggil ListObjects
. Untuk listBucketResult
, S3 Lambda Objek mengharapkan properti tertentu memiliki jenis tertentu dan akan memunculkan pengecualian jika tidak dapat menguraikannya. listResultXml
dan listBucketResult
tidak dapat diberikan secara bersamaan.
Contoh berikut menunjukkan cara menggunakan presigned URL untuk memanggil Amazon S3 dan menggunakan hasilnya untuk mengisi respons, termasuk pemeriksaan kesalahan.
- Python
-
import requests
import xmltodict
def lambda_handler(event, context):
# Extract the presigned URL from the input.
s3_url = event["listObjectsContext"]["inputS3Url"]
# Get the head of the object from Amazon S3.
response = requests.get(s3_url)
# Return the error to S3 Object Lambda (if applicable).
if (response.status_code >= 400):
error = xmltodict.parse(response.content)
return {
"statusCode": response.status_code,
"errorCode": error["Error"]["Code"],
"errorMessage": error["Error"]["Message"]
}
# Store the XML result in a dict.
response_dict = xmltodict.parse(response.content)
# This obscures StorageClass in a transformation, it is optional to add
for item in response_dict['ListBucketResult']['Contents']:
item['StorageClass'] = ""
# Convert back to XML.
listResultXml = xmltodict.unparse(response_dict)
# Create response with listResultXml.
response_with_list_result_xml = {
'statusCode': 200,
'listResultXml': listResultXml
}
# Create response with listBucketResult.
response_dict['ListBucketResult'] = sanitize_response_dict(response_dict['ListBucketResult'])
response_with_list_bucket_result = {
'statusCode': 200,
'listBucketResult': response_dict['ListBucketResult']
}
# Return the list to S3 Object Lambda.
# Can return response_with_list_result_xml or response_with_list_bucket_result
return response_with_list_result_xml
# Converting the response_dict's key to correct casing
def sanitize_response_dict(response_dict: dict):
new_response_dict = dict()
for key, value in response_dict.items():
new_key = key[0].lower() + key[1:] if key != "ID" else 'id'
if type(value) == list:
newlist = []
for element in value:
if type(element) == type(dict()):
element = sanitize_response_dict(element)
newlist.append(element)
value = newlist
elif type(value) == dict:
value = sanitize_response_dict(value)
new_response_dict[new_key] = value
return new_response_dict
Contoh berikut menunjukkan struktur respons JSON Lambda untuk. ListObjects
{
"statusCode": <number>; // Required
"errorCode": <string>;
"errorMessage": <string>;
"listResultXml": <string>; // This can also be Error XML string in case S3 returned error response when calling the pre-signed URL
"listBucketResult": { // listBucketResult can be provided instead of listResultXml, however they can not both be provided in the JSON response
"name": <string>, // Required for 'listBucketResult'
"prefix": <string>,
"marker": <string>,
"nextMarker": <string>,
"maxKeys": <int>, // Required for 'listBucketResult'
"delimiter": <string>,
"encodingType": <string>
"isTruncated": <boolean>, // Required for 'listBucketResult'
"contents": [ {
"key": <string>, // Required for 'content'
"lastModified": <string>,
"eTag": <string>,
"checksumAlgorithm": <string>, // CRC32, CRC32C, SHA1, SHA256
"size": <int>, // Required for 'content'
"owner": {
"displayName": <string>, // Required for 'owner'
"id": <string>, // Required for 'owner'
},
"storageClass": <string>
},
...
],
"commonPrefixes": [ {
"prefix": <string> // Required for 'commonPrefix'
},
...
],
}
}
Bekerja dengan permintaan ListObjectsV2
di Lambda
Bagian ini mengasumsikan bahwa Titik Akses Lambda Objek Anda telah dikonfigurasi untuk memanggil fungsi Lambda ListObjectsV2
. Lambda akan menerima JSON payload dengan objek baru bernama. listObjectsV2Context
listObjectsV2Context
berisi properti tunggal,inputS3Url
, yang merupakan presigned URL untuk jalur akses pendukung untukListObjectsV2
.
Tidak seperti GetObject
danHeadObject
, presigned URL akan menyertakan properti berikut, jika mereka ditentukan:
Untuk URI parameter sintaks permintaan, lihat ListObjectsV2
di APIReferensi Layanan Penyimpanan Sederhana Amazon.
Contoh berikut menunjukkan payload JSON input Lambda untuk. ListObjectsV2
{
"xAmzRequestId": "requestId
",
"**listObjectsV2Context**": {
"**inputS3Url**": "https://my-s3-ap-111122223333
.s3-accesspoint.us-east-1
.amazonaws.com/?list-type=2&X-Amz-Security-Token=<snip>",
},
"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"
}
Fungsi Lambda Anda harus mengembalikan JSON objek yang berisi kode status, XML hasil daftar, atau informasi kesalahan yang akan dikembalikan dari S3 Object Lambda.
S3 Lambda Objek tidak memproses atau memvalidasi listResultXml
, melainkan meneruskannya ke pemanggil ListObjectsV2
. Untuk listBucketResult
, S3 Lambda Objek mengharapkan properti tertentu memiliki jenis tertentu dan akan memunculkan pengecualian jika tidak dapat menguraikannya. listResultXml
dan listBucketResult
tidak dapat diberikan secara bersamaan.
Contoh berikut menunjukkan cara menggunakan presigned URL untuk memanggil Amazon S3 dan menggunakan hasilnya untuk mengisi respons, termasuk pemeriksaan kesalahan.
- Python
-
import requests
import xmltodict
def lambda_handler(event, context):
# Extract the presigned URL from the input.
s3_url = event["listObjectsV2Context"]["inputS3Url"]
# Get the head of the object from Amazon S3.
response = requests.get(s3_url)
# Return the error to S3 Object Lambda (if applicable).
if (response.status_code >= 400):
error = xmltodict.parse(response.content)
return {
"statusCode": response.status_code,
"errorCode": error["Error"]["Code"],
"errorMessage": error["Error"]["Message"]
}
# Store the XML result in a dict.
response_dict = xmltodict.parse(response.content)
# This obscures StorageClass in a transformation, it is optional to add
for item in response_dict['ListBucketResult']['Contents']:
item['StorageClass'] = ""
# Convert back to XML.
listResultXml = xmltodict.unparse(response_dict)
# Create response with listResultXml.
response_with_list_result_xml = {
'statusCode': 200,
'listResultXml': listResultXml
}
# Create response with listBucketResult.
response_dict['ListBucketResult'] = sanitize_response_dict(response_dict['ListBucketResult'])
response_with_list_bucket_result = {
'statusCode': 200,
'listBucketResult': response_dict['ListBucketResult']
}
# Return the list to S3 Object Lambda.
# Can return response_with_list_result_xml or response_with_list_bucket_result
return response_with_list_result_xml
# Converting the response_dict's key to correct casing
def sanitize_response_dict(response_dict: dict):
new_response_dict = dict()
for key, value in response_dict.items():
new_key = key[0].lower() + key[1:] if key != "ID" else 'id'
if type(value) == list:
newlist = []
for element in value:
if type(element) == type(dict()):
element = sanitize_response_dict(element)
newlist.append(element)
value = newlist
elif type(value) == dict:
value = sanitize_response_dict(value)
new_response_dict[new_key] = value
return new_response_dict
Contoh berikut menunjukkan struktur respons JSON Lambda untuk. ListObjectsV2
{
"statusCode": <number>; // Required
"errorCode": <string>;
"errorMessage": <string>;
"listResultXml": <string>; // This can also be Error XML string in case S3 returned error response when calling the pre-signed URL
"listBucketResult": { // listBucketResult can be provided instead of listResultXml, however they can not both be provided in the JSON response
"name": <string>, // Required for 'listBucketResult'
"prefix": <string>,
"startAfter": <string>,
"continuationToken": <string>,
"nextContinuationToken": <string>,
"keyCount": <int>, // Required for 'listBucketResult'
"maxKeys": <int>, // Required for 'listBucketResult'
"delimiter": <string>,
"encodingType": <string>
"isTruncated": <boolean>, // Required for 'listBucketResult'
"contents": [ {
"key": <string>, // Required for 'content'
"lastModified": <string>,
"eTag": <string>,
"checksumAlgorithm": <string>, // CRC32, CRC32C, SHA1, SHA256
"size": <int>, // Required for 'content'
"owner": {
"displayName": <string>, // Required for 'owner'
"id": <string>, // Required for 'owner'
},
"storageClass": <string>
},
...
],
"commonPrefixes": [ {
"prefix": <string> // Required for 'commonPrefix'
},
...
],
}
}