在lambda中解压缩作为二进制数据接收的数据-错误的标头检查

时间:2019-04-10 11:45:09

标签: node.js curl post aws-lambda gzip

我想将压缩数据(gzip)发送到某个URL,该URL将触发(代理)lambda函数,从而对数据进行解压缩。

lambda函数(NodeJS 8):

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

对于我用gzip压缩example.gz的某些文件,我通过向URL的curl命令触发了它(通过API网关):

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 个答案:

答案 0 :(得分:1)

Michael - sqlbot所说,默认情况下,API网关无法将二进制数据传递到Lambda函数中。

对我有用的是: 我在curl命令中添加了标题Content-Type: application/octet-stream,并且在API网关设置中的Binary Media Types上添加了application/octet-stream

通过这种方式,数据在base64中传递,然后我将base64中的日期转换为缓冲区:

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

然后解压缩它。

有关更多信息,read here

答案 1 :(得分:0)

1 /首先,您需要正确构建gzip,确保不存在gzip文件头:curl command a gzipped POST body to an apache server

错误的方式:

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中,别忘了用-p指定内容编码

-H "Content-Encoding: gzip"

3 /另外,如果您使用express + compress,则无需调用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' }
});