I am working with serverless framework and serverless-http library and trying to decompress the binary request. The weird thing that the identical part of code works in ordinary expressjs server but fails to work with serverless-http.
The working minimal representation part of ordinary expressjs server that works fine.
const express = require("express");
const { unzip } = require("node:zlib");
const zlib = require("node:zlib");
const { promisify } = require("node:util");
const compression = require("compression");
const http = require("http");
const app = express();
const port = process.env.PORT || 5002;
app.use(express.json());
app.use(compression());
const do_unzip = promisify(unzip);
app.post("/unzip", async (req, res, next) => {
const isAccepted = req.headers["content-type"] === "application/gzip";
if (!isAccepted) return res.status(406).json({ message: "Not Acceptable" });
const data = [];
req.addListener("data", (chunk) => {
data.push(Buffer.from(chunk));
});
req.addListener("end", async () => {
const buff = Buffer.concat(data);
try {
const buffRes = await do_unzip(buff);
const result = buffRes.toString();
return res.status(200).json({
result,
});
} catch (error) {
next(error);
}
});
});
const server = http.createServer(app).listen(port, () => {
const addressInfo = server.address();
console.log(`Listening on port ${addressInfo.port}`);
});
The minimal representation of serverless lambda handler with serverless-http that does not work:
const serverless = require("serverless-http");
const express = require("express");
const { gunzip } = require("node:zlib");
const zlib = require("node:zlib");
const { promisify } = require("node:util");
const compression = require("compression");
const app = express();
app.use(express.json());
app.use(compression());
const do_unzip = promisify(gunzip);
app.post("/unzip", async (req, res, next) => {
const isAccepted = req.headers["content-type"] === "application/gzip";
if (!isAccepted) return res.status(406).json({ message: "Not Acceptable" });
const data = [];
req.addListener("data", (chunk) => {
data.push(Buffer.from(chunk));
});
req.addListener("end", async () => {
const buff = Buffer.concat(data);
try {
const buffRes = await do_unzip(buff, {
finishFlush: zlib.constants.Z_SYNC_FLUSH,
});
const result = buffRes.toString();
return res.status(200).json({
result,
});
} catch (error) {
next(error);
}
});
});
app.use((err, req, res, next) => {
console.error(err);
return res.status(500).json({
error: err,
message: err.message,
});
});
module.exports.handler = serverless(app);
Sending binary files with postman
The part of code shown above fails with error:
Error: incorrect header check
at Zlib.zlibOnError [as onerror] (node:zlib:189:17)
at Zlib.callbackTrampoline (node:internal/async_hooks:130:17) {
errno: -3,
code: 'Z_DATA_ERROR'
}
and error response
{
"error": {
"errno": -3,
"code": "Z_DATA_ERROR"
},
"message": "incorrect header check"
}
Can not understand what am I doing wrong. Or maybe I should use different approach to decompress binary file with gz extension in the serverless expressjs app ?