In my node.js-application, I need to read data from a MongoDB with GridFS and upload it to another server via POST
request, I am using the modules gridfs-stream
, request
and multer
.
According to the request
docs I can simply add a stream for multipart/form-data
, so I'm doing this:
var fileUuid = "myFilename";
var options = {
url: "url.to/my/target/",
method: "POST",
header: {"Content-Type": "multipart/form-data"},
formData: {
filedata: gfs.createReadStream({filename: fileUuid})
}
}
request(options, function(error, response, body) {
if (error) {
console.log("[" + getDateTime() + "] Error replicating file:");
console.log(error);
return;
}
console.log('statusCode: ', response && response.statusCode);
console.log('body: ', body);
});
On my receiving server, I have the following code:
var upload = multer({ dest: './tmp_upload/' })
app.post('/my/target', upload.single('filedata'), function(req, res) {
console.log('['+getDateTime()+'] Request received');
}
But whenever I am executing the request, I get the following error on my sending server:
[2019:07:26:16:52:00] Error replicating file:
Error: write ECONNRESET
and this on my receiving server:
Error: Unexpected end of multipart data
at c:\Users\...\node_modules\dicer\lib\Dicer.js:62:28
at process._tickCallback (internal/process/next_tick.js:61:11)
Can anybody please give me a hint how to POST
my file from one server to another?
EDIT:
The issue seems to be the gfs.createReadStream({filename: fileUuid})
type of stream... When I write the file to the filesystem first and instead put an fs.createReadStream(...)
into the form as formData, then it works.
But is there an option to direct the stream directly into the formData, without having to write it to disk first?
So I ended up working with a temporary file that I read from the database, write it to disk and create a new readStream
that I then put into the request. After the request was successful, I delete the temporary file from my disk and continue with my code:
var fsstreamwrite = fs.createWriteStream("./tmp/" + myFile);
var readstream = gfs.createReadStream( {filename: myFile} );
readstream.pipe(fsstreamwrite);
readstream.on("close", function () {
console.log("File read successfully from database");
var options = {
url: "url.to/my/target/",
method: "POST",
enctype: "multipart/form-data",
formData: {
"filedata": fs.createReadStream('./tmp/' + myFile)
}
}
request(options, function(error, response, body) {
if (error) {
// error handling
return;
}
// delete temporary file
fs.unlinkSync('./tmp/' + myFile)
// continue with my stuff...
});
});