Giter VIP home page Giter VIP logo

node-ftp's Introduction

Description

node-ftp is an FTP client module for node.js that provides an asynchronous interface for communicating with an FTP server.

Requirements

Install

npm install ftp

Examples

  • Get a directory listing of the current (remote) working directory:
  var Client = require('ftp');

  var c = new Client();
  c.on('ready', function() {
    c.list(function(err, list) {
      if (err) throw err;
      console.dir(list);
      c.end();
    });
  });
  // connect to localhost:21 as anonymous
  c.connect();
  • Download remote file 'foo.txt' and save it to the local file system:
  var Client = require('ftp');
  var fs = require('fs');

  var c = new Client();
  c.on('ready', function() {
    c.get('foo.txt', function(err, stream) {
      if (err) throw err;
      stream.once('close', function() { c.end(); });
      stream.pipe(fs.createWriteStream('foo.local-copy.txt'));
    });
  });
  // connect to localhost:21 as anonymous
  c.connect();
  • Upload local file 'foo.txt' to the server:
  var Client = require('ftp');
  var fs = require('fs');

  var c = new Client();
  c.on('ready', function() {
    c.put('foo.txt', 'foo.remote-copy.txt', function(err) {
      if (err) throw err;
      c.end();
    });
  });
  // connect to localhost:21 as anonymous
  c.connect();

API

Events

  • greeting(< string >msg) - Emitted after connection. msg is the text the server sent upon connection.

  • ready() - Emitted when connection and authentication were sucessful.

  • close(< boolean >hadErr) - Emitted when the connection has fully closed.

  • end() - Emitted when the connection has ended.

  • error(< Error >err) - Emitted when an error occurs. In case of protocol-level errors, err contains a 'code' property that references the related 3-digit FTP response code.

Methods

* Note: As with the 'error' event, any error objects passed to callbacks will have a 'code' property for protocol-level errors.

  • (constructor)() - Creates and returns a new FTP client instance.

  • connect(< object >config) - (void) - Connects to an FTP server. Valid config properties:

    • host - string - The hostname or IP address of the FTP server. Default: 'localhost'

    • port - integer - The port of the FTP server. Default: 21

    • secure - mixed - Set to true for both control and data connection encryption, 'control' for control connection encryption only, or 'implicit' for implicitly encrypted control connection (this mode is deprecated in modern times, but usually uses port 990) Default: false

    • secureOptions - object - Additional options to be passed to tls.connect(). Default: (none)

    • user - string - Username for authentication. Default: 'anonymous'

    • password - string - Password for authentication. Default: 'anonymous@'

    • connTimeout - integer - How long (in milliseconds) to wait for the control connection to be established. Default: 10000

    • pasvTimeout - integer - How long (in milliseconds) to wait for a PASV data connection to be established. Default: 10000

    • keepalive - integer - How often (in milliseconds) to send a 'dummy' (NOOP) command to keep the connection alive. Default: 10000

  • end() - (void) - Closes the connection to the server after any/all enqueued commands have been executed.

  • destroy() - (void) - Closes the connection to the server immediately.

Required "standard" commands (RFC 959)

  • list([< string >path, ][< boolean >useCompression, ]< function >callback) - (void) - Retrieves the directory listing of path. path defaults to the current working directory. useCompression defaults to false. callback has 2 parameters: < Error >err, < array >list. list is an array of objects with these properties:

    * type - _string_ - A single character denoting the entry type: 'd' for directory, '-' for file (or 'l' for symlink on **\*NIX only**).
    
    * name - _string_ - The name of the entry.
    
    * size - _string_ - The size of the entry in bytes.
    
    * date - _Date_ - The last modified date of the entry.
    
    * rights - _object_ - The various permissions for this entry **(*NIX only)**.
    
        * user - _string_ - An empty string or any combination of 'r', 'w', 'x'.
    
        * group - _string_ - An empty string or any combination of 'r', 'w', 'x'.
    
        * other - _string_ - An empty string or any combination of 'r', 'w', 'x'.
    
    * owner - _string_ - The user name or ID that this entry belongs to **(*NIX only)**.
    
    * group - _string_ - The group name or ID that this entry belongs to **(*NIX only)**.
    
    * target - _string_ - For symlink entries, this is the symlink's target **(*NIX only)**.
    
    * sticky - _boolean_ - True if the sticky bit is set for this entry **(*NIX only)**.
    
  • get(< string >path, [< boolean >useCompression, ]< function >callback) - (void) - Retrieves a file at path from the server. useCompression defaults to false. callback has 2 parameters: < Error >err, < ReadableStream >fileStream.

  • put(< mixed >input, < string >destPath, [< boolean >useCompression, ]< function >callback) - (void) - Sends data to the server to be stored as destPath. input can be a ReadableStream, a Buffer, or a path to a local file. useCompression defaults to false. callback has 1 parameter: < Error >err.

  • append(< mixed >input, < string >destPath, [< boolean >useCompression, ]< function >callback) - (void) - Same as put(), except if destPath already exists, it will be appended to instead of overwritten.

  • rename(< string >oldPath, < string >newPath, < function >callback) - (void) - Renames oldPath to newPath on the server. callback has 1 parameter: < Error >err.

  • logout(< function >callback) - (void) - Logout the user from the server. callback has 1 parameter: < Error >err.

  • delete(< string >path, < function >callback) - (void) - Deletes a file, path, on the server. callback has 1 parameter: < Error >err.

  • cwd(< string >path, < function >callback) - (void) - Changes the current working directory to path. callback has 2 parameters: < Error >err, < string >currentDir. Note: currentDir is only given if the server replies with the path in the response text.

  • abort(< function >callback) - (void) - Aborts the current data transfer (e.g. from get(), put(), or list()). callback has 1 parameter: < Error >err.

  • site(< string >command, < function >callback) - (void) - Sends command (e.g. 'CHMOD 755 foo', 'QUOTA') using SITE. callback has 3 parameters: < Error >err, < _string >responseText, < integer >responseCode.

  • status(< function >callback) - (void) - Retrieves human-readable information about the server's status. callback has 2 parameters: < Error >err, < string >status.

  • ascii(< function >callback) - (void) - Sets the transfer data type to ASCII. callback has 1 parameter: < Error >err.

  • binary(< function >callback) - (void) - Sets the transfer data type to binary (default at time of connection). callback has 1 parameter: < Error >err.

