uploading file to ftp server in node.js - javascript

I am trying to upload a file on ftp server using node.js as below-
I am using library- https://github.com/sergi/jsftp
var fs = require('fs');
var Ftp = new JSFtp({
host: "ftp.some.net",
port: 21, // defaults to 21
user: "username", // defaults to "anonymous"
pass: "pass",
debugMode: true // defaults to "#anonymous"
});
Uploading file-
exports.UploadToFtP = function (req, res) {
Ftp.put('public/Test.html', '/Test/index.html', function (err) {
if (!err)
res.send(200);
else
res.send(err);
});
};
I tried uploading file with this method above and it responds me back with 200 OK . But I get no file on server.
Is this has to do something with connection time out of server ? Why this is not writing file on server?

If the debug mode is on, the jsftp instance will emit jsftp_debug events.
In order to react to print all debug events, we would listen to the debug messages like this:
Ftp.on('jsftp_debug', function(eventType, data) {
console.log('DEBUG: ', eventType);
console.log(JSON.stringify(data, null, 2));
});

The raw FTP accepts no parameters and returns the farewell
message from the server. Embed raw FTP function in the FTP GET method
We can use raw FTP commands directly as well. In this case, we use FTP
'QUIT' method, which accepts no parameters and returns the farewell
message from the server
ftp.raw.quit(function(err, res) {
if (err)
return console.error(err);
console.log("FTP session finalized! See you soon!");
});

The file needs to be converted to bytes first.
var fs = require('fs');
fs.readFile('example.txt', function (err, data ) {
Ftp.put(data, 'example.txt', function (err) {
if (!err) {
console.log('OK');
} else {
console.log('ERR');
}
});
});

Related

Sending file through HTTP request

I tried to receive the file and store it in the multer storage
Node js code
enter code here
app.post('/createLicence', upload.single('photo'),function(req, res ,next) {
// any logic goes here
console.log("filename" ,req.body.name)
if (!req.file) {
console.log("No file received");
return res.send({
success: false
});
} else {
console.log('file received');
var function_name = 'createLicence'
var arguments_array = [req.file.path,'Raghav','Mumbai','Approved']
invoke = require('/Users/sanjeev.natarajan/fabric-samples/fabcar/invoke.js');
invoke.invokechaincode(function_name,arguments_array)
return res.send({
success: true
})
}
});
but i am receiving no file is receivedi have send the request through postman
-
From : https://www.npmjs.com/package/multer
In order to use the multer package, you have first to define a few parameters so that it can work on your fileDirectory.
In your server.js :
let multer = require('multer');
let storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, '/path/to/storage/')
},
filename: function(req, file, callback) {
callback(null, file.originalname + '-' + Date.now());
}
});
let upload = multer({
storage: storage
});
Now, configure your route
router.route('/your/payload')
.post(authController.isAuthenticated, upload.any(), albumController.postFile)
Note that upload.any() will allow you to upload multiple different formatted files at once. Feel free to use any other kind of upload.method() depending on your needs.
From this point, multer already is doing its job, however you might want to keep track of the files uploaded on your server.
So, in your own module, the logic is pretty much straight forward :
(I'm assuming that you're using mongoose models since you're not giving much information, but that's not the relevant part anyway)
exports.postFile = async (req, res) => {
if (!req || !req.files || !req.files[0]) return res.status(400).send("Bad request.");
for (let i = 0; req.files[i]; i++) {
await File.create({
path: req.files[i],
originalName: req.files[i].originalName,
mimetype: req.files[i].mimetype,
owner: req.user.userId
}, (err, file) => {
if (err) console.log("Something went wrong: " + err); else {
// Do something with file
}
});
}
return res.status(418).send("I'm a teapot.");
}
This configuration and middleware use is ONLY for testing purpose, never ever let anyone upload something to your server without carefully handle that uploading process (file integrity, resource management, ...). An open uploading system can become a very wide backdoor getting straight to your server.
Hope this helps,
regards.

Node JS file transfer via Request Module

