Skip to content

Commit

Permalink
SFTPStream: fix mode handling for uploaded files
Browse files Browse the repository at this point in the history
Fixes: mscdex#55
  • Loading branch information
mscdex committed Nov 7, 2016
1 parent b01a2a0 commit 22f820a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 34 deletions.
20 changes: 11 additions & 9 deletions SFTPStream.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,21 +227,23 @@ SFTPStream methods

* **fastGet**(< _string_ >remotePath, < _string_ >localPath[, < _object_ >options], < _function_ >callback) - _(void)_ - Downloads a file at `remotePath` to `localPath` using parallel reads for faster throughput. `options` can have the following properties:

* concurrency - _integer_ - Number of concurrent reads **Default:** `64`
* **concurrency** - _integer_ - Number of concurrent reads **Default:** `64`

* chunkSize - _integer_ - Size of each read in bytes **Default:** `32768`
* **chunkSize** - _integer_ - Size of each read in bytes **Default:** `32768`

* step - _function_(< _integer_ >total_transferred, < _integer_ >chunk, < _integer_ >total) - Called every time a part of a file was transferred
* **step** - _function_(< _integer_ >total_transferred, < _integer_ >chunk, < _integer_ >total) - Called every time a part of a file was transferred

`callback` has 1 parameter: < _Error_ >err.

* **fastPut**(< _string_ >localPath, < _string_ >remotePath[, < _object_ >options], < _function_ >callback) - _(void)_ - Uploads a file from `localPath` to `remotePath` using parallel reads for faster throughput. `options` can have the following properties:

* concurrency - _integer_ - Number of concurrent reads **Default:** `64`
* **concurrency** - _integer_ - Number of concurrent reads **Default:** `64`

* chunkSize - _integer_ - Size of each read in bytes **Default:** `32768`
* **chunkSize** - _integer_ - Size of each read in bytes **Default:** `32768`

* step - _function_(< _integer_ >total_transferred, < _integer_ >chunk, < _integer_ >total) - Called every time a part of a file was transferred
* **step** - _function_(< _integer_ >total_transferred, < _integer_ >chunk, < _integer_ >total) - Called every time a part of a file was transferred

* **mode** - _mixed_ - Integer or string representing the file mode to set for the uploaded file.

`callback` has 1 parameter: < _Error_ >err.

