@@ -146,11 +146,14 @@ Ftp.prototype.parseResponse = function(data) {
146146 var next = this . cmdBuffer_ [ 0 ] [ 1 ] ;
147147 if ( data . isMark ) {
148148 // If we receive a Mark and it is not expected, we ignore that command
149- if ( ! next . expectsMark || next . expectsMark . marks . indexOf ( data . code ) === - 1 )
149+ if ( ! next . expectsMark || next . expectsMark . marks . indexOf ( data . code ) === - 1 ) {
150150 return ;
151+ }
152+
151153 // We might have to ignore the command that comes after the mark.
152- if ( next . expectsMark . ignore )
154+ if ( next . expectsMark . ignore ) {
153155 this . ignoreCmdCode = next . expectsMark . ignore ;
156+ }
154157 }
155158
156159 if ( this . ignoreCmdCode && this . ignoreCmdCode === data . code ) {
@@ -300,8 +303,9 @@ Ftp.prototype.auth = function(user, pass, callback) {
300303
301304 function notifyAll ( err , res ) {
302305 var cb ;
303- while ( cb = self . pending . shift ( ) )
306+ while ( cb = self . pending . shift ( ) ) {
304307 cb ( err , res ) ;
308+ }
305309 }
306310
307311 if ( this . authenticating ) return ;
@@ -410,26 +414,22 @@ Ftp.prototype.emitProgress = function(data) {
410414 * case the operation was not successful.
411415 *
412416 * @param {String } remotePath File to be retrieved from the FTP server
413- * @param {String } localPath Local path where the new file will be created
414- * @param {Function } callback Gets called on either success or failure
417+ * @param {Function| String } localPath Local path where we create the new file
418+ * @param {Function } [ callback] Gets called on either success or failure
415419 */
416420Ftp . prototype . get = function ( remotePath , localPath , callback ) {
417421 var self = this ;
418- if ( arguments . length === 2 ) {
419- callback = once ( localPath || NOOP ) ;
420- this . getGetSocket ( remotePath , callback ) ;
422+ var finalCallback ;
423+
424+ if ( typeof localPath === 'function' ) {
425+ finalCallback = once ( localPath || NOOP ) ;
421426 } else {
422427 callback = once ( callback || NOOP ) ;
423- this . getGetSocket ( remotePath , function ( err , socket ) {
428+ finalCallback = function ( err , socket ) {
424429 if ( err ) {
425430 return callback ( err ) ;
426431 }
427432
428- if ( ! socket ) {
429- return callback ( new Error (
430- 'An unknown error occurred when trying to retrieve PASV socket' ) ) ;
431- }
432-
433433 var writeStream = fs . createWriteStream ( localPath ) ;
434434 writeStream . on ( 'error' , callback ) ;
435435
@@ -440,11 +440,20 @@ Ftp.prototype.get = function(remotePath, localPath, callback) {
440440 socket : this
441441 } ) ;
442442 } ) ;
443+
444+ // This ensures that any expected outcome is handled. There is no
445+ // danger of the callback being executed several times, because it is
446+ // wrapped in `once`.
447+ socket . on ( 'error' , callback ) ;
443448 socket . on ( 'end' , callback ) ;
449+ socket . on ( 'close' , callback ) ;
450+
444451 socket . pipe ( writeStream ) ;
445452 socket . resume ( ) ;
446- } ) ;
453+ } ;
447454 }
455+
456+ this . getGetSocket ( remotePath , finalCallback ) ;
448457} ;
449458
450459/**
@@ -473,12 +482,19 @@ Ftp.prototype.getGetSocket = function(path, callback) {
473482 socket . pause ( ) ;
474483
475484 function cmdCallback ( err , res ) {
476- if ( err ) return callback ( err ) ;
485+ if ( err ) {
486+ return callback ( err ) ;
487+ }
477488
478- if ( res . code === 125 || res . code === 150 )
479- callback ( null , socket ) ;
480- else
481- callback ( new Error ( 'Unexpected command ' + res . text ) ) ;
489+ if ( ! socket ) {
490+ return callback ( new Error ( 'Error when retrieving PASV socket' ) ) ;
491+ }
492+
493+ if ( res . code === 125 || res . code === 150 ) {
494+ return callback ( null , socket ) ;
495+ }
496+
497+ return callback ( new Error ( 'Unexpected command ' + res . text ) ) ;
482498 }
483499
484500 cmdCallback . expectsMark = {
@@ -547,7 +563,7 @@ Ftp.prototype.getPutSocket = function(path, callback, doneCallback) {
547563 callback ( err ) ;
548564 return doneCallback ( err ) ;
549565 }
550- return callback ( err , _socket ) ;
566+ return callback ( null , _socket ) ;
551567 } ) ;
552568
553569 var self = this ;
@@ -563,15 +579,17 @@ Ftp.prototype.getPutSocket = function(path, callback, doneCallback) {
563579 socket . on ( 'close' , doneCallback ) ;
564580 socket . on ( 'error' , doneCallback ) ;
565581 self . pasvTimeout . call ( self , socket , doneCallback ) ;
566- _callback ( null , socket ) ;
567- } else {
568- return _callback ( new Error ( 'Unexpected command ' + res . text ) ) ;
582+ return _callback ( null , socket ) ;
569583 }
584+
585+ return _callback ( new Error ( 'Unexpected command ' + res . text ) ) ;
570586 } ) ;
587+
571588 putCallback . expectsMark = {
572589 marks : [ 125 , 150 ] ,
573590 ignore : 226
574591 } ;
592+
575593 self . execute ( 'stor ' + path , putCallback ) ;
576594 } ) ;
577595} ;
0 commit comments