@@ -5,7 +5,7 @@ var async = require('async');
55var EventEmitter = require ( 'events' ) . EventEmitter ;
66var Connection = require ( 'ssh2' ) ;
77var _ = require ( 'lodash' ) ;
8-
8+ var progressStream = require ( 'progress-stream' ) ;
99
1010function Client ( options ) {
1111 this . _options = options || { } ;
@@ -24,22 +24,24 @@ Client.prototype.defaults = function(options) {
2424
2525Client . prototype . parse = function ( remote ) {
2626 if ( _ . isString ( remote ) ) {
27- // username[ :password] @host [:port][: /path/to]
28- var regex = / ^ ( [ a - z A - Z 0 - 9 \- \. _ ] + ) (?: \: ( .* ) ) ? @ ( [ ^ : ] + ) (?: \: ( [ 0 - 9 ] + ) ) ? (?: \: ( . * ) ) ? $ / ;
27+ // username:password@host : /path/to
28+ var regex = / ^ ( [ a - z A - Z 0 - 9 \- \. ] + ) ( \: .* ) ? @ ( [ ^ : ] + ) : ( [ ^ : ] + : ) ? ( . * ) ? $ / ;
2929 var m = remote . match ( regex ) ;
3030 if ( ! m ) return { } ;
3131 var ret = {
3232 username : m [ 1 ] ,
3333 host : m [ 3 ] ,
3434 } ;
3535 if ( m [ 2 ] ) {
36- ret . password = m [ 2 ] ;
36+ ret . password = m [ 2 ] . slice ( 1 ) ;
3737 }
38- if ( m [ 4 ] ) {
39- ret . port = m [ 4 ] ;
38+ if ( m . length === 6 && m [ 4 ] ) {
39+ ret . port = m [ 4 ] . slice ( 0 , - 1 ) ;
4040 }
41- if ( m [ 5 ] ) {
41+ if ( m . length === 6 && m [ 5 ] ) {
4242 ret . path = m [ 5 ] ;
43+ } else if ( m . length === 5 && m [ 4 ] ) {
44+ ret . path = m [ 4 ] ;
4345 }
4446 this . remote = ret ;
4547 return ret ;
@@ -262,10 +264,7 @@ Client.prototype.upload = function(src, dest, callback) {
262264 // Get the attributes of the source directory
263265 fs . stat ( path . dirname ( src ) , function ( err , dirStat ) {
264266 if ( err ) return callback ( err ) ;
265-
266- var cleanDirStat = { mode : dirStat . mode } ;
267-
268- self . mkdir ( path . dirname ( dest ) , cleanDirStat , function ( err ) { callback ( err , stat ) } ) ;
267+ self . mkdir ( path . dirname ( dest ) , dirStat , function ( err ) { callback ( err , stat ) } ) ;
269268 } ) ;
270269 } ,
271270 function ( stat , callback ) {
@@ -284,7 +283,7 @@ Client.prototype.upload = function(src, dest, callback) {
284283 } ) ;
285284} ;
286285
287- Client . prototype . download = function ( src , dest , callback ) {
286+ /* Client.prototype.download = function(src, dest, callback) {
288287 var self = this;
289288
290289 self.sftp(function(err,sftp){
@@ -299,13 +298,47 @@ Client.prototype.download = function(src, dest, callback) {
299298 sftp_readStream.pipe(fs.createWriteStream(dest))
300299 .on('close',function(){
301300 self.emit('read', src);
302- self . close ( ) ;
303301 callback(null);
304302 })
305303 .on('error', function(err){
306304 callback(err);
307305 });
308306 });
307+ };*/
308+ Client . prototype . download = function ( src , dest , callback ) {
309+ var self = this ;
310+
311+ self . sftp ( function ( err , sftp ) {
312+ if ( err ) {
313+ return callback ( err ) ;
314+ }
315+
316+ sftp . stat ( src , function ( err , stat ) {
317+ if ( err ) {
318+ return callback ( err ) ;
319+ }
320+ var ps = progressStream ( {
321+ length : stat . size ,
322+ time : 100
323+ } ) ;
324+ ps . on ( 'progress' , function ( progress ) {
325+ self . emit ( 'progress' , progress ) ;
326+ } ) ;
327+ var sftp_readStream = sftp . createReadStream ( src ) ;
328+ sftp_readStream . on ( 'error' , function ( err ) {
329+ callback ( err ) ;
330+ } ) ;
331+ sftp_readStream . pipe ( ps ) . pipe ( fs . createWriteStream ( dest ) )
332+ . on ( 'close' , function ( ) {
333+ self . emit ( 'read' , src ) ;
334+ callback ( null ) ;
335+ } )
336+ . on ( 'error' , function ( err ) {
337+ callback ( err ) ;
338+ } ) ;
339+ return self ;
340+ } ) ;
341+ } ) ;
309342} ;
310343
311344exports = module . exports = new Client ( ) ;
0 commit comments