Permalink
Browse files

Merge pull request #6 from ajaxorg/handlers

Added onConnect, onError and onDisconnect handlers
  • Loading branch information...
2 parents 52f65ca + 359a0a4 commit 5f6055e6219a997c0c223ffa4f7dc9a4a5d4cf5a Sergi Mansilla committed Nov 26, 2012
Showing with 215 additions and 121 deletions.
  1. +9 −0 Makefile
  2. +2 −3 index.js
  3. +111 −110 lib/ftpParser.js
  4. +20 −5 lib/jsftp.js
  5. +1 −1 package.json
  6. +47 −0 test/jsftp_test.js
  7. +25 −2 test/parser_test.js
View
@@ -0,0 +1,9 @@
+test:
+ npm test
+
+coverage:
+ -jscoverage --no-highlight lib lib-cov
+ -env VFS_FTP_COV=1 mocha -t 5000 -R html-cov > coverage.html
+ rm -rf lib-cov
+
+.PHONY: test
View
@@ -1,3 +1,2 @@
-module.exports = process.env.JSFTP_COV
- ? require('./lib-cov/jsftp')
- : require('./lib/jsftp');
+var libpath = process.env['VFS_FTP_COV'] ? './lib-cov' : './lib';
+module.exports = require(libpath + "/jsftp");
View
@@ -117,140 +117,141 @@ exports.entryParser = function(entry) {
if (RE_SERVER_RESPONSE.test(entry) || RE_MULTI_RESPONSE.test(entry))
return null;
- if ('bcdlps-'.indexOf(c) > -1)
+ if ('bcdlps-'.indexOf(c) > -1) {
return parsers.unix(entry);
-
- else if ('0123456789'.indexOf(c) > -1)
+ }
+ else if ('0123456789'.indexOf(c) > -1) {
return parsers.msdos(entry);
-
+ }
else {
console.log("Unrecognized format: \n" + entry);
return null;
}
};
-var parsers = {
- unix: function(entry) {
- var target, writePerm, readPerm, execPerm;
- var group = entry.match(RE_UnixEntry);
-
- if (group) {
- var type = group[1];
- var hardLinks = group[15];
- var usr = group[16];
- var grp = group[17];
- var size = group[18];
- var name = group[21];
-
- var date;
- // Check whether we are given the time (recent file) or the year
- // (older file) in the file listing.
- if (group[20].indexOf(":") === -1) {
- date = +new Date(group[19] + " " + group[20]).getTime();
- }
- else {
- var currentMonth = new Date().getMonth();
- var month = new Date(group[19]).getMonth();
- var year = new Date().getFullYear() - (currentMonth < month ? 1 : 0);
+var parsers = {};
+
+parsers.unix = function(entry) {
+ var target, writePerm, readPerm, execPerm;
+ var group = entry.match(RE_UnixEntry);
+
+ if (group) {
+ var type = group[1];
+ //var hardLinks = group[15];
+ var usr = group[16];
+ var grp = group[17];
+ var size = group[18];
+ var name = group[21];
+
+ var date;
+ // Check whether we are given the time (recent file) or the year
+ // (older file) in the file listing.
+ if (group[20].indexOf(":") === -1) {
+ date = +new Date(group[19] + " " + group[20]).getTime();
+ }
+ else {
+ var currentMonth = new Date().getMonth();
+ var month = new Date(group[19]).getMonth();
+ var year = new Date().getFullYear() - (currentMonth < month ? 1 : 0);
- date = +new Date(group[19] + " " + group[20] + " " + year);
- }
+ date = +new Date(group[19] + " " + group[20] + " " + year);
+ }
- // Ignoring '.' and '..' entries for now
- if (name === "." || name === "..")
- return;
+ // Ignoring '.' and '..' entries for now
+ if (name === "." || name === "..")
+ return;
- var endtoken = group[22];
+ //var endtoken = group[22];
+
+ switch (type[0]) {
+ case 'd':
+ type = exports.nodeTypes.DIRECTORY_TYPE;
+ break;
+ case 'l':
+ type = exports.nodeTypes.SYMBOLIC_LINK_TYPE;
+ var isLink = /(.*)\s->\s(.*)/.exec(name);
+ if (isLink) {
+ name = isLink[1];
+ target = isLink[2];
+ }
+ break;
+ case 'b':
+ case 'c':
+ // break; - fall through
+ case 'f':
+ case '-':
+ type = exports.nodeTypes.FILE_TYPE;
+ break;
+ default:
+ type = exports.nodeTypes.UNKNOWN_TYPE;
+ }
- var isLink = /(.*)\s->\s(.*)/.exec(name);
- if (isLink) {
- name = isLink[1];
- target = isLink[2];
- }
+ var file = {
+ name: name,
+ type: type,
+ time: date,
+ size: size,
+ owner: usr,
+ group: grp
+ };
- switch (type[0]) {
- case 'd':
- type = exports.nodeTypes.DIRECTORY_TYPE;
- break;
- case 'l':
- type = exports.nodeTypes.SYMBOLIC_LINK_TYPE;
- break;
- case 'b':
- case 'c':
- // break; - fall through
- case 'f':
- case '-':
- type = exports.nodeTypes.FILE_TYPE;
- break;
- default:
- type = exports.nodeTypes.UNKNOWN_TYPE;
- }
+ if (target) file.target = target;
- var file = {
- name: name,
- type: type,
- time: date,
- size: size,
- owner: usr,
- group: grp
- };
+ var g = 4;
+ ["user", "group", "other"].forEach(function(access) {
+ // Use != '-' to avoid having to check for suid and sticky bits
+ readPerm = group[g] !== "-";
+ writePerm = group[g + 1] !== "-";
- if (target) file.target = target;
+ var execPermStr = group[g + 2];
- var g = 4;
- ["user", "group", "other"].forEach(function(access) {
- // Use != '-' to avoid having to check for suid and sticky bits
- readPerm = group[g] !== "-";
- writePerm = group[g + 1] !== "-";
+ file[access + "Permissions"] = {
+ read : readPerm,
+ write: writePerm,
+ exec : (execPermStr !== "-") && !(/[A-Z]/.test(execPermStr[0]))
+ };
- var execPermStr = group[g + 2];
+ g +=4;
+ });
- file[access + "Permissions"] = {
- read : readPerm,
- write: writePerm,
- exec : (execPermStr !== "-") && !(/[A-Z]/.test(execPermStr[0]))
- };
+ return file;
+ }
+};
- g +=4;
- });
+parsers.msdos = function(entry) {
+ var group = entry.match(RE_DOSEntry);
+ var type;
- return file;
- }
- },
- msdos: function(entry) {
- var group = entry.match(RE_DOSEntry);
- var type;
+ if (!group)
+ return;
- if (!group)
- return;
+ var replacer = function replacer(str, hour, min, ampm, offset, s) {
+ return hour + ":" + min + " " + ampm;
+ };
+
+ var time = group[2].replace(/(\d{2}):(\d{2})([AP]M)/, replacer);
+ var date = new Date(group[1] + " " + time).getTime();
+ var dirString = group[3];
+ var size = group[4];
+ var name = group[5];
- var replacer = function replacer(str, hour, min, ampm, offset, s) {
- return hour + ":" + min + " " + ampm;
- }
- var time = group[2].replace(/(\d{2}):(\d{2})([AP]M)/, replacer);
- var date = new Date(group[1] + " " + time).getTime();
- var dirString = group[3];
- var size = group[4];
- var name = group[5];
-
- if (null == name || name === "." || name === "..")
- return null;
-
- if (dirString === "<DIR>") {
- type = exports.nodeTypes.DIRECTORY_TYPE;
- size = 0;
- }
- else {
- type = exports.nodeTypes.FILE_TYPE;
- }
+ if (null == name || name === "." || name === "..")
+ return null;
- return {
- name: name,
- type: type,
- time: date,
- size: size
- };
+ if (dirString === "<DIR>") {
+ type = exports.nodeTypes.DIRECTORY_TYPE;
+ size = 0;
+ }
+ else {
+ type = exports.nodeTypes.FILE_TYPE;
}
+
+ return {
+ name: name,
+ type: type,
+ time: date,
+ size: size
+ };
};
/*
View
@@ -145,8 +145,13 @@ Ftp.getPasvPort = function(text) {
);
pairStreamer(parse, function(hadError) {
- if (!hadError) // Error case handled by error event.
- self.emitter.emit("disconnect", "Ftp disconnected.");
+ if (!hadError) {// Error case handled by error event.
+ if (self.connected) {
+ self.emitter.emit("disconnect", "Ftp disconnected.");
+ self.onDisconnect && self.onDisconnect();
+ }
+ self.connected = false;
+ }
});
if (this.waitingForEnqueue.length > 0) {
@@ -252,7 +257,15 @@ Ftp.getPasvPort = function(text) {
this.socket.on("error", function(err) {
var errString = "Error on ftp socket: " + err;
- self.emitter.emit("disconnect", errString);
+
+ if (self.connected) {
+ self.emitter.emit("disconnect", errString);
+ self.onDisconnect && self.onDisconnect(err);
+ }
+ self.connected = false;
+
+ if (self.onError)
+ self.onError(err);
// We still want the error to appearin the logs if we are not in debug mode.
if (!DEBUG_MODE)
@@ -261,10 +274,12 @@ Ftp.getPasvPort = function(text) {
this.socket.on("connect", function() {
self.connecting = false;
+ self.connected = true;
+
self.emitter.emit("connect", "connect");
if (self.onConnect)
- self.onConnect();
+ self.onConnect(self.socket);
self._createStreams(self.socket);
@@ -821,4 +836,4 @@ Ftp._concatStream = function(err, socket, callback) {
callback(null, Ftp._concat(pieces));
});
socket.resume();
-};
+};
View
@@ -1,7 +1,7 @@
{
"name": "jsftp",
"id": "jsftp",
- "version": "0.5.1",
+ "version": "0.5.2",
"description": "A sane FTP client implementation for NodeJS",
"keywords": [ "ftp", "protocol", "files", "server", "client", "async" ],
"author": "Sergi Mansilla <sergi.mansilla@gmail.com> (http://sergimansilla.com)",
View
@@ -54,6 +54,7 @@ describe("jsftp test suite", function() {
afterEach(function(next) {
if (daemon)
daemon.kill();
+
setTimeout(function() {
if (ftp) {
ftp.destroy();
@@ -467,4 +468,50 @@ describe("jsftp test suite", function() {
next();
});
});
+
+ it("Test that onConnect is called", function(next) {
+ var FTPCredentials = {
+ host: "localhost",
+ user: "user",
+ port: 3334,
+ pass: "12345",
+ onConnect: function(socket) {
+ assert(ftp2.connected);
+ assert(socket);
+ next();
+ },
+ };
+
+ var ftp2 = new Ftp(FTPCredentials);
+ });
+
+ it("Test that onDisconnect is called", function(next) {
+ var FTPCredentials = {
+ host: "localhost",
+ user: "user",
+ port: 3334,
+ pass: "12345",
+ onDisconnect: function() {
+ next();
+ },
+ };
+
+ var ftp2 = new Ftp(FTPCredentials);
+ ftp2.raw.quit();
+ });
+
+ it("Test that onError is called", function(next) {
+ var FTPCredentials = { // Bad credentials
+ host: "localhost",
+ user: "user_",
+ port: 33342,
+ pass: "12345_",
+ onError: function(error) {
+ assert(error);
+ next();
+ },
+ };
+
+ var ftp2 = new Ftp(FTPCredentials);
+ });
});
Oops, something went wrong.

0 comments on commit 5f6055e

Please sign in to comment.