Writing express middleware to get raw request body before body-parser

kiewic picture kiewic · Nov 16, 2016 · Viewed 7.4k times · Source

I wrote an Express middleware to retrieve the raw body from the request, and I set it before body-parser middleware.

My custom middleware is calling req.setEncoding('utf8'), but this causes the following body-parser error:

Error: stream encoding should not be set

at readStream (/node_modules/body-parser/node_modules/raw-body/index.js:211:17) 
at getRawBody (/node_modules/body-parser/node_modules/raw-body/index.js:106:12)
at read (/node_modules/body-parser/lib/read.js:76:3)
at jsonParser (/node_modules/body-parser/lib/types/json.js:127:5)

Here is my code:

var express = require('express');
var bodyParser = require('body-parser')

function myMiddleware() {
  return function(req, res, next) {
    req.rawBody = '';
    req.setEncoding('utf8');

    req.on('data', function(chunk) {
      req.rawBody += chunk;
    });

    req.on('end', function() {
      next();
    });
  }
}

var app = express();
app.use(myMiddleware());
app.use(bodyParser.json());

var listener = app.listen(3000, function() {
});

app.get('/webhook/', function (req, res) {
  res.sendStatus(200);
});

Is there a way to unset the encoding? Is there another way to retrieve the raw body, but still use body-parser after it?

Answer

kiewic picture kiewic · Nov 17, 2016

It turns out that body-parser has a verify option to call a function when the request body has been read. The function receives the body as a buffer.

Here is an example:

var express = require('express');
var bodyParser = require('body-parser')

function verifyRequest(req, res, buf, encoding) {
  // The raw body is contained in 'buf'
  console.log( buf.toString( encoding ) );
};

var app = express();
var listener = app.listen(3000);

// Hook 'verifyRequest' with body-parser here.
app.use(bodyParser.json({ verify: verifyRequest }))

app.post('/webhook/', function (req, res) {
  res.status(200).send("done!");
});