Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reproducing fs.createReadStream with a buffer

I need to send a pdf to an api with formData. I download the pdf which when logged look like this: <Buffer 6d 61 67 65 49 2f ... > If I fs.writeFileSync it is perfectly readable. But I want to try to pass it to the api without having to write it with fs, to manipulate the pdf as a buffer. My post look like this:

const formData = new FormData();
formData.append('access_key', this.config.redacted);
formData.append('redacted','redacted');
formData.append('file', fs.createReadStream('./filename.pdf'));
return post('urlRedacted', formData, {
    headers: formData.getHeaders(),
})

This request will succeed and but it requires me to write the file with fs, which I want to avoid. I tried a few things like using the library node-streamifier to help me create readable stream from a buffer, but the api send me back an error: { error: 'Invalid parameter \'file\' or \'bucket\': Object expected' }.

So my question is, how to reproduce fs.createReadStream behaviour, which seems to be the only one working for my use case?

note: I tried to implement this solution like this: formData.append('file', createReadStream(myBuffer)) and like this formData.append('file', createReadStream(myBuffer,{ encoding: 'binary' })) but did not changed anything to the error.

SOLUTION:

fs was streaming the data and was intelligently adding some info from the file that it was reading and thus provided this line at the start of the stream of data:

_streams:
[ '----------------------------622545709057705753853273\r\nContent-
Disposition: form-data; name="file"; filename="tickets.pdf"\r\nContent-Type: application/pdf\r\n\r\n',

This data were required to be a valid upload, so I added them to the my formData like this: formData.append("file", buffer, {contentType: "application/pdf", filename: "tickets.pdf"})

It seems to have something to do with Blob, which I know nothing about! But this solution work perfectly!

like image 842
Mathias Ducancel Avatar asked Dec 07 '17 10:12

Mathias Ducancel


1 Answers

I recreated the FormData object as JSON and ended up using the following.

const formData = {
  file: {
    value: (my-file.pdf as a Buffer),
    options: {
      contentType: 'application/pdf',
      filename: 'my-file.pdf'
    }
  }
like image 181
AJ Speller Avatar answered Oct 10 '22 05:10

AJ Speller