Optional "standard" commands (RFC 959)

  • mkdir(< string >path, [< boolean >recursive, ]< function >callback) - (void) - Creates a new directory, path, on the server. recursive is for enabling a 'mkdir -p' algorithm and defaults to false. callback has 1 parameter: < Error >err.

  • rmdir(< string >path, [< boolean >recursive, ]< function >callback) - (void) - Removes a directory, path, on the server. If recursive, this call will delete the contents of the directory if it is not empty. callback has 1 parameter: < Error >err.

  • cdup(< function >callback) - (void) - Changes the working directory to the parent of the current directory. callback has 1 parameter: < Error >err.

  • pwd(< function >callback) - (void) - Retrieves the current working directory. callback has 2 parameters: < Error >err, < string >cwd.

  • system(< function >callback) - (void) - Retrieves the server's operating system. callback has 2 parameters: < Error >err, < string >OS.

  • listSafe([< string >path, ][< boolean >useCompression, ]< function >callback) - (void) - Similar to list(), except the directory is temporarily changed to path to retrieve the directory listing. This is useful for servers that do not handle characters like spaces and quotes in directory names well for the LIST command. This function is "optional" because it relies on pwd() being available.

Extended commands (RFC 3659)

  • size(< string >path, < function >callback) - (void) - Retrieves the size of path. callback has 2 parameters: < Error >err, < integer >numBytes.

  • lastMod(< string >path, < function >callback) - (void) - Retrieves the last modified date and time for path. callback has 2 parameters: < Error >err, < Date >lastModified.

  • restart(< integer >byteOffset, < function >callback) - (void) - Sets the file byte offset for the next file transfer action (get/put) to byteOffset. callback has 1 parameter: < Error >err.

node-ftp's People

Contributors

avranju avatar doug65536 avatar georgephillips avatar kgilpin avatar ljxia avatar martinvl avatar maximethebault avatar mscdex avatar temich avatar tp avatar unixpickle avatar victorstanciu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-ftp's Issues

.list() ignores path parameter

When trying to list the contents of a subdirectory, the .list method completely ignores the path parameter and only lists the CWD. If I cwd to a subdirectory first, and then call list without an additional path argument, it works:

var FTPClient = require('ftp');

var c = new FTPClient();

c.on('ready', function() {
    c.list(function (error, items) {
        if (error) { return console.log("ERROR: ", error); }

        console.log(
            "CWD contents:",
            items.map(function (item) { return item.name; })
        );

        c.list('subdirectory', function (error, items) {
            if (error) { return console.log("ERROR: ", error); }

            // This outputs the exact same items as before, despite having received a custom path parameter:
            console.log(
                "Subdirectory contents:",
                items.map(function (item) { return item.name; })
            );

            // If we CWD to the desired subdirectory first, IT WORKS:
            c.cwd('subdirectory', function (error, items) {
                c.list(function (error, items) {
                    if (error) { return console.log("ERROR: ", error); }

                    console.log(
                        "Subdirectory contents after CWD:",
                        items.map(function (item) { return item.name; })
                    );
                });
            });
        });
    });
});

c.connect({
    host: 'localhost',
    port: 21,
    user: 'ftp',
    password: 'ftp'
});

Queue processing should be prevented until login is complete

When a connection attempt succeeds, but the subsequent login fails, the socket is ended at https://github.com/mscdex/node-ftp/blob/master/lib/connection.js#L193

