Max
Max

Reputation: 1459

Node.js: serving dynamic pdf, coming up empty

I have a node service that fetches a pdf from an API and serves that pdf.

When I curl or directly open the API, I do see the correct pdf.

But when I serve it from my Node app, I get an empty pdf.

Here's the section of my code that does the pdf render.

} else if (options.type === 'pdf') {
  res.writeHead(200, {'content-type' : 'application/pdf', 'content-disposition': 'attachment; filename=invoice.pdf'});
  res.end(data.invoice);

I've console.log'ed data.invoice to know it's the right stuff.

typeof(data.invoice) gives string; but I've also tried res.end(new Buffer(data.invoice)); which didn't work either.

Here's the section of my code that fetches the data

var http_options = {
  method : options.method
, host : Config.API.host
, path : options.path
, port : Config.API.port
, headers : options.headers
};

var req = http.request(http_options, function (response) {
  var raw_response = "";

  response.on('data', function (response_data) {
    raw_response += response_data.toString();
  });

  response.on('end', function () {
    if (response.statusCode !== 200) {
      cb(raw_response);
    } else {
      cb(false, raw_response);
    }
  });
});

req.setTimeout(timeout, function () {
  req.abort();
  cb("API connection timed out");
});

req.on('error', function (error) {
  cb("API error while requesting for " + options.path + '\n' + error + '\n' + "http   options: " + JSON.stringify(http_options)
});

req.end();

Upvotes: 1

Views: 2626

Answers (2)

Peter Lyons
Peter Lyons

Reputation: 145994

Since you don't intend to modify or read this data in transit, I suggest just using the pipe function to pipe all the data coming in from response out to req. this question has a good sample, but here's an excerpt.

req.on('response', function (proxy_response) {
    proxy_response.pipe(response);
    response.writeHead(proxy_response.statusCode, proxy_response.headers);
});

Note that there's no reason to convert the chunks coming in from the response from Buffers to something else, just write them through as unmodified buffers, and stream them (this is what pipe will do for you) instead of accumulating them to get maximum efficiency (and node.js streaming hipster points).

Upvotes: 1

ebohlman
ebohlman

Reputation: 15003

It's quite likely that the toString() and concatenation when you're receiving the PDF are corrupting it. Try writing raw_response to a file (you can use writeFileSync() since this is just a one-time test) and doing a byte-for-byte comparison with the same PDF retrieved with curl.

Note that if the process of string conversion has corrupted it, trying to convert it back to a buffer before sending it won't help. You'll have to keep the whole thing as a buffer from start to finish.

Upvotes: 2

Related Questions