[SOLVED] - Access raw request body

I’m working on an app that has to accept webhook requests and needs access to the raw request body. I’m currently using simple:json-routes to make the process of setting up route handlers simple. This unfortunately means that a json body parser gets run at some point in the process and makes using bodyParser.raw() useless. I’ve tried setting request.on('data/end') events to get the raw body, and using the raw-body module, and both of these methods just cause the request to hang till it times out.

Any idea how I might get access to this… At this point I don’t even care if it’s a horridly ugly hack :joy:, I just need it to work.

You are better off just using WebApp from the meteor/webapp package.

Example:

import { WebApp } from 'meteor/webapp';

WebApp.connectHandlers
	.use(bodyParser.urlencoded({ extended: true }))
	.use(bodyParser.text())
	.use(bodyParser.json())
	.use('/path/for/route', (req, res, next) => {
		if (
			req.method !== 'POST' // that is, if you're only interested in POST
		) {
			next();
		} else {
			const { body } = req;
			... rest of code here ...
		}
	});

Hope this helps!

4 Likes

I haven’t used simple:json-routes before, but I have used Picker in the past. And following code worked for me.

//somewhere on the server
import  bodyParser from "body-parser";

Picker.middleware(bodyParser.raw());


Picker.route("/callback/item/:id", (params, req, res) => {
  res.setHeader('Content-Type', 'text/html');

  let data = '';
  req.on('data', (chunk) => {
    data += chunk;
  });

  req.on('end', () => {
    console.log('No more data.');
    console.log(data);
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('ok');
  });

});

Yes, I was afraid it would come down to this. I was really hoping not to have to refactor everything though :joy:

You could make a local copy and add some first middleware that stores the rawBody somewhere?

Yeah, I’ve actually cloned and I’m in the process of rewriting the package. Turns out that the raw body parser and json body parser conflict in some way… If I add the raw body parser first the json body parser hangs and vice versa.

To fix this I’m adding an option to the add method that if true will add the raw body parser to the individual route, otherwise add the json body parser.

Houston, we have a liftoff. :rocket:

2 Likes

@laddih THANK YOU this was killing me. Tagging this for SEO: [Object: null prototype] solved

Yeah this is still one of the most clean answer in similar questions. :wink:

If you use Iron Router, the following can be added in your server routes. Per the Iron Router guide it bundles body-parser:

Router.onBeforeAction(Iron.Router.bodyParser.raw({
  type: 'application/json'
}), {
  only: ['stripeWebhooks']
});

This will set the action of the route’s this.request.body to the raw request body. Useful for authenticating Stripe webhooks as they require the raw request body.