Skip to content

Commit

Permalink
Simplify PUT and fix some skipped tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sergi committed Dec 1, 2017
1 parent b4f7626 commit c9642dc
Show file tree
Hide file tree
Showing 5 changed files with 406 additions and 473 deletions.
10 changes: 0 additions & 10 deletions CHANGELOG.md

This file was deleted.

94 changes: 42 additions & 52 deletions lib/jsftp.js
Expand Up @@ -12,6 +12,7 @@
const createConnection = require("net").createConnection;
const EventEmitter = require("events").EventEmitter;
const inherits = require("util").inherits;
const stream = require("stream");
const fs = require("fs");
const combine = require("stream-combiner");

Expand Down Expand Up @@ -368,7 +369,18 @@ Ftp.prototype.list = function(path, callback) {
this.pasvTimeout(socket, callback);

socket.once("close", err => {
callback(err, listing);
if (err) {
return callback(err);
} else if (!listing) {
// Some servers return empty string
return callback({
code: 451,
text: `Could not retrieve a file listing for ${path}.`,
isMark: false,
isError: true
});
}
callback(null, listing);
});
socket.once("error", callback);

Expand Down Expand Up @@ -509,38 +521,22 @@ Ftp.prototype.getGetSocket = function(path, callback) {
* @param {String} to path for the remote destination.
* @param {Function} callback Function to execute on error or success.
*/
Ftp.prototype.put = function(from, to, callback) {
const putReadable = (from, to, totalSize, callback) => {
Ftp.prototype.put = function(from, destination, callback) {
const putReadable = (from, to, totalSize) => {
from.on("readable", () => {
this.emitProgress({
filename: to,
action: "put",
socket: from,
totalSize: totalSize
totalSize
});
});

this.getPutSocket(
to,
(err, socket) => {
if (!err) {
from.pipe(socket);
}
},
callback
);
this.getPutSocket(from, to, callback);
};

if (from instanceof Buffer) {
this.getPutSocket(
to,
(err, socket) => {
if (!err) {
socket.end(from);
}
},
callback
);
this.getPutSocket(from, destination, callback);
} else if (typeof from === "string") {
fs.stat(from, (err, stats) => {
if (err && err.code === "ENOENT") {
Expand All @@ -552,56 +548,50 @@ Ftp.prototype.put = function(from, to, callback) {
}

const totalSize = err ? 0 : stats.size;
const localFileStream = fs.createReadStream(from, {
bufferSize: 4 * 1024
});
putReadable(localFileStream, to, totalSize, callback);
putReadable(fs.createReadStream(from), destination, totalSize);
});
} else if (from instanceof stream.Readable) {
putReadable(from, destination, 0);
} else {
// `from` is a readable stream
putReadable(from, to, from.size, callback);
callback(
new Error("Expected `from` parameter to be a Buffer, Stream, or a String")
);
}
};

Ftp.prototype.getPutSocket = function(path, callback, doneCallback) {
if (!callback) {
throw new Error("A callback argument is required.");
}

doneCallback = once(doneCallback || NOOP);
const _callback = once((err, _socket) => {
if (err) {
callback(err);
return doneCallback(err);
}
return callback(null, _socket);
});
Ftp.prototype.getPutSocket = function(from, path, next) {
next = once(next || NOOP);

this.getPasvSocket((err, socket) => {
if (err) {
return _callback(err);
return next(err);
}
socket.on("close", doneCallback);
socket.on("error", doneCallback);

const putCallback = once((err, res) => {
socket.on("close", next);
socket.on("error", next);

const callback = once((err, res) => {
if (err) {
return _callback(err);
return next(err);
}

// Mark 150 indicates that the 'STOR' socket is ready to receive data.
// Anything else is not relevant.
if (res.code === 125 || res.code === 150) {
this.pasvTimeout(socket, doneCallback);
return _callback(null, socket);
this.pasvTimeout(socket, next);
if (from instanceof Buffer) {
socket.end(from);
} else if (from instanceof stream.Readable) {
from.pipe(socket);
}
} else {
return next(new Error("Unexpected command " + res.text));
}

return _callback(new Error("Unexpected command " + res.text));
});

putCallback.expectsMark = expectedMarks;
callback.expectsMark = expectedMarks;

this.execute("stor " + path, putCallback);
this.execute(`stor ${path}`, callback);
});
};

Expand Down
12 changes: 7 additions & 5 deletions package.json
@@ -1,10 +1,11 @@
{
"name": "jsftp",
"id": "jsftp",
"version": "2.0.0",
"version": "2.1.0",
"description": "A sane FTP client implementation for NodeJS",
"keywords": ["ftp", "protocol", "files", "server", "client", "async"],
"author": "Sergi Mansilla <sergi.mansilla@gmail.com> (http://sergimansilla.com)",
"author":
"Sergi Mansilla <sergi.mansilla@gmail.com> (http://sergimansilla.com)",
"homepage": "https://github.com/sergi/jsftp",
"repository": {
"type": "git",
Expand All @@ -26,17 +27,18 @@
"ftp-test-server": "0.0.2",
"ftpd": "sstur/nodeftpd#0d299f7",
"istanbul": "^0.3.22",
"mocha": "^3.5.0",
"mocha": "^4.0.1",
"mocha-istanbul": "0.2.0",
"nyc": "^11.3.0",
"rimraf": "^2.6.1",
"sinon": "^1.17.7"
"sinon": "^4.1.2"
},
"main": "lib/jsftp.js",
"engines": {
"node": ">=0.12"
},
"scripts": {
"test": "mocha -R spec -t 5000",
"test": "nyc mocha -R spec -t 5000",
"clean": "rm -rf reports"
},
"license": "MIT"
Expand Down

0 comments on commit c9642dc

Please sign in to comment.