If at this point there are items in the queue, an attempt is made to write to the socket after the socket is ended (but before the socket's end event is processed).

This in itself is a minor issue, but it makes obvious a more serious issue: it's possible to have queued requests discarded without notice.

If there are items in the queue when a login fails, _reset() is called which destroys the queue, but none of the callbacks in the queue are called, and so they disappear without trace.

A scenario:

A connection has been established, and 10 put requests are made immediately which all go into the queue. The queue is successfully processed for the first five items, but then, for whatever reason, the connection gets reset by the server (some FTP is flaky).

The callback for the 6th put request will be called with an error passed. Sweet. We can do what ever is necessary to handle the error.

A listener on the 'close' or 'end' events automatically attempts to re-connect. The connection succeeds, but for whatever reason, the login fails (some FTP is flaky).

Even though a new attempt at connecting can now be made, the socket end event will trigger a call to _reset(), and the remaining items in the queue just disappear. We have no way to know they've disappeared. Callbacks are never called and errors never raised.

"TypeError: Cannot read property '1' of null" on successful cwd

When cwd-ing into an existing directory, the following error is thrown:

TypeError: Cannot read property '1' of null

The first item of the backtrace is:

cb(undefined, /"(.+)"(?: |$)/.exec(text)[1]);

The code I am using:

var FTPClient = require('ftp');

var c = new FTPClient();

c.on('ready', function() {
    c.cwd('/directory-that-exists', function (error) {
        if (error) {
            return console.log(error);
        }
        c.list(function (error, list) {
            if (error) {
                return console.log(error);
            }

            console.dir(list);
        });
    })
});

c.connect({
    host: 'localhost',
    port: 21,
    user: 'ftp',
    password: 'ftp'
});

I've tested this on three separate servers. The only thing they have in common is that they respond to the CWD statement with:

250 CWD command successful

I can also tell you the server software running on two of them:

ProFTPD 1.3.2e
ProFTPD 1.3.4a

Otherwise, everything seems to work I can .list just fine if I don't cwd first.

put(), get() method does not work, but list() works.

Hi,
I am trying to make FTP client by this module.
List() command works well.
but put(), get() as upload, download doesn't work.
I think I tried like your example.
I will show you my source.

In case of put(),

after greeting event, ready event,
I execute this code.

ftpWrok.ftpConnection.put('./ftp.txt', 'ftpcopy.txt', function(err){
        if(err){
            console.log(err);
        }else{
            console.log("====FTP file upload success?==");
        }
    });

ftp.txt is same directory with javascript source file.
but "ftpcopy.txt" created on FTPserver just include text "./ftp.txt".
it seems not to recognize first parameter input filename but just String.

In case of get(),

ftpWrok.ftpConnection.get('./ftpTest/ftp.txt', function(err, stream){
        if(err){
            console.log(err);
            throw err;
        }

        stream.once('close', function(){ftpWrok.ftpConnection.end();});
        stream.pipe(fs.createWriteStream('ftplocalcopy.txt'));
    });

emitted error.

console.logs are like below,

==============FTP greeting event===
=============FTP ready event===========
(execute download command)
===========FTP error event=========
{ [Error: OOPS: vsf_sysutil_recv_peek: no data] code: 500 }
===========FTP error event=========
{ [Error: OOPS: child died] code: 500 }
============FTP end event====
===========FTP close event====

if I have a mistake, could you comment some advice?

0 bytes transferred on put

Hello, I am attempting to do an ftp put but no bytes get transferred. It creates the file but it is an empty file. below, I am using a buffer and confirm that it has loaded the buffer. I also tried using the filepath string, as well as a read stream (fs.createReadStream(filepath)) but there is no change in behavior with any of those alternatives. I have confirmed that my credentials allow for me to put files. I did this using filezilla. I am not getting any error being reported. Any thoughts on how I can further diagnose this issue, or do you have any suggestions as to what I might be doing wrong? thanks.

        var c = new FTPClient();
        c.on('ready', function () {
            c.cwd(p, function(err){
                if(err){callback(err)}
                else{
                    var buf = fs.readFileSync(filepath)
                    console.log('buffer length is '+buf.length)
                    c.put(buf, filename, function (err) {
                        if(err){callback(err)}
                        else{
                            c.end();
                            callback()
                        }
                    });
                }
            })
        });
        c.on('error', function(err){
            callback(err)
        })
        c.connect(config);

my config looks like this
{
"host":"ftp.blah.com",
"port":21,
"secure":false,
"user":"00054921",
"password":"",
"connTimeout":10000,
"pasvTimeout":10000,
"keepalive":10000
}

get stuck, no call back

I can connect and download test.txt via a normal ftp client but the get callback never gets called using the code below. If I try an incorrect filename an error gets correctly thrown. Tried with and without the leading './'

coffee code:

c.on 'ready',->
    c.get "./test.txt",(err,stream) ->
        if err
            throw err
        stream.once 'close', -> 
            c.end()
        stream.pipe(fs.createWriteStream('foo.local-copy.txt'))

debug:

[connection] < '220 ProFTPD 1.3.4a Server (Debian) [::ffff:192.168.0.20]\r\n'
[parser] < '220 ProFTPD 1.3.4a Server (Debian) [::ffff:192.168.0.20]\r\n'
[parser] Response: code=220, buffer='ProFTPD 1.3.4a Server (Debian) [::ffff:192.0.168.20]'
[connection] > 'USER localadmin'
[connection] < '331 Password required for localadmin\r\n'
[parser] < '331 Password required for localadmin\r\n'
[parser] Response: code=331, buffer='Password required for localadmin'
[connection] > 'PASS XXXXXX'
[connection] < '230 User localadmin logged in\r\n'
[parser] < '230 User localadmin logged in\r\n'
[parser] Response: code=230, buffer='User localadmin logged in'
[connection] > 'FEAT'
[connection] < '211-Features:\r\n LANG en-US.UTF-8;en-US*\r\n MDTM\r\n MFMT\r\n TVFS\r\n UTF8\r\n MFF modify;UNIX.group;UNIX.mode;\r\n MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;\r\n SITE MKDIR\r\n SITE RMDIR\r\n SITE UTIME\r\n SITE SYMLINK\r\n REST STREAM\r\n SITE COPY\r\n SIZE\r\n'
[connection] < '211 End\r\n'
[parser] < '211-Features:\r\n LANG en-US.UTF-8;en-US*\r\n MDTM\r\n MFMT\r\n TVFS\r\n UTF8\r\n MFF modify;UNIX.group;UNIX.mode;\r\n MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;\r\n SITE MKDIR\r\n SITE RMDIR\r\n SITE UTIME\r\n SITE SYMLINK\r\n REST STREAM\r\n SITE COPY\r\n SIZE\r\n211 End\r\n'
[parser] Response: code=211, buffer='Features:\r\n LANG en-US.UTF-8;en-US*\r\n MDTM\r\n MFMT\r\n TVFS\r\n UTF8\r\n MFF modify;UNIX.group;UNIX.mode;\r\n MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;\r\n SITE MKDIR\r\n SITE RMDIR\r\n SITE UTIME\r\n SITE SYMLINK\r\n REST STREAM\r\n SITE COPY\r\n SIZE\r\nEnd'
[connection] > 'TYPE I'
[connection] < '200 Type set to I\r\n'
[parser] < '200 Type set to I\r\n'
[parser] Response: code=200, buffer='Type set to I'
[connection] > 'PASV'
[connection] < '227 Entering Passive Mode (192,168,0,20,200,240).\r\n'
[parser] < '227 Entering Passive Mode (192,168,0,20,200,240).\r\n'
[parser] Response: code=227, buffer='Entering Passive Mode (192,168,0,20,200,240).'
[connection] > 'RETR ./test.txt'

Crash on certificate error

node-ftp crashes when there is a certificate error. Callbacks do not work in this case.

Error: Hostname/IP doesn't match certificate's altnames
    at SecurePair.<anonymous> (tls.js:1355:23)
    at SecurePair.EventEmitter.emit (events.js:92:17)
    at SecurePair.maybeInitFinished (tls.js:959:10)
    at CleartextStream.read [as _read] (tls.js:463:15)
    at CleartextStream.Readable.read (_stream_readable.js:320:10)
    at EncryptedStream.write [as _write] (tls.js:366:25)
    at doWrite (_stream_writable.js:219:10)
    at writeOrBuffer (_stream_writable.js:209:5)
    at EncryptedStream.Writable.write (_stream_writable.js:180:11)
    at Socket.ondata (stream.js:51:26)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:736:14)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at Socket.Readable.push (_stream_readable.js:127:10)
    at TCP.onread (net.js:526:21) exceptionHandler.js:28
