У меня настроен API-шлюз для обслуживания некоторых файлов из корзины S3 с помощью Lambda. Когда я пытаюсь запросить несуществующие файлы, API Gateway иногда отвечает 403 Forbidden
(в большинстве случаев и даже не запускает лямбда-функцию), а иногда и с ошибкой 404 Not Found
(я бы хотел вызвать 404 в таких случаях).
Моя функция Lambda очень проста:
exports.handler = async event => {
try {
const Bucket = 'testing-bucket';
const Key = `${event.documentType}/${event.requestParams.document}`;
const file = await s3.getObject({ Bucket, Key }).promise();
return {
body: file.Body.toString('base64'),
headers: {
'Content-Disposition': `attachment; filename=test.jpg`,
'Content-Length': file.ContentLength,
'Content-Type': file.ContentType,
},
statusCode: 200,
isBase64Encoded: true,
};
} catch (e) {
return {
body: JSON.stringify({ message: `[${e.code}] ${e.message}` }),
statusCode: e.statusCode,
};
}
};
Роль IAM, присоединенная к функции Lambda, настраивается следующим образом:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::testing-bucket",
"arn:aws:s3:::testing-bucket/*"
]
}
]
}
Кэширование полностью отключено вAPI-шлюз и команда, которую я пытался проверить это:
curl -X GET -H 'Authorization: 123xyz' -H 'Accept: image/jpeg' -H 'Cache-Control: no-cache' -I https://test.com/existing_folder/non-existing-file.xxx
Ответы:
HTTP/2 403
content-type: application/json
content-length: 60
date: Mon, 07 Oct 2019 10:32:30 GMT
x-amzn-requestid: ae870104-9045-4c23-9794-226992bad591
x-amzn-errortype: AccessDeniedException
x-amz-apigw-id: BMAZwGSyoAMFftw=
x-cache: Error from cloudfront
via: 1.1 ccf34ecc11e5579d8083b17d9d39a622.cloudfront.net (CloudFront)
x-amz-cf-pop: LHR62-C2
x-amz-cf-id: zgtgfJX9TQLcI8F2RLWdgTz-RN_1j7MXblQ1498ucoeFY3dhjitOdg==
и
HTTP/2 404
content-type: application/json
content-length: 59
date: Mon, 07 Oct 2019 10:32:31 GMT
x-amzn-requestid: 2de49681-4f21-4cd1-989c-9b36327badb1
x-amz-apigw-id: BMAZ5E52IAMFwEg=
x-amzn-trace-id: Root=1-5d9b143f-aadf0a24a5f60f4c939b77c0;Sampled=0
x-cache: Error from cloudfront
via: 1.1 be00537a2361673ea48963d6e04d04a1.cloudfront.net (CloudFront)
x-amz-cf-pop: LHR62-C2
x-amz-cf-id: 9VI26GH3-ZuJSQrEt5Fc7EjuMt8IV0TPzPwna8dvvr6UtsgiqwwIkw==
Как сделатьAPI-шлюз отвечает согласованным образом?
ОБНОВЛЕНИЕ:
После просмотра журналов API-шлюза и попытки спамить одну и ту же команду curl
для существующих и несуществующих файлов пару раз встрока, это был вывод для несуществующего файла (временные метки не повреждены):
# curl -X GET -H 'Authorization: 123xyz' -H 'Accept: image/jpeg' -H 'cache-control: private, no-cache, no-store, max-age=1, s-maxage=1' https://my.url/foo/nobar
{
"requestId": "d19602e8-3a32-4445-b9e6-99f05a59fac4",
"ip": "redacted",
"caller": "-",
"user": "-",
"requestTime": "08/Oct/2019:00:05:03 +0000",
"httpMethod": "GET",
"resourcePath": "/foo/{bar}",
"status": "404",
"protocol": "HTTP/1.1",
"responseLength": "59"
}
# and
{
"requestId": "b33bf6c7-55db-4e1f-b4e4-b1e826139556",
"ip": "redacted",
"caller": "-",
"user": "-",
"requestTime": "08/Oct/2019:00:05:05 +0000",
"httpMethod": "GET",
"resourcePath": "/foo/{bar}",
"status": "403",
"protocol": "HTTP/1.1",
"responseLength": "60"
}
и для существующего файла:
# curl -X GET -H 'Authorization: 123xyz' -H 'Accept: image/jpeg' -H 'cache-control: private, no-cache, no-store, max-age=1, s-maxage=1' https://my.url/foo/bar
{
"requestId": "122ef31e-c587-470c-a0b5-51c6d9838fe4",
"ip": "redacted",
"caller": "-",
"user": "-",
"requestTime": "07/Oct/2019:23:58:35 +0000",
"httpMethod": "GET",
"resourcePath": "/foo/{bar}",
"status": "403",
"protocol": "HTTP/1.1",
"responseLength": "60"
}
# and then later
{
"requestId": "c8ad1b40-006f-4d03-9d10-c6d91e366380",
"ip": "redacted",
"caller": "-",
"user": "-",
"requestTime": "07/Oct/2019:23:59:58 +0000",
"httpMethod": "GET",
"resourcePath": "/foo/{bar}",
"status": "200",
"protocol": "HTTP/1.1",
"responseLength": "80280"
}