

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Schreiben von Lambda-Funktionen für S3 Object Lambda Access Points
<a name="olap-writing-lambda"></a>

**Anmerkung**  
Seit dem 7. November 2025 ist S3 Object Lambda nur für Bestandskunden verfügbar, die den Service derzeit nutzen, sowie für ausgewählte AWS Partner Network (APN) -Partner. Weitere Informationen zu Features, die S3 Object Lambda ähneln, finden Sie hier – Änderung der [Verfügbarkeit von Amazon S3 Object Lambda](https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazons3-ol-change.html).

In diesem Abschnitt wird beschrieben, wie AWS Lambda Funktionen für die Verwendung mit Amazon S3 Object Lambda Access Points geschrieben werden.

Informationen zu den vollständigen end-to-end Verfahren für einige S3 Object Lambda-Aufgaben finden Sie im Folgenden:
+ [Tutorial: Transformieren von Daten für Ihre Anwendung mit S3 Object Lambda](tutorial-s3-object-lambda-uppercase.md)
+ [Tutorial: Erkennen und Redigieren von PII-Daten mit S3 Object Lambda und Amazon Comprehend](tutorial-s3-object-lambda-redact-pii.md)
+ [Tutorial: Verwenden von S3 Object Lambda, um Bilder beim Abrufen dynamisch mit Wasserzeichen zu versehen](https://aws.amazon.com/getting-started/hands-on/amazon-s3-object-lambda-to-dynamically-watermark-images/?ref=docs_gateway/amazons3/olap-writing-lambda.html)

**Topics**
+ [Arbeiten mit `GetObject`-Anforderungen in Lambda](#olap-getobject-response)
+ [Arbeiten mit `HeadObject`-Anforderungen in Lambda](#olap-headobject)
+ [Arbeiten mit `ListObjects`-Anforderungen in Lambda](#olap-listobjects)
+ [Arbeiten mit `ListObjectsV2`-Anforderungen in Lambda](#olap-listobjectsv2)
+ [Format und Verwendung des Ereigniskontexts](olap-event-context.md)
+ [Arbeiten mit Range- und partNumber-Headern](range-get-olap.md)

## Arbeiten mit `GetObject`-Anforderungen in Lambda
<a name="olap-getobject-response"></a>

In diesem Abschnitt wird davon ausgegangen, dass Ihr Object Lambda Access Point für den Aufruf der Lambda-Funktion für `GetObject` konfiguriert ist. S3 Objekt Lambda enthält die Amazon-S3-API-Operation `WriteGetObjectResponse`, mit der die Lambda-Funktion dem `GetObject`-Aufrufer benutzerdefinierte Daten und Antwort-Header bereitstellen kann. 

`WriteGetObjectResponse` bietet Ihnen eine umfassende Kontrolle über den Statuscode, die Antwort-Header und den Antworttext, basierend auf Ihren Verarbeitungsanforderungen. Sie können `WriteGetObjectResponse` verwenden, um mit dem gesamten transformierten Objekt, Teilen des transformierten Objekts oder anderen Antworten basierend auf dem Kontext Ihrer Anwendung zu antworten. Der folgende Abschnitt zeigt eindeutige Beispiele für die Verwendung des `WriteGetObjectResponse`-API-Vorgangs.
+ **Beispiel 1:** Mit einem HTTP-Statuscode 403 (Forbidden) antworten 
+ **Beispiel 2:** Reagieren Sie mit einem transformierten Bild
+ **Beispiel 3:** Komprimierte Inhalte streamen

**Beispiel 1: Mit einem HTTP-Statuscode 403 (Forbidden) antworten **

Sie können `WriteGetObjectResponse` verwenden, um basierend auf dem Inhalt des Objekts mit dem HTTP-Statuscode 403 (Forbidden) zu antworten.

------
#### [ Java ]



```
package com.amazon.s3.objectlambda;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.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 {
        S3Client s3Client = S3Client.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(WriteGetObjectResponseRequest.builder()
                    .requestRoute(event.outputRoute())
                    .requestToken(event.outputToken())
                    .statusCode(403)
                    .contentLength(0L)
                    .errorCode("MissingRequiredToken")
                    .errorMessage("The required token was not present in the request.")
                    .build(),
                    RequestBody.fromInputStream(new ByteArrayInputStream(new byte[0]), 0L));
            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(WriteGetObjectResponseRequest.builder()
                .requestRoute(event.outputRoute())
                .requestToken(event.outputToken())
                .build(),
                RequestBody.fromInputStream(presignedResponse.body(),
                    presignedResponse.headers().firstValueAsLong("content-length").orElse(-1L)));
    }
}
```

------
#### [ 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 };
}
```

------

**Beispiel 2:** Reagieren Sie mit einem transformierten Bild

Wenn Sie eine Bildtransformation durchführen, stellen Sie möglicherweise fest, dass Sie alle Bytes des Quellobjekts benötigen, bevor Sie mit der Verarbeitung beginnen können. In diesem Fall gibt Ihre `WriteGetObjectResponse`-Anforderung das gesamte Objekt in einem Aufruf an die anfragende Anwendung zurück.

------
#### [ Java ]



```
package com.amazon.s3.objectlambda;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.WriteGetObjectResponseRequest;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Image;
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 Example2V2 {

    private static final int HEIGHT = 250;
    private static final int WIDTH = 250;

    public void handleRequest(S3ObjectLambdaEvent event, Context context) throws Exception {
        S3Client s3Client = S3Client.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(WriteGetObjectResponseRequest.builder()
                .requestRoute(event.outputRoute())
                .requestToken(event.outputToken())
                .build(), RequestBody.fromBytes(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 };
}
```

------

**Beispiel 3:** Komprimierte Inhalte streamen

Beim Komprimieren von Objekten werden komprimierte Daten inkrementell erzeugt. Folglich können Sie Ihre `WriteGetObjectResponse`-Anforderung verwenden, um die komprimierten Daten zurückzugeben, sobald sie bereit sind. Wie in diesem Beispiel gezeigt, ist es nicht notwendig, die Länge der abgeschlossenen Transformation zu kennen.

------
#### [ Java ]



```
package com.amazon.s3.objectlambda;

import com.amazonaws.services.lambda.runtime.events.S3ObjectLambdaEvent;
import com.amazonaws.services.lambda.runtime.Context;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.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 {
        S3Client s3Client = S3Client.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(WriteGetObjectResponseRequest.builder()
                .requestRoute(event.outputRoute())
                .requestToken(event.outputToken())
                .build(),
                RequestBody.fromInputStream(bodyStream,
                    presignedResponse.headers().firstValueAsLong("content-length").orElse(-1L)));
    }
}
```

------
#### [ 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 };
}
```

------

**Anmerkung**  
Obwohl S3 Object Lambda ermöglicht, bis zu 60 Sekunden eine vollständige Antwort an den Aufrufer über die `WriteGetObjectResponse`-Anforderung zu senden, ist die tatsächlich verfügbare Zeit möglicherweise geringer. Zum Beispiel kann Ihr Timeout für Lambda-Funktionen weniger als 60 Sekunden betragen. In anderen Fällen kann der Aufrufer strengere Zeitbeschränkungen haben. 

Damit der ursprüngliche Aufrufer eine andere Antwort als einen HTTP-Statuscode 500 (Interner Serverfehler) erhält, muss der `WriteGetObjectResponse`-Aufruf abgeschlossen sein. Wenn die Lambda-Funktion mit einer Ausnahme oder anderweitig Ergebnisse zurückgibt, bevor die API-Operation `WriteGetObjectResponse` aufgerufen wird, erhält der ursprüngliche Aufrufer eine 500-Antwort (Interner Serverfehler). Ausnahmen, die während der Zeit ausgelöst werden, die zum Abschließen der Antwort benötigt wird, führen zu verkürzten Antworten an den Aufrufer. Wenn die Lambda-Funktion eine HTTP-Statuscode 200 (OK)-Antwort vom `WriteGetObjectResponse`-API-Aufruf erhält, hat der ursprüngliche Aufrufer die vollständige Anforderung gesendet. Die Antwort der Lambda-Funktion, wird von S3 Object Lambda, unabhängig davon, ob eine Ausnahme ausgelöst wird oder nicht, ignoriert.

Beim Aufruf der API-Operation `WriteGetObjectResponse` benötigt Amazon S3 den Routen- und Anforderungstoken aus dem Ereigniskontext. Weitere Informationen finden Sie unter [Format und Verwendung des Ereigniskontexts](olap-event-context.md).

Die Routen- und Anforderungstokenparameter sind erforderlich, um die `WriteGetObjectResult`-Antwort mit dem ursprünglichen Aufrufer zu verbinden. Obwohl es immer angemessen ist, 500-Antworten (Interner Serverfehler) zu wiederholen, beachten Sie, dass es sich bei dem Anforderungstoken um ein einmaliges Verwendungstoken handelt und nachfolgende Verwendungsversuche zu HTTP-Statuscode 400 (Bad Request)-Antworten führen können. Obwohl der Aufruf an `WriteGetObjectResponse` mit den Routen- und Anforderungstoken nicht von der aufgerufenen Lambda-Funktion erfolgen muss, ist hierfür eine Identität im selben Konto erforderlich. Der Aufruf muss außerdem abgeschlossen sein, bevor die Lambda-Funktion die Ausführung beendet.

## Arbeiten mit `HeadObject`-Anforderungen in Lambda
<a name="olap-headobject"></a>

In diesem Abschnitt wird davon ausgegangen, dass Ihr Object Lambda Access Point für den Aufruf der Lambda-Funktion für `HeadObject` konfiguriert ist. Lambda erhält eine JSON-Nutzlast, die einen Schlüssel namens `headObjectContext` enthält. Innerhalb des Kontexts gibt es eine einzelne Eigenschaft namens `inputS3Url`, bei der es sich um eine vorsignierte URL für den unterstützenden Zugriffspunkt für `HeadObject` handelt.

Die vorsignierte URL enthält die folgenden Eigenschaften, wenn sie angegeben sind: 
+ `versionId` (in den Abfrageparametern)
+ `requestPayer` (im `x-amz-request-payer`-Header)
+ `expectedBucketOwner` (im `x-amz-expected-bucket-owner`-Header)

Andere Eigenschaften werden nicht vorsigniert und daher nicht berücksichtigt. Nicht signierte Optionen, die als Header gesendet werden, können manuell zur Anforderung hinzugefügt werden, wenn die vorsignierte URL aufgerufen wird, die sich in den `userRequest`-Headern befindet. Serverseitige Verschlüsselungsoptionen werden für `HeadObject` nicht unterstützt.

Informationen zu den URI-Parametern der Anforderungssyntax finden Sie unter [https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html) in der *API-Referenz für Amazon Simple Storage Service*.

Das folgende Beispiel zeigt eine Lambda-JSON-Eingabe-Nutzlast für `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"
}
```

Ihre Lambda-Funktion sollte ein JSON-Objekt zurückgeben, das die Header und Werte enthält, die für den `HeadObject`-Aufruf zurückgegeben werden.

Das folgende Beispiel zeigt die Struktur der JSON-Nachricht der Lambda-Antwort für `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>
        ...
    };
}
```

Das folgende Beispiel zeigt, wie Sie die vorsignierte URL verwenden, um Ihre Antwort aufzufüllen, indem Sie die Header-Werte nach Bedarf ändern, bevor das JSON-Objekt zurückgegeben wird.

------
#### [ 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     
        }
```

------

## Arbeiten mit `ListObjects`-Anforderungen in Lambda
<a name="olap-listobjects"></a>

In diesem Abschnitt wird davon ausgegangen, dass Ihr Object Lambda Access Point für den Aufruf der Lambda-Funktion für `ListObjects` konfiguriert ist. Lambda erhält die JSON-Nutzlast mit einem neuen Objekt namens `listObjectsContext`. `listObjectsContext` enthält eine einzelne Eigenschaft, `inputS3Url`, bei der es sich um eine vorsignierte URL für den unterstützenden Zugriffspunkt `ListObjects` handelt.

Im Gegensatz zu `GetObject` und `HeadObject` enthält die vorsignierte URL die folgenden Eigenschaften, wenn sie angegeben sind:
+ Alle Abfrageparameter
+ `requestPayer` (im `x-amz-request-payer`-Header) 
+ `expectedBucketOwner` (im `x-amz-expected-bucket-owner`-Header)

Informationen zu den URI-Parametern der Anforderungssyntax finden Sie unter [https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) in der *API-Referenz für Amazon Simple Storage Service*.

**Wichtig**  
Wir empfehlen, bei der Entwicklung von Anwendungen die neuere Version [ListObjectsV2](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) zu verwenden. Aus Gründen der Abwärtskompatibilität unterstützt Amazon S3 weiterhin `ListObjects`.

Das folgende Beispiel zeigt die Lambda-JSON-Eingabe-Nutzlast für `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"
}
```

Ihre Lambda-Funktion sollte ein JSON-Objekt zurückgeben, das den Statuscode, das Listen-XML-Ergebnis oder die Fehlerinformationen enthält, die von S3 Object Lambda zurückgegeben werden.

S3 Object Lambda verarbeitet oder validiert `listResultXml` nicht, sondern leitet es an den `ListObjects`-Aufrufer weiter. Für `listBucketResult` erwartet S3 Object Lambda, dass bestimmte Eigenschaften von einem speziellen Typ sind, und löst Ausnahmen aus, wenn es sie nicht analysieren kann. `listResultXml` und `listBucketResult` können nicht gleichzeitig bereitgestellt werden.

Das folgende Beispiel zeigt, wie die vorsignierte URL verwendet wird, um Amazon S3 aufzurufen und das Ergebnis zum Auffüllen einer Antwort einschließlich der Fehlerprüfung zu nutzen.

------
#### [ 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
```

------

Das folgende Beispiel zeigt die Struktur der JSON-Nachricht der Lambda-Antwort für `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'
        },  
        ...  
        ],  
    }
}
```

## Arbeiten mit `ListObjectsV2`-Anforderungen in Lambda
<a name="olap-listobjectsv2"></a>

In diesem Abschnitt wird davon ausgegangen, dass Ihr Object Lambda Access Point für den Aufruf der Lambda-Funktion für `ListObjectsV2` konfiguriert ist. Lambda erhält die JSON-Nutzlast mit einem neuen Objekt namens `listObjectsV2Context`. `listObjectsV2Context` enthält eine einzelne Eigenschaft, `inputS3Url`, bei der es sich um eine vorsignierte URL für den unterstützenden Zugriffspunkt `ListObjectsV2` handelt.

Im Gegensatz zu `GetObject` und `HeadObject` enthält die vorsignierte URL die folgenden Eigenschaften, wenn sie angegeben sind: 
+ Alle Abfrageparameter
+ `requestPayer` (im `x-amz-request-payer`-Header) 
+ `expectedBucketOwner` (im `x-amz-expected-bucket-owner`-Header)

Informationen zu den URI-Parametern der Anforderungssyntax finden Sie unter [https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html) in der *API-Referenz für Amazon Simple Storage Service*.

Das folgende Beispiel zeigt die Lambda-JSON-Eingabe-Nutzlast für `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" 
}
```

Ihre Lambda-Funktion sollte ein JSON-Objekt zurückgeben, das den Statuscode, das Listen-XML-Ergebnis oder die Fehlerinformationen enthält, die von S3 Object Lambda zurückgegeben werden.

S3 Object Lambda verarbeitet oder validiert `listResultXml` nicht, sondern leitet es an den `ListObjectsV2`-Aufrufer weiter. Für `listBucketResult` erwartet S3 Object Lambda, dass bestimmte Eigenschaften von einem speziellen Typ sind, und löst Ausnahmen aus, wenn es sie nicht analysieren kann. `listResultXml` und `listBucketResult` können nicht gleichzeitig bereitgestellt werden.

Das folgende Beispiel zeigt, wie die vorsignierte URL verwendet wird, um Amazon S3 aufzurufen und das Ergebnis zum Auffüllen einer Antwort einschließlich der Fehlerprüfung zu nutzen.

------
#### [ 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
```

------

Das folgende Beispiel zeigt die Struktur der JSON-Nachricht der Lambda-Antwort für `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'  
            },  
        ...  
        ],  
    }  
}
```

# Format und Verwendung des Ereigniskontexts
<a name="olap-event-context"></a>

**Anmerkung**  
Seit dem 7. November 2025 ist S3 Object Lambda nur für Bestandskunden verfügbar, die den Service derzeit nutzen, sowie für ausgewählte AWS Partner Network (APN) -Partner. Weitere Informationen zu Features, die S3 Object Lambda ähneln, finden Sie hier – Änderung der [Verfügbarkeit von Amazon S3 Object Lambda](https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazons3-ol-change.html).

Amazon S3 Object Lambda bietet Kontext zu der Anfrage, die in dem Ereignis gestellt wird, das an Ihre AWS Lambda Funktion übergeben wird. Nachstehend finden Sie eine Beispielanforderung: Beschreibungen der Felder folgen nach dem Beispiel.

```
{
    "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"
}
```

Die folgenden Felder sind in der Anforderung enthalten:
+ `xAmzRequestId` – Die Amazon-S3-Anforderungs-ID für diese Anforderung. Wir empfehlen, diesen Wert zu protokollieren, um beim Debuggen zu helfen.
+ `getObjectContext` – Die Eingabe- und Ausgabedetails für Verbindungen zu Amazon S3 und S3 Object Lambda.
  + `inputS3Url` – Eine vorsignierte URL, die verwendet werden kann, um das ursprüngliche Objekt von Amazon S3 abzurufen. Die URL wird mit der Identität des ursprünglichen Aufrufers signiert und die Berechtigungen des entsprechenden Benutzers gelten, wenn die URL verwendet wird. Wenn die URL signierte Header enthält, muss die Lambda-Funktion diese Header in den Aufruf von Amazon S3 aufnehmen, mit Ausnahme des `Host`-Headers.
  + `outputRoute` – Ein Routing-Token, das der Lambda-URL des S3-Objekts hinzugefügt wird, wenn die Lambda-Funktion `WriteGetObjectResponse` aufruft.
  + `outputToken` – Ein undurchsichtiges Token, das von S3 Object Lambda verwendet wird, um den `WriteGetObjectResponse`-Aufruf mit dem ursprünglichen Aufrufer abzugleichen.
+ `configuration` – Informationen zur Konfiguration des Object Lambda Access Point.
  + `accessPointArn` – Der Amazon-Ressourcenname (ARN) des Object Lambda Access Point, der diese Anforderung erhalten hat.
  + `supportingAccessPointArn` – Der ARN des unterstützenden Zugriffspunkts, der in der Konfiguration des Object Lambda Access Point angegeben ist.
  + `payload` – Benutzerdefinierte Daten, die auf die Konfiguration des Object Lambda Access Point angewendet werden. S3 Object Lambda behandelt diese Daten als eine undurchsichtige Zeichenfolge, daher muss sie möglicherweise vor der Verwendung dekodiert werden.
+ `userRequest` – Informationen über den ursprünglichen Aufruf von S3 Object Lambda.
  + `url` – Die dekodierte URL der Anforderung, wie sie von S3 Object Lambda empfangen wurde, ohne autorisierungsbezogene Abfrageparameter.
  + `headers` – Eine Zuordnung von Zeichenfolgen zu Zeichenfolgen, die die HTTP-Header und ihre Werte aus dem ursprünglichen Aufruf enthalten, ohne autorisierungsbezogene Header. Wenn derselbe Header mehrfach erscheint, werden die Werte von jeder Instance desselben Header zu einer durch Kommata getrennten Liste zusammengefasst. Der Fall der ursprünglichen Header wird in dieser Zuordnung beibehalten.
+ `userIdentity` – Details zur die Identität, die den Aufruf von S3 Object Lambda getätigt hat. Weitere Informationen finden Sie unter [Protokollieren von Datenereignissen für Trails](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html) im *AWS CloudTrail -Benutzerhandbuch.*
  + `type` – Die Art der Identität.
  + `accountId`— Der AWS-Konto , zu dem die Identität gehört.
  + `userName` – Der Anzeigename der Identität, von der der Aufruf stammt.
  + `principalId` – Die eindeutige ID für die Entität, von der der Aufruf stammt.
  + `arn` – Der ARN des Prinzipals, von dem der Aufruf stammt. Der letzte Abschnitt des ARN enthält den Benutzer oder die Rolle, von dem/der der Aufruf stammt.
  + `sessionContext` – Erfolgte die Abfrage mittels temporärer Sicherheitsanmeldeinformationen, stellt dieses Element Informationen über die Sitzung bereit, das für diese Anmeldeinformationen erstellt wurde.
  + `invokedBy`— Der Name desjenigen AWS-Service , der die Anfrage gestellt hat, z. B. Amazon EC2 Auto Scaling oder AWS Elastic Beanstalk.
  + `sessionIssuer` – Erfolgte die Abfrage mittels temporärer Sicherheitsanmeldeinformationen, gibt dieses Element Auskunft darüber, wie die Anmeldeinformationen erhalten wurden.
+ `protocolVersion` – Die Versions-ID des bereitgestellten Kontextes. Das Format des Felds ist `{Major Version}.{Minor Version}`. Die Nebenversionsnummern sind immer zweistellige Zahlen. Jede Entfernung oder Änderung der Semantik eines Feldes erfordert einen Sprung der Hauptversion und erfordert ein aktives Opt-In. Amazon S3 kann jederzeit neue Felder hinzufügen. Zu diesem Zeitpunkt kann es zu einem Sprung der Nebenversion kommen. Aufgrund der Art der Software-Einführung sehen Sie möglicherweise die Verwendung mehrerer Nebenversionen gleichzeitig.

# Arbeiten mit Range- und partNumber-Headern
<a name="range-get-olap"></a>

**Anmerkung**  
Seit dem 7. November 2025 ist S3 Object Lambda nur für Bestandskunden verfügbar, die den Service derzeit nutzen, sowie für ausgewählte AWS Partner Network (APN) -Partner. Weitere Informationen zu Features, die S3 Object Lambda ähneln, finden Sie hier – Änderung der [Verfügbarkeit von Amazon S3 Object Lambda](https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazons3-ol-change.html).

Wenn Sie mit großen Objekten in Amazon S3 Object Lambda arbeiten, können Sie den `Range`-HTTP-Header verwenden, um einen bestimmten Bytebereich von einem Objekt herunterzuladen. Sie können gleichzeitige Verbindungen zu Amazon S3 verwenden, um verschiedene Bytebereiche aus demselben Objekt abzurufen. Sie können auch den `partNumber`-Parameter (eine Ganzzahl zwischen 1 und 10 000) verwenden, der eine „ranged“ Anforderung für das angegebene Teil des Objekts ausführt.

Weil es mehrere Möglichkeiten gibt, eine Anforderung zu bearbeiten, die den `Range`- oder `partNumber`-Parameter beinhaltet, wendet S3 Object Lambda diese Parameter nicht auf das transformierte Objekt an. Stattdessen muss Ihre AWS Lambda Funktion diese Funktionalität nach Bedarf für Ihre Anwendung implementieren.

Wenn Sie die Parameter `Range` und `partNumber` mit S3 Object Lambda verwenden möchten, gehen Sie wie folgt vor: 
+ Aktivieren Sie diese Parameter in der Konfiguration Ihres Object Lambda Access Point.
+ Schreiben Sie eine Lambda-Funktion, die Anforderungen verarbeiten kann, die diese Parameter enthalten.

In den folgenden Schritten wird beschrieben, wie Sie dies erreichen.

## Schritt 1: Konfigurieren Ihres Object Lambda Access Point
<a name="range-get-olap-step-1"></a>

Standardmäßig antworten Object Lambda Access Points mit dem HTTP-Statuscodefehler 501 (Nicht implementiert) auf jede `GetObject`- oder `HeadObject`-Anforderung, die entweder in den Headern oder in den Abfrageparametern einen `Range`- oder `partNumber`-Parameter enthält. 

Damit ein Object-Lambda-Zugriffspunkt solche Anforderungen annehmen kann, müssen Sie `GetObject-Range`, `GetObject-PartNumber`, `HeadObject-Range` oder `HeadObject-PartNumber` in den `AllowedFeatures`-Abschnitt die Konfiguration Ihres Object-Lambda-Zugangspunkts einschließen. Weitere Informationen zur Aktualisierung der Konfiguration Ihres Object Lambda Access Point finden Sie unter [Erstellen von Object Lambda Zugangspunkten](olap-create.md). 

## Schritt 2: Implementieren Sie das `Range` oder `partNumber` in Ihrer Lambda-Funktion
<a name="range-get-olap-step-2"></a>

Wenn Ihr Object Lambda Access Point Ihre Lambda-Funktion mit einer `GetObject`- oder `HeadObject`-Bereichsanforderung aufruft, ist der `Range`- oder `partNumber`-Parameter im Ereigniskontext enthalten. Die Position des Parameters im Ereigniskontext hängt davon ab, welcher Parameter verwendet wurde und wie er in die ursprüngliche Anforderung an den Object Lambda Access Point aufgenommen wurde, wie in der folgenden Tabelle erläutert. 


| Parameter | Ort des Ereigniskontexts | 
| --- | --- | 
|  `Range` (Header)  |  `userRequest.headers.Range`  | 
|  `Range` (Abfrageparameter)  |  `userRequest.url` (Abfrageparameter `Range`)  | 
|  `partNumber`  |  `userRequest.url` (Abfrageparameter `partNumber`)  | 

**Wichtig**  
Die bereitgestellte vorsignierte URL für Ihren Object Lambda Access Point enthält nicht den `Range`- oder `partNumber`-Parameter aus der ursprünglichen Anforderung. In den folgenden Optionen erfahren Sie, wie Sie diese Parameter in Ihrer AWS Lambda Funktion handhaben können.

Nachdem Sie den `Range`- oder `partNumber`-Wert extrahiert haben, können Sie einen der folgenden Ansätze wählen, basierend auf den Anforderungen Ihrer Anwendung:

1. **Ordnen Sie den angeforderten `Range`- oder `partNumber`-Wert dem transformierten Objekt zu (empfohlen).** 

   Die zuverlässigste Art, `Range`- oder `partNumber`-Anforderungen zu bearbeiten, ist folgende: 
   + Rufen Sie das vollständige Objekt aus Amazon S3 ab.
   + Transformieren Sie das Objekt.
   + Wenden Sie die angeforderten `Range`- oder `partNumber`-Parameter auf das transformierte Objekt an.

   Verwenden Sie dazu die bereitgestellte vorsignierte URL, um das gesamte Objekt von Amazon S3 abzurufen und das Objekt dann nach Bedarf zu verarbeiten. Ein Beispiel für eine Lambda-Funktion, die einen `Range` Parameter auf diese Weise verarbeitet, finden Sie in [diesem Beispiel](https://github.com/aws-samples/amazon-s3-object-lambda-default-configuration/blob/main/function/nodejs_20_x/src/response/range_mapper.ts) im AWS GitHub Samples-Repository.

1. **Ordnen Sie den angeforderten `Range` der vorsignierten URL zu.**

   In einigen Fällen kann Ihre Lambda-Funktion den angeforderten `Range` direkt der vorsignierten URL zuordnen, um nur einen Teil des Objekts von Amazon S3 abzurufen. Dieser Ansatz ist nur dann geeignet, wenn Ihre Transformation die beiden folgenden Kriterien erfüllt:

   1. Ihre Transformationsfunktion kann auf partielle Objektbereiche angewendet werden.

   1. Das Anwenden der `Range`-Parameter vor oder nach der Transformationsfunktion führt zu demselben transformierten Objekt.

   Beispielsweise erfüllt eine Transformationsfunktion, die alle Zeichen in einem ASCII-kodierten Objekt in Großbuchstaben konvertiert, beide vorhergehenden Kriterien. Die Transformation kann auf einen Teil eines Objekts angewendet werden, und durch Anwenden des `Range`-Parameters vor der Transformation wird das gleiche Ergebnis erzielt wie beim Anwenden des Parameters nach der Transformation.

   Im Gegensatz dazu erfüllt eine Funktion, die die Zeichen in einem ASCII-kodierten Objekt umkehrt, diese Kriterien nicht. Eine solche Funktion erfüllt Kriterium 1, da sie auf partielle Objektbereiche angewendet werden kann. Sie erfüllt jedoch nicht Kriterium 2, da das Anwenden des `Range`-Parameters vor der Transformation andere Ergebnisse erzielt als das Anwenden des Parameters nach der Transformation. 

   Betrachten Sie eine Anforderung, die Funktion auf die ersten drei Zeichen eines Objekts mit dem Inhalt `abcdefg` anzuwenden. Das Anwenden des `Range`-Parameters vor der Transformation ruft nur `abc`ab und kehrt dann die Daten um und gibt `cba` zurück. Wenn der Parameter jedoch nach der Transformation angewendet wird, ruft die Funktion das gesamte Objekt ab, kehrt es um und wendet dann den `Range`-Parameter, um `gfe` zurückzugeben. Da diese Ergebnisse unterschiedlich sind, sollte diese Funktion den `Range`-Parameter beim Abrufen des Objekts von Amazon S3 nicht anwenden. Stattdessen sollte es das gesamte Objekt abrufen, die Transformation durchführen und erst dann den `Range`-Parameter anwenden. 
**Warnung**  
In vielen Fällen führt die Anwendung des `Range`-Parameters für die vorsignierte URL zu einem unerwarteten Verhalten durch die Lambda-Funktion oder den anfordernden Client. Wenn Sie nicht sicher sind, dass Ihre Anwendung ordnungsgemäß funktioniert, wenn Sie nur ein Teilobjekt von Amazon S3 abrufen, empfehlen wir Ihnen, vollständige Objekte abzurufen und zu transformieren, wie zuvor in Ansatz A beschrieben. 

   Wenn Ihre Anwendung die zuvor in Ansatz B beschriebenen Kriterien erfüllt, können Sie Ihre AWS Lambda Funktion vereinfachen, indem Sie nur den angeforderten Objektbereich abrufen und dann Ihre Transformation für diesen Bereich ausführen. 

   Im folgenden Java-Codebeispiel wird folgende Vorgehensweise gezeigt: 
   + Rufen Sie den `Range`-Header aus der `GetObject`-Anforderung ab.
   + Fügen Sie der vorsignierten URL den `Range`-Header hinzu, mit dem Lambda den angeforderten Bereich von Amazon S3 abrufen kann.

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