(anonymous function) exceptionHandler.js:28
Error: read ECONNRESET
    at errnoException (net.js:901:11)
    at TCP.onread (net.js:556:19)

Here is my code

//Start FTP connection
  ftp.connect({
    host: HOST,
    port: PORT,
    secure: true,
    user: USERNAME,
    password: PASSWORD
  });

   ftp.on('error', function(e) {
      console.log(e);
   });

missing starttls support

A number of servers require this to function. There is no support for starttls nor any way to use an existing SSL/TLS socket with node-ftp, making it unusable for connecting to servers requiring one or the other.

Multiple Concurrent Connections

Hello,

I would like if this feature is supported by node-ftp. I went through documentation but i couldn't find anything. If not, is it going to?

Thank you for your time

SFTP Example

Not seeing an example for SFTP. Trying to change around the secure param settings and not having much luck. I noticed FTPS hasn't been added, but is SFTP supported?

Cheers,D

"end" event not being fired when secure = true

If I connect to a FTPS server, the end event never gets fired. The close event works just fine:

var FTPClient = require('ftp');

var c = new FTPClient();

c.on('ready', function() {
    c.end();
});
c.on('end', function () {
    console.log('This will never happen when secure = true');
});
c.on('close', function () {
    console.log('This will');
})

c.connect({
    host: 'localhost',
    port: 21,
    user: 'ftp',
    password: 'ftp',
    secure: true
});

"get" finished premature

The 'get' command seems randomly finish the stream premature. Around 10% of the time. File size is around 60k. No error was fired.

encoding problem

hi, I'm using node-ftp at win7 cmd (chinese, gbk), and got trouble at list file name.

here is a workaround only for test, could you plz add support to this issue?


var iconv = require('../iconv-lite');
var BufferHelper = require('../bufferhelper');

FTP.prototype._pasvGetLines = function(emitter, type, cb) {
  return this.send('PASV', function(e, stream) {
    if (e)
      return cb(e);
    var curData = '', lines;

    //stream.setEncoding('utf8');
    
    stream.on('data', function(data) {

      var bufferHelper = new BufferHelper();
      bufferHelper.concat(data);

      curData += data;
      if (/\r\n|\n/.test(curData)) {

        curData = iconv.decode(bufferHelper.toBuffer(),'gbk');

        if (curData[curData.length-1] === '\n') {
          lines = curData.split(/\r\n|\n/);
          curData = '';
        } else {
          var pos = curData.lastIndexOf('\r\n');
          if (pos === -1)
            pos = curData.lastIndexOf('\n');
          lines = curData.substring(0, pos).split(/\r\n|\n/);
          curData = curData.substring(pos+1);
        }
        processDirLines(lines, emitter, type);
      }
    });
    stream.on('end', function() {
      emitter.emit('end');
    });
    stream.on('error', function(e) {
      emitter.emit('error', e);
    });
    cb();
  });
};

No data received from put()

I am issuing a put() command, which reports success but the target file is empty.

FTP.prototype.put has:

  instream.resume();
  instream.pipe(outstream); 

When I swapped it to:

  instream.pipe(outstream); 
  instream.resume();

then my target file appeared as expected.

Missing chmod function

I find this function missing. I've added

FTP.prototype.chmod = function(path, mod, cb) {
this._send('CHMOD ' + mod + ' ' + path, cb);
};

to "connection.js". Would be nice to have this function included in on the following versions.

Incorrect work within callback fs.mkdir

var ftp = require('ftp'),
    fs = require('fs');

var client = new ftp();

client.connect({
    host: 'ftp.volia.net'
});

client.on('ready', function() {
    fs.mkdir('justFolder', 0777, function (err) {
        client.get('/speedtest.php5', function(err, stream) {
            if (err) {
                console.log(err);
                return;
            }
            var f = fs.createWriteStream(Date.now()+'');
            stream.pipe(f);
            stream.on('close', function() {
                console.log('finish');
            });
        });
    });
});

If you run this code several times, then in the folder appear the following files:

$ ls -l
-rw-r--r--   1 user  staff   9636  6 ั„ะตะฒ 23:09 1360192177690
-rw-r--r--   1 user  staff   8248  6 ั„ะตะฒ 23:09 1360192181474
-rw-r--r--   1 user  staff   9636  6 ั„ะตะฒ 23:09 1360192185042
-rw-r--r--   1 user  staff   9636  6 ั„ะตะฒ 23:09 1360192188521
-rw-r--r--   1 user  staff   6860  6 ั„ะตะฒ 23:09 1360192191929
-rw-r--r--   1 user  staff      0  6 ั„ะตะฒ 23:09 1360192195450
-rw-r--r--   1 user  staff   9636  6 ั„ะตะฒ 23:09 1360192198630

See on files size. It's all copies of one file.
If I will comment this line

// fs.mkdir('justFolder', 0777, function (err) {

Then problem will disappear. What am I doing wrong?

Cannot call method 'write' on undefined

I'm using this module to delete files on my server. Here is what I'm doing:

  1. on ready, cwd to a specific folder.
  2. once we're in that folder, get the pwd (because the server doesn't return it)
  3. then list all of the files in the pwd
  4. loop each file in the list
  5. call delete on it.

Here is my code:

var ftp = new ftpClient();
ftp.on('ready', function() {
    ftp.cwd("/somefolder/", function(err) {
        if(err) throw err;
        ftp.pwd(function(err, pwd) {
            ftp.list(function(err, list) {
                if(err) throw err;
                for(var file in list) {
                    var thisFile = list[file];
                    if(thisFile.name !== '.' && thisFile.name !== '..') {
                        ftp.delete(pwd + "/" + thisFile.name, function(err) {
                            if(err) throw err;
                            console.log("> Deleting " + pwd +"/"+ thisFile.name);
                        });
                    }
                }
                ftp.end();
            });
        })
    });
});
ftp.connect({
    host: process.env.FTP_HOST,
    user: process.env.FTP_USER,
    password: process.env.FTP_PASS
});

