Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unzip POST body with node + express

I've a simple node app that should write metrics from clients. Clients send metrics in json format zipped with python's zlib module, I'm trying to add a middleware to unzip the request post before the express bodyParse takes place.

My middlewares are simply the ones provided by express by default:

app.configure(function(){
    app.set('port', process.env.PORT || 3000);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser('your secret here'));
    app.use(express.session());
    app.use(app.router);
    app.use(require('less-middleware')({ src: __dirname + '/public' }));
    app.use(express.static(path.join(__dirname, 'public')));
});

I've tried to add a simple middleware that gets the data and then unzips it:

app.use(function(req, res, next) {
    var data = '';
    req.addListener("data", function(chunk) {
        data += chunk;
    });

    req.addListener("end", function() {
        zlib.inflate(data, function(err, buffer) {
            if (!err) {
                req.body = buffer;
                next();
            } else {
                next(err);
            }
        });
    });
});

The problem is with zlib.inflate I get this error:

Error: incorrect header check

The data has been compressed with python's zlib module:

zlib.compress(jsonString)

but seems that neither unzip, inflate, gunzip works.

like image 613
alex88 Avatar asked Jan 07 '13 11:01

alex88


People also ask

How do I get a body in Express?

JSON Request Body Express has a built-in express. json() function that returns an Express middleware function that parses JSON HTTP request bodies into JavaScript objects. The json() middleware adds a body property to the Express request req . To access the parsed request body, use req.

How do you use bodyParser?

To use the Text body parser, we have to write app. use(bodyParser. text()) and the Content-Type in your fetch API would be text/html . That's it, now your backend service will accept POST request with text in the request body.


2 Answers

Found the solution on my own, the problem was with this piece of code:

req.addListener("data", function(chunk) {
    data += chunk;
});

seems that concatenating request data isn't correct, so I've switched my middleware to this:

app.use(function(req, res, next) {
    var data = [];
    req.addListener("data", function(chunk) {
        data.push(new Buffer(chunk));
    });
    req.addListener("end", function() {
        buffer = Buffer.concat(data);
        zlib.inflate(buffer, function(err, result) {
            if (!err) {
                req.body = result.toString();
                next();
            } else {
                next(err);
            }
        });
    });
});

concatenating buffers works perfectly and I'm now able to get request body decompressed.

like image 157
alex88 Avatar answered Sep 17 '22 15:09

alex88


I know this is a very late response, but with module body-parser, it will:

Returns middleware that only parses json. This parser accepts any Unicode encoding of the body and supports automatic inflation of gzip and deflate encodings.

var bodyParser = require('body-parser');
app.use( bodyParser.json() );       // to support JSON-encoded bodies
like image 30
Foo L Avatar answered Sep 18 '22 15:09

Foo L