Назад | Перейти на главную страницу

AWS Application Load Balancer возвращает '412 Precondition Failed', если присутствует условный заголовок

У меня есть ALB с лямбдой в качестве цели. Лямбда - это простой Python, и единственное, что он делает, - это возврат жестко запрограммированного dict. Ответ является действительным ответом для 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>

Однако из журналов лямбда я вижу, что лямбда была выполнена и завершена правильно для обоих запросов:

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. Значение этих заголовков не имеет значения. Кроме того, не имеет значения, возвращает ли лямбда Etag, Last-Modified заголовки или ни один из них. По сути, в любое время один из условных заголовков If-Unmodified-Since или If-Match присутствует, ALB возвращает 412 Precondition Failed.

Как я могу правильно использовать If-Unmodified-Since и If-Match заголовки с ALB и Lambda? Кроме того, я не понимаю, почему в журналах доступа не указано, что запрос был перенаправлен на цель, когда на самом деле он был перенаправлен (Lambda была выполнена и завершена правильно). Эта проблема не возникает с API Gateway, но в моем случае мне нужно использовать ALB.