我有一个以 Lambda 为目标的 ALB。lambda 是一个简单的 Python 代码,它唯一能做的事情就是返回一个硬编码的字典。响应是 ALB 的有效响应,包括Etag
标头:
import json
def lambda_handler(event, context):
result = {
'statusCode': 200,
'statusDescription': '200 OK',
'isBase64Encoded': False,
'body': event['body'],
'headers': {
'Etag': 'someetag-1',
'Content-Type': 'application/json'
}
}
print(event)
print(result)
return result
当我发送 POST 请求时,我收到状态代码为 200 的响应:
$ curl -X POST \
> http://test-alb-000000000000.us-east-1.elb.amazonaws.com \
> -H 'Content-Type: application/json' \
> -d '{"some": "body"}'
{"some": "body"}
但是,当我提供其中一个If-Unmodified-Since
标题时If-Match
,我收到412 Precondition Failed
:
$ curl -X POST \
> http://test-alb-000000000000.us-east-1.elb.amazonaws.com \
> -H 'Content-Type: application/json' \
> -H 'If-Match: someetag' \
> -d '{"some": "body"}'
<html>
<head><title>412 Precondition Failed</title></head>
<body bgcolor="white">
<center><h1>412 Precondition Failed</h1></center>
</body>
</html>
然而,从 lambda 日志中我可以看到,对于这两个请求,lambda 都已执行并正确完成:
START RequestId: 91ea1dd7-9ad4-430d-b9d0-36d6d857455f Version: $LATEST
{'requestContext': {'elb': {'targetGroupArn': 'arn:aws:elasticloadbalancing:us-east-1:000000000000:targetgroup/TargetGroupName/f27b55fbd94d7be6'}}, 'httpMethod': 'POST', 'path': '/', 'queryStringParameters': {}, 'headers': {'accept': '*/*', 'content-length': '16', 'content-type': 'application/json', 'host': 'test-alb-000000000000.us-east-1.elb.amazonaws.com', 'user-agent': 'curl/7.54.0', 'x-amzn-trace-id': 'Root=1-7c349c62-54934927ad90ded6e9cb166e', 'x-forwarded-for': '157.12.13.14', 'x-forwarded-port': '80', 'x-forwarded-proto': 'http'}, 'body': '{"some": "body"}', 'isBase64Encoded': False}
{'statusCode': 200, 'statusDescription': '200 OK', 'isBase64Encoded': False, 'body': '{"some": "body"}', 'headers': {'Etag': 'someetag-1', 'Content-Type': 'application/json'}}
END RequestId: 91ea1dd7-9ad4-430d-b9d0-36d6d857455f
REPORT RequestId: 91ea1dd7-9ad4-430d-b9d0-36d6d857455f Duration: 5.45 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 55 MB Init Duration: 113.41 ms
XRAY TraceId: 1-5d832f3d-54934927ad90ded6e9cb166e SegmentId: 458533393206659a Sampled: false
START RequestId: d2c41e28-8ffd-4a20-b9ee-97aac9a2a7e4 Version: $LATEST
{'requestContext': {'elb': {'targetGroupArn': 'arn:aws:elasticloadbalancing:us-east-1:000000000000:targetgroup/TargetGroupName/f27b55fbd94d7be6'}}, 'httpMethod': 'POST', 'path': '/', 'queryStringParameters': {}, 'headers': {'accept': '*/*', 'content-length': '16', 'content-type': 'application/json', 'host': 'test-alb-000000000000.us-east-1.elb.amazonaws.com', 'if-match': 'someetag', 'user-agent': 'curl/7.54.0', 'x-amzn-trace-id': 'Root=1-5d832f44-54934927ad90ded6e9cb166e', 'x-forwarded-for': '157.12.13.14', 'x-forwarded-port': '80', 'x-forwarded-proto': 'http'}, 'body': '{"some": "body"}', 'isBase64Encoded': False}
{'statusCode': 200, 'statusDescription': '200 OK', 'isBase64Encoded': False, 'body': '{"some": "body"}', 'headers': {'Etag': 'someetag-1', 'Content-Type': 'application/json'}}
END RequestId: d2c41e28-8ffd-4a20-b9ee-97aac9a2a7e4
REPORT RequestId: d2c41e28-8ffd-4a20-b9ee-97aac9a2a7e4 Duration: 7.13 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 56 MB
XRAY TraceId: 1-5d832f44-54934927ad90ded6e9cb166e SegmentId: 7a6071cb33eb8af2 Sampled: false
无标头的请求的 ALB 访问日志If-Match
:
http 2019-09-19T07:32:06.546111Z app/test-alb/4c92127c7308 157.12.13.14:32255 - 0.007 0.277 0.000 200 200 180 186 "POST http://test-alb-00000000.us-east-1.elb.amazonaws.com:80/ HTTP/1.1" "curl/7.54.0" - - arn:aws:elasticloadbalancing:us-east-1:000000000000:targetgroup/TargetGroupName/f27b55fbd94d7be6 "Root=1-7c349c62-54934927ad90ded6e9cb166e" "-" "-" 0 2019-09-19T07:32:06.262000Z "forward" "-" "-"
带有标头的请求的 ALB 访问日志If-Match
:
http 2019-09-19T07:32:14.645790Z app/test-alb/4c92127c7308 157.12.13.14:5361 - 0.008 0.059 0.000 412 - 200 317 "POST http://test-alb-00000000.us-east-1.elb.amazonaws.com:80/ HTTP/1.1" "curl/7.54.0" - - - "-" "-" "-" - 2019-09-19T07:32:14.579000Z "-" "-" "-"
412 Precondition Failed
每次我使用If-Unmodified-Since
或时,都会返回相同的响应If-Match
。这些标头的值无关紧要。此外,lambda 是否返回Etag
、Last-Modified
标头或都不返回也无关紧要。基本上,只要存在条件标头If-Unmodified-Since
或之一If-Match
,ALB 就会返回412 Precondition Failed
。
如何正确使用ALB 和 Lambda 的If-Unmodified-Since
标If-Match
头?另外,我不明白为什么访问日志没有显示请求已转发到目标,而实际上请求已转发(Lambda 已执行并正确完成)。API 网关不会出现此问题,但在我的案例中我需要使用 ALB。