I want my web server to have a file POSTed, then forward it in a POST request to another server.
const pug = require('pug');
var cloudinary = require('cloudinary');
var express = require('express');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var request = require('request');
var bodyParser = require('body-parser');
var JSON = require('JSON');
var https = require('https');
var fs = require('fs');
var request = require('request');
var upload = multer({ dest: 'uploads/' });
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; // We are OK with self-signed
var serverURL = 'https://ec2-54-202-139-197.us-west-2.compute.amazonaws.com:443';
var app = express();
var parser = bodyParser.raw();
var result = null;
app.use(parser);
app.set('view engine', 'pug');
app.get('/',upload.single('avatar'), function (req, res) {
return res.render('index.pug', {results: [], result_pics: {}});
});
app.post('/makeRequest*', upload.single('uploadPicture'), function(req, res) {
console.log("Files:");
console.log(req.file);
console.log(req.body);
var r = request.post({url: serverURL, headers: {'User-Agent': 'Client Webserver'}}, function (err, httpResponse, body) {
console.log('got response');
console.log(err);
console.log(body);
body = JSON.parse(body);
content = body['content'];
console.log(content);
message_type = body.message_type;
result_pics = [];
result = [];
if (message_type == "error") {
result = ["ERROR: " + body.content];
}
else if (message_type == "student created") {
result = ["Student created."];
}
else if (message_type == "student deleted") {
result = ["Student deleted."]
}
else if (message_type == "picture inserted") {
result = ["Picture inserted."];
}
else if (message_type == "viewed pictures") {
pics = body.pictures;
for (key in pics) {
result_pics.push(cloudinary.image(pics[key], {width: 300, height: 200, crop: "crop"}));
}
}
else if (message_type == "listing information") {
student_table = body.content["student_table"];
student_to_pic_table = body.content["student_to_pic_table"];
for (i in student_table) {
student = student_table[i];
result.push("Student ID: " + student["student_id"] + " Nickname: " + student["nickname"]);
}
for (i in student_to_pic_table) {
student_pic = student_to_pic_table[i];
result.push("Student ID: " + student_pic["student_id"] + " Pic ID: " + student_pic["image_id"]);
}
}
else {
result = ["ERROR: returned message is not of valid type"];
}
res.render('index.pug', {results: result, result_pics: result_pics});
res.end();
});
var form = r.form();
if (req.file) {
form.append('uploadPicture', req.file);
}
form.append('content', JSON.stringify(req.body));
});
app.listen(3000, function() { console.log('listening'); });
So, I get the following error when req.file is true:
TypeError: source.on is not a function
at Function.DelayedStream.create (/home/daniel/node_modules/delayed-stream/lib/delayed_stream.js:33:10)
at FormData.CombinedStream.append (/home/daniel/node_modules/combined-stream/lib/combined_stream.js:43:37)
at FormData.append (/home/daniel/node_modules/form-data/lib/form_data.js:68:3)
at /home/daniel/WebstormProjects/CloudA3 Client/CloudA3/skrpt.js:95:18
at Layer.handle [as handle_request] (/home/daniel/node_modules/express/lib/router/layer.js:95:5)
at next (/home/daniel/node_modules/express/lib/router/route.js:131:13)
at Immediate.<anonymous> (/home/daniel/node_modules/multer/lib/make-middleware.js:53:37)
at Immediate.immediate._onImmediate (timers.js:440:18)
at processImmediate [as _immediateCallback] (timers.js:383:17)
got response
{ [Error: socket hang up] code: 'ECONNRESET' }
I am guessing that I need to convert req.file to some other type in order to transfer it, but I cannot find any information about this anywhere, nor any examples, nor can I find out what the type of req.file even is!
How can I solve this problem?
Since you're using multer and DiskStorage the req.file object has the full path where the file content is stored locally in the req.file.path property. You can use this to create a stream.Readable via fs.createReadStream() and pass that directly to the form. So very easily you can do something like this.
form.append('uploadPicture', fs.createReadStream(req.file.path))
I am working on uploading a file to another server through a backend. I'm currently using multer with MemoryStorage and req.file.buffer for the form data, where I also had to include the filename, which also caused the content type to be set correctly.
form.append('uploadPicture', req.file.buffer, { filename: req.file.originalname });
It is also possible to copy the content type from the request:
form.append('uploadPicture', req.file.buffer, { contentType: req.file.mimetype, filename: req.file.originalname });
I'm expecting low usage for the service, so for me MemoryStorage should be fine, but DiskStorage may be better for your use case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With