wake-up-neo.com

API-Gateway - Mehrteilige Formulardaten veröffentlichen

Scheint meine Frage vielleicht ein wenig ähnlich zu dieser .

Ich habe eine API in meinem API-Gateway und mache einen HTTP-Proxy bis zu einem Endpunkt der Multipart-/Formulardatendateien von POST.

Wenn ich den http-Endpunkt direkt anrufe (nicht über das API-Gateway) - mit Postman funktioniert er wie erwartet, jedoch schlägt der API-Gateway-Endpunkt (über Postman) fehl.

Ich habe beide Anforderungen verglichen (über Fiddler- und CloudWatch-Protokolle), die identisch zu sein scheinen:

Anforderung eines direkten API-Aufrufs (funktioniert):

POST https://domainname/api/v1/documents HTTP/1.1
Host: api.service
Connection: keep-alive
Content-Length: 202
Authorization: AuthToken
Postman-Token: a75869d6-1d64-6b9f-513d-a80ac192c8e1
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
docMetaInfo: some extra data needed
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryB85rsPlMffA2fziS
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundaryB85rsPlMffA2fziS
Content-Disposition: form-data; name=""; filename="Test.txt"
Content-Type: text/plain

This is a test Text File
------WebKitFormBoundaryB85rsPlMffA2fziS--

Anforderung vom API-Gateway (funktioniert nicht):

POST https://GATEWAY_domainname/api/v1/documents HTTP/1.1
Host: api-Gateway.service
Connection: keep-alive
Content-Length: 202
Authorization: AuthToken
Postman-Token: e25536fa-3dfa-ddcb-8ca6-3f3552d2bc40
Cache-Control: no-cache
Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
docMetaInfo: some extra data needed
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarybX9MyWBsuLGm6QIC

x-api-key: *********************
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundarybX9MyWBsuLGm6QIC
Content-Disposition: form-data; name=""; filename="Test.txt"
Content-Type: text/plain

This is a test Text File
------WebKitFormBoundarybX9MyWBsuLGm6QIC--

Ich habe ein paar Dinge von der Gateway-Seite aus versucht, einschließlich des Änderns von Integration Request, um einen neuen Body für denselben Inhaltstyp zuzuordnen, kein Glück.

Soweit mir bekannt ist, sollte ich nur diese Variable passthrough brauchen, weshalb es etwas verwirrend wird - es sollte keine Datenmanipulation abfangen notwendig sein?

Der Fehler, den ich erhalte, ist 400 - eine fehlerhafte Anforderung (die sich ärgert, dass die file nicht gefunden wurde), aber wie Sie in der Anfrage sehen können, ist sie da.

Irgendwelche Ideen? 

EDIT Protokolle von CloudWatch auf demselben APIGateway-POST

/ - enter image description here

Fehler ist immer noch 400 - keine Datei gefunden

15
Hexie

API Gateway unterstützt derzeit keine mehrteiligen Formulardaten. Dies wird für die zukünftige Entwicklung in Betracht gezogen. In der Zwischenzeit müssen Sie Ihren Client so ändern, dass er mehrere Anfragen oder eine einzige einteilige Anfrage verwendet.

Update : API Gateway unterstützt jetzt binäre Payloads. Definieren Sie einfach "multipart/form-data" als binären Medientyp für Ihre API, und geben Sie die Nutzdaten direkt an eine Lambda-Funktion weiter. Von dort aus können Sie den Körper analysieren, um Ihren Dateiinhalt zu erhalten. Es sollten Bibliotheken verfügbar sein, die beim Parsen des mehrteiligen Hauptteils helfen ('parse-multipart' in NodeJS zum Beispiel).

11
RyanG

Für diejenigen, die noch Hilfe benötigen, ist dies jetzt offiziell dokumentiert:

https://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-configure-with-console.html

Zusammenfassend sind die Schritte wie folgt:

  1. Wechseln Sie zur Registerkarte "API-Gateway-Einstellungen" für Ihre API und fügen Sie "Multipart/Formulardaten" zum Abschnitt "Binäre Medientypen" hinzu.
  2. Fügen Sie "Content-Type" und "Accept" zu den Anforderungsköpfen für Ihre Proxy-Methode hinzu
  3. Fügen Sie dieselben Header zu den Integrationsanforderungsheadern hinzu
  4. erneut bereitstellen

Prost

4
Dre

