Skip to content

Commit 0a0d263

Browse files
committed
Add debug mode and some style changes. Fixes #87.
1 parent a78fb8f commit 0a0d263

File tree

3 files changed

+107
-22
lines changed

3 files changed

+107
-22
lines changed

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,54 @@ Refreshes the interval thats keep the server connection active. `wait` is an opt
203203
You can find more usage examples in the [unit tests](https://github.com/sergi/jsftp/blob/master/test/jsftp_test.js). This documentation
204204
will grow as jsftp evolves.
205205

206+
207+
Debugging
208+
---------
209+
210+
In order to enable debug mode in a FTP connection, a `debugMode` parameter can
211+
be used in the constructors's config object:
212+
213+
```javascript
214+
var Ftp = new JSFtp({
215+
host: "myserver.com",
216+
port: 3331,
217+
user: "user",
218+
pass: "1234",
219+
debugMode: true
220+
});
221+
```
222+
223+
It can also be activated or deactivated by calling the `setDebugMode` method:
224+
225+
```javascript
226+
Ftp.setDebugMode(true); // Debug Mode on
227+
Ftp.setDebugMode(false; // Debug mode off
228+
```
229+
230+
If the debug mode is on, the jsftp instance will emit `jsftp_debug` events with
231+
two parameters: the first is the type of the event and the second and object
232+
including data related to the event. There are 3 possible types of events:
233+
234+
- `response` events: These are response from the FTP server to the user's FTP
235+
commands
236+
237+
- `user_command` events: These are commands that the user issuendss to the
238+
FTP server.
239+
240+
- `event:{event name}` events: These are other events mostly related to the server
241+
connection, such as `timeout`, `connect` or `disconnect`. For example,
242+
a timeout event will have the name `event:timeout`.
243+
244+
In order to react to print all debug events (for example), we would listen to the
245+
debug messages like this:
246+
247+
```javascript
248+
Ftp.on('jsftp_debug', function(eventType, data) {
249+
console.log('DEBUG: ', eventType);
250+
console.log(JSON.stringify(data, null, 2));
251+
});
252+
```
253+
206254
Installation
207255
------------
208256

lib/jsftp.js

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ var fs = require("fs");
1717
var once = require("once");
1818

1919
var FTP_PORT = 21;
20-
var DEBUG_MODE = false;
2120
var TIMEOUT = 10 * 60 * 1000;
2221
var IDLE_TIME = 30000;
2322
var NOOP = function() {};
@@ -31,14 +30,17 @@ var COMMANDS = [
3130
"chmod", "size"
3231
];
3332

34-
function getPasvPort(text) {
33+
function getPasvPort(text, cb) {
3534
var RE_PASV = /([-\d]+,[-\d]+,[-\d]+,[-\d]+),([-\d]+),([-\d]+)/;
3635
var match = RE_PASV.exec(text);
37-
if (!match) return false;
36+
if (!match) {
37+
return cb(new Error("Bad passive host/port combination"));
38+
}
3839

39-
// Array containing the passive host and the port number
40-
return [match[1].replace(/,/g, "."),
41-
(parseInt(match[2], 10) & 255) * 256 + (parseInt(match[3], 10) & 255)];
40+
cb(null, {
41+
host: match[1].replace(/,/g, "."),
42+
port: (parseInt(match[2], 10) & 255) * 256 + (parseInt(match[3], 10) & 255)
43+
});
4244
}
4345

4446
function runCmd(cmd) {
@@ -75,21 +77,37 @@ var Ftp = module.exports = function(cfg) {
7577
// Generate generic methods from parameter names. they can easily be
7678
// overriden if we need special behavior. they accept any parameters given,
7779
// it is the responsability of the user to validate the parameters.
78-
this.raw = function () {
80+
this.raw = function() {
7981
return runCmd.apply(this, arguments);
8082
}.bind(this);
8183
COMMANDS.forEach(function(cmd) {
8284
this.raw[cmd] = runCmd.bind(this, cmd);
8385
}, this);
8486

87+
var self = this;
88+
this.on('data', function(data) {
89+
if (self.debugMode) {
90+
self.emit('jsftp_debug', 'response', data || {});
91+
}
92+
});
93+
8594
this.socket = this._createSocket(this.port, this.host);
8695
};
8796

8897
util.inherits(Ftp, EventEmitter);
8998

99+
Ftp.prototype.setDebugMode = function(debugOn) {
100+
this.debugMode = (debugOn !== false);
101+
};
102+
90103
Ftp.prototype.reemit = function(event) {
91104
var self = this;
92-
return function(data) { self.emit(event, data); }
105+
return function(data) {
106+
self.emit(event, data);
107+
if (self.debugMode) {
108+
self.emit('jsftp_debug', 'event:' + event, data || {});
109+
}
110+
}
93111
};
94112

95113
Ftp.prototype._createSocket = function(port, host, firstAction) {
@@ -155,6 +173,10 @@ Ftp.prototype.send = function(command) {
155173

156174
this.emit("cmdSend", command);
157175
this.pipeline.write(command + "\r\n");
176+
177+
if (this.debugMode) {
178+
this.emit('jsftp_debug', 'user_command', command || {});
179+
}
158180
};
159181

160182
Ftp.prototype.nextCmd = function() {
@@ -489,11 +511,11 @@ Ftp.prototype.put = function(from, to, callback) {
489511
return callback(new Error("Local file doesn't exist."));
490512

491513
fs.stat(from, function(err, stats) {
492-
var totalSize = err ? 0 : stats.size;
493-
var read = fs.createReadStream(from, {
494-
bufferSize: 4 * 1024
495-
});
496-
putReadable(read, to, totalSize, callback);
514+
var totalSize = err ? 0 : stats.size;
515+
var read = fs.createReadStream(from, {
516+
bufferSize: 4 * 1024
517+
});
518+
putReadable(read, to, totalSize, callback);
497519
});
498520
});
499521
} else {
@@ -546,23 +568,21 @@ Ftp.prototype.pasvTimeout = function(socket, cb) {
546568
socket.destroy();
547569
cb(new Error("Passive socket timeout"));
548570
});
549-
}
571+
};
550572

551573
Ftp.prototype.getPasvSocket = function(callback) {
552574
var timeout = this.timeout;
553575
callback = once(callback || NOOP);
554576
this.execute("pasv", function(err, res) {
555577
if (err) return callback(err);
556578

557-
var pasvRes = getPasvPort(res.text);
558-
if (pasvRes === false)
559-
return callback(new Error("PASV: Bad host/port combination"));
579+
getPasvPort(res.text, function(err, res) {
580+
if (err) return callback(err);
560581

561-
var host = pasvRes[0];
562-
var port = pasvRes[1];
563-
var socket = Net.createConnection(port, host);
564-
socket.setTimeout(timeout || TIMEOUT);
565-
callback(null, socket);
582+
var socket = Net.createConnection(res.port, res.host);
583+
socket.setTimeout(timeout || TIMEOUT);
584+
callback(null, socket);
585+
});
566586
});
567587
};
568588

test/jsftp_test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,4 +743,21 @@ describe("jsftp test suite", function() {
743743
next();
744744
}, 5000);
745745
});
746+
747+
it("Test debug mode", function(next) {
748+
var debugCredentials = JSON.parse(JSON.stringify(FTPCredentials));
749+
debugCredentials.debugMode = true;
750+
751+
var ftp2 = new Ftp(debugCredentials);
752+
ftp2.once('jsftp_debug', function(type, data) {
753+
next();
754+
});
755+
});
756+
757+
it("Test debug mode `setDebugMode`", function(next) {
758+
ftp.setDebugMode(true);
759+
ftp.once('jsftp_debug', function(type, data) {
760+
next();
761+
});
762+
});
746763
});

0 commit comments

Comments
 (0)