Currently, I am tackling an issue with the serverless framework and serverless-http library while attempting to decompress a binary request. The peculiar thing is that the exact code segment functions properly in a typical expressjs server but encounters issues when used with serverless-http.
The following portion showcases the minimal representation of a functional ordinary expressjs server:
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}`);
});
Here is the minimal representation of a serverless lambda handler using serverless-http that fails to 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);
When sending binary files with Postman https://i.sstatic.net/7xI7J.png,
The aforementioned code snippet encounters an 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'
}
resulting in the error response:
{
"error": {
"errno": -3,
"code": "Z_DATA_ERROR"
},
"message": "incorrect header check"
}
I am puzzled about what I might be doing incorrectly. Perhaps, should I consider employing a different approach to decompress binary files with a gz extension in the serverless expressjs application?