I am creating a node server to which files can be uploaded an then sent to a storage server which is also using node.
To do this i am using this method described on the Form-Data module page:
var formData = {
my_field: 'my_value',
my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
};
request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
My Problem is that when i try to write the file on the storage server it creates a text file with the content [object Object].
Here is my code:
main.js
var form = new formData();
form = {
'oldFileName': oldName,
'newFileName': newName,
'file': fs.createReadStream(FILEPATH),
};
request.post({url:'http://127.0.0.1:9001/upload', form: form}, function(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
});
storage.js
app.post('/upload', function(req,res){
//Filenames are displayed without problem
console.log(req.body.newFileName);
console.log(req.body.oldFileName);
fs.writeFile('./testing/' + req.body.newFileName, req.body.file, function(err) {
if(err) {
return console.log(err);
}
})
I'm sure I'm missing something really obvious, but I cant seem to get it to work.
You are passing formData in form option of request that changes the content to application/x-www-form-urlencodedinstead of multipart/form-data.
app.js
var form = {
'oldFileName': oldName,
'newFileName': newName,
'file': fs.createReadStream(FILEPATH),
};
request.post({url:'http://127.0.0.1:9001/upload', formData: form}, function(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
});
Also, to parse multipart/form-data, you have to use multer or similar library, body-parser doesn't work in that case. Please find following working storage.js code for saving file.
storage.js
var multer = require('multer')
var upload = multer({
storage: multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './testing/');
},
filename: function (req, file, cb) {
cb(null, req.body.newFileName);
}
})
}).single('file');
app.post('/upload', function(req, res, next){
upload(req, res, function (err) {
if(err){
return res.send(err);
} else{
return res.send("Upload successfully");
}
});
});
Hope it helps you.
Alternatively, wrapping the [object Object] within a JSON.stringify() method should reveal the literal string content of the objects.
In my situation I was using the NodeJS Library for YouTube video uploads, following OAuth2.0 protocol.
Within this standard, you post your Client ID and Client Secret to authenticate your usage of the YouTube Data API.
In return, the server returns tokens, in the form of an Access Token and Refresh Token. These tokens are need to refresh the ability to use the API without expiry.
However, I was receiving (Object, object) in the terminal when requesting the 'tokens'....
Logger.log(Got the tokens:(token));
To rectify the problem and reveal the tokens in the terminal in a readable string format, I done the following...
Logger.log(Got the tokens: ${JSON.stringify(token)});
Now I can use the tokens accordingly.
//Note - ES6 backticks are used as string literals, but the backticks don't seem to be displaying in the parameters.

How do I write an image to buffer using native Node JS HTTP library?

I am really new to JavaScript and Node JS. I have various image URLs that I want to buffer. I have tried the request npm module but want a lower level library for what I want to achieve.
For example:
http://assets.loeildelaphotographie.com/uploads/article_photo/image/128456/_Santu_Mofokeng_-_TOWNSHIPS_Shebeen_Soweto_1987.jpg
I see lots of examples that suggest using the request module or examples that save files to disk. However, I cannot find an HTTP GET request example that simply buffers the image so I can pass to another function. It needs to have an "end" event so I upload the buffered image data with confidence in another step. Is there a sample pattern or "how to" on this someone could provide? Thanks!
This is the native way:
var http=require('http'), imageBuffer;
http.get(
'http://www.kame.net/img/kame-anime-small.gif',
function(res) {
var body=new Buffer(0);
if (res.statusCode!==200) {
return console.error('HTTP '+res.statusCode);
}
res.on('data', function(chunk) {
body=Buffer.concat([body, chunk]);
});
res.on('end', function() {
imageBuffer=body;
});
res.on('error', function(err) {
console.error(err);
});
}
);
// Small webserver serving the image at http://127.0.0.1:4567
http.createServer(function(req, res) {
res.write(imageBuffer || 'Please reload page');
res.end();
}).listen(4567, '127.0.0.1');
and using request (encoding:null for binary response):
var request=require('request'), imageBuffer;
request({
uri: 'http://www.kame.net/img/kame-anime-small.gif',
encoding: null
}, function(err, res, body) {
if (err) {
return console.error(err);
} else if (res.statusCode!==200) {
return console.error('HTTP '+res.statusCode);
}
imageBuffer=body;
});
// Small webserver serving the image at http://127.0.0.1:4567
require('http').createServer(function(req, res) {
res.write(imageBuffer || 'Please reload page');
res.end();
}).listen(4567, '127.0.0.1');
Here's a simple example using the built-in streaming that the http response has:
var http = require('http');
var fs = require('fs');
var file = fs.createWriteStream("test.png");
var request = http.get("some URL to an image", function(response) {
response.pipe(file);
});
I ran this myself and successfully downloaded an image from an external web site and saved it to a file and then loaded the file into the browser to see the same image.

How to send response to client when files is too large with Multer

