Access SFTP from NodeJS - node.js

I have a need where i have to open a SFTP connection with a server, copy a file from there to local.
To that end, i have tried installing node-sftp module using
npm install node-sftp
It didnt work out of the box, i had to replace the sftp.js file that was installed by npm with that of github repository here : https://github.com/ajaxorg/node-sftp
(npm version was using TTY and github version was using PTY. i am not sure what they are)
After start the server and invoking the code, i see this in console.
launching: sftp -o Port=22 jash#xxx.63.xxx.49
listening...
console just hangs here. I am trying to print all files in the current directory after connection is opened.
This is the code
var http = require('http');
var Sftp = require('node-sftp');
var port = process.env.PORT || 1337;
var msgHandler = function(request, response) {
var options = {
host:"xxx.63.xxx.49",
username:"jash",
password:"mypassword",
port:22
};
var conn = new Sftp(options,function(err){
console.log(err);
});
conn.cd(".", function(err) {
console.log(err);
conn.ls(".", function(err, res) {
console.log(res[0].path);
});
});
console.log("listening...");
}
http.createServer(msgHandler).listen(port);
The credentials are fine, i used them in SecureCRT and was able to login.

The second argument to Sftp() (the function(err)...) is where you want to place your conn.cd(... code. It (said 2nd argument) is a function that gets called once the connection has been established. Make sure to check for err of course.

Related

Issues Getting Highcharts Export Server Running Under iisnode

I am working on trying to set up the Highcharts export server under node.js using iisnode (https://github.com/tjanczuk/iisnode). It basically acts as a pipe between requests to IIS through to node. Great! Only, how do I "install" the highcharts export server so it is using iisnode? I did the instructions on how to install the highcharts-export node module but it is installed under (Windows) AppData\Roaming\npm. How to move or point iisnode to the export server?
This export server is run via the following once installed from npm:
highcharts-export-server --enableServer 1
So, to get this installed and used in IIS8 + iisnode
1) What is the right directory to install export server locally (on Windows the modules pulled in via npm go to C:\Users\\AppData\Roaming\nmp\ where is the logged in user using npm to install the package)?
2) What is the iisnode configuration necessary for this?
I have the iisnode setup and running on our development box and all the examples work. My confusion lies partly with the utter lack of documentation for issnode. All the links I have found just repeat the items listed in the links from the issnode developer with no actual "here is how you take a node app that exists in npm and have it work in issnode." I don't necessarily need my hand held every step of the way. I am just seeing no list of steps to even follow.
install node (if not already installed)
install iisnode (if not already installed => https://github.com/tjanczuk/iisnode)
verify IIS has iisnode registered as a module
create a new Application Pool, set to "No Managed Code"
create a new empty web site
load the iisnode sample content into it, update the web.config
verify you can hit it and it runs and can write it's logs
go to the IIS web site folder and run these npm commands
npm init /empty
npm install --save highcharts-export-server
npm install --save tmp
add file hcexport.js and reconfigure web.config
var fs = require('fs');
var http = require('http');
var path = require("path");
var tmp = require('tmp');
const exporter = require('highcharts-export-server');
http.createServer(function (req, res) {
try {
if (req.method !== 'POST') { throw "POST Only"; }
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function () {
if (body === '') { throw "Empty body"; }
var tempFile = tmp.fileSync({discardDescriptor: true, postfix: ".svg", dir: process.cwd()});
var input = JSON.parse(body);
input.outfile = path.basename(tempFile.name);
exporter.initPool();
exporter.export(input, function (err, exres) {
if (err) { throw "Export failed"; }
var filename = path.join(process.cwd(), exres.filename);
exporter.killPool();
fs.readFile(filename, function(err, file) {
res.writeHead(200, { 'Content-Type': 'image/svg+xml', 'Content-disposition': 'attachment; filename=' + exres.filename });
res.write(file.toString());
res.end();
tempFile.removeCallback();
});
});
});
} catch (err) {
console.log({port: process.env.PORT, error: err});
res.writeHead(409, { 'Content-Type': 'text/html' });
res.end(err.message);
}
}).listen(process.env.PORT);
Extend as needed to support the export types you plan to use.
The highcharts-export-server uses phantomjs internally and this can run away under some error conditions using up 100% of available CPU, if you see this you can kill it using:
Taskkill /IM phantomjs.exe /F
The solution from saukender seems to work, however it seems that it always initializes a new pool of phantom workers every time.
If you already have node and issnode setup, another solution is to directly start the highcharts export server and not call the export function manually. This seems to provide a better performance, since it doesn't initialze the worker pool on every request.
// app.js
const highcharts = require("highcharts-export-server");
highcharts.initPool();
highcharts.startServer(process.env.PORT || 8012);
Don't forget to point your web.config to app.js.
I found these two resource quite useful during setup:
https://www.galaco.me/node-js-on-windows-server-2012/
https://tomasz.janczuk.org/2011/08/hosting-nodejs-applications-in-iis-on.html

Forever module with node app executable file

I am working on Node JS application.
In this I have to check first user is connected with internet or not. If yes then check KinectRuntime-v2.0_1409-Setup installed or not.. and further more such kind of validations are there. so I have used the following code in my entry script:
What I have Done:
broadcast.js: // entry file which we use to start app
var tempkinect = require('./controllers/tempkinect.js');
tempkinect.controller(app);
require('dns').lookup('google.com',function(err) {
if (err){
server.listen(8000, function(req, res){
open('http://localhost:8000/internetnotfound'); // internet not found page.
return false;
});
}
else{
try{
var Kinect2 = require("kinect2");
var kinect = new Kinect2();
}
catch(ex) {
server.listen(8000, function(req, res){
open('http://localhost:8000/kinectnotfound');
open('https://www.microsoft.com/en-in/download/confirmation.aspx?id=44559');
return false;
}
} //else ends here
});
tempkinect.js file: // my controller file
module.exports.controller = function(app){
app.get('/kinectnotfound',function(req,res){
var errmsg = "KinectRuntime-v2.0_1409-Setup not installed on your computer. Download will start automatically, if not then";
var link = "https://www.microsoft.com/en-in/download/confirmation.aspx?id=44559";
var click = "Click Here!"
res.render('initialerror',{errormessage:errmsg, downloadlink : link, clickhere: click, title : 'Kinect Not Found'});
});
app.get('/internetnotfound', function(req,res){
require('dns').lookup('google.com',function(err) {
if (err){
res.render('initialerror',{errormessage:'Please Connect Internet for Login.',downloadlink : '', clickhere : '', title : 'Internet Not Connected'});
}
else{
res.redirect('/restart');
}
});
});
app.get('/restart', function (req, res, next) {
process.exit(1);
});
}
I am using enclose module which compiled the node js application and creates .exe file. Now, If I run application on my local machine using command prompt:
run > node broadcast.js
then in case of internet not found app displays corresponding page.( then I connect internet manually ) after connecting internet when I refresh the page it restarts the process, which is good as per required.
BUT, when I do the same using compiled application then it is giving me error:
What Error I am getting:
So can anyone please suggest what should be modified there?
Besides this, Forever should be installed as global on the system so it is working fine on my system but not on others with the compiled app.
Looks like you already have something running at port 8000 (possibly other copy of your app). I would make sure your app port is configurable either through environment variables or command line options. Likewise make sure it can be shut down gracefully to release the port.
As for forever, there is no reason to install it globally, package it with the application and then its available at ./node_modules/.bin

How to setup FTP static ip with QuotaGuard static?

I'm using a nodejs FTP client that's hosted on heroku, but the endpoint I'm connected to needs to whitelist my static IP. Heroku doesn't offer static IPs so I'm using the QuotaGuard addon. I'm a bit lost on how to use the QuotaGuard url to proxy my FTP connection.
I appreciate any help!
You can use a fork of the node-ftp package to do this but it isn't in NPM so requires a bit of manual install.
Clone the repo locally: git clone git#github.com:choonyme/node-socksftp.git
Copy the socksftp directory in to your project directory (e.g. cp -r node-socksftp/socksftp ./node_modules/
export your QuotaGuard Static connection details in to a local env variable called QUOTAGUARDSTATIC_URL.
You can then use all the same FTP commands as in the original node-ftp package.
var url = require('url');
var Client = require('socksftp');
var httpProxyUrl = process.env.QUOTAGUARDSTATIC_URL;
// Make sure to switch to the SOCKS5 proxy port 1080
var socksProxyUrl = httpProxyUrl.replace(":9293",":1080");
var server = {
'host': 'ftp.linuxjournal.com',
'port': 21,
'socksproxy': socksProxyUrl
};
var c = new Client();
c.on('ready', function() {
c.list(function(err, list) {
if (err) throw err;
console.dir(list);
c.end();
});
});
c.on('error', function(err){
console.error('socksftp error: ' + err);
return;
});
c.connect(server);
For future reference you can contact our support team at http://support.quotaguard.com and we'll respond a bit quicker.

why data event not working on http.get response stream

Handling images in nodejs, I got stuck on an issue that the data event is not working with piped response stream.
var http = require('http'),
url = require('url');
var httpServer = http.createServer(function(req,res){
var path = url.parse(req.url).pathname;
var fstream = $.FS.createReadStream('/root/image'+path);
fstream.on('error',function(){
res.writeHead(404);
return res.end();
});
fstream.pipe(res);
});
httpServer.listen(8080);
http.get({
host : '127.0.0.1',
port : 8080,
path : '/image.jpg'
},function(res){
res.on('data',function(){
console.log('data received'); //nothing happened
});
}).on('error',function(er){
throw er;
});
Did I do anything wrong? Or is this a node bug?
In my testing if the response has a status of 304 (not modified), then no data event is fired. The solution is fairly easy if you are not afraid of the terminal (or command line in Windows). Open your command tool and cd to the directory containing your image. Once there, you can use the following command to make it appear that your file has been updated (replace filename.ext with the name of your file):
Unix/Linux
touch filename.ext
Windows
copy /b filename.ext +,,
To rerun the command, hit the ↑ up arrow and then hit enter

Simple socket.io example not work

This is server file
var io = require('socket.io').listen(7000);
io.sockets.on('connection', function(socket) {
console.log("### new connection ###");
});
This is for client
$j(document).ready(function() {
var socket = io.connect('http://address.net:7000');
console.log(socket);
});
Server starts correct without any errors.
I copied from node_modules and attach to my site < head > section file "socket.io.min.js" file for client from dist folder.
And in output of server isn't any ### new connection ### when I run my site.
Why?
Problem resolved. It was about wrong server address in socket.io connection function.

Resources