3

I'm writing a http server using node.js and having trouble isolating the request body as a stream readable. Here is a basic sample of my code:

var http = require('http')
  , fs = require('fs');

http.createServer(function(req, res) {
  if ( req.method.toLowerCase() == 'post') {
    req.pipe(fs.createWriteStream('out.txt'));
    req.on('end', function() {
      res.writeHead(200, {'content-type': 'text/plain'})
      res.write('Upload Complete!\n');
      res.end();
    });
  }
}).listen(8182);
console.log('listening on port 8182');

According to node's documentation the a request param is an instance of http.IncomingObject which implements node's readable stream interface. The problem with just using stream.pipe() as I did above is the readable stream includes the plain text of the request headers along with the request body. Is there a way to isolate only the request body as a readable stream?

I'm aware that there are frameworks for file uploads such as formidable. My ultimate goal is not to create an upload server but to act as a proxy and stream the request body to another web service.

thanks in advance.

Edit>> working server for "Content-type: multipart/form-data" using busboy

var http = require('http')
  , fs = require('fs')
  , Busboy = require('busboy');

http.createServer(function(req, res) {
  if ( req.method.toLowerCase() == 'post') {
    var busboy = new Busboy({headers: req.headers});
    busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
      file.pipe(fs.createWriteStream('out.txt'));
    });
    req.pipe(busboy);
    req.on('end', function() {
      res.writeHead(200, 'Content-type: text/plain');
      res.write('Upload Complete!\n');
      res.end();
    });
  }
}).listen(8182);
console.log('listening on port 8182');
1
  • Are you sure these are headers? this is not supposed to happen Commented May 9, 2014 at 23:45

1 Answer 1

1

Check your req.headers['content-type']. If it's multipart/form-data then you could use a module like busboy to parse the request for you and give you readable streams for file parts (and plain strings for non-file parts if they exist).

If the content-type is some other multipart/* type, then you could use dicer, which is the underlying module that busboy uses for parsing multipart.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @mscdex your notion of request headers was spot on. I played around a bit and if I sent my request with Content-type: application/x-www-form-urlencoded my original code worked. If I sent my request with Content-type: multipart/form-data then the busboy solution worked nicely. See my edit above for that solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.