首页 文章

API网关 - 发布multipart \ form-data

提问于
浏览
15

似乎我的问题可能有点类似to this one .

我的API网关中有一个API,我正在通过POST的multipart / form-data文件的 endpoints 进行HTTP代理 .

如果我直接调用http endpoints (而不是通过API网关) - 使用邮递员,它按预期工作,但是,使用API网关 endpoints (通过邮递员)失败 .

我已经比较了两个似乎相同的请求(通过fiddler和CloudWatch日志):

请求直接API调用(工作):

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--

来自API网关的请求(不工作):

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--

我从网关端尝试了一些东西,包括更改 Integration Request 以映射相同内容类型的新主体,没有运气 .

据我所知,我只需要 passthrough 这个调用,因此它变得有点混乱 - 应该不需要数据操作/拦截?

我得到的错误是400 - 错误的请求(抱怨没有找到 file ),但正如你在请求中看到的那样,它就在那里 .

有任何想法吗?

EDIT 在同一个APIGateway POST上从CloudWatch登录

enter image description here

错误仍然是400 - 找不到文件

3 回答

  • 13

    API网关当前不支持多部分表单数据 . 这正在考虑用于未来的发展 . 在此期间,您需要修改您的客户端以使用多个请求或单个部分请求 .

    Update :API网关现在支持二进制有效负载 . 只需将"multipart/form-data"定义为API的二进制媒体类型,并将有效负载直接代理到Lambda函数 . 从那里你可以解析正文以获取你的文件内容 . 应该有可用于帮助解析多部分主体的库(例如,NodeJS中的'parse-multipart') .

  • 1

    似乎有一个变化,API网关不再对整个Content-Type标头值进行严格匹配,所以现在“二进制”支持的所有内容都按预期工作 .

    将您的API设置为POST(或PUT)并将Lambda集成设置为"proxy" . 转到API的“设置”,然后添加要用作"binary"的媒体类型 . 我添加了 multipart/signed . 接收的媒体类型实际上是: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha256"; boundary="----54645645645664564563424768"

    API GW仍然选择“二进制”并将其作为base64传递给我的Lambda .

    在你的Lambda中你会发现:

    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": "ignored@example.com",
        "Host": "123.execute-api.eu-west-1.amazonaws.com",
        "Message-ID": "<456-9d44-4c61-456-456546@172.17.0.3>",
        "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
    }
    
  • 0

    我有同样的问题与我的tomcat服务器集成,我发现下面需要修改它来修改它 .

    • 通过控制台在api网关的api的 HTTP Request Headers 中添加 Content-Type ,或者在open api文档中添加
    {
        "/yourApi":{
            "post":{
                "operationId":"uploadImageUsingPOST",
                "produces":[
                    "application/json"
                ],
                "parameters":[
                {
                    "name":"Content-Type",
                    "in":"header",
                    "required":false,
                    "type":"string"
                },
                {
                    //Other headers
                }]   
            }
        }
    
    • 上面的步骤还在你的api的HTTP集成请求中添加Content-Type,如果没有在那里添加它,并通过控制台在api网关中添加一个 Headers Accept ='/' 或者在open api文档中添加它
    "requestParameters":{
        "integration.request.header.Accept":"'*/*'",
        "integration.request.header.Content-Type":"method.request.header.Content-Type",
        //Other headers
    }
    
    • 在api的集成请求中将内容处理设置为直通 .

    • 通过控制台或打开的api文档在api的设置中将multipart / form-data添加为二进制媒体类型

    "x-amazon-apigateway-binary-media-types": [
        "multipart/form-data"
    ]
    
    • 将上面的部署更改为您要将图像作为multipart上传的所需阶段 .

    Api网关将您的多部分文件作为二进制数组传递,您仍然可以在控制器中使用@RequestBody MultipartFile multipartFile,spring会将此二进制文件解析为多部分 .

相关问题