Expand All @@ -251,7 +253,7 @@ SFTPStream methods
{ flags: 'r',
encoding: null,
handle: null,
mode: 0666,
mode: 0o666,
autoClose: true
}
```
Expand All @@ -272,7 +274,7 @@ SFTPStream methods
{
flags: 'w',
encoding: null,
mode: 0666,
mode: 0o666,
autoClose: true
}
```
Expand All @@ -281,7 +283,7 @@ SFTPStream methods
If 'autoClose' is set to false and you pipe to this stream, this stream will not automatically close after there is no more data upstream -- allowing future pipes and/or manual writes.
* **open**(< _string_ >filename, < _string_ >mode, [< _ATTRS_ >attributes, ]< _function_ >callback) - _boolean_ - Opens a file `filename` for `mode` with optional `attributes`. `mode` is any of the modes supported by fs.open (except sync mode). Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _Buffer_ >handle.
* **open**(< _string_ >filename, < _string_ >flags, [< _mixed_ >attrs_mode, ]< _function_ >callback) - _boolean_ - Opens a file `filename` with `flags` with optional _ATTRS_ object or file mode `attrs_mode`. `flags` is any of the flags supported by `fs.open` (except sync flag). Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 2 parameters: < _Error_ >err, < _Buffer_ >handle.
* **close**(< _Buffer_ >handle, < _function_ >callback) - _boolean_ - Closes the resource associated with `handle` given by open() or opendir(). Returns `false` if you should wait for the `continue` event before sending any more traffic. `callback` has 1 parameter: < _Error_ >err.
Expand Down
85 changes: 60 additions & 25 deletions lib/sftp.js
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,9 @@ SFTPStream.prototype.open = function(path, flags_, attrs, cb) {

var attrFlags = 0;
var attrBytes = 0;
if (typeof attrs === 'string' || typeof attrs === 'number') {
attrs = { mode: attrs };
}
if (typeof attrs === 'object') {
attrs = attrsToBytes(attrs);
attrFlags = attrs.flags;
Expand Down Expand Up @@ -973,10 +976,11 @@ function fastXfer(src, dst, srcPath, dstPath, opts, cb) {
var chunkSize = 32768;
var preserve = false;
var onstep;
var mode;

if (typeof opts === 'function')
if (typeof opts === 'function') {
cb = opts;
else if (typeof opts === 'object') {
} else if (typeof opts === 'object') {
if (typeof opts.concurrency === 'number'
&& opts.concurrency > 0
&& !isNaN(opts.concurrency))
Expand All @@ -988,6 +992,8 @@ function fastXfer(src, dst, srcPath, dstPath, opts, cb) {
if (typeof opts.step === 'function')
onstep = opts.step;
preserve = (opts.preserve ? true : false);
if (typeof opts.mode === 'string' || typeof opts.mode === 'number')
mode = modeNum(opts.mode);
}

// internal state variables
Expand Down Expand Up @@ -1031,6 +1037,7 @@ function fastXfer(src, dst, srcPath, dstPath, opts, cb) {
src.open(srcPath, 'r', function(err, sourceHandle) {
if (err)
return onerror(err);

srcHandle = sourceHandle;

src.fstat(srcHandle, function tryStat(err, attrs) {
Expand All @@ -1052,11 +1059,28 @@ function fastXfer(src, dst, srcPath, dstPath, opts, cb) {
dst.open(dstPath, 'w', function(err, destHandle) {
if (err)
return onerror(err);

dstHandle = destHandle;

if (fsize <= 0)
return onerror();

if (mode !== undefined) {
dst.fchmod(dstHandle, mode, function tryAgain(err) {
if (err) {
// Try chmod() for sftp servers that may not support fchmod() for
// whatever reason
dst.chmod(dstPath, mode, function(err_) {
tryAgain();
});
return;
}
read();
});
} else {
read();
}

function onread(err, nb, data, dstpos, datapos) {
if (err)
return onerror(err);
Expand Down Expand Up @@ -1116,7 +1140,6 @@ function fastXfer(src, dst, srcPath, dstPath, opts, cb) {
}
psrc = 0;
}
read();
});
});
});
Expand Down Expand Up @@ -2797,29 +2820,41 @@ WriteStream.prototype.open = function() {
}

self.handle = handle;
// SFTPv3 requires absolute offsets, no matter the open flag used
if (self.flags[0] === 'a') {
self.sftp.fstat(handle, function tryStat(err, st) {
if (err) {
// Try stat() for sftp servers that may not support fstat() for
// whatever reason
self.sftp.stat(self.path, function(err_, st_) {
if (err_) {
self.destroy();
self.emit('error', err);
return;
}
tryStat(null, st_);
});
return;
}

self.pos = st.size;
self.emit('open', handle);
});
return;
}
self.emit('open', handle);
self.sftp.fchmod(handle, self.mode, function tryAgain(err) {
if (err) {
// Try chmod() for sftp servers that may not support fchmod() for
// whatever reason
self.sftp.chmod(self.path, self.mode, function(err_) {
tryAgain();
});
return;
}

// SFTPv3 requires absolute offsets, no matter the open flag used
if (self.flags[0] === 'a') {
self.sftp.fstat(handle, function tryStat(err, st) {
if (err) {
// Try stat() for sftp servers that may not support fstat() for
// whatever reason
self.sftp.stat(self.path, function(err_, st_) {
if (err_) {
self.destroy();
self.emit('error', err);
return;
}
tryStat(null, st_);
});
return;
}

self.pos = st.size;
self.emit('open', handle);
});
return;
}
self.emit('open', handle);
});
});
};

Expand Down

0 comments on commit 22f820a

Please sign in to comment.