Ich hatte das gleiche Problem bei der Integration in meinen Tomcat-Server. Nachfolgend sind die Änderungen aufgeführt, die zur Fehlerbehebung erforderlich sind.

  1. Füge Content-Type in die HTTP Request Headers deines API-Gateways über die Konsole ein oder füge sie in die offene API-Dokumentation wie

    {
        "/yourApi":{
            "post":{
                "operationId":"uploadImageUsingPOST",
                "produces":[
                    "application/json"
                ],
                "parameters":[
                {
                    "name":"Content-Type",
                    "in":"header",
                    "required":false,
                    "type":"string"
                },
                {
                    //Other headers
                }]   
            }
        }
    
  2. Fügen Sie oben auch den Inhaltstyp in die HTTP-Header der Integrationsanforderung Ihrer API ein. Wenn nicht, fügen Sie dort auch einen weiteren Header hinzu. Accept = '/ ' in api gateway per konsole oder in offene api dokumentation wie hinzufügen

    "requestParameters":{
        "integration.request.header.Accept":"'*/*'",
        "integration.request.header.Content-Type":"method.request.header.Content-Type",
        //Other headers
    }
    
  3. Stellen Sie die Inhaltsbehandlung in der Integrationsanforderung Ihrer API als Passthrough ein.

  4. Fügen Sie Multipart-/Formulardaten als binäre Medientypen in den Einstellungen Ihrer API über die Konsole oder durch Öffnen der API-Dokumentation hinzu

    "x-Amazon-apigateway-binary-media-types": [
        "multipart/form-data"
    ]
    
  5. Stellen Sie die obigen Änderungen in der gewünschten Phase bereit, in der Sie das Bild als Multipart hochladen möchten.

Das API-Gateway übergibt Ihre mehrteilige Datei als binäres Array, und Sie können weiterhin @RequestBody MultipartFile multipartFile in Ihrem Controller verwenden, und spring analysiert diese Binärdatei für Sie in multipart.

1
Swalih

Es scheint eine Änderung stattgefunden zu haben und API Gateway führt keine strikte Übereinstimmung des gesamten Content-Type-Header-Werts mehr durch, sodass nun alles für die "binäre" Unterstützung wie erwartet funktioniert.

Stellen Sie Ihre API auf POST (oder PUT) und die Lambda-Integration auf "Proxy". Gehen Sie zu Einstellungen für Ihre API und fügen Sie die Medientypen hinzu, die Sie als "binär" verwenden möchten. Ich habe multipart/signed..__ hinzugefügt. Der erhaltene Medientyp ist tatsächlich: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha256"; boundary="----54645645645664564563424768"

Das API-GW nimmt dies immer noch als "binary" auf und liefert es als base64 an meinen Lambda.

In deiner Lambda wirst du dann folgendes fangen:

Context:
{
  "callbackWaitsForEmptyEventLoop": true,
  "logGroupName": "/aws/lambda/api-invoice",
  "logStreamName": "2018/04/27/[$LATEST]3454",
  "functionName": "api-invoice",
  "memoryLimitInMB": "128",
  "functionVersion": "$LATEST",
  "invokeid": "345-49e2-11e8-34-345",
  "awsRequestId": "345-49e2-11e8-34-345",
  "invokedFunctionArn": "arn:aws:lambda:eu-west-1:12345:function:api-invoice"
}
-------
Event:
{
  "resource": "/peppol/as2",
  "path": "/peppol/as2",
  "httpMethod": "POST",
  "headers": {
    "Accept": "*/*",
    "AS2-From": "PEPPOL_AP",
    "AS2-To": "234567890",
    "AS2-Version": "1.1",
    "cache-control": "no-cache",
    "Content-Type": "multipart/signed; protocol=\"application/pkcs7-signature\"; micalg=\"sha256\"; boundary=\"----54645645645664564563424768\"",
    "Date": "Fri, 27 Apr 2018 06:17:10 GMT",
    "Disposition-Notification-Options": "signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, sha1,md5",
    "Disposition-Notification-To": "[email protected]",
    "Host": "123.execute-api.eu-west-1.amazonaws.com",
    "Message-ID": "<[email protected]>",
    "MIME-Version": "1.0",
    "Postman-Token": "ert-59c1-45656-94d1-456546",
    "Recipient-Address": "as2s://123.execute-api.eu-west-1.amazonaws.com/dev/peppol/as2",
    "Subject": "234567890;PEPPOL_AP",
    "User-Agent": "PostmanRuntime/7.1.1",
    "Via": "1.1 ert-",
    "X-Amzn-Trace-Id": "Root=1-4556-ertfd6554",
    "X-CLIENT-IP": "172.17.0.1",
    "X-Forwarded-For": "xx.xxx.xx.80",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "queryStringParameters": null,
  "pathParameters": null,
  "stageVariables": null,
  "requestContext": {
    "resourceId": "80r6gp",
    "resourcePath": "/peppol/as2",
    "httpMethod": "POST",
    "extendedRequestId": "sdsdd343434=",
    "requestTime": "27/Apr/2018:06:17:11 +0000",
    "path": "/dev/peppol/as2",
    "accountId": "123",
    "protocol": "HTTP/1.1",
    "stage": "dev",
    "requestTimeEpoch": 1524809831262,
    "requestId": "354-49e2-3445-b2ba-535345",
    "identity": {
      "cognitoIdentityPoolId": null,
      "accountId": null,
      "cognitoIdentityId": null,
      "caller": null,
      "sourceIp": "xx.xxx.xx.80",
      "accessKey": null,
      "cognitoAuthenticationType": null,
      "cognitoAuthenticationProvider": null,
      "userArn": null,
      "userAgent": "PostmanRuntime/7.1.1",
      "user": null
    },
    "apiId": "123"
  },
  "body": "VGhpcyBpcyBhbiBTL01/ [snip] /S0NCg==",
  "isBase64Encoded": true
}
1
Anders