When it gets to deleting the file however, I get the following error:

ftp.js:959
    this._socket.write(this._curReq.cmd)
                 ^
TypeError: Cannot call method of 'write' of undefined
    at FTP._send (/lib/ftp.js:959:18)
    at Socket.ondata (/lib/ftp.js:279:14)
    at Socket.EventEmitter.emit (events.js:88:17)
    at TCP.onread (net.js:391:31)
    at process.startup.processMakeCallback.process._makeCallback (node.js:248:20)
exited with code 1

I've tried appending the file name with the pwd path etc, but still this error. I'm logged in as an administrator, the permissions are 755 on the file, but that's not changed anything.

when ftp.put() multifile ,the comput CPU will be 100%.how to solve this problem

mainFtpNumAll =2005;
var mainFtpNum=0;

function uploadOneFile(mainFtpNum){
try {
mainFtpNumAll = mainFtpNum;
ftp.put(localFileList[mainFtpNum][0],localFileList[mainFtpNum][1], function(err) {
mainFtpNum = mainFtpNum + 1;
if(parseInt(mainFtpNum) <= parseInt(localAllFileLength)){
uploadOneFile(mainFtpNum);
}else{
console.log("====")
}
});
} catch (e) {
var cbsd = mainFtpNumAll+1;
console.log("====="+cbsd);
uploadOneFile(cbsd);
}
}

sometime stream is undefined

//Node.js v0.5.7 on windows7

/*
G:\node>node node_modules\sh_sz\gp
18 Sep 08:38:58 - sh20110801.rar
18 Sep 08:39:00 - sh20110802.rar
18 Sep 08:39:03 - sh20110803.rar
18 Sep 08:39:03 - stream is null, try again...
18 Sep 08:39:03 - sh20110803.rar
18 Sep 08:39:03 - sfklhweroi

node.js:205
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Cannot call method 'emit' of undefined
at G:\node\node_modules\node-ftp\ftp.js:250:31
at Array. (G:\node\node_modules\node-ftp\ftp.js:572:35)
at EventEmitter._tickCallback (node.js:197:26)

*/

var fs = require('fs');
var FTPClient = require('node-ftp'), util = require('util'), conn;
var filename, i, day;

function get_file(c, d) {
    if (d>31) return;
    day=d.toString();
    if (day.length==1)
    {
        day='0'+day;
    }
    filename='sh201108'+day+'.rar';
    util.log(filename);
    c.get(filename, function(e, stream) {
        if (e) throw e;
        if (stream) //?????????here,  sometime stream is undefined ???????????????
        {
            stream.on('success', function() {
                if (d>=31) 
                {
                    c.end();
                }
                else
                {
                    get_file(c, d+1);
                }
            });
            stream.on('error', function(e) {
                console.log(util.inspect(e));
                if (d>=31) 
                {
                    c.end();
                }
                else
                {
                    get_file(c, d+1);
                }
            });
            stream.pipe(fs.createWriteStream(__dirname+'\\'+filename));
        }
        else
        {
            util.log('stream is null, try again...');
            get_file(c, d);
            util.log('sfklhweroi');
        }
    });
}

conn = new FTPClient({ host: '121.17.126.60' });
conn.on('connect', function() {
    conn.auth('datadown', '88158', function(e) {
        if (e) throw e;
        conn.cwd('gpday',function(e){
            if (e) throw e;
            get_file(conn, 1);
        });
    });
});
conn.connect();

LastMod returns Invalid Date

Hi
When running 'lastMod' function I get Invalid Date.
Looking and the callback for _send('MDTM ' + path, ...) I received the following arguments:
{ '0': undefined, '1': '20130409042604', '2': 213 }

Problem is down in line:
var secs = parseInt(val.second, 10);
because secs now equals 4 and Date parsing fails. It expects 04 instead.

If you want I can send a pull request.

Cheers, great module! The LastMod was a pleasant feature :)

can't connect to xlight

the debug output:


Connected
Connected
Response: code = 220; text = 'Xlight FTP 3.6 ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ...'
> FEAT
Disconnected
Response: code = 220; text = 'Xlight FTP 3.6 ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ...'
Response: code = 530; text = 'รป๏ฟฝะต๏ฟฝยผ,๏ฟฝ๏ฟฝ๏ฟฝศต๏ฟฝยผ'

the server seems to require auth before FEAT.

"Timed out while making data connection" when issuing commands to FTPES server

I am connecting to an FTPES (FTP through Explicit TLS/SSL) server. The connection and authentication seems to work, because if I change the login information I get the Login incorrect error, but any command (list, cwd, etc) times out:

Error: Timed out while making data connection

Here is the code I am using (I also called .status so you have more information to go on):

var FTPClient = require('ftp');

var c = new FTPClient();

c.on('ready', function() {
    c.status(function (error, status) {
        if (error) {
            return console.log("ERROR: ", error);
        }
        console.log(status);

        c.list(function (error, list) {
            if (error) {
                return console.log("ERROR: ", error);
            }
            console.log(list);
        })
    });
});

c.connect({
    host: 'example.org',
    port: 21,
    user: 'username',
    password: 'password',
    secure: true
});

And here is the full output:

Status of 'ProFTPD server'
 Connected from [my IP] ([my IP])
 Logged in as [my username]
 TYPE: BINARY, STRUcture: File, Mode: Stream
 No data connection
End of status
ERROR:  [Error: Timed out while making data connection]

`put` stuck on `Ok to send data`

Is anyone else seeing this?

When I attempt to do a put it just hangs. Debug output looks like this:

