ALB 未正确传播响应 headers

ALB is not propagating response headers correctly

我在 ALB 后面有一个 lambda 目标。我的 lambda 是 python lambda。

def handler(event, context):
response = {
    "statusCode": 200,
    "statusDescription": "200 OK",
    "isBase64Encoded": False,
    "headers": {
        "Content-Type": "text/html; charset=utf-8"
    }
}

不过,在使用 curl 击中我的 url 时,我收到了一个

< HTTP/1.1 200 OK
< Server: awselb/2.0
< Date: Sat, 06 Apr 2019 04:46:50 GMT
< Content-Type: application/octet-stream
< Content-Length: 0
< Connection: keep-alive

注意 Content-Type 是一个 octet-stream,它会导致浏览器将响应下载为文件而不是显示它。我尝试在响应中添加额外的 headers "Foo":"Bar",但它们没有出现在 curl 响应中。 ALB 似乎正在吃掉我提供的 lambda headers。我该如何解决这个问题?

AWS Application Load Balancer 将所有响应 header 转换为小写,您需要仔细检查您的 header。遗憾的是,您无法更改或修改由 ALB 操纵的 header。您可以参考下面 link 的 HTTP Headers:

https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html

对于应用程序负载均衡器的请求跟踪:

https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-request-tracing.html

此外,您需要检查负载均衡器的限制:

  • 负载均衡器在收到传入请求时更新 header,而不是在收到响应时更新。

  • 如果 HTTP header 大于 7 KB,负载平衡器会用 Root 字段重写 X-Amzn-Trace-Id header。

  • 使用 WebSockets,您只能跟踪到升级请求成功。

原来我为我的目标组启用了多值 headers。启用该设置后,我的 lambda 表达式需要 return 设置字段 multiValueHeaders 而不是 headers 的响应。所以我的 lambda 代码需要是:

def handler(event, context):
response = {
    "statusCode": 200,
    "statusDescription": "200 OK",
    "isBase64Encoded": False,
    "multiValueHeaders": {
        "Content-Type": ["text/html; charset=utf-8"]
    }
}

更多信息on AWS' release blog post