mscdex / node-ftp

An FTP client module for node.js
MIT License
1.13k stars 243 forks source link

get() always returns empty / no data #180

Open mkloubert opened 7 years ago

mkloubert commented 7 years ago

When I try to download a file from FTP server, by using get() method, it pipes to a local file, but does not write data.

My code looks like that:

var FS = require('fs');

// open connection
// and write it to 'conn'...

conn.get('/path/to/REMOTE.file', function(err, stream) {
    if (err) {
        // handle error
        return;
    }

    stream.once('error', function (err) {
        // handle error
    });

    // pipe to local file...
    stream.pipe(FS.createWriteStream('/path/to/LOCAL.file'));

    stream.once('end', function() {
        // download completed

        // is invoked BEFORE the 'close' event
    });

    stream.once('close', function() {
        // is invoked AFTER the 'end' event

        conn.end();
    });
});

My test environment is

Is the code correct or did I forget something?

Uploading files works fine, btw,

devkev16 commented 7 years ago

Hi @mkloubert,

I was able to fix this by calling stream.resume() because in the get function there is a call to stream.pause() which ensures the data event is not fired (The data event is consumed by the write stream and if there is none the writestream thinks there is no data).

When you take a look at the get function theres a call to stream.pause() (Which in fact is the socket unless you use the zcomp option).

Heres my code (It's used inside the download function of my FTPClient class, callback, local_path and remote_file are parameters and current_path is a member variable)

client.get(path.join(current_path, remote_file), function (err, stream) {
                    if (err) {
                        callback(err);
                    } else {
                        //Wenn der Stream schließt callback aufrufen
                        stream.once('close', function () {
                            busy = false;
                            callback();
                        }).on('error', function (err) {
                            busy = false;
                            callback(err);
                        });

                        var writestream = fs.createWriteStream(local_path);

                        writestream.on('error', function (err) {
                            callback(err);
                        });

                        //Write file to local path
                        stream.pipe(writestream);
                        stream.resume();
                    }
                });

The funny thing is that the bug affected my download for small files so much that no data was written and there was a complete shutdown for large files.

deyhle commented 6 years ago

I also had this problem, but only when running inside a docker container. Locally (macOS) it always worked. On the (official node debian jessie) docker container, I needed to call stream.resume().