Comparing version 0.0.2 to 0.0.3
@@ -55,2 +55,17 @@ /* | ||
"test features command": function(next) { | ||
var ftp = this.ftp; | ||
ftp.auth(FTPCredentials.user, FTPCredentials.pass, function(err, res) { | ||
assert.ok(!err); | ||
assert.ok(Array.isArray(ftp.features)); | ||
if (ftp.features.length) { | ||
var feat = ftp.features[0]; | ||
assert.ok(ftp.hasFeat(feat)); | ||
} | ||
next(); | ||
}); | ||
}, | ||
"test print working directory": function(next) { | ||
@@ -57,0 +72,0 @@ var ftp = this.ftp; |
113
jsftp.js
@@ -21,3 +21,3 @@ /* | ||
// Commands without parameters | ||
"ABOR", "PWD", "CDUP", "NOOP", "QUIT", "PASV", "SYST", | ||
"ABOR", "PWD", "CDUP", "FEAT", "NOOP", "QUIT", "PASV", "SYST", | ||
// Commands with one or more parameters | ||
@@ -53,3 +53,2 @@ "CWD", "DELE", "LIST", "MDTM", "MKD", "MODE", "NLST", "PASS", "RETR", "RMD", | ||
var socket = this.createSocket(cfg.port || FTP_PORT, cfg.host); | ||
var cmd; | ||
@@ -74,2 +73,27 @@ /** | ||
/** | ||
* Stream of FTP commands from the client. | ||
*/ | ||
var 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(this.serverResponse(input), S.append(S.list(null), cmds)); | ||
tasks(this.parse.bind(this), function(){}); | ||
}; | ||
(function() { | ||
this.createSocket = function(port, host) { | ||
this.socket = Net.createConnection(port, host); | ||
this.socket.setEncoding("utf8"); | ||
return this.socket; | ||
}; | ||
/** | ||
* `requests` receives a stream of responses from the server and filters | ||
@@ -80,3 +104,3 @@ * them before pushing them back into the stream. The filtering is | ||
*/ | ||
function requests(source) { | ||
this.serverResponse = function requests(source) { | ||
var NL = "\n"; | ||
@@ -118,30 +142,5 @@ var buffer = []; | ||
}; | ||
} | ||
/** | ||
* Stream of FTP commands from the client. | ||
*/ | ||
var 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(requests(input), S.append(S.list(null), cmds)); | ||
tasks(this.parse.bind(this), function(){}); | ||
}; | ||
(function() { | ||
this.createSocket = function(port, host) { | ||
this.socket = Net.createConnection(port, host); | ||
this.socket.setEncoding("utf8"); | ||
return this.socket; | ||
}; | ||
/** | ||
* Parse is called each time that a comand and a request are paired | ||
@@ -200,3 +199,26 @@ * together. That is, each time that there is a round trip of actions | ||
this.hasFeat = function(feature) { | ||
feature = feature.toLowerCase(); | ||
return this.features && (this.features.indexOf(feature) > -1); | ||
}; | ||
/** | ||
* Returns an array of features supported by the current FTP server | ||
* | ||
* @param {String} Server response for the 'FEAT' command | ||
* @returns {Array} Array of feature names | ||
*/ | ||
this._parseFeats = function(featResult) { | ||
var features = featResult.split(RE_NL); | ||
if (features.length) { | ||
// Ignore header and footer | ||
features = features.slice(1, -1).map(function(feature) { | ||
return /^\s*(\w*)\s*/.exec(feature)[1].trim().toLowerCase(); | ||
}); | ||
} | ||
return features; | ||
}; | ||
// Below this point all the methods are action helpers for FTP that compose | ||
@@ -214,15 +236,24 @@ // several actions in one command | ||
var self = this; | ||
this.raw.user(user, function(err, res) { | ||
if ([230, 331, 332].indexOf(res.code) > -1) { | ||
self.raw.pass(pass, function(err, res) { | ||
if ([230, 202].indexOf(res.code) > -1) | ||
callback(null, res); | ||
else if (res.code === 332) | ||
self.raw.acct("noaccount"); | ||
else | ||
callback(new Error("Login not accepted")); | ||
}); | ||
} else { | ||
callback(new Error("Login not accepted")); | ||
} | ||
this.raw.feat(function(err, response) { | ||
if (err) | ||
self.features = []; | ||
else | ||
self.features = self._parseFeats(response.text); | ||
console.log("FEATS", self.features) | ||
self.raw.user(user, function(err, res) { | ||
if ([230, 331, 332].indexOf(res.code) > -1) { | ||
self.raw.pass(pass, function(err, res) { | ||
if ([230, 202].indexOf(res.code) > -1) | ||
callback(null, res); | ||
else if (res.code === 332) | ||
self.raw.acct("noaccount"); | ||
else | ||
callback(new Error("Login not accepted")); | ||
}); | ||
} else { | ||
callback(new Error("Login not accepted")); | ||
} | ||
}); | ||
}); | ||
@@ -229,0 +260,0 @@ }; |
{ | ||
"name": "jsftp", | ||
"id": "jsftp", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "A sane FTP client implementation for NodeJS", | ||
@@ -6,0 +6,0 @@ "keywords": [ "ftp", "streams", "files", "server", "client", "async" ], |
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
175840
2932