Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

How to disable Express BodyParser for file uploads (Node.js)

How to disable Express BodyParser for file uploads (Node.js)

Problem

This seems like it should be a fairly simple question, but I'm having a really hard time figuring out how to approach it.

I'm using Node.js + Express to build a web application, and I find the connect BodyParser that express exposes to be very useful in most cases. However, I would like to have more granular access to multipart form-data POSTS as they come - I need to pipe the input stream to another server, and want to avoid downloading the whole file first.

Because I'm using the Express BodyParser, however, all file uploads are parsed automatically and uploaded and available using "request.files" before they ever get to any of my functions.

Is there a way for me to disable the BodyParser for Multipart Formdata Posts without disabling it for everything else?

Problem courtesy of: Myk

Solution

When you type app.use(express.bodyParser()), almost each request will go through bodyParser functions (which one will be executed depends on Content-Type header).

By default, there are 3 headers supported (AFAIR). You could see sources to be sure. You can (re)define handlers for Content-Types with something like this:

var express = require('express');
var bodyParser = express.bodyParser;

// redefine handler for Content-Type: multipart/form-data
bodyParser.parse('multipart/form-data') = function(req, options, next) {
  // parse request body your way; example of such action:
  // https://github.com/senchalabs/connect/blob/master/lib/middleware/multipart.js

  // for your needs it will probably be this:
  next();
}

upd.

Things have changed in Express 3, so I'm sharing updated code from working project (should be app.useed before express.bodyParser()):

var connectUtils = require('express/node_modules/connect/lib/utils');

/**
 * Parses body and puts it to `request.rawBody`.
 * @param  {Array|String} contentTypes Value(s) of Content-Type header for which
                                       parser will be applied.
 * @return {Function}                  Express Middleware
 */
module.exports = function(contentTypes) {
  contentTypes = Array.isArray(contentTypes) ? contentTypes
                                             : [contentTypes];
  return function (req, res, next) {
    if (req._body)
      return next();

    req.body = req.body || {};

    if (!connectUtils.hasBody(req))
      return next();

    if (-1 === contentTypes.indexOf(req.header('content-type')))
      return next();

    req.setEncoding('utf8');  // Reconsider this line!
    req._body   = true;       // Mark as parsed for other body parsers.
    req.rawBody = '';

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

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

And some pseudo-code, regarding original question:

function disableParserForContentType(req, res, next) {
  if (req.contentType in options.contentTypes) {
    req._body = true;
    next();
  }
}
Solution courtesy of: elmigranto

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

How to disable Express BodyParser for file uploads (Node.js)

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×