title: Stream binary file with http post
body: <p>I'm using the request library to send a binary (pdf) file in the body of the request using http post  (NOTE: This API does not accept multi-part forms).  However, I have only been able to get it to work using <code>fs.readFilesync()</code>.  For some reason, when I try to use <code>fs.createReadStream()</code> the pdf file is still sent, <strong>but it is empty</strong>, and <strong>the request never finishes</strong> (I never get a response back from the server).</p>
  
  <p>Here is my working version using <code>fs.readFileSync()</code>:</p>
  
  <pre><code>const request = require('request');
  const fs = require('fs');
  
  const filename = 'test.pdf';
  
  request({
      url: 'http://localhost:8083/api/v1/endpoint',
      method: 'POST',
      headers: {
          'Content-Type': 'application/octet-stream',
          'Accept': 'application/vnd.api+json',
          'Content-Disposition': `file; filename="${filename}"`
      },
      encoding: null,
      body: fs.readFileSync(filename)
  }, (error, response, body) =&gt; {
      if (error) {
          console.log('error:', error);
      } else {
          console.log(JSON.parse(response.body.toString()));
      }
  });
  </code></pre>
  
  <p>If I try to replace the body with the below, it doesn't work:</p>
  
  <pre><code>body: fs.createReadStream(filename)
  </code></pre>
  
  <p>I have also tried piping the http request on to the stream, like it says in the request library docs, but I get the same result:</p>
  
  <pre><code>fs.createReadStream(filename).pipe(request({...}))
  </code></pre>
  
  <p>I've tried to monitor the stream by doing the following:</p>
  
  <pre><code>var upload = fs.createReadStream('test.pdf');
  
  upload.pipe(req);
  
  var upload_progress = 0;
  upload.on("data", function (chunk) {
      upload_progress += chunk.length
      console.log(new Date(), upload_progress);
  })
  
  upload.on("end", function (res) {
      console.log('Finished');
      req.end();
  })
  </code></pre>
  
  <p>I see progress for the stream and <code>Finished</code>, but still no response is returned from the API.</p>
  
  <p>I'd prefer to create a read stream because of the benefits of working better with larger files, but am clueless as to what is going wrong.  I am making sure I'm not altering the file with any special encoding as well.  </p>
  
  <p>Is there some way to get some kind of output to see what process is taking forever?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>I decided to test with a simple 1 KB <code>.txt</code> file.  I found that it is still empty using <code>fs.createReadStream()</code>, however, this time I got a response back from the server.  The test PDF I'm working with is 363 KB, which isn't outrageous in size, but still... weren't streams made for large files anyway?  Using <code>fs.readFileSync()</code> also worked fine for the text file.</p>
  
  <p>I'm beginning to wonder if this is an synchronous vs asynchronous issue.  I know that <code>fs.readFileSync()</code> is synchronous.  Do I need to wait until <code>fs.createReadStream()</code> finishes before trying to append it to the body?</p>