How to serve a file (exe or rar) to a client to download from a node.js server?

I have a node.js server that serves index.html with text-based password entry. After checking the server password, you must start the download for the client. The client should not see the location path where the file is on the server.

here is my server.js:

var http = require('http'), qs = require('querystring'), fs = require('fs') ; console.log('server started'); var host = process.env.VCAP_APP_HOST || "127.0.0.1"; var port = process.env.VCAP_APP_PORT || 1337; http.createServer(function (req, res) { if(req.method=='GET') { console.log ( ' login request from ' + req.connection.remoteAddress ); fs.readFile(__dirname +'/index.html', function(error, content) { if (error) { res.writeHead(500); res.end(); } else { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(content, 'utf-8'); } }); } // method GET end else{ // method POST start console.log('POST request from ' + req.connection.remoteAddress); var body = ''; req.on('data', function (data) { body += data; if (body.length > 500) { // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST req.connection.destroy(); console.log('too much data')} }); req.on('end', function () { var postdata = qs.parse(body); var password = postdata.passwordpost ; if (password == '7777777') { console.log('the password is right, download starting'); // ??????????????????????????????????? here I need help from stackoverflow } else{ console.log ('password wrong'); fs.readFile(__dirname +'/wrongpassword.html', function(error, content) { if (error) { res.writeHead(500); res.end(); } else { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(content, 'utf-8'); } }); } }); // req on end function end } }).listen(port, host); 

the part where I need help is marked with a symbol

here is my index.html:

 <html> <body> <br> <br> &nbsp;&nbsp;&nbsp; please enter your password to start your download <br> <br> <form method="post" action="http://localhost:1337"> &nbsp;&nbsp;&nbsp; <input type="text" name="passwordpost" size="50"><br><br> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <input type="submit" value="download" /> </form> </body> </html> 

Do you know how to do this?

+4
source share
4 answers

Of course you can use this in your code:

 res.setHeader('Content-disposition', 'attachment; filename='+filename); //filename is the name which client will see. Don't put full path here. res.setHeader('Content-type', 'application/x-msdownload'); //for exe file res.setHeader('Content-type', 'application/x-rar-compressed'); //for rar file var file = fs.createReadStream(filepath); //replace filepath with path of file to send file.pipe(res); //send file 
+5
source

You need to declare and require path : path = require("path")

then you can do:

 var uri = url.parse(request.url).pathname , filename = path.join(process.cwd(), uri); path.exists(filename, function(exists) { if(!exists) { response.writeHead(404, {"Content-Type": "text/plain"}); response.write("404 Not Found\n"); response.end(); return; } response.writeHead(200); response.write(file, "binary"); response.end(); } 

check out these complete example .

+4
source

If you want to use the express framework, then this can be done much easier.

 app.get('/download', function(req, res){ var file = __dirname + 'learn_express.mp4'; res.download(file); // Sets disposition, content-type etc. and sends it }); 

API Express Download

+1
source

I found additional information about fs.createReadStream () (especially error handling) here and combined it with user568109's answer. Here is my working download server:

 var http = require('http'), qs = require('querystring'), fs = require('fs') ; console.log('server started'); var host = process.env.VCAP_APP_HOST || "127.0.0.1"; var port = process.env.VCAP_APP_PORT || 1337; http.createServer(function (req, res) { if(req.method=='GET') { console.log ( ' login request from ' + req.connection.remoteAddress ); fs.readFile(__dirname +'/index.html', function(error, content) { if (error) { res.writeHead(500); res.end(); } else { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(content, 'utf-8'); } }); } // method GET end else{ // method POST start console.log('POST request from ' + req.connection.remoteAddress); var body = ''; req.on('data', function (data) { body += data; if (body.length > 500) { // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST req.connection.destroy(); console.log('too much data')} }); req.on('end', function () { var postdata = qs.parse(body); var password = postdata.passwordpost ; if (password == '7777777') { console.log('the password is right, download starting'); res.setHeader('Content-disposition', 'attachment; filename='+'test1.exe'); //filename is the name which client will see. Don't put full path here. res.setHeader('Content-type', 'application/x-msdownload'); //for exe file res.setHeader('Content-type', 'application/x-rar-compressed'); //for rar file var readStream = fs.createReadStream('/test1.exe'); //replace filepath with path of file to send readStream.on('open', function () { // This just pipes the read stream to the response object (which goes to the client) readStream.pipe(res); }); // This catches any errors that happen while creating the readable stream (usually invalid names) readStream.on('error', function(err) { console.log (err) ; res.writeHead(200, { 'Content-Type': 'text/html' }); res.end('an error occured', 'utf-8'); }); //send file } else{ console.log ('password wrong'); fs.readFile(__dirname +'/wrongpassword.html', function(error, content) { if (error) { res.writeHead(500); res.end(); } else { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(content, 'utf-8'); } }); } }); // req on end function end } }).listen(port, host); 
0
source

Source: https://habr.com/ru/post/1480281/


All Articles