Comparing version 0.3.4 to 0.3.5
@@ -103,14 +103,14 @@ /* | ||
var ftp = this.ftp; | ||
ftp.raw.pwd(function(err, res) { | ||
if (err) throw err; | ||
ftp.raw.pwd(function(err, res) { | ||
if (err) throw err; | ||
var code = parseInt(res.code, 10); | ||
assert.ok(code === 257, "PWD command was not successful"); | ||
var code = parseInt(res.code, 10); | ||
assert.ok(code === 257, "PWD command was not successful"); | ||
ftp.raw.quit(function(err, res) { | ||
if (err) throw err; | ||
ftp.raw.quit(function(err, res) { | ||
if (err) throw err; | ||
next(); | ||
}); | ||
next(); | ||
}); | ||
}); | ||
}, | ||
@@ -134,8 +134,8 @@ "test current working directory": function(next) { | ||
ftp.raw.cwd("/unexistentDir/", function(err, res) { | ||
if (err) | ||
assert.ok(err); | ||
else { | ||
if (err) | ||
assert.ok(err); | ||
else { | ||
code = parseInt(res.code, 10); | ||
assert.ok(code === 550, "A (wrong) CWD command was successful. It should have failed"); | ||
} | ||
} | ||
next(); | ||
@@ -383,4 +383,20 @@ }); | ||
} | ||
} | ||
}, | ||
"test reconnect": function(next) { | ||
var ftp = this.ftp; | ||
ftp.raw.pwd(function(err, res) { | ||
if (err) throw err; | ||
var code = parseInt(res.code, 10); | ||
assert.ok(code === 257, "PWD command was not successful"); | ||
ftp.socket.end(); | ||
ftp.raw.quit(function(err, res) { | ||
if (err) throw err; | ||
next(); | ||
}); | ||
}); | ||
}, | ||
}; | ||
@@ -387,0 +403,0 @@ |
186
jsftp.js
@@ -91,35 +91,18 @@ /* | ||
// Generate generic methods from parameter names. They can easily be | ||
// overriden if we need special behavior. They accept any parameters given, | ||
// it is the responsability of the user to validate the parameters. | ||
var self = this; | ||
COMMANDS.forEach(function(cmd) { | ||
var lcCmd = cmd.toLowerCase(); | ||
self.raw[lcCmd] = function() { | ||
var callback; | ||
var action = lcCmd; | ||
var cmdfn = function(action, callback) { | ||
clearInterval(self._keepAliveinterval); | ||
if (action.indexOf("quit") !== 0) { | ||
self.keepAlive(); | ||
} | ||
if (arguments.length) { | ||
var args = slice.call(arguments); | ||
if (typeof args[args.length - 1] == "function") | ||
callback = args.pop(); | ||
if (args.length) | ||
action += " " + args.join(" "); | ||
} | ||
if (lcCmd === "quit" && self._keepAliveInterval) | ||
clearInterval(self._keepAliveInterval); | ||
else | ||
self.keepAlive(); | ||
// Check whether the FTP user is authenticated at the moment of the | ||
// enqueing. Ideally this should happen in the `push` method, just | ||
// before writing to the socket, but that would be complicated, | ||
// since we would have to 'unshift' the auth chain into the queue | ||
// or play the raw auth commands (that is, without enqueuing in | ||
// order to not mess up the queue order. Ideally, that would be | ||
// built into the queue object. All this explanation to justify a | ||
// slight slopiness in the code flow. | ||
// check whether the ftp user is authenticated at the moment of the | ||
// enqueing. ideally this should happen in the `push` method, just | ||
// before writing to the socket, but that would be complicated, | ||
// since we would have to 'unshift' the auth chain into the queue | ||
// or play the raw auth commands (that is, without enqueuing in | ||
// order to not mess up the queue order. ideally, that would be | ||
// built into the queue object. all this explanation to justify a | ||
// slight slopiness in the code flow. | ||
var authAndEnqueue = function() { | ||
var isAuthCmd = /feat|user|pass/.test(action); | ||
@@ -134,2 +117,33 @@ if (!self.authenticated && !isAuthCmd) { | ||
} | ||
} | ||
if (self.socket && self.socket.writable) { | ||
authAndEnqueue(); | ||
} | ||
else if (!self.connecting) { | ||
self.authenticated = false; | ||
self._createSocket(self.port, self.host, function(_socket) { | ||
createStreams(_socket); | ||
authAndEnqueue(); | ||
}); | ||
} | ||
}; | ||
// generate generic methods from parameter names. they can easily be | ||
// overriden if we need special behavior. they accept any parameters given, | ||
// it is the responsability of the user to validate the parameters. | ||
COMMANDS.forEach(function(cmd) { | ||
cmd = cmd.toLowerCase(); | ||
self.raw[cmd] = function() { | ||
var callback; | ||
if (arguments.length) { | ||
var args = slice.call(arguments); | ||
if (typeof args[args.length - 1] === "function") | ||
callback = args.pop(); | ||
if (args.length) | ||
cmd += " " + args.join(" "); | ||
} | ||
cmdfn(cmd, callback || function(){}); | ||
}; | ||
@@ -149,4 +163,3 @@ }); | ||
var socket = this._createSocket(this.port, this.host); | ||
var cmd; | ||
this._createSocket(this.port, this.host); | ||
@@ -160,39 +173,21 @@ // Writes a new command to the server, but before that it pushes the | ||
var self = this; | ||
function send() { | ||
socket.write(command + "\r\n"); | ||
self.emitter.emit("command", self._sanitize(command)); | ||
this.socket.write(command + "\r\n"); | ||
self.emitter.emit("command", this._sanitize(command)); | ||
if (onWriteCallback) | ||
onWriteCallback(); | ||
} | ||
if (socket && socket.writable) { | ||
send(); | ||
} | ||
else { | ||
if (!this.connecting) { | ||
try { | ||
socket = this._createSocket(this.port, this.host, send); | ||
this.emitter.emit("reconnect", "reconnect"); | ||
createStreams(); | ||
} | ||
catch (e) { | ||
console.log(e); | ||
} | ||
} | ||
} | ||
if (onWriteCallback) | ||
onWriteCallback(this.socket); | ||
}; | ||
// Stream of incoming data from the FTP server. | ||
var input = function(next, stop) { | ||
socket.on("connect", self.onConnect || function(){}); | ||
socket.on("data", next); | ||
socket.on("end", stop); | ||
socket.on("error", stop); | ||
socket.on("close", stop); | ||
}; | ||
var createStreams; | ||
(createStreams = function(_socket) { | ||
var cmd | ||
// Stream of incoming data from the FTP server. | ||
var input = function(next, stop) { | ||
_socket.on("connect", self.onConnect || function(){}); | ||
_socket.on("data", next); | ||
_socket.on("end", stop); | ||
_socket.on("error", stop); | ||
_socket.on("close", stop); | ||
}; | ||
var cmds, tasks; | ||
var createStreams = function() { | ||
self.cmdQueue = queue(); | ||
@@ -206,26 +201,22 @@ (self.nextCmd = function nextCmd() { | ||
// Stream of FTP commands from the client. | ||
cmds = function(next, stop) { | ||
cmd = next; | ||
}; | ||
// Zips (as in array zipping) commands with responses. This creates | ||
// a stream that keeps yielding command/response pairs as soon as each pair | ||
// becomes available. | ||
var tasks = S.zip(S.filter(function(x) { | ||
// We ignore FTP marks for now. They don't convey useful | ||
// information. A more elegant solution should be found in the | ||
// future. | ||
return !isMark(x.code); | ||
}, | ||
self.serverResponse(input)), | ||
S.append(S.list(null), function(next, stop) { | ||
// Stream of FTP commands from the client. | ||
cmd = next; | ||
}) | ||
); | ||
/** | ||
* Zips (as in array zipping) commands with responses. This creates | ||
* a stream that keeps yielding command/response pairs as soon as each pair | ||
* becomes available. | ||
*/ | ||
tasks = S.zip(S.filter(function(x) { | ||
// We ignore FTP marks for now. They don't convey useful | ||
// information. A more elegant solution should be found in the | ||
// future. | ||
return !isMark(x.code); | ||
}, self.serverResponse(input)), S.append(S.list(null), cmds)); | ||
tasks(self.parse.bind(self), function(err) { | ||
self.emitter.emit("disconnect", "disconnect"); | ||
}); | ||
}; | ||
createStreams(); | ||
this.cmd = cmd; | ||
})(this.socket); | ||
}; | ||
@@ -239,7 +230,10 @@ | ||
this._createSocket = function(port, host, firstTask) { | ||
var self = this; | ||
if (this.socket && this.socket.destroy) | ||
this.socket.destroy(); | ||
this.connecting = true; | ||
var socket = this.socket = Net.createConnection(port, host); | ||
this.socket = Net.createConnection(port, host); | ||
socket.setTimeout(TIMEOUT, function() { | ||
var self = this; | ||
this.socket.setTimeout(TIMEOUT, function() { | ||
if (self.onTimeout) | ||
@@ -251,11 +245,11 @@ self.onTimeout(new Error("FTP socket timeout")); | ||
socket.on("connect", function() { | ||
self.emitter.emit("connect"); | ||
this.socket.on("connect", function() { | ||
self.connecting = false; | ||
self.emitter.emit("connect", "connect"); | ||
if (firstTask) { | ||
firstTask(); | ||
firstTask(self.socket); | ||
} | ||
self.connecting = false; | ||
}); | ||
return socket; | ||
return this.socket; | ||
}; | ||
@@ -353,3 +347,4 @@ | ||
callback(err); | ||
} else { | ||
} | ||
else { | ||
callback(null, ftpResponse); | ||
@@ -427,3 +422,2 @@ } | ||
this.features = null; | ||
this.tasks = null; | ||
this.authenticated = false; | ||
@@ -430,0 +424,0 @@ }; |
{ | ||
"name": "jsftp", | ||
"id": "jsftp", | ||
"version": "0.3.4", | ||
"version": "0.3.5", | ||
"description": "A sane FTP client implementation for NodeJS", | ||
@@ -6,0 +6,0 @@ "keywords": [ "ftp", "protocol", "files", "server", "client", "async" ], |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
398516
1671
3
24