From d2bf0eba1c5d6696eb10953362ecaef71a37d1af Mon Sep 17 00:00:00 2001 From: Maurice Streubel Date: Wed, 22 Jan 2014 22:09:42 +0100 Subject: [PATCH 1/4] Changed restart function to be executed after PASV --- lib/connection.js | 62 +++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/lib/connection.js b/lib/connection.js index 73bc3a7..e6774b4 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -65,6 +65,7 @@ var FTP = module.exports = function() { this._keepalive = undefined; this._ending = false; this._parser = undefined; + this._offset = 0; this.options = { host: undefined, port: undefined, @@ -585,39 +586,46 @@ FTP.prototype.get = function(path, zcomp, cb) { // this callback will be executed multiple times, the first is when server // replies with 150, then a final reply after the data connection closes // to indicate whether the transfer was actually a success or not - self._send('RETR ' + path, function(err, text, code) { - if (sockerr || err) { - sock.destroy(); - if (!started) { - if (zcomp) { - self._send('MODE S', function() { + self._send('REST ' + self._offset, function(){ + self._send('RETR ' + path, function(err, text, code) { + self._offset = 0; + if (sockerr || err) { + sock.destroy(); + if (!started) { + if (zcomp) { + self._send('MODE S', function() { + cb(sockerr || err); + }, true); + } else cb(sockerr || err); - }, true); - } else - cb(sockerr || err); + } else { + source._emit('error', sockerr || err); + source._emit('close', true); + } + return; + } + // server returns 125 when data connection is already open; we treat it + // just like a 150 + if (code === 150 || code === 125) { + started = true; + cb(undefined, source); + sock.resume(); } else { - source._emit('error', sockerr || err); - source._emit('close', true); + lastreply = true; + ondone(); } - return; - } - // server returns 125 when data connection is already open; we treat it - // just like a 150 - if (code === 150 || code === 125) { - started = true; - cb(undefined, source); - sock.resume(); - } else { - lastreply = true; - ondone(); - } - }, true); + }, true); + }); } }); }; FTP.prototype.put = function(input, path, zcomp, cb) { - this._store('STOR ' + path, input, zcomp, cb); + self = this; + self._send('REST ' + this._goffset, function(){ + this._store('STOR ' + path, input, zcomp, cb); + self._offset = 0; + }); }; FTP.prototype.append = function(input, path, zcomp, cb) { @@ -779,7 +787,9 @@ FTP.prototype.lastMod = function(path, cb) { }; FTP.prototype.restart = function(offset, cb) { - this._send('REST ' + offset, cb); + self = this; + self._offset = offset; + cb(); }; From a5c6440034a077639a23bda9f68b8b2bd8fce81b Mon Sep 17 00:00:00 2001 From: Maurice Streubel Date: Wed, 22 Jan 2014 23:11:35 +0100 Subject: [PATCH 2/4] Rest command will be sended before STOR or RETR if offset is set with c.restat --- lib/connection.js | 82 +++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/lib/connection.js b/lib/connection.js index e6774b4..6ab9c70 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -65,7 +65,7 @@ var FTP = module.exports = function() { this._keepalive = undefined; this._ending = false; this._parser = undefined; - this._offset = 0; + this._offset = undefined; this.options = { host: undefined, port: undefined, @@ -577,55 +577,69 @@ FTP.prototype.get = function(path, zcomp, cb) { sock.destroy(); return cb(makeError(code, 'Compression not supported')); } - sendRetr(); + if(self._offset !== undefined){//Append at offset + self._send('REST ' + self._offset, function(){ + sendRetr(); + self._offset = undefined; + }); + }else + sendRetr(); }, true); - } else - sendRetr(); + } else{ + if(self._offset !== undefined){//Append at offset + self._send('REST ' + self._offset, function(){ + sendRetr(); + self._offset = undefined; + }); + }else + sendRetr(); + } + function sendRetr() { // this callback will be executed multiple times, the first is when server // replies with 150, then a final reply after the data connection closes // to indicate whether the transfer was actually a success or not - self._send('REST ' + self._offset, function(){ - self._send('RETR ' + path, function(err, text, code) { - self._offset = 0; - if (sockerr || err) { - sock.destroy(); - if (!started) { - if (zcomp) { - self._send('MODE S', function() { - cb(sockerr || err); - }, true); - } else + self._send('RETR ' + path, function(err, text, code) { + if (sockerr || err) { + sock.destroy(); + if (!started) { + if (zcomp) { + self._send('MODE S', function() { cb(sockerr || err); - } else { - source._emit('error', sockerr || err); - source._emit('close', true); - } - return; - } - // server returns 125 when data connection is already open; we treat it - // just like a 150 - if (code === 150 || code === 125) { - started = true; - cb(undefined, source); - sock.resume(); + }, true); + } else + cb(sockerr || err); } else { - lastreply = true; - ondone(); + source._emit('error', sockerr || err); + source._emit('close', true); } - }, true); - }); + return; + } + // server returns 125 when data connection is already open; we treat it + // just like a 150 + if (code === 150 || code === 125) { + started = true; + cb(undefined, source); + sock.resume(); + } else { + lastreply = true; + ondone(); + } + }, true); } }); }; FTP.prototype.put = function(input, path, zcomp, cb) { self = this; - self._send('REST ' + this._goffset, function(){ + if(self._offset !== undefined){ //Append at offset + self._send('REST ' + self._offset, function(){ + this._store('STOR ' + path, input, zcomp, cb); + self._offset = undefined; + }); + }else this._store('STOR ' + path, input, zcomp, cb); - self._offset = 0; - }); }; FTP.prototype.append = function(input, path, zcomp, cb) { From ee6e1944d3190a13612491801734229f8169b319 Mon Sep 17 00:00:00 2001 From: holymoly Date: Thu, 22 May 2014 07:31:32 +0200 Subject: [PATCH 3/4] removed self = this in FTP.prototype.restart Issue #76 --- lib/connection.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/connection.js b/lib/connection.js index 6ab9c70..69aa8fe 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -801,8 +801,7 @@ FTP.prototype.lastMod = function(path, cb) { }; FTP.prototype.restart = function(offset, cb) { - self = this; - self._offset = offset; + this._offset = offset; cb(); }; From 0417a620094825ee4efb693096729045bd313672 Mon Sep 17 00:00:00 2001 From: holymoly Date: Thu, 22 May 2014 08:06:09 +0200 Subject: [PATCH 4/4] restart will call cb on nextTick issue #76 --- lib/connection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/connection.js b/lib/connection.js index 69aa8fe..bf9feec 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -802,7 +802,7 @@ FTP.prototype.lastMod = function(path, cb) { FTP.prototype.restart = function(offset, cb) { this._offset = offset; - cb(); + process.nextTick(cb); };