I'm using NodeJs Multer to upload files. I need to send response back to a client when file user tries to upload is too large. The problem is that onFileSizeLimit only has file as argument and I dont know how to send response to client. What I need to do is basically soomething like below:
app.use('/users/gyms/upload-logo', multer({
// other settings here then:
onFileSizeLimit: function (file) {
// but res (response) object is not existing here
res.json({
message: "Upload failed",
status: MARankings.Enums.Status.FILE_TOO_LARGE
// status: -6
});
}
});
res object dosent exists in there however and I'm wondering what is the best way to send some sort of response to client.
try this:
app.use('/users/gyms/upload-logo', multer({
// other settings here then:
onFileSizeLimit: function (file) {
// but res (response) object is not existing here
file.error = {
message: "Upload failed",
status: MARankings.Enums.Status.FILE_TOO_LARGE
// status: -6
};
}, onFileUploadComplete: function (file, req, res) {
if (file.error){
res.send(file.error);
}
}
});
In this case, it's good to remember that Multer itself is just a (middleware) function that Express calls to get its response.
You could perhaps try with this:
app.use('/users/gyms/upload-logo', function(req, res, next) {
var handler = multer({
// other settings here then:
onFileSizeLimit: function (file) {
// res does exist here now :)
res.json({
message: "Upload failed",
status: MARankings.Enums.Status.FILE_TOO_LARGE
// status: -6
});
}
});
handler(req, res, next);
});
This basically aliases multer to handler, passes req, res, next from the Express callback, and means you get access to the req, res, next variables from within Multer's configuration.
I haven't tested this but I think the theory is sound!
This is an issue which has not been resolved by the author of multer yet. This github issue has quite a lot of discussion about it:
There is one work around which I have used in my current project
File: make-middleware.js
change "function done(err)" at end of this function
Replace
Line 52: onFinished(req, function () { next(err) })
With:
Line 52: onFinished(req, function () { if(err.code == 'LIMIT_FILE_SIZE') { req.fileSizeError = 1; next() } else next(err) })
And in app file you can change the code to
app.post('/upload', upload.single('upload'), function (req, res, next) {
if(typeof req.fileSizeError != "undefined") {
res.send({"error":"File too large"});// to display filesize error
} else {
res.send({"file":req.file}); // when file uploaded successfully
}
});
The multer file object actually contains a property indicating whether the file exceeded the size limit. See https://www.npmjs.com/package/multer#multer-file-object
To accept only one file with a maximum size of 2 MB and the name "data" I did something like this:
app.use(multer({
dest: "./uploads/",
putSingleFilesInArray: true, // see https://www.npmjs.com/package/multer#putsinglefilesinarray
limits: {
files: 1,
fileSize: 2097152 // 2 MB
}
}));
app.post("/foo", function(request, response) {
if (!request.files.hasOwnProperty("data")) {
// 400 Bad Request
return response.status(400).end();
}
var file = request.files.data[0];
if (file.truncated) {
// 413 Request Entity Too Large
console.log("Request aborted.");
return response.status(413).end();
}
// do stuff with file
});

How to trigger browser download from Node.JS socket stream?

my node.js app connects through var socket = net.createConnection(port, ip); to download a file from another server. As soon as connection is made the server sends the file as data.
I catch it then by doing
socket.on('data', function(data) {
}).on('connect', function() {
}).on('end', function() {
console.log('DONE');
});
My initial goal is, to download the file using the method above and at the same time give the bytes to the client's browser as a downloadable file. For example: user clicks a button on the site which triggers the server-side download function and the user gets the file-save prompt. Node.JS then downloads the file from the remote server and at the same time gives each new byte to the user at the browser client. Is this possible? I imagine it would need to send headers of octet-stream to trigger file transfer between browser Node.JS. But how?
Update
Now I tried the code below with the help of the answer below:
app.get('/download', function (req, res) {
res.setHeader('Content-disposition', 'attachment; filename=' + "afile.txt");
res.setHeader('Content-Length', "12468")
var socket = net.createConnection(1024, "localhost");
console.log('Socket created.');
socket.on('data', function(data) {
socket.pipe(res)
}).on('connect', function() {
// // Manually write an HTTP request.
// socket.write("GET / HTTP/1.0\r\n\r\n");
}).on('end', function() {
console.log('DONE');
socket.end();
});
});
The data is being sent to the user's browser as a download, but the end result is a broken file. I checked the contents within and it seeems that something along the process causes the file to corrupt.
I think now I have to write byte per byte? rather than doing socket.pipe?
You need to set content-disposition header in your http response:
response.writeHead(200, {
'Content-Disposition': 'attachment; filename=genome.jpeg; modification-date="Wed, 12 Feb 1997 16:29:51 -0500"'
});
yourDataStream.pipe(response);
see RFC2183
It looks like you may want this:
app.get('/download', function (req, res) {
res.attachment('afile.txt');
require('http').get('http://localhost:1234/', function(response) {
response.pipe(res);
}).on('error', function(err) {
res.send(500, err.message);
});
});
I found the solution!
by doing res.write(d) i was able to direct the bytes from the other connection to the user browser download.
app.get('/download', function (req, res) {
res.setHeader('Content-disposition', 'attachment; filename=' + "afile.jpg");
res.setHeader('Content-Length', "383790");
res.setHeader('Content-Type','image/jpeg');
var socket = net.createConnection(1024, "localhost");
console.log('Socket created.');
//socket.setEncoding("utf8");
socket.on('data', function(d) {
console.log(d);
res.write(d);
}).on('connect', function() {
// // Manually write an HTTP request.
// socket.write("GET / HTTP/1.0\r\n\r\n");
}).on('end', function() {
console.log('DONE');
socket.end();
});
});

Categories