download file from url to server using node.js - javascript

I need a requirement to download file from any url to the server that running the app. I used the following code in Node.js. And its working in the case of localhost. But not in the case of server.
var express = require('express');
var app = express();
var http = require('http');
var https = require('https');
var request = require('request');
var fs = require('fs');
var path = require('path');
app.get('/', function( request, response ){
response.send('connection established...!');
});
app.get('/download', function(request, response){
var file = "https://c1.staticflickr.com/6/5219/5450451580_7f066f7868_b.jpg";
var filename = path.basename( file );
var ssl = file.split(':')[0];
var dest = __dirname +'downloads/'+ filename;
var stream = fs.createWriteStream( dest );
if ( ssl == 'https') {
https.get( file, function( resp ) {
resp.pipe( stream );
response.send('file saved successfully.*');
}).on('error', function(e) {
response.send("error connecting" + e.message);
});
} else {
http.get( file, function( resp ) {
resp.pipe( stream );
response.send('file saved successfully.*');
}).on('error', function(e) {
response.send("error connecting" + e.message);
});
}
});
app.listen(process.env.PORT || 3000);

do you have write privileges to the server(assuming your local is mac/windows and server is a linux box)? if not assign the privileges

Related

res.send is not a function

I am making an api call and recieving the data, however, I am having trouble sending the data back to my js file. I tried using res.send but I am getting an error. I can't seem to figure out how to send the information back to the javascript file. (I took my key out of the request link. For security reasons, however, I am getting the data back from the api call). The only problem I am having is returning the data to the frontend javascript file.
This is the Javascript file that sends the original request:
/ ********** options button function makes api call to get selected cities forecast *****************
function getCityForecast(e){
var id = document.getElementById('cities');
var getValue = id.options[id.selectedIndex].value;
var suffix = getValue + ".json";
var newObj = JSON.stringify({link : suffix});
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/", true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(newObj);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
console.log(xhr.response);
console.log('recieved');
} else {
console.log('error');
}
}
}
My server.js file looks like this:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var http = require('http');
var path = require('path');
var request = require('request');
// ****************** Middle Ware *******************
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/public'));
var retrievedString;
// **************** Post Request *******************
app.post('/', function(req, res){
var link = "http://api.wunderground.com/api/key/forecast";
retrievedString = link.concat(req.body.link);
request = http.get(retrievedString , function(res){
var body = '';
res.on('data', function(data){
body += data;
});
res.on('end', function(){
var parsed = JSON.parse(body);
console.log(parsed.forecast.txt_forecast);
res.send(parsed.forecast.txt_forecast);
});
})
.on('error', function(e) {
console.log("Got error: " + e.message);
});
});
app.listen(3000, function() { console.log('listening')});
You are overloading the definition of the variable res which is also what you called the response variable for your Express route handler method. In the callback function of the request, use a different name for that variable - for example:
request = http.get(retrievedString , function(resDoc){

Pass a parameter to another JavaScript and run the script

Send a parameter(URL) from another script through recursion to this script.
var express = require('express');
var request = require('request');
var cheerio = require('cheerio');
var mongodb = require('mongodb');
var app = express();
var MongoClient = mongodb.MongoClient;
// Connection URL. This is where your mongodb server is running.
var murl = 'mongodb://localhost:27017/getData';
url = '';
app.get('/getData', function(req, res){
firstCall(req,res)
//console.log("cookie",req.cookies);
})
var firstCall = function(req, res, data){
console.log("URL: ", url);
res.send('Check your console!');
}
app.listen('3000')
console.log('Magic happens on port 3000');
module.exports = function(app) {
app.get('/getData', function() {});
};
I want this code to act as backbone or logic board. And some other file should be able to trigger this logic board file by adding the URL to this file.
Like we pass parameters to function to call. How do I do it here.

How to make the websocket server be at a router?

I'm writing a websocket server using nodejs-ws module, but the server can only be at the root of the server, so how I can make it at a child router like localhost:3000/chat?
I need your help, thanks a lot!
Working example:
var ws = require('ws');
var http = require('http');
var httpServer = http.createServer();
httpServer.listen(3000, 'localhost');
var ws1 = new ws.Server({server:httpServer, path:"/chat"});
ws1.on('connection', function(){
console.log("connection on /chat");
});
var ws2 = new ws.Server({server:httpServer, path:"/notifications"});
ws2.on('connection', function(){
console.log("connection on /notifications");
});
could you please tell me how to use this in express?
To route websockets with Express I'd rather use express-ws-routes
var express = require('express');
var app = require('express-ws-routes')();
app.websocket('/myurl', function(info, cb, next) {
console.log(
'ws req from %s using origin %s',
info.req.originalUrl || info.req.url,
info.origin
);
cb(function(socket) {
socket.send('connected!');
});
});

node.js write filestream disordered in p2p file download

guys. I try to use node.js to create a p2p file sharing application. While downloading a file, it will download the file block by block.
The block size used in the following code is 1KB. But it has a problem, when available sockets number MAX_SOCKET_CNT is set to 30, it will not work.
How to run the code:
First, run node server.js, then, run node client.js, this will download the file named fav.mp3 to fav-local.mp3.
After downloading, try to run diff fav.mp3 fav-local.mp3 to check if the file downloaded completely.
Could you help me to figure out where the problem is?
Any answer or suggestion is welcome. Thanks in advance.
Here is the source code:
server.js
var http = require("http");
var url = require("url");
var fs = require('fs');
function downloadBlock(request, response){
var urlParts = url.parse(request.url, true);
var query = urlParts.query;
if('block_id' in query){
response.writeHead(200, {"Content-Type": "audio/mpeg"});
var startHere=parseInt(query["block_id"]);
var BLOCK_SIZE=1024;
var currentPosition=startHere*BLOCK_SIZE;
var readStream = fs.createReadStream('fav.mp3',{start: startHere*BLOCK_SIZE, end:startHere*BLOCK_SIZE+BLOCK_SIZE-1});
readStream.pipe(response);
}else{
response.writeHead(200, {"Content-Type": "text/html"});
response.write("refused");
response.end();
console.log("Warning: not a file block download request...");
}
}
http.createServer(downloadBlock).listen(8801);
console.log("Server has started. please ensure that the fav.mp3 file(size=439355B) is here.");
client.js
var http = require('http');
var fs = require('fs');
var remoteFile='fav.mp3';
var fileSize=439355;
var localFile='fav-local.mp3';
var totalBlocks=Math.floor((fileSize+1023)/1024);
/**************************************************/
//KEY POINT
var MAX_SOCKET_CNT=totalBlocks; //worked
//var MAX_SOCKET_CNT=30;//not work //????because of recursive downloadBlock function????
/*************************************************/
for(var i=0;i<MAX_SOCKET_CNT;++i){
downloadBlock('127.0.0.1',8801,remoteFile, localFile,i,totalBlocks);
}
function downloadBlock(IP,PORT,remoteFile,localFile,blockID,totalBlocksNum){
if(blockID >= totalBlocksNum) return;
var BLOCK_SIZE=1024;
var file = fs.createWriteStream(localFile,{start: blockID*BLOCK_SIZE});
var request = http.get("http://localhost:"+PORT+"/download_block?block_id="+blockID, function(response) {
response.pipe(file);
file.on('finish', function() {
var callback=function downloadBlockOver(){
console.log("compelete download blockID:"+blockID);
var nextBlockID=blockID+MAX_SOCKET_CNT;
if(nextBlockID<totalBlocksNum){
downloadBlock(IP,PORT,remoteFile,localFile,nextBlockID,totalBlocksNum); //why not this work if MAX_SOCKET_CNT=30???
}
}
file.close(callback);
});
});
}
Aha.
Finally, I find out the solution. You have to create the file first. Then change the flag of write stream with "r+" before download.
function touchFile(fileName,fileSize){
var BLOCK_SIZE=1024;
var totalBlocks=Math.floor((fileSize+BLOCK_SIZE-1)/BLOCK_SIZE);
var file = fs.createWriteStream(fileName);
var blockBuffer=new Buffer(BLOCK_SIZE);
for(var i=0;i<totalBlocks-1;++i){
file.write(blockBuffer,0, BLOCK_SIZE);
}
var leftToFill=new Buffer(fileSize-(totalBlocks-1)*BLOCK_SIZE);
file.write(leftToFill,0, leftToFill.Length);
file.end();
}
add the function "touchFile(localFile,fileSize);" before downloadBlock.
Then change:
var file = fs.createWriteStream(localFile,{start: blockID*BLOCK_SIZE});
to
var file = fs.createWriteStream(localFile,{start: blockID*BLOCK_SIZE,flags:'r+',autoClose: true});
It will work now.
touchFile just work when MAX_SOCKET_CNT==3.
The final solution is use node module random-access-file:https://github.com/mafintosh/random-access-file
The client.js code:
var http = require('http');
var fs = require('fs');
var randomAccessFile = require('random-access-file');
var remoteFile='fav.mp3';
var fileSize=439355;
//var fileSize=6000;//363213; //439355;
var localFile='fav-local.mp3';
var totalBlocks=Math.floor((fileSize+1023)/1024);
/**************************************************/
//KEY POINT
//var MAX_SOCKET_CNT=totalBlocks; //worked
var MAX_SOCKET_CNT=20;//worked
/*************************************************/
var file = randomAccessFile('fav-local.mp3');
for(var i=0;i<MAX_SOCKET_CNT;++i){
downloadBlock('127.0.0.1',8801,remoteFile, localFile,i,totalBlocks);
}
file.close();
function downloadBlock(IP,PORT,remoteFile,localFile,blockID,totalBlocksNum){
if(blockID >= totalBlocksNum) return;
var BLOCK_SIZE=1024;
var chunks=[];
var request = http.get("http://localhost:"+PORT+"/download_block?block_id="+blockID, function(response) {
response.on('data', function (chunk) {
chunks.push(chunk);
});
response.on('error', function (e) {
console.log('error.......'+e);
});
response.on('close', function () {
console.log('close ....');
});
response.on('end', function () {
var dataToProcess=Buffer.concat(chunks);
console.log('block data size: ' + dataToProcess.length);
file.write(blockID*BLOCK_SIZE, dataToProcess,
function(err) {
if(err){
console.log("error in write...");
}else{
var nextBlockID=blockID+MAX_SOCKET_CNT;
if(nextBlockID<totalBlocksNum){
console.log("download next block:"+nextBlockID);
downloadBlock(IP,PORT,remoteFile,localFile,nextBlockID,totalBlocksNum);
}
}
}
);
});
});
}

send PDF file using websocket node.js

I have the following server:
var pvsio = require("./pvsprocess"),
ws = require("ws"),
util = require("util"),
http = require("http"),
fs = require("fs"),
express = require("express"),
webserver = express(),
procWrapper = require("./processwrapper"),
uploadDir = "/public/uploads",
host = "0.0.0.0",
port = 8082,
workspace = __dirname + "/public",
pvsioProcessMap = {},//each client should get his own process
httpServer = http.createServer(webserver),
baseProjectDir = __dirname + "/public/projects/",
PDFDocument = require ("pdfkit");
var p, clientid = 0, WebSocketServer = ws.Server;
...
var wsServer = new WebSocketServer({server: httpServer});
wsServer.on("connection", function (socket) {
var socketid = clientid++;
var functionMaps = createClientFunctionMaps();
socket.on("message", function (m) {
Is possible send a pdf file to the client inside socket.on("message" .. function ?
I can send message using send(), there is some function to send files?
Thanks
I would just send the pdf in binary.
fs.readFile(something.pdf,function(err,data){
if(err){console.log(err)}
ws.send(data,{binary:true});
}
And at the client side, I would create a blob and an object url from the received binary data. From this onward, you can pretty much do anything, says open the pdf file in a new window/tab.
conn.onmessage = function(e){
pdfBlob = new Blob([e.data],{type:"application/pdf"});
url = webkitURL.createObjectURL(pdfBlob);
window.open(url);
}
Hope this help.

Categories

Resources