Skip to content

Commit

Permalink
Use marks for streaming uploads, upload done callback
Browse files Browse the repository at this point in the history
  • Loading branch information
bancek committed Nov 27, 2012
1 parent 08d3859 commit 5fb6cd7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 17 deletions.
32 changes: 15 additions & 17 deletions lib/jsftp.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,28 +586,26 @@ Ftp.getPasvPort = function(text) {
});
};

this.getPutSocket = function(path, callback) {
this.getPutSocket = function(path, callback, doneCallback) {
var self = this;
this.getPasvSocket(function(err, socket) {
if (err) return callback(err);

var hadErr;
self._enqueueCmd("stor " + path, function(err, res) {
if (err) hadErr = err;
});
var called = false;

// This is not a great solution. A STOR command only gives back an error
// or a Mark. Marks are not very reliable, which is why jsftp doesn't
// take them into account. But then if STOR is successful we never
// know because we don't receive any response.
// Still, the socket is just open and we can start to pump, so we set
// a timeout and after that we pass the socket to the callback along
// with any errors that STOR gave back.
// A way to make this more reliable would be to look at the response
// mark (Should be 150) and only then if it is ok send the socket back.
setTimeout(function(err, res) {
callback(hadErr, socket);
}, 100);
var cmdCallback = function(err, res) {
if (!called) {
called = true;
callback(err, socket);
} else {
if (!Ftp.isMark(res.code) && doneCallback) {
doneCallback(res)
}
}
};
cmdCallback.acceptsMarks = true;

self._enqueueCmd("stor " + path, cmdCallback);
});
};

Expand Down
37 changes: 37 additions & 0 deletions test/jsftp_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,43 @@ describe("jsftp test suite", function() {
});
});

it("test put a big file stream", function(next) {
var remotePath = remoteCWD + "/bigfile.test";

var data = (new Array(1*1024*1024)).join("x");

var buffer = new Buffer(data, "binary");

ftp.getPutSocket(remotePath, function(err, socket) {
assert.ok(!err, err);

socket.write(data, function(err) {
assert.ok(!err, err);

socket.end();
});
}, function(res) {
assert.equal(res.code, 226);

ftp.raw.dele(remotePath, function(err, data) {
assert.ok(!err);
next();
});
});
});

it("test put a big file stream fail", function(next) {
var remotePath = remoteCWD + "/nonexisting/path/to/file.txt";

ftp.getPutSocket(remotePath, function(err, socket, res) {
assert.ok(err, err);
assert.equal(err.code, 550);
next();
}, function(res) {
assert.ok(false);
});
});

it("test get fileList array", function(next) {
var file1 = "testfile.txt";

Expand Down

0 comments on commit 5fb6cd7

Please sign in to comment.