Response: code = 220; text = 'FTP Server'
> FEAT
Response: code = 211; text = 'Features:\n EPRT\n EPSV\n MDTM\n PASV\n REST STREAM\n SIZE\n TVFS\nEnd'
Features: { EPRT: true,
  EPSV: true,
  MDTM: true,
  PASV: true,
  REST: 'STREAM',
  SIZE: true,
  TVFS: true }
> USER idomoo
Response: code = 331; text = 'Please specify the password.'
> PASS xxxxxxxxxxxxxx
Response: code = 230; text = 'Login successful.'
> TYPE I
Response: code = 200; text = 'Switching to Binary mode.'
> CWD /upload
Response: code = 250; text = 'Directory successfully changed.'
changed dir
> PASV
Response: code = 227; text = 'Entering Passive Mode (xxxxxxxxxxxxxxx)'
(PASV) About to attempt data connection to: xxxxxxxxxx:57081
(PASV) Data connection successful
> STOR test.xml
Response: code = 150; text = 'Ok to send data.'

Then after a little while:

Response: code = 421; text = 'Data timeout. Reconnect. Sorry.'

Here is my test code:

FTPClient = require('ftp')
fs = require('fs')

client = new FTPClient host: hostname, debug: console.log

client.on 'connect', ->
  client.auth username, password, (err) ->
    if err then throw err

    client.cwd '/upload', (err) ->
      if err then throw err
      console.log 'changed dir'
      stream = fs.createReadStream('output/xml/test.xml')
      client.put stream, 'test.xml', (err) ->
        if err then throw err
        client.end()

client.connect() 

I've been able to issue other commands -- it just seems to be the put that fails.

Any help or suggestions of things to try are greatly appreciated!

Update: removed some code that I was using to debug the issue.

Active mode ftp

Is active ftp supported (I know it is fairly unpopular)? I didn't see any documentation or an indication of that capability in the code, but maybe I missed it.

Error: OOPS: vsf_sysutil_recv_peek: no data

Getting this error using the simple FTP put command:

Error: OOPS: vsf_sysutil_recv_peek: no data
at makeError (/Volumes/Data/Node/ddoservices/node_modules/ftp/lib/ftp.js:1089:13)
at Socket.ondata (/Volumes/Data/Node/ddoservices/node_modules/ftp/lib/ftp.js:271:30)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket. (stream_readable.js:736:14)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable
(_stream_readable.js:408:10)
at emitReadable (_stream_readable.js:404:5)
at readableAddChunk (_stream_readable.js:165:9)
at Socket.Readable.push (_stream_readable.js:127:10)
at TCP.onread (net.js:525:21)

pwd calback never send the string as second parameter

When I call pwd, I receive undefined as the second parameter string and not the current directory path as expected (according to the DOCS on the README.md file).

The command is executed correctly, when I activate debug, is shows the current directory in the logs.

FTP PUT fails for files above certain size (128k in my case)

It keep getting this error.

2013-08-05T10:47:45.504Z - error: Error: Could not create file.
at makeError (/Users/rajiv/projects/myproject/node_modules/ftp/lib/connection.js:958:13)
at Parser. (/Users/rajiv/projects/myproject/node_modules/ftp/lib/connection.js:106:25)
at Parser.EventEmitter.emit (events.js:98:17)
at Parser._write (/Users/rajiv/projects/myproject/node_modules/ftp/lib/parser.js:58:10)
at doWrite (/Users/rajiv/projects/myproject/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:211:10)
at writeOrBuffer (/Users/rajiv/projects/myproject/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:201:5)
at Parser.Writable.write (/Users/rajiv/projects/myproject/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:172:11)
at Socket.ondata (/Users/rajiv/projects/myproject/node_modules/ftp/lib/connection.js:258:20)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket. (_stream_readable.js:736:14)

/Users/rajiv/projects/myproject/node_modules/tmp/lib/tmp.js:260
throw err;
^
Error: Could not create file.
at makeError (/Users/rajiv/projects/myproject/node_modules/ftp/lib/connection.js:958:13)
at Parser. (/Users/rajiv/projects/myproject/node_modules/ftp/lib/connection.js:106:25)
at Parser.EventEmitter.emit (events.js:98:17)
at Parser._write (/Users/rajiv/projects/myproject/node_modules/ftp/lib/parser.js:58:10)
at doWrite (/Users/rajiv/projects/myproject/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:211:10)
at writeOrBuffer (/Users/rajiv/projects/myproject/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:201:5)
at Parser.Writable.write (/Users/rajiv/projects/myproject/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:172:11)
at Socket.ondata (/Users/rajiv/projects/myproject/node_modules/ftp/lib/connection.js:258:20)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket. (_stream_readable.js:736:14)

Multiple Call Fail

Not sure it is just not supported, but when attempting to send multiple commands it crashes, or stops working. Please note I understand how to work with asynchronous code, so while my examples look synchronous they are not.

I issued the following when stopped working with no reporting, I think it connected to the anonymous server but the change directory should still error out:

conn = new ftp( { host:"localhost" } );
conn.on( 'connect', function(){
  conn.auth( username, password );
  conn.cwd( folder );
  conn.mkdir( "data" );
});

The following crashes ftp.js:160 if( code == 250 && self._queue[0][0] === 'MLST' ) TypeError: Cannot read property '0' of undefined:

conn = new ftp( { host:"localhost" } );
conn.on( 'connect', function(){
  conn.auth( username, password, function( e ){ );
    conn.cwd( folder );
    conn.mkdir( "data" );
    conn.rmdir( "data" );
  });
});

My work around was to make my own queue in my main function, but having the system work with queues would help make it easy to use and avoid over anonymoizing.

mkdir at nested path

So here's my situation. I have one folder called 'stuff', which i create using the mkdir function like this, and it works great:

conn.mkdir('stuff', function(){ if (err){ throw err } });

Inside the stuff folder, I have another folder called 'more_stuff', which I attempt to create like this:

conn.mkdir('stuff/more_stuff', function(err){ if (err){ throw err } });

...unfortunately, this one throws me an error saying that 'stuff' already exists. Does this mean it's not possible to create a nested directory like this, and I need to cd into that directory first?

put() not hitting callback?

There's a solid chance that I'm just an idiot or something else is going wrong, but I've run into a roadblock in which the put method is executing but not hitting the callback at all. Was hoping I could get some sort of clue as to why this is happening - apologies in advance if this is just something stupid i did ๐Ÿ˜„

The general process I'm aiming for here is just to transfer a given directory (nested directories and files) to a given ftp folder. This code assumes that a connection has already been made without issue. It relies on underscore, readdirp, and async, which do more or less what's expected. The part that's not returning as expected is the client.put() call - nothing ever gets logged from the callback, indicating that it's not being called. The mkdir call however is working fantastically well - it completes and the files are transferred. For the put call, only a single file is transferred (the first in the list), then it just hangs.

readdirp({ root: path.join(process.cwd(), 'public') }, function(err, res){
  if (err) { return console.error(err) }

  var folders = _.pluck(res.directories, 'path');
  var files = _.pluck(res.files, 'path');

  async.map(folders, mkdir, function(err){
    if (err){ return console.error(err) }
    async.map(files, put_file, function(err){
      if (err){ return console.error(err) }
      console.log('done transferring files');
      client.end();
    });
  });

  function mkdir(dir, cb){
    console.log(dir);
    client.mkdir(dir, true, cb)
  }

  function put_file(file, cb){
    console.log(file);
    client.put(file, file, function(err){
      console.log('worked?')
    });
  }
});

.Pipe's Flow Control fails on slow Writeable Stream

It appears the readable stream is automatically cleaned up when the library has finished receiving a file. This can be a problem when using .pipe when piped to a slower stream (such a a HTTP response.)

The best way to replicate this is to download a file over FTP, and pipe to an HTTP response where the HTTP connection is considerably slower than the FTP connection.

Cannot call method 'write' on undefined

Hello,

I'm writting a script that connects to multiple FTP servers and get some files. It downloads very well for everything but crashes every time with this message. I'm thinking it could be related to an FTP server that doesn't answer correctly or takes too much time to do so.

Is there a better way to debug this?

Thanks.

node_modules/ftp/lib/ftp.js:969
    this._socket.write(this._curReq.cmd);
                 ^
TypeError: Cannot call method 'write' of undefined
    at FTP._send (node_modules/ftp/lib/ftp.js:969:18)
    at ondone node_modules/ftp/lib/ftp.js:544:14)
    at Socket.source.emit (node_modules/ftp/lib/ftp.js:535:11)
    at _stream_readable.js:910:16
    at process._tickCallback (node.js:415:13)

Progress of transfer

Is there a way to get file upload/download progress? I'm moving large files and want to provide a progress to the user.

I'm thinking something as simple as on('hash', or on('tick' events just so we can inform the user bytes are still moving (and how fast).

fail under active mode

while connect the FTP server under active mode, the operations would fail.

[Error: connect Unknow system errno 10080]

mkdir and rmdir method miss a space

FTP.prototype.mkdir = function(path, cb) { // MKD is optional
this._send('MKD' + path, cb);
};

FTP.prototype.rmdir = function(path, cb) { // RMD is optional
this._send('RMD' + path, cb);
};

these two method throw error: { [Error: Unknown command.] code: 500 }

because miss a space between "MKD"/"RMD" and path.

List and Get

I'm trying to list all the files in a directory and then get each file. For some reason my simple example is not working. Can commands be nested like this? As soon as I introduce the c.get the program stops responding.

var FTP = require("ftp");
var fs = require('fs');

var options = {

    host: 'remoteip',
    port: 21,
    user: 'username',
    password: 'password'

};
var c = new FTP();
c.on('ready', function() {
    c.list(function(err, list) {
        console.log('LIST');
        console.log(list);
        for (var i = 0; i < list.length; i++) {
            var file = list[i];
            console.log(file.name);
            if (file.type === '-') {
                // download it
                c.get(file.name, function(err, stream) {
                    if (err) throw err;
                    stream.once('close', function() {
                        c.end();
                    });
                    stream.pipe(fs.createWriteStream('/tmp/' + file.name ));
                });
            }
        }
    });
});

c.connect(options);

Put writing 0 byte file.

Hello again,

Could you please explain what i am doing wrong when doing a Get from one FTP Server and trying to Put to another FTP Server.

My bad code is below.

var Client = require('ftp'),
connects = 0;

var srcparams = { // Windows FTP Server
host: "ftptest1.com",
port: 21,
user: "ftp",
password: "password",
debug: console.log
};

var destparams = {
host: "ftptest2.com",
port: 21,
user: "ftp",
password: "password",
debug: console.log
};

var src = new Client();

var dest = new Client();

src.connect(srcparams);

dest.connect(destparams);

src.on('ready', function() {
console.log('source ready');
connects++;
copy();
});

dest.on('ready', function() {
console.log('destination ready');
connects++;
copy();
});

function copy() {
if (connects === 2) {
copyfile();
}
}

function copyfile(source, destination, callback) {
src.get('www/index.html', function(err, stream) {
if (err) {
throw err;
}
stream.once('close', function() {
src.end();
});
//stream.pipe(fs.createWriteStream('foo.local-copy.txt'));
dest.put(stream, 'www/index.html', function(err) {
if (err) {
throw err;
}
dest.close();
});
});
}

the debug output is

[connection] < '230 User logged in.\r\n'
[parser] < '230 User logged in.\r\n'
[parser] Response: code=230, buffer='User logged in.'
[connection] > 'FEAT'
[connection] < '211-Extended features supported:\r\n LANG EN_\r\n UTF8\r\n AUTH TLS;TLS-C;SSL;TLS-P;\r\n PBSZ\r\n PROT C;P;\r\n CCC\r\n HOST\r\n SIZE\r\n MDTM\r\n REST STREAM\r\n211 END\r\n'
[parser] < '211-Extended features supported:\r\n LANG EN_\r\n UTF8\r\n AUTH TLS;TLS-C;SSL;TLS-P;\r\n PBSZ\r\n PROT C;P;\r\n CCC\r\n HOST\r\n SIZE\r\n MDTM\r\n REST STREAM\r\n211 END\r\n'
[parser] Response: code=211, buffer='Extended features supported:\r\n LANG EN*\r\n UTF8\r\n AUTH TLS;TLS-C;SSL;TLS-P;\r\n PBSZ\r\n PROT C;P;\r\n CCC\r\n HOST\r\n SIZE\r\n MDTM\r\n REST STREAM\r\nEND'
[connection] > 'TYPE I'
[connection] < '200 Type set to I.\r\n'
[parser] < '200 Type set to I.\r\n'
[parser] Response: code=200, buffer='Type set to I.'
source ready
[connection] > 'PASV'
[connection] < '227 Entering Passive Mode (192,96,210,12,7,222).\r\n'
[parser] < '227 Entering Passive Mode (192,96,210,12,7,222).\r\n'
[parser] Response: code=227, buffer='Entering Passive Mode (192,96,210,12,7,222).'
[connection] PASV socket connected
[connection] > 'RETR www/index.html'
[connection] < '125 Data connection already open; Transfer starting.\r\n'
[parser] < '125 Data connection already open; Transfer starting.\r\n'
[parser] Response: code=125, buffer='Data connection already open; Transfer starting.'
[connection] > 'PASV'
[connection] < '226 Transfer complete.\r\n'
[parser] < '226 Transfer complete.\r\n'
[parser] Response: code=226, buffer='Transfer complete.'
[connection] > 'MODE S'
[connection] < '227 Entering Passive Mode (192,96,210,17,7,231).\r\n'
[parser] < '227 Entering Passive Mode (192,96,210,17,7,231).\r\n'
[parser] Response: code=227, buffer='Entering Passive Mode (192,96,210,17,7,231).'
[connection] PASV socket connected
[connection] > 'STOR www/index.html'
[connection] < '200 Mode S ok.\r\n'
[parser] < '200 Mode S ok.\r\n'
[parser] Response: code=200, buffer='Mode S ok.'
[connection] < '125 Data connection already open; Transfer starting.\r\n'
[parser] < '125 Data connection already open; Transfer starting.\r\n'
[parser] Response: code=125, buffer='Data connection already open; Transfer starting.'

secure ftp supported?

Hi,

I am not able to establish the connection with my ftp which is a secure one. I don't see anything special mentioned into the documentation about this option. Who know?

Thanks,
Johnny B

DELE not understood

There is a space missing on this line:

this._send('DELE' + path, cb);

The missing space causes the client to interpret the filename as part of the command. It should be:

this._send('DELE ' + path, cb);

Doesn't emit connection for reconnection after authorizing

I was trying to reconnect into an ftp account of which I already authenticated, but my on connect method was not getting called the 2nd time I would make the connection. I found with looking at the code, that the on connection is never called from a pre-authorized connection. That would be find if on connect end it would log out, but it doesn't. A fix that would work is when the connect method is called signal that it is attempting a connection, if authorized as the status returns on connection attempt then emit connection. Which is the work around I added to my local code.

Uncatchable error

I'm getting the following error:

TypeError: Cannot call method 'end' of undefined
    at reentry (/Users/elverys7d/Documents/news-dev/infoplum-connector/node_modules/ftp/lib/connection.js:184:29)
    at Parser.<anonymous> (/Users/elverys7d/Documents/news-dev/infoplum-connector/node_modules/ftp/lib/connection.js:108:22)
    at EventEmitter.emit (events.js:98:17)
    at Parser._write (/Users/elverys7d/Documents/news-dev/infoplum-connector/node_modules/ftp/lib/parser.js:57:10)
    at doWrite (/Users/elverys7d/Documents/news-dev/infoplum-connector/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:211:10)
    at writeOrBuffer (/Users/elverys7d/Documents/news-dev/infoplum-connector/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:201:5)
    at Writable.write (/Users/elverys7d/Documents/news-dev/infoplum-connector/node_modules/ftp/node_modules/readable-stream/lib/_stream_writable.js:172:11)
    at ondata (/Users/elverys7d/Documents/news-dev/infoplum-connector/node_modules/ftp/lib/connection.js:260:20)

The relevant block of connect.js is with the error thrown on the return self._socket.end();:

      if (err && (!cmd || cmd === 'USER' || cmd === 'PASS' || cmd === 'TYPE')) {
        self.emit('error', err);
        return self._socket.end();
      }

As far as I can tell, there's no way to catch this error (aside from catching uncaught exceptions at the process level, which isn't ideal).

425 Cannot open data connection

does the following mean i am trying to use too many data connections at once?

I randomly get this error when listing all the directories on a ftp server before i try to retrieve any files.

if it is too many connections is the a max connection setting somewhere that i am missing?

{ name: 'button-l.png',
type: '-',
size: 329,
date: Fri Oct 18 2013 05:52:00 GMT-0400 (EDT),
path: '/www/images/button' },
{ name: 'button-r.png',
type: '-',
size: 343,
date: Fri Oct 18 2013 05:52:00 GMT-0400 (EDT),
path: '/www/images/button' } ]
[connection] < '150 Opening BINARY mode data connection.\r\n425 Cannot open data connection.\r\n'
[parser] < '150 Opening BINARY mode data connection.\r\n'
[parser] Response: code=150, buffer='Opening BINARY mode data connection.'
[parser] < '425 Cannot open data connection.\r\n'
[parser] Response: code=425, buffer='Cannot open data connection.'
{ [Error: Cannot open data connection.] code: 425 }

Piping http request stream to ftp stream

Hi, this is part of code I'm trying to make working:

function uploadFile(req, res) {
    res.writeHeader(200, {'Content-Type': 'text/html'});
    res.write('Uploading, please wait!');

    ftp.put(req, 'test.txt', function(e) {
        if (e) throw e;
        res.end('<br>__uploaded__');
        console.log('ftp: uploaded');
        ftp.end();
    });
}

The "test.txt" file is created on my FTP server, but nothing is written into it. Why? I have no problem to pipe http request stream to eg. process.stdout. Wiriting content of some file to test.txt with file system stream works as well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.