AWS Lambda – 未理解返回的数据

huangapple go评论65阅读模式
英文:

AWS Lambda - not understanding returned data

问题

我正在编写我的第一个Lambda脚本。它是一个非常简单的HTTP到电子邮件网关。在解析请求和生成电子邮件时,我在前端(通过Cloudfront)收到502错误:

> Lambda函数在头部对象中返回了无效的条目:头部对象中的每个头部条目必须是一个数组。我们无法连接到此应用程序或网站的服务器。此时可能有太多的流量或配置错误。请稍后再试,或联系应用程序或网站的所有者。
如果您通过CloudFront向客户提供内容,可以通过查阅CloudFront文档来找到排除故障和帮助预防此错误的步骤。

要创建返回的对象,我只是装饰了传递给lambda_handler()的事件对象:

def lambda_handler(event, context):
    returnAddr=do_clever_stuff(event)
    response = {
        "headers": { "location": [ { "key": "Location", "value": returnAddr } ] },
        "status": 303,
        "statusDescription": "See Other"
        }
    event['Records'][0]['cf']['response']=response
    return event

Lambda编辑器/测试控制台中显示的整个数据如下。

认为 我的响应符合要求。我漏掉了什么吗?

{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionDomainName": "redacted.cloudfront.net",
          "distributionId": "EDFDVBD6EXAMPLE",
          "eventType": "origin-request",
          "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
        },
        "request": {
          "clientIp": "203.0.113.178",
          "headers": {
            "x-forwarded-for": [
              {
                "key": "X-Forwarded-For",
                "value": "203.0.113.178"
              }
            ],
            "user-agent": [
              {
                "key": "User-Agent",
                "value": "Amazon CloudFront"
              }
            ],
            "via": [
              {
                "key": "Via",
                "value": "2.0 2afae0d44e2540f472c0635ab62c232b.cloudfront.net (CloudFront)"
              }
            ],
            "host": [
              {
                "key": "Host",
                "value": "example.org"
              }
            ],
            "cache-control": [
              {
                "key": "Cache-Control",
                "value": "no-cache"
              }
            ]
          },
          "method": "POST",
          "origin": {
            "custom": {
              "customHeaders": {},
              "domainName": "example.org",
              "keepaliveTimeout": 5,
              "path": "",
              "port": 443,
              "protocol": "https",
              "readTimeout": 30,
              "sslProtocols": [
                "TLSv1",
                "TLSv1.1",
                "TLSv1.2"
              ]
            }
          },
          "querystring": "",
          "uri": "/",
          "body": {
            "data": "<<redacted>>"
          }
        },
        "response": {
          "headers": {
            "location": [
              {
                "key": "Location",
                "value": "/"
              }
            ]
          },
          "status": 303,
          "statusDescription": "See Other"
        }
      }
    }
  ]
}

更新 查看AWS文档中的其他示例,这些示例并没有返回装饰的事件对象,而只是返回响应对象,但是将上述代码修改为 return response 不会改变行为。

英文:

I am writing my first Lambda script. It is a very simple HTTP to email gateway. While it is parsing the request and generating the email, I get a 502 error at the front end (via Cloudfront):

> The Lambda function returned an invalid entry in the headers object: Each header entry in the headers object must be an array. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.

To create the returned object, I am simply decorating the event object passed to lambda_handler():

def lambda_handler(event, context):
returnAddr=do_clever_stuff(event)
response = {
&quot;headers&quot;: { &quot;location&quot;: [ { &quot;key&quot;: &quot;Location&quot;, &quot;value&quot;: returnAddr } ] },
&quot;status&quot;: 303,
&quot;statusDescription&quot;: &quot;See Other&quot;
}
event[&#39;Records&#39;][0][&#39;cf&#39;][&#39;response&#39;]=response
return event

The entire data returned in the Lambda editor / test console is shown below.

I think that my response conforms to the requirements. What am I missing?

{
&quot;Records&quot;: [
{
&quot;cf&quot;: {
&quot;config&quot;: {
&quot;distributionDomainName&quot;: &quot;redacted.cloudfront.net&quot;,
&quot;distributionId&quot;: &quot;EDFDVBD6EXAMPLE&quot;,
&quot;eventType&quot;: &quot;origin-request&quot;,
&quot;requestId&quot;: &quot;4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ==&quot;
},
&quot;request&quot;: {
&quot;clientIp&quot;: &quot;203.0.113.178&quot;,
&quot;headers&quot;: {
&quot;x-forwarded-for&quot;: [
{
&quot;key&quot;: &quot;X-Forwarded-For&quot;,
&quot;value&quot;: &quot;203.0.113.178&quot;
}
],
&quot;user-agent&quot;: [
{
&quot;key&quot;: &quot;User-Agent&quot;,
&quot;value&quot;: &quot;Amazon CloudFront&quot;
}
],
&quot;via&quot;: [
{
&quot;key&quot;: &quot;Via&quot;,
&quot;value&quot;: &quot;2.0 2afae0d44e2540f472c0635ab62c232b.cloudfront.net (CloudFront)&quot;
}
],
&quot;host&quot;: [
{
&quot;key&quot;: &quot;Host&quot;,
&quot;value&quot;: &quot;example.org&quot;
}
],
&quot;cache-control&quot;: [
{
&quot;key&quot;: &quot;Cache-Control&quot;,
&quot;value&quot;: &quot;no-cache&quot;
}
]
},
&quot;method&quot;: &quot;POST&quot;,
&quot;origin&quot;: {
&quot;custom&quot;: {
&quot;customHeaders&quot;: {},
&quot;domainName&quot;: &quot;example.org&quot;,
&quot;keepaliveTimeout&quot;: 5,
&quot;path&quot;: &quot;&quot;,
&quot;port&quot;: 443,
&quot;protocol&quot;: &quot;https&quot;,
&quot;readTimeout&quot;: 30,
&quot;sslProtocols&quot;: [
&quot;TLSv1&quot;,
&quot;TLSv1.1&quot;,
&quot;TLSv1.2&quot;
]
}
},
&quot;querystring&quot;: &quot;&quot;,
&quot;uri&quot;: &quot;/&quot;,
&quot;body&quot;: {
&quot;data&quot;: &quot;&lt;&lt;redacted&gt;&gt;&quot;
}
},
&quot;response&quot;: {
&quot;headers&quot;: {
&quot;location&quot;: [
{
&quot;key&quot;: &quot;Location&quot;,
&quot;value&quot;: &quot;/&quot;
}
]
},
&quot;status&quot;: 303,
&quot;statusDescription&quot;: &quot;See Other&quot;
}
}
}
]
}

Update Looking at other examples in the AWS documentation, these are not returning a decorated event object, but rather just the response object, however amending the code above to return response does not change the behaviour.

答案1

得分: 1

首先,(如您所发现)您不需要返回更新后的 event 对象,应该直接返回响应对象。

其次,如果将代码更改为仅返回响应对象仍然导致返回相同的事件/响应情况,那么您在测试函数之前忘记在Lambda控制台中单击“部署”按钮。

英文:

First, (as you have found) you don't return an updated event object, you should simply return the response object directly.

Second, if changing your code to simply return the response object is still resulting in the same event/response thing coming back, then you forgot to click the "deploy" button in the Lambda console before testing the function again.

答案2

得分: 0

问题的原因是在Lambda控制台中点击“部署”按钮不会将脚本部署到Lambda@edge。

要使当前的代码生效,显然需要切换到“版本”选项卡,创建一个新版本,然后编辑CloudFront分发以更新函数ARN为新版本的ARN。

为了澄清之前的混淆,lambda_handler() 需要返回一个响应对象 - 而不是完整的事件对象。

英文:

The issue turned out to be that clicking "deploy" in the Lambda console does not deploy the script to Lambda@edge.

To make the current code live, I apparently need to switch to the "versions" tab, create a new version, then edit the cloudfront distribution to update the function ARN to that of the new version.

Just to clarify the earlier confusion, lambda_handler() needs to return a response object - not a complete event object.

huangapple
  • 本文由 发表于 2023年5月31日 23:28:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375119.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定