Распаковка данных, полученных в виде двоичных данных в лямбде - неверная проверка заголовка - PullRequest
1 голос
/ 10 апреля 2019

Я хочу отправить сжатые данные (gzip) на некоторый URL, который вызовет (прокси) лямбда-функцию, которая будет распаковывать данные.

Лямбда-функция (NodeJS 8):

let zlib = require('zlib');
exports.handler = async (event) => {
    let decompressedData = zlib.gunzipSync(event['body'])
    return {
        "statusCode": 200,
        "body": decompressedData.toString()
    };
};

Я запускаю его с помощью команды curl для URL (через шлюз API) для некоторого файла, который я сжал example.gz с помощью gzip:

curl -X POST --data-binary @example.gz https://URL...

В результате я получаю:

{"message": "Internal server error"}

А ошибка такая (входит в Cloudwatch):

   "errorMessage": "incorrect header check",
    "errorType": "Error",
    "stackTrace": [
        "Gunzip.zlibOnError (zlib.js:153:15)",
        "Gunzip._processChunk (zlib.js:411:30)",
        "zlibBufferSync (zlib.js:144:38)",
        "Object.gunzipSync (zlib.js:590:14)",
        "exports.handler (/var/task/test_index.js:5:33)"
    ]

Когда я смотрю на сам event['body'], я вижу точные данные, как я вижу в example.gz. Возможно, мне нужен какой-то специальный заголовок? Я просто хочу передать данные как есть.

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

как Майкл - sqlbot сказал: По умолчанию API-шлюз не может передавать двоичные данные в функцию Lambda.

Что сработало для меня: я добавил заголовок Content-Type: application/octet-stream вкоманда curl и в настройках шлюза API на Binary Media Types я добавил application/octet-stream.

Таким образом, данные передаются в base64, а затем я просто преобразовал дату в base64 вбуфер:

let data = Buffer.from(event['body'], "base64")

А затем просто распакуйте его.

Для получения дополнительной информации читайте здесь

0 голосов
/ 10 апреля 2019

1 / Сначала вам нужно правильно построить gzip, убедитесь, что заголовок gzip-файла отсутствует: команда curl отправляет тело POST gzip на сервер apache

Неправильный путь:

echo '{ "mydummy" : "json" }' > body
gzip body
hexdump -C body.gz
00000000  1f 8b 08 08 20 08 30 59  00 03 62 6f 64 79 00 ab  |.... .0Y..body..|
00000010  56 50 ca ad 4c 29 cd cd  ad 54 52 b0 52 50 ca 2a  |VP..L)...TR.RP.*|
00000020  ce cf 53 52 a8 e5 02 00  a6 6a 24 99 17 00 00 00  |..SR.....j$.....|
00000030

Хороший способ:

echo '{ "mydummy" : "json" }' | gzip > body.gz
hexdump -C body.gz
00000000  1f 8b 08 00 08 0a 30 59  00 03 ab 56 50 ca ad 4c  |......0Y...VP..L|
00000010  29 cd cd ad 54 52 b0 52  50 ca 2a ce cf 53 52 a8  |)...TR.RP.*..SR.|
00000020  e5 02 00 a6 6a 24 99 17  00 00 00                 |....j$.....|
0000002b

2 / В curl не забудьте указать кодировку содержимого с помощью

-H "Content-Encoding: gzip"

3 / Кроме того, если вы используетеэкспресс + сжатие вам не нужно звонить zlib

 curl -X POST "http://example.org/api/a" -H "Content-Encoding: gzip" -H "Content-Type: application/json" --data-binary @body.gz

router.post("/api/a", function(req, res){
    console.log(req.body); // { mydummy: 'json' }
});
...