diff --git a/lib/jsftp.js b/lib/jsftp.js index c4e6c95..d9ac8ea 100644 --- a/lib/jsftp.js +++ b/lib/jsftp.js @@ -10,6 +10,7 @@ 'use strict'; var Net = require('net'); +var tls = require('tls'); var EventEmitter = require('events').EventEmitter; var es = require('event-stream'); var ResponseParser = require('ftp-response-parser'); @@ -117,13 +118,26 @@ Ftp.prototype._createSocket = function(port, host, firstAction) { } this.authenticated = false; - var socket = Net.createConnection(port, host, firstAction || NOOP); - socket.on('connect', this.reemit('connect')); - socket.on('timeout', this.reemit('timeout')); + var self = this; + var socket; + + if (this.ssl) { + socket = tls.connect(port, host, this.sslOptions, function() { + //runt PROT command to specify that the data channel is secure + self.runCommand('prot p', function() { + self.reemit('connect'); + //TODO timeout for tls connection? + }); + }); + } + else{ + socket = Net.createConnection(port, host, firstAction || NOOP); + socket.on('connect', this.reemit('connect')); + socket.on('timeout', this.reemit('timeout')); + } - this.pipeline = es.pipeline(socket, this.resParser); - var self = this; + this.pipeline = es.pipeline(socket, this.resParser); this.pipeline.on('data', function(data) { self.emit('data', data); self.parseResponse.call(self, data); @@ -583,13 +597,22 @@ Ftp.prototype.pasvTimeout = function(socket, cb) { Ftp.prototype.getPasvSocket = function(callback) { var timeout = this.timeout; callback = once(callback || NOOP); + var self = this; this.execute('pasv', function(err, res) { if (err) return callback(err); getPasvPort(res.text, function(err, res) { if (err) return callback(err); - var socket = Net.createConnection(res.port, res.host); + var socket; + if (self.ssl) { + socket = tls.connect(res.port, res.host, self.sslOptions, function() { + self.reemit('connect'); + }); + } + else{ + socket = Net.createConnection(res.port, res.host); + } socket.setTimeout(timeout || TIMEOUT); callback(null, socket); }); diff --git a/test/jsftp_test.js b/test/jsftp_test.js index 6921393..b645cf1 100755 --- a/test/jsftp_test.js +++ b/test/jsftp_test.js @@ -66,6 +66,8 @@ var FTPCredentials = { pass: "12345" }; +var createLocal = true; //Set to false if you are using your own local FTP server + function getRemotePath(path) { return Path.join('test', 'test_c9', path); } @@ -73,11 +75,11 @@ function getRemotePath(path) { function getLocalPath(path) { return Path.join(process.cwd(), 'test', 'test_c9', path); } -var CWD = process.cwd() + "/test"; +var CWD = Path.join(process.cwd(),"test"); var remoteCWD = "test/test_c9"; exec('mkdir', [__dirname + "/" + remoteCWD]); -describe("jsftp test suite", function() { +function testRoutine(){ var ftp, server; beforeEach(function(next) { rimraf(getLocalPath(''), function() { @@ -85,7 +87,7 @@ describe("jsftp test suite", function() { Fs.writeFileSync(getLocalPath('testfile.txt'), "test"); Fs.writeFileSync(getLocalPath('testfile2.txt'), "test2"); - if (FTPCredentials.host === "localhost") { + if (createLocal && FTPCredentials.host === "localhost") { server = new ftpServer(); server.init(FTPCredentials); } @@ -99,7 +101,7 @@ describe("jsftp test suite", function() { afterEach(function(next) { setTimeout(function() { - server.stop(); + server && server.stop(); if (ftp) { ftp.destroy(); ftp = null; @@ -362,7 +364,7 @@ describe("jsftp test suite", function() { ftp.ls(filePath, function(err, res) { assert.ok(!err); - assert.equal(buffer.length, Fs.statSync(CWD + "/jsftp_test.js").size); + assert.equal(buffer.length, Fs.statSync(Path.join(CWD,"jsftp_test.js")).size); ftp.raw.dele(filePath, function(err, data) { assert.ok(!err); @@ -406,7 +408,7 @@ describe("jsftp test suite", function() { ftp.ls(filePath, function(err, res) { assert.ok(!err); - assert.equal(res[0].size, Fs.statSync(CWD + "/jsftp_test.js").size); + assert.equal(res[0].size, Fs.statSync(Path.join(CWD,"jsftp_test.js")).size); ftp.raw.dele(filePath, function(err, data) { assert.ok(!err); @@ -443,7 +445,7 @@ describe("jsftp test suite", function() { }); it("test get a file", function(next) { - var localPath = CWD + '/test_c9/testfile.txt'; + var localPath = Path.join(CWD,"test_c9","testfile.txt"); var remotePath = remoteCWD + "/testfile.txt"; var realContents = Fs.readFileSync(localPath, "utf8"); var str = ""; @@ -795,4 +797,26 @@ describe("jsftp test suite", function() { onDone(); }); }); +} + +describe("jsftp test suite", function(){ + describe("without ssl", testRoutine); + describe("with ssl", function(){ + before(function(){ + //change ftp credentials to ssl + FTPCredentials = { + host: "localhost", + user: "user", + port: 990, + pass: "12345", + ssl:true, + //extra options added for testing locally without valid certs + sslOptions:{ + requestCert: false, + rejectUnauthorized: false + } + }; + }); + testRoutine(); + }); });