oliakaoil
oliakaoil

Reputation: 1699

How to send HTTP response directly as ExpressJS response without writing to disk

I am trying to request an image from a URL using the HTTP module, and then send the contents of the response directly as the response given by my ExpressJS app (without writing the image request response to disk first). Basically, I want to download the file from its external URL into the memory of my app server, and then send it as as a response.

Here's what I have so far:

 var http = require('http');
 var imageUrl = 'http://vignette3.wikia.nocookie.net/clubpenguinpookie/images/d/d0/Extremely-cute-kitten_large.jpg/revision/latest?cb=20140614000321';

 var req = http.request( imageUrl  , function(response) {

    var contents = [];
    var content_length = 0;

    response.setEncoding('binary');

    response.on('data', function (chunk) {
      contents.push( chunk );
      content_length += chunk.length;
    });

    response.on('end', function() {

      res.set('Content-Type', 'image/jpeg');
      res.set('Content-Length', content_length );

      contents.forEach(function(chunk){
        res.send( chunk );
      });

      res.end();
    })

});      

req.end();

As you can see from the above, I am storing the request response as a series of chunks in an array. I then send each chunk using the ExpressJS response object. When I hit this endpoint in the browser, I get the correct content type and length headers back, and some data, but the image does not load and Firefox tells me it contains errors.

Upvotes: 0

Views: 84

Answers (1)

mscdex
mscdex

Reputation: 106736

Just set the appropriate header(s) and pipe the streams together. For example:

var http = require('http');
var imageUrl = 'http://vignette3.wikia.nocookie.net/clubpenguinpookie/images/d/d0/Extremely-cute-kitten_large.jpg/revision/latest?cb=20140614000321';

http.get(imageUrl, function(response) {
  if (response.statusCode !== 200) {
    res.statusCode = 500;
    return res.end();
  }

  res.set('Content-Type', 'image/jpeg');
  response.pipe(res);
});

Piping is simpler, ensures that there are no binary data conversion issues, and it allows stream backpressure to do its thing.

Upvotes: 1

Related Questions