ssh2-sftp-client 5.2.1 → 5.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.org +205 -0
- package/README.md +203 -313
- package/README.org +349 -297
- package/package.json +3 -3
- package/src/index.js +75 -31
- package/src/utils.js +15 -3
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
- [
|
|
1
|
+
- [Overview](#sec-1)
|
|
2
2
|
- [Installation](#sec-2)
|
|
3
3
|
- [Basic Usage](#sec-3)
|
|
4
4
|
- [Version 5.x](#sec-4)
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
- [Version 5.1.3](#sec-4-8)
|
|
15
15
|
- [Version 5.2.0](#sec-4-9)
|
|
16
16
|
- [Version 5.2.1](#sec-4-10)
|
|
17
|
+
- [Version 5.2.2](#sec-4-11)
|
|
18
|
+
- [Version 5.3.0](#sec-4-12)
|
|
19
|
+
- [Version 5.3.1](#sec-4-13)
|
|
20
|
+
- [Version 5.3.2](#sec-4-14)
|
|
17
21
|
- [Documentation](#sec-5)
|
|
18
22
|
- [Specifying Paths](#sec-5-1)
|
|
19
23
|
- [Methods](#sec-5-2)
|
|
@@ -39,49 +43,19 @@
|
|
|
39
43
|
- [downloadDir(srcDir, dstDir) ==> string](#sec-5-2-20)
|
|
40
44
|
- [end() ==> boolean](#sec-5-2-21)
|
|
41
45
|
- [Add and Remove Listeners](#sec-5-2-22)
|
|
42
|
-
- [
|
|
43
|
-
- [
|
|
44
|
-
- [
|
|
45
|
-
- [
|
|
46
|
-
- [
|
|
47
|
-
|
|
48
|
-
- [
|
|
49
|
-
- [
|
|
50
|
-
- [
|
|
51
|
-
- [
|
|
52
|
-
- [
|
|
53
|
-
- [
|
|
54
|
-
|
|
55
|
-
- [v5.1.0](#sec-8-6)
|
|
56
|
-
- [v5.0.2](#sec-8-7)
|
|
57
|
-
- [v5.0.1](#sec-8-8)
|
|
58
|
-
- [v5.0.0](#sec-8-9)
|
|
59
|
-
- [v4.3.1](#sec-8-10)
|
|
60
|
-
- [v4.3.0](#sec-8-11)
|
|
61
|
-
- [v4.2.4](#sec-8-12)
|
|
62
|
-
- [v4.2.3](#sec-8-13)
|
|
63
|
-
- [v4.2.2](#sec-8-14)
|
|
64
|
-
- [v4.2.1](#sec-8-15)
|
|
65
|
-
- [v4.2.0](#sec-8-16)
|
|
66
|
-
- [v4.1.0](#sec-8-17)
|
|
67
|
-
- [v4.0.4](#sec-8-18)
|
|
68
|
-
- [v4.0.3](#sec-8-19)
|
|
69
|
-
- [v4.0.2](#sec-8-20)
|
|
70
|
-
- [v4.0.0](#sec-8-21)
|
|
71
|
-
- [Older Versions](#sec-8-22)
|
|
72
|
-
- [v2.5.2](#sec-8-22-1)
|
|
73
|
-
- [v2.5.1](#sec-8-22-2)
|
|
74
|
-
- [v2.5.0](#sec-8-22-3)
|
|
75
|
-
- [v2.4.3](#sec-8-22-4)
|
|
76
|
-
- [v2.4.2](#sec-8-22-5)
|
|
77
|
-
- [v2.4.1](#sec-8-22-6)
|
|
78
|
-
- [v2.4.0](#sec-8-22-7)
|
|
79
|
-
- [v2.3.0](#sec-8-22-8)
|
|
80
|
-
- [v3.0.0 – deprecate this version](#sec-8-22-9)
|
|
81
|
-
- [v2.1.1](#sec-8-22-10)
|
|
82
|
-
- [v2.0.1](#sec-8-22-11)
|
|
83
|
-
- [v1.1.0](#sec-8-22-12)
|
|
84
|
-
- [v1.0.5:](#sec-8-22-13)
|
|
46
|
+
- [Platform Quirks & Warnings](#sec-6)
|
|
47
|
+
- [Server Capabilities](#sec-6-1)
|
|
48
|
+
- [Promises & Events](#sec-6-2)
|
|
49
|
+
- [Windows Based Servers](#sec-6-3)
|
|
50
|
+
- [Don't Re-use SftpClient Objects](#sec-6-4)
|
|
51
|
+
- [FAQ](#sec-7)
|
|
52
|
+
- [Remote server drops connections with only an end event](#sec-7-1)
|
|
53
|
+
- [How can I pass writable stream as dst for get method?](#sec-7-2)
|
|
54
|
+
- [How can I upload files without having to specify a password?](#sec-7-3)
|
|
55
|
+
- [How can I connect through a Socks Proxy](#sec-7-4)
|
|
56
|
+
- [Timeout while waiting for handshake or handshake errors](#sec-7-5)
|
|
57
|
+
- [How can I limit upload/download speed](#sec-7-6)
|
|
58
|
+
- [Examples](#sec-8)
|
|
85
59
|
- [Troubleshooting](#sec-9)
|
|
86
60
|
- [Common Errors](#sec-9-1)
|
|
87
61
|
- [Not returning the promise in a `then()` block](#sec-9-1-1)
|
|
@@ -92,19 +66,28 @@
|
|
|
92
66
|
- [Pull Requests](#sec-11)
|
|
93
67
|
- [Contributors](#sec-12)
|
|
94
68
|
|
|
95
|
-
|
|
69
|
+
|
|
70
|
+
# Overview<a id="sec-1"></a>
|
|
96
71
|
|
|
97
72
|
an SFTP client for node.js, a wrapper around [SSH2](https://github.com/mscdex/ssh2) which provides a high level convenience abstraction as well as a Promise based API.
|
|
98
73
|
|
|
99
74
|
Documentation on the methods and available options in the underlying modules can be found on the [SSH2](https://github.com/mscdex/ssh2) and [SSH2-STREAMS](https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md) project pages.
|
|
100
75
|
|
|
101
|
-
Current stable release is **v5.2
|
|
76
|
+
Current stable release is **v5.3.2**.
|
|
102
77
|
|
|
103
78
|
Code has been tested against Node versions 12.18.2 and 13.14.0
|
|
104
79
|
|
|
105
80
|
Node versions < 10.x are not supported.
|
|
106
81
|
|
|
107
|
-
<span class="underline">WARNING</span> There is currently
|
|
82
|
+
<span class="underline">WARNING</span> There is currently a regression error with versions of node later than version 14.0. It appears that when using streams with chunk sizes which exceed the high water mark for the stream, a drain event is no longer emitted. As a result, streams with sufficient data will hang indefinitely. This appears to affect fastput, fastget, put and possibly get operations. Until this issue is resolved and a new version of ssh2/ssh2-streams is released, using node v14 is not recommended.
|
|
83
|
+
|
|
84
|
+
A bug report hass been logged against the ssh2-streams library as [issue 156](https://github.com/mscdex/ssh2-streams/issues/156).
|
|
85
|
+
|
|
86
|
+
<span class="underline">UPDATE</span>: The author of the upstream ssh2 and ssh2-streams module has decided on a re-write of the ssh2 module to address the above issues as well as some other design limitations and to allow the module to better fit in with newer versions of node. As part of that process, the functionality of ssh2-streams is being incorporated into the main ssh2 module and the ssh2-streams module is being deprecated. This will require a significant update to this module and may result in some API changes, depending on what changes in the re-write of ssh2.
|
|
87
|
+
|
|
88
|
+
To support these changes, a new branch called *version-6* has been created. This branch will use the newest version of ssh2 and for now is very much experimental and subject to change.
|
|
89
|
+
|
|
90
|
+
<span class="underline">UPDATE</span>: Apparently the change in core node which cause the issue with ssh2 has been rolled back in node version 15.3.0. Testing seems to indicate the above issue does not exist in that version of node.
|
|
108
91
|
|
|
109
92
|
# Installation<a id="sec-2"></a>
|
|
110
93
|
|
|
@@ -222,6 +205,26 @@ In addition to the Promise error handlers, there is a default error handler whic
|
|
|
222
205
|
|
|
223
206
|
- Move some dev dependencies from dependencies to devDependencies.
|
|
224
207
|
|
|
208
|
+
## Version 5.2.2<a id="sec-4-11"></a>
|
|
209
|
+
|
|
210
|
+
- Bug fix. Some servers appear to issue errors with code 4 instead of code 2 for file not found errors. This version adds checks for error code 4 to the stat() method. Thanks to teenangst for the fix.
|
|
211
|
+
|
|
212
|
+
## Version 5.3.0<a id="sec-4-12"></a>
|
|
213
|
+
|
|
214
|
+
- Add code to only add connect() and end() event handlers if they are not already active. For connect(), remove event handlers as late as possible to help catch error events raised late on some platforms (like win32). don't remove end() error handler as some platforms, like win32, send an additional error event even after a successful and requested end() call.
|
|
215
|
+
- Fix path handling when connecting to a remoe SFTP server running on win32 platform. Assume server honours 'nix' path convention rather than using native win32 path format.
|
|
216
|
+
- Add additional documentation on events/promises, platform quirks and platform differences.
|
|
217
|
+
|
|
218
|
+
## Version 5.3.1<a id="sec-4-13"></a>
|
|
219
|
+
|
|
220
|
+
- Fix bug in handling of relative local paths
|
|
221
|
+
- Modified `get()` and `put()` methods to support special purpose streams which require `autoClose` to be `false`. These methods will now look for the `autoClose: false` property in the options object and if it is false, will issue a `destroy()` on the underlying stream just before the promise is resolved. The default is `autoClose: true` and this default should be used unless there is a known specific reason to change it to false.
|
|
222
|
+
|
|
223
|
+
## Version 5.3.2<a id="sec-4-14"></a>
|
|
224
|
+
|
|
225
|
+
- Minor README typo fixes
|
|
226
|
+
- Fix error in local file path checks (#294)
|
|
227
|
+
|
|
225
228
|
# Documentation<a id="sec-5"></a>
|
|
226
229
|
|
|
227
230
|
The connection options are the same as those offered by the underlying SSH2 module. For full details, please see [SSH2 client methods](https://github.com/mscdex/ssh2#user-content-client-methods)
|
|
@@ -230,6 +233,8 @@ All the methods will return a Promise, except for `on()` and `removeListener()`,
|
|
|
230
233
|
|
|
231
234
|
## Specifying Paths<a id="sec-5-1"></a>
|
|
232
235
|
|
|
236
|
+
The convention with both FTP and SFTP is that paths are specified using a 'nix' style i.e. use '*' as the path separator. This means that even if your SFTP server is running on a win32 platform, you should use '*' instead of '\\' as the path separator. For example, for a win32 path of 'C:\Users\fred' you would actually use '/C:/Users/fred'. If your win32 server does not support the 'nix' path convention, you can try setting the `remotePathSep` property of the `SftpClient` object to the path separator of your remote server. This **might** work, but has not been tested. Please let me know if you need to do this and provide details of the SFTP server so that I can try to create an appropriate environment and adjust things as necessary. At this point, I'm not aware of any win32 based SFTP servers which do not support the 'nix' path convention.
|
|
237
|
+
|
|
233
238
|
All remote paths must either be absolute e.g. `/absolute/path/to/file` or they can be relative with a prefix of either `./` (relative to current remote directory) or `../` (relative to parent of current remote directory) e.g. `./relative/path/to/file` or `../relative/to/parent/file`. It is also possible to do things like `../../../file` to specify the parent of the parent of the parent of the current remote directory. The shell tilde (`~`) and common environment variables like `$HOME` are NOT supported.
|
|
234
239
|
|
|
235
240
|
It is important to recognise that the current remote directory may not always be what you may expect. A lot will depend on the remote platform of the SFTP server and how the SFTP server has been configured. When things don't seem to be working as expected, it is often a good idea to verify your assumptions regarding the remote directory and remote paths. One way to do this is to login using a command line program like `sftp` or `lftp`.
|
|
@@ -270,17 +275,17 @@ Constructor to create a new `ssh2-sftp-client` object. An optional `name` string
|
|
|
270
275
|
|
|
271
276
|
```javascript
|
|
272
277
|
'use strict';
|
|
273
|
-
|
|
278
|
+
|
|
274
279
|
const Client = require('ssh2-sftp-client');
|
|
275
|
-
|
|
280
|
+
|
|
276
281
|
const config = {
|
|
277
282
|
host: 'example.com',
|
|
278
283
|
username: 'donald',
|
|
279
284
|
password: 'my-secret'
|
|
280
285
|
};
|
|
281
|
-
|
|
286
|
+
|
|
282
287
|
const sftp = new Client('example-client');
|
|
283
|
-
|
|
288
|
+
|
|
284
289
|
sftp.connect(config)
|
|
285
290
|
.then(() => {
|
|
286
291
|
return sftp.cwd();
|
|
@@ -301,12 +306,12 @@ Connect to an sftp server. Full documentation for connection options is availabl
|
|
|
301
306
|
1. Connection Options
|
|
302
307
|
|
|
303
308
|
This module is based on the excellent [SSH2](https://github.com/mscdex/ssh2#client) module. That module is a general SSH2 client and server library and provides much more functionality than just SFTP connectivity. Many of the connect options provided by that module are less relevant for SFTP connections. It is recommended you keep the config options to the minimum needed and stick to the options listed in the `commonOpts` below.
|
|
304
|
-
|
|
309
|
+
|
|
305
310
|
The `retries`, `retry_factor` and `retry_minTimeout` options are not part of the SSH2 module. These are part of the configuration for the [retry](https://www.npmjs.com/package/retry) package and what is used to enable retrying of sftp connection attempts. See the documentation for that package for an explanation of these values.
|
|
306
|
-
|
|
311
|
+
|
|
307
312
|
```javascript
|
|
308
313
|
// common options
|
|
309
|
-
|
|
314
|
+
|
|
310
315
|
let commonOpts {
|
|
311
316
|
host: 'localhost', // string Hostname or IP of server.
|
|
312
317
|
port: 22, // Port number of the server.
|
|
@@ -316,7 +321,7 @@ Connect to an sftp server. Full documentation for connection options is availabl
|
|
|
316
321
|
password: 'borsch', // string Password for password-based user authentication
|
|
317
322
|
agent: process.env.SSH_AGENT, // string - Path to ssh-agent's UNIX socket
|
|
318
323
|
privateKey: fs.readFileSync('/path/to/key'), // Buffer or string that contains
|
|
319
|
-
passphrase
|
|
324
|
+
passphrase: 'a pass phrase', // string - For an encrypted private key
|
|
320
325
|
readyTimeout: 20000, // integer How long (in ms) to wait for the SSH handshake
|
|
321
326
|
strictVendor: true // boolean - Performs a strict server vendor check
|
|
322
327
|
debug: myDebug // function - Set this to a function that receives a single
|
|
@@ -325,9 +330,9 @@ Connect to an sftp server. Full documentation for connection options is availabl
|
|
|
325
330
|
retry_factor: 2 // integer. Time factor used to calculate time between retries
|
|
326
331
|
retry_minTimeout: 2000 // integer. Minimum timeout between attempts
|
|
327
332
|
};
|
|
328
|
-
|
|
333
|
+
|
|
329
334
|
// rarely used options
|
|
330
|
-
|
|
335
|
+
|
|
331
336
|
let advancedOpts {
|
|
332
337
|
localAddress,
|
|
333
338
|
localPort,
|
|
@@ -368,16 +373,16 @@ Retrieves a directory listing. This method returns a Promise, which once realise
|
|
|
368
373
|
|
|
369
374
|
```javascript
|
|
370
375
|
const Client = require('ssh2-sftp-client');
|
|
371
|
-
|
|
376
|
+
|
|
372
377
|
const config = {
|
|
373
378
|
host: 'example.com',
|
|
374
379
|
port: 22,
|
|
375
380
|
username: 'red-don',
|
|
376
381
|
password: 'my-secret'
|
|
377
382
|
};
|
|
378
|
-
|
|
383
|
+
|
|
379
384
|
let sftp = new Client;
|
|
380
|
-
|
|
385
|
+
|
|
381
386
|
sftp.connect(config)
|
|
382
387
|
.then(() => {
|
|
383
388
|
return sftp.list('/path/to/remote/dir');
|
|
@@ -396,7 +401,7 @@ Retrieves a directory listing. This method returns a Promise, which once realise
|
|
|
396
401
|
2. Return Objects
|
|
397
402
|
|
|
398
403
|
The objects in the array returned by `list()` have the following properties;
|
|
399
|
-
|
|
404
|
+
|
|
400
405
|
```javascript
|
|
401
406
|
{
|
|
402
407
|
type: // file type(-, d, l)
|
|
@@ -417,11 +422,11 @@ Retrieves a directory listing. This method returns a Promise, which once realise
|
|
|
417
422
|
3. Pattern Filter
|
|
418
423
|
|
|
419
424
|
The filter options can be a regular expression (most powerful option) or a simple *glob*-like string where \* will match any number of characters, e.g.
|
|
420
|
-
|
|
425
|
+
|
|
421
426
|
foo* => foo, foobar, foobaz
|
|
422
427
|
*bar => bar, foobar, tabbar
|
|
423
428
|
*oo* => foo, foobar, look, book
|
|
424
|
-
|
|
429
|
+
|
|
425
430
|
The *glob*-style matching is very simple. In most cases, you are best off using a real regular expression which will allow you to do more powerful matching and anchor matches to the beginning/end of the string etc.
|
|
426
431
|
|
|
427
432
|
### exists(path) ==> boolean<a id="sec-5-2-4"></a>
|
|
@@ -432,16 +437,16 @@ Tests to see if remote file or directory exists. Returns type of remote object i
|
|
|
432
437
|
|
|
433
438
|
```javascript
|
|
434
439
|
const Client = require('ssh2-sftp-client');
|
|
435
|
-
|
|
440
|
+
|
|
436
441
|
const config = {
|
|
437
442
|
host: 'example.com',
|
|
438
443
|
port: 22,
|
|
439
444
|
username: 'red-don',
|
|
440
445
|
password: 'my-secret'
|
|
441
446
|
};
|
|
442
|
-
|
|
447
|
+
|
|
443
448
|
let sftp = new Client;
|
|
444
|
-
|
|
449
|
+
|
|
445
450
|
sftp.connect(config)
|
|
446
451
|
.then(() => {
|
|
447
452
|
return sftp.exists('/path/to/remote/dir');
|
|
@@ -466,7 +471,7 @@ Returns the attributes associated with the object pointed to by `path`.
|
|
|
466
471
|
1. Attributes
|
|
467
472
|
|
|
468
473
|
The `stat()` method returns an object with the following properties;
|
|
469
|
-
|
|
474
|
+
|
|
470
475
|
```javascript
|
|
471
476
|
let stats = {
|
|
472
477
|
mode: 33279, // integer representing type and permissions
|
|
@@ -489,7 +494,7 @@ Returns the attributes associated with the object pointed to by `path`.
|
|
|
489
494
|
|
|
490
495
|
```javascript
|
|
491
496
|
let client = new Client();
|
|
492
|
-
|
|
497
|
+
|
|
493
498
|
client.connect(config)
|
|
494
499
|
.then(() => {
|
|
495
500
|
return client.stat('/path/to/remote/file');
|
|
@@ -518,7 +523,7 @@ In general, if your going to pass in a string as the destination, you are better
|
|
|
518
523
|
1. Options
|
|
519
524
|
|
|
520
525
|
The options object can be used to pass options to the underlying readStream used to read the data from the remote server.
|
|
521
|
-
|
|
526
|
+
|
|
522
527
|
```javascript
|
|
523
528
|
{
|
|
524
529
|
flags: 'r',
|
|
@@ -528,17 +533,17 @@ In general, if your going to pass in a string as the destination, you are better
|
|
|
528
533
|
autoClose: true
|
|
529
534
|
}
|
|
530
535
|
```
|
|
531
|
-
|
|
536
|
+
|
|
532
537
|
Most of the time, you won't want to use any options. Sometimes, it may be useful to set the encoding. For example, to 'utf-8'. However, it is important not to do this for binary files to avoid data corruption.
|
|
533
538
|
|
|
534
539
|
2. Example Use
|
|
535
540
|
|
|
536
541
|
```javascript
|
|
537
542
|
let client = new Client();
|
|
538
|
-
|
|
543
|
+
|
|
539
544
|
let remotePath = '/remote/server/path/file.txt';
|
|
540
545
|
let dst = fs.createWriteStream('/local/file/path/copy.txt');
|
|
541
|
-
|
|
546
|
+
|
|
542
547
|
client.connect(config)
|
|
543
548
|
.then(() => {
|
|
544
549
|
return client.get(remotePath, dst);
|
|
@@ -550,7 +555,7 @@ In general, if your going to pass in a string as the destination, you are better
|
|
|
550
555
|
console.error(err.message);
|
|
551
556
|
});
|
|
552
557
|
```
|
|
553
|
-
|
|
558
|
+
|
|
554
559
|
- **Tip:** See examples file in the Git repository for more examples. You can pass any writeable stream in as the destination. For example, if you pass in `zlib.createGunzip()` writeable stream, you can both download and decompress a gzip file 'on the fly'.
|
|
555
560
|
|
|
556
561
|
### fastGet(remotePath, localPath, options) ===> string<a id="sec-5-2-7"></a>
|
|
@@ -571,7 +576,7 @@ Downloads a file at remotePath to localPath using parallel reads for faster thro
|
|
|
571
576
|
// chunk is transferred
|
|
572
577
|
}
|
|
573
578
|
```
|
|
574
|
-
|
|
579
|
+
|
|
575
580
|
- **Warning:** Some servers do not respond correctly to requests to alter chunk size. This can result in lost or corrupted data.
|
|
576
581
|
|
|
577
582
|
2. Sample Use
|
|
@@ -580,7 +585,7 @@ Downloads a file at remotePath to localPath using parallel reads for faster thro
|
|
|
580
585
|
let client = new Client();
|
|
581
586
|
let remotePath = '/server/path/file.txt';
|
|
582
587
|
let localPath = '/local/path/file.txt';
|
|
583
|
-
|
|
588
|
+
|
|
584
589
|
client.connect(config)
|
|
585
590
|
.then(() => {
|
|
586
591
|
client.fastGet(remotePath, localPath);
|
|
@@ -604,7 +609,7 @@ Upload data from local system to remote server. If the `src` argument is a strin
|
|
|
604
609
|
1. Options
|
|
605
610
|
|
|
606
611
|
The following options are supported;
|
|
607
|
-
|
|
612
|
+
|
|
608
613
|
```javascript
|
|
609
614
|
{
|
|
610
615
|
flags: 'w', // w - write and a - append
|
|
@@ -613,17 +618,17 @@ Upload data from local system to remote server. If the `src` argument is a strin
|
|
|
613
618
|
autoClose: true // automatically close the write stream when finished
|
|
614
619
|
}
|
|
615
620
|
```
|
|
616
|
-
|
|
621
|
+
|
|
617
622
|
The most common options to use are mode and encoding. The values shown above are the defaults. You do not have to set encoding to utf-8 for text files, null is fine for all file types. However, using utf-8 encoding for binary files will often result in data corruption.
|
|
618
623
|
|
|
619
624
|
2. Example Use
|
|
620
625
|
|
|
621
626
|
```javascript
|
|
622
627
|
let client = new Client();
|
|
623
|
-
|
|
628
|
+
|
|
624
629
|
let data = fs.createReadStream('/path/to/local/file.txt');
|
|
625
630
|
let remote = '/path/to/remote/file.txt';
|
|
626
|
-
|
|
631
|
+
|
|
627
632
|
client.connect(config)
|
|
628
633
|
.then(() => {
|
|
629
634
|
return client.put(data, remote);
|
|
@@ -635,7 +640,7 @@ Upload data from local system to remote server. If the `src` argument is a strin
|
|
|
635
640
|
console.error(err.message);
|
|
636
641
|
});
|
|
637
642
|
```
|
|
638
|
-
|
|
643
|
+
|
|
639
644
|
- **Tip:** If the src argument is a path string, consider just using `fastPut()`.
|
|
640
645
|
|
|
641
646
|
### fastPut(localPath, remotePath, options) ==> string<a id="sec-5-2-9"></a>
|
|
@@ -657,7 +662,7 @@ Uploads the data in file at `localPath` to a new file on remote server at `remot
|
|
|
657
662
|
// a part of a file was transferred
|
|
658
663
|
}
|
|
659
664
|
```
|
|
660
|
-
|
|
665
|
+
|
|
661
666
|
- **Warning:** There have been reports that some SFTP servers will not honour requests for non-default chunk sizes. This can result in data loss or corruption.
|
|
662
667
|
|
|
663
668
|
2. Example Use
|
|
@@ -666,7 +671,7 @@ Uploads the data in file at `localPath` to a new file on remote server at `remot
|
|
|
666
671
|
let localFile = '/path/to/file.txt';
|
|
667
672
|
let remoteFile = '/path/to/remote/file.txt';
|
|
668
673
|
let client = new Client();
|
|
669
|
-
|
|
674
|
+
|
|
670
675
|
client.connect(config)
|
|
671
676
|
.then(() => {
|
|
672
677
|
client.fastPut(localFile, remoteFile);
|
|
@@ -690,7 +695,7 @@ Append the `input` data to an existing remote file. There is no integrity checki
|
|
|
690
695
|
1. Options
|
|
691
696
|
|
|
692
697
|
The following options are supported;
|
|
693
|
-
|
|
698
|
+
|
|
694
699
|
```javascript
|
|
695
700
|
{
|
|
696
701
|
flags: 'a', // w - write and a - append
|
|
@@ -699,7 +704,7 @@ Append the `input` data to an existing remote file. There is no integrity checki
|
|
|
699
704
|
autoClose: true // automatically close the write stream when finished
|
|
700
705
|
}
|
|
701
706
|
```
|
|
702
|
-
|
|
707
|
+
|
|
703
708
|
The most common options to use are mode and encoding. The values shown above are the defaults. You do not have to set encoding to utf-8 for text files, null is fine for all file types. Generally, I would not attempt to append binary files.
|
|
704
709
|
|
|
705
710
|
2. Example Use
|
|
@@ -707,7 +712,7 @@ Append the `input` data to an existing remote file. There is no integrity checki
|
|
|
707
712
|
```javascript
|
|
708
713
|
let remotePath = '/path/to/remote/file.txt';
|
|
709
714
|
let client = new Client();
|
|
710
|
-
|
|
715
|
+
|
|
711
716
|
client.connect(config)
|
|
712
717
|
.then(() => {
|
|
713
718
|
return client.append(Buffer.from('Hello world'), remotePath);
|
|
@@ -732,7 +737,7 @@ Create a new directory. If the recursive flag is set to true, the method will cr
|
|
|
732
737
|
```javascript
|
|
733
738
|
let remoteDir = '/path/to/new/dir';
|
|
734
739
|
let client = new Client();
|
|
735
|
-
|
|
740
|
+
|
|
736
741
|
client.connect(config)
|
|
737
742
|
.then(() => {
|
|
738
743
|
return client.mkdir(remoteDir, true);
|
|
@@ -752,12 +757,14 @@ Remove a directory. If removing a directory and recursive flag is set to `true`,
|
|
|
752
757
|
- **path:** string. Path to remote directory
|
|
753
758
|
- **recursive:** boolean. If true, remove all files and directories in target directory. Defaults to false
|
|
754
759
|
|
|
760
|
+
**Note**: There has been at least one report that some SFTP servers will allow non-empty directories to be removed even without the recursive flag being set to true. While this is not standard behaviour, it is recommended that users verify the behaviour of rmdir if there are plans to rely on the recursive flag to prevent removal of non-empty directories.
|
|
761
|
+
|
|
755
762
|
1. Example Use
|
|
756
763
|
|
|
757
764
|
```javascript
|
|
758
765
|
let remoteDir = '/path/to/remote/dir';
|
|
759
766
|
let client = new Client();
|
|
760
|
-
|
|
767
|
+
|
|
761
768
|
client.connect(config)
|
|
762
769
|
.then(() => {
|
|
763
770
|
return client.rmdir(remoteDir, true);
|
|
@@ -781,7 +788,7 @@ Delete a file on the remote server.
|
|
|
781
788
|
```javascript
|
|
782
789
|
let remoteFile = '/path/to/remote/file.txt';
|
|
783
790
|
let client = new Client();
|
|
784
|
-
|
|
791
|
+
|
|
785
792
|
client.connect(config)
|
|
786
793
|
.then(() => {
|
|
787
794
|
return client.delete(remoteFile);
|
|
@@ -807,7 +814,7 @@ Rename a file or directory from `fromPath` to `toPath`. You must have the necess
|
|
|
807
814
|
let from = '/remote/path/to/old.txt';
|
|
808
815
|
let to = '/remote/path/to/new.txt';
|
|
809
816
|
let client = new Client();
|
|
810
|
-
|
|
817
|
+
|
|
811
818
|
client.connect(config)
|
|
812
819
|
.then(() => {
|
|
813
820
|
return client.rename(from, to);
|
|
@@ -855,9 +862,9 @@ Change the mode (read, write or execute permissions) of a remote file or directo
|
|
|
855
862
|
|
|
856
863
|
```javascript
|
|
857
864
|
let path = '/path/to/remote/file.txt';
|
|
858
|
-
let
|
|
865
|
+
let newMode = 0o644; // rw-r-r
|
|
859
866
|
let client = new Client();
|
|
860
|
-
|
|
867
|
+
|
|
861
868
|
client.connect(config)
|
|
862
869
|
.then(() => {
|
|
863
870
|
return client.chmod(path, newMode);
|
|
@@ -872,7 +879,9 @@ Change the mode (read, write or execute permissions) of a remote file or directo
|
|
|
872
879
|
|
|
873
880
|
### realPath(path) ===> string<a id="sec-5-2-17"></a>
|
|
874
881
|
|
|
875
|
-
Converts a relative path to an absolute path on the remote server. This method is mainly used internally to resolve remote path names.
|
|
882
|
+
Converts a relative path to an absolute path on the remote server. This method is mainly used internally to resolve remote path names.
|
|
883
|
+
|
|
884
|
+
**Warning**: Currently, there is a platform inconsistency with this method on win32 platforms. For servers running on non-win32 platforms, providing a path which does not exist on the remote server will result in an empty e.g. '', absolute path being returned. On servers running on win32 platforms, a normalised path will be returned even if the path does not exist on the remote server. It is therefore advised not to use this method to also verify a path exists. instead, use the `exist()` method.
|
|
876
885
|
|
|
877
886
|
- **path:** A file path, either relative or absolute. Can handle '.' and '..', but does not expand '~'.
|
|
878
887
|
|
|
@@ -893,28 +902,28 @@ The upload process also emits 'upload' events. These events are fired for each s
|
|
|
893
902
|
|
|
894
903
|
```javascript
|
|
895
904
|
'use strict';
|
|
896
|
-
|
|
905
|
+
|
|
897
906
|
// Example of using the uploadDir() method to upload a directory
|
|
898
907
|
// to a remote SFTP server
|
|
899
|
-
|
|
908
|
+
|
|
900
909
|
const path = require('path');
|
|
901
910
|
const SftpClient = require('../src/index');
|
|
902
|
-
|
|
911
|
+
|
|
903
912
|
const dotenvPath = path.join(__dirname, '..', '.env');
|
|
904
913
|
require('dotenv').config({path: dotenvPath});
|
|
905
|
-
|
|
914
|
+
|
|
906
915
|
const config = {
|
|
907
916
|
host: process.env.SFTP_SERVER,
|
|
908
917
|
username: process.env.SFTP_USER,
|
|
909
918
|
password: process.env.SFTP_PASSWORD,
|
|
910
919
|
port: process.env.SFTP_PORT || 22
|
|
911
920
|
};
|
|
912
|
-
|
|
921
|
+
|
|
913
922
|
async function main() {
|
|
914
923
|
const client = new SftpClient('upload-test');
|
|
915
924
|
const src = path.join(__dirname, '..', 'test', 'testData', 'upload-src');
|
|
916
925
|
const dst = '/home/tim/upload-test';
|
|
917
|
-
|
|
926
|
+
|
|
918
927
|
try {
|
|
919
928
|
await client.connect(config);
|
|
920
929
|
client.on('upload', info => {
|
|
@@ -926,7 +935,7 @@ The upload process also emits 'upload' events. These events are fired for each s
|
|
|
926
935
|
client.end();
|
|
927
936
|
}
|
|
928
937
|
}
|
|
929
|
-
|
|
938
|
+
|
|
930
939
|
main()
|
|
931
940
|
.then(msg => {
|
|
932
941
|
console.log(msg);
|
|
@@ -934,7 +943,7 @@ The upload process also emits 'upload' events. These events are fired for each s
|
|
|
934
943
|
.catch(err => {
|
|
935
944
|
console.log(`main error: ${err.message}`);
|
|
936
945
|
});
|
|
937
|
-
|
|
946
|
+
|
|
938
947
|
```
|
|
939
948
|
|
|
940
949
|
### downloadDir(srcDir, dstDir) ==> string<a id="sec-5-2-20"></a>
|
|
@@ -950,28 +959,28 @@ The method also emites `download` events to provide a way to monitor download pr
|
|
|
950
959
|
|
|
951
960
|
```javascript
|
|
952
961
|
'use strict';
|
|
953
|
-
|
|
962
|
+
|
|
954
963
|
// Example of using the downloadDir() method to upload a directory
|
|
955
964
|
// to a remote SFTP server
|
|
956
|
-
|
|
965
|
+
|
|
957
966
|
const path = require('path');
|
|
958
967
|
const SftpClient = require('../src/index');
|
|
959
|
-
|
|
968
|
+
|
|
960
969
|
const dotenvPath = path.join(__dirname, '..', '.env');
|
|
961
970
|
require('dotenv').config({path: dotenvPath});
|
|
962
|
-
|
|
971
|
+
|
|
963
972
|
const config = {
|
|
964
973
|
host: process.env.SFTP_SERVER,
|
|
965
974
|
username: process.env.SFTP_USER,
|
|
966
975
|
password: process.env.SFTP_PASSWORD,
|
|
967
976
|
port: process.env.SFTP_PORT || 22
|
|
968
977
|
};
|
|
969
|
-
|
|
978
|
+
|
|
970
979
|
async function main() {
|
|
971
980
|
const client = new SftpClient('upload-test');
|
|
972
981
|
const dst = '/tmp';
|
|
973
982
|
const src = '/home/tim/upload-test';
|
|
974
|
-
|
|
983
|
+
|
|
975
984
|
try {
|
|
976
985
|
await client.connect(config);
|
|
977
986
|
client.on('download', info => {
|
|
@@ -983,7 +992,7 @@ The method also emites `download` events to provide a way to monitor download pr
|
|
|
983
992
|
client.end();
|
|
984
993
|
}
|
|
985
994
|
}
|
|
986
|
-
|
|
995
|
+
|
|
987
996
|
main()
|
|
988
997
|
.then(msg => {
|
|
989
998
|
console.log(msg);
|
|
@@ -991,7 +1000,7 @@ The method also emites `download` events to provide a way to monitor download pr
|
|
|
991
1000
|
.catch(err => {
|
|
992
1001
|
console.log(`main error: ${err.message}`);
|
|
993
1002
|
});
|
|
994
|
-
|
|
1003
|
+
|
|
995
1004
|
```
|
|
996
1005
|
|
|
997
1006
|
### end() ==> boolean<a id="sec-5-2-21"></a>
|
|
@@ -1002,7 +1011,7 @@ Ends the current client session, releasing the client socket and associated reso
|
|
|
1002
1011
|
|
|
1003
1012
|
```javascript
|
|
1004
1013
|
let client = new Client();
|
|
1005
|
-
|
|
1014
|
+
|
|
1006
1015
|
client.connect(config)
|
|
1007
1016
|
.then(() => {
|
|
1008
1017
|
// do some sftp stuff
|
|
@@ -1031,9 +1040,43 @@ Although normally not required, you can add and remove custom listeners on the s
|
|
|
1031
1040
|
|
|
1032
1041
|
Removes the specified listener from the event specified in eventType. Note that the `end()` method automatically removes all listeners from the client object.
|
|
1033
1042
|
|
|
1034
|
-
#
|
|
1043
|
+
# Platform Quirks & Warnings<a id="sec-6"></a>
|
|
1044
|
+
|
|
1045
|
+
## Server Capabilities<a id="sec-6-1"></a>
|
|
1046
|
+
|
|
1047
|
+
All SFTP servers and platforms are not equal. Some facilities provided by `ssh2-sfto-client` either depend on capabilities of the remote server or the underlying capabilities of the remote server platform. As an example, consider `chmod()`. This command depends on a remote filesystem which implements the 'nix' concept of users and groups. The *win32* platform does not have the same concept of users and groups, so `chmod()` will not behave in the same way.
|
|
1048
|
+
|
|
1049
|
+
One way to determine whether an issue you are encountering is due to `ssh2-sftp-client` or due to the remote server or server platform is to use a simple CLI sftp program, such as openSSH's sftp command. If you observe the same behaviour using plain `sftp` on the command line, the issue is likely due to server or remote platform limitations. Note that you should not use a GUI sftp client, like `Filezilla` or `winSCP` as such GUI programs often attempt to hide these server and platform incompatibilities and will take additional steps to simulate missing functionality etc. You want to use a CLI program which does as little as possible.
|
|
1050
|
+
|
|
1051
|
+
One way to determine whether an issue you are encountering is due to `ssh2-sftp-client` or due to the remote server or server platform is to use a simple CLI sftp program, such as openSSH's sftp command. If you observe the same behaviour using plain `sftp` on the command line, the issue is likely due to server or remote platform limitations. Note that you should not use a GUI sftp client, like `Filezilla` or `winSCP` as such GUI programs often attempt to hide these server and platform incompatibilities and will take additional steps to simulate missing functionality etc.
|
|
1052
|
+
|
|
1053
|
+
## Promises & Events<a id="sec-6-2"></a>
|
|
1054
|
+
|
|
1055
|
+
The reality of the current Node environment is that Promises and Events don't play nicely together. Part of the problem is that events are asynchronous in nature and can occur at any time. It is very difficult to ensure an event is captured inside a Promise and handled appropriately. More information can be found in the Node documentation for Events.
|
|
1056
|
+
|
|
1057
|
+
Node v12 has introduced some experimental features to make working with Events and Promises a little easier. At this stage, we are not using these features because they are experimental and because it would mean you cannot use this module with Node v10. Use of these features will likely be examined more closely once they become stable and non-experimental.
|
|
1058
|
+
|
|
1059
|
+
So, what does this mean for this module? The `ssh2-sftp-client` module works hard to ensure things work as expected. In most cases, events are handled appropriately. However, there are some edge cases where events may not be handled and you may see an uncaught error exception. The most common place to see this is when you keep an SFTP connection open, but don't use it for some time. When the connection is open, but no methods are active (running), there are no error handlers defined. Should an error event be emitted (for exmaple, because the network connection has been lost), there is no handler and you will get an uncaught error exception.
|
|
1035
1060
|
|
|
1036
|
-
|
|
1061
|
+
One way to handle this is to add your own error handler using the on() method. Note however, you need to be careful how many times your error handler is added. If you begin to see a warning about a possible memory leak, it is an indication your error handler is being added multiple times (Node will generate this warning if it finds more than 11 listeners attached to an event emitter).
|
|
1062
|
+
|
|
1063
|
+
The other issue that can occur is that in some rare cases, the error message you get will be potentially misleading. For example, SFTP servers running on Windows appear to emit an *ECONNRESET* error in addition to the main error (for example, for failed authentication). This can result in an error which looks like a connection was reset by the remote host when in fact the real error was due to bad authentication (bad password or bad username). This situation can be made even worse by some platforms which deliberately hide the real error for security reasons e.g. does not report an error indicating a bad username because that information can be used to try and identify legitimate usernames. While this module attempts to provide meaningful error messages which can assist developers track down problems, it is a good idea to consider these errors with a grain of salt and verify the error when possible.
|
|
1064
|
+
|
|
1065
|
+
## Windows Based Servers<a id="sec-6-3"></a>
|
|
1066
|
+
|
|
1067
|
+
It appears that when the sftp server is running on Windows, a *ECONNRESET* error signal is raised when the end() method is called. Unfortunately, this signal is raised after a considerable delay. This means we cannot remove the error handler used in the end() promise as otherwise you will get an uncaught exception error. Leaving the handler in place, even though we will ignore this error, solves that issue, but unfortunately introduces a new problem. Because we are not removing the listener, if you re-use the client object for subsequent connections, an additional error handler will be added. If this happens more than 11 times, you will eventually see the Node warning about a possible memory leak. This is because node monitors the number of error handlers and if it sees more than 11 added to an object, it assumes there is a problem and generates the warning.
|
|
1068
|
+
|
|
1069
|
+
The best way to avoid this issue is to not re-use client objects. Always generate a new sftp client object for each new connection.
|
|
1070
|
+
|
|
1071
|
+
## Don't Re-use SftpClient Objects<a id="sec-6-4"></a>
|
|
1072
|
+
|
|
1073
|
+
Due to an issue with *ECONNRESET* error signals when connecting to Windows based SFTP servers, it is not possible to remove the error handler in the end() method. This means that if you re-use the SftpClient object for multiple connections e.g. calling connect(), then end(), then connect() etc, you run the risk of multiple error handlers being added to the SftpClient object. After 11 handlers have been added, Node will generate a possible memory leak warning.
|
|
1074
|
+
|
|
1075
|
+
To avoid this problem, don't re-use SftpClient objects. Generate a new SftpClient object for each connection. You can perform multiple actions with a single connection e.g. upload multiple files, download multiple files etc, but after you have called end(), you should not try to re-use the object with a further connect() call. Create a new object instead.
|
|
1076
|
+
|
|
1077
|
+
# FAQ<a id="sec-7"></a>
|
|
1078
|
+
|
|
1079
|
+
## Remote server drops connections with only an end event<a id="sec-7-1"></a>
|
|
1037
1080
|
|
|
1038
1081
|
Many SFTP servers have rate limiting protection which will drop connections once a limit has been reached. In particular, openSSH has the setting `MaxStartups`, which can be a tuple of the form `max:drop:full` where `max` is the maximum allowed unauthenticated connections, `drop` is a percentage value which specifies percentage of connections to be dropped once `max` connections has been reached and `full` is the number of connections at which point all subsequent connections will be dropped. e.g. `10:30:60` means allow up to 10 unauthenticated connections after which drop 30% of connection attempts until reaching 60 unauthenticated connections, at which time, drop all attempts.
|
|
1039
1082
|
|
|
@@ -1041,7 +1084,7 @@ Clients first make an unauthenticated connection to the SFTP server to begin neg
|
|
|
1041
1084
|
|
|
1042
1085
|
One way to avoid this type of issue is to add a delay between connection attempts. It does not need to be a very long delay - just sufficient to permit the previous connection to be authenticated. In fact, the default setting for openSSH is `10:30:60`, so you really just need to have enough delay to ensure that the 1st connection has completed authentication before the 11th connection is attempted.
|
|
1043
1086
|
|
|
1044
|
-
## How can
|
|
1087
|
+
## How can I pass writable stream as dst for get method?<a id="sec-7-2"></a>
|
|
1045
1088
|
|
|
1046
1089
|
If the dst argument passed to the get method is a writeable stream, the remote file will be piped into that writeable. If the writeable you pass in is a writeable stream created with `fs.createWriteStream()`, the data will be written to the file specified in the constructor call to `createWriteStream()`.
|
|
1047
1090
|
|
|
@@ -1097,7 +1140,7 @@ sftp
|
|
|
1097
1140
|
});
|
|
1098
1141
|
```
|
|
1099
1142
|
|
|
1100
|
-
## How can I upload files without having to specify a password?<a id="sec-
|
|
1143
|
+
## How can I upload files without having to specify a password?<a id="sec-7-3"></a>
|
|
1101
1144
|
|
|
1102
1145
|
There are a couple of ways to do this. Essentially, you want to setup SSH keys and use these for authentication to the remote server.
|
|
1103
1146
|
|
|
@@ -1129,7 +1172,7 @@ sftp.connect({
|
|
|
1129
1172
|
}
|
|
1130
1173
|
```
|
|
1131
1174
|
|
|
1132
|
-
## How can I connect through a Socks Proxy<a id="sec-
|
|
1175
|
+
## How can I connect through a Socks Proxy<a id="sec-7-4"></a>
|
|
1133
1176
|
|
|
1134
1177
|
This solution was provided by @jmorino.
|
|
1135
1178
|
|
|
@@ -1162,218 +1205,50 @@ client.connect({
|
|
|
1162
1205
|
// client is connected
|
|
1163
1206
|
```
|
|
1164
1207
|
|
|
1165
|
-
## Timeout while waiting for handshake or handshake errors<a id="sec-
|
|
1208
|
+
## Timeout while waiting for handshake or handshake errors<a id="sec-7-5"></a>
|
|
1166
1209
|
|
|
1167
1210
|
Some users have encountered the error 'Timeout while waiting for handshake' or 'Handshake failed, no matching client->server ciphers. This is often due to the client not having the correct configuration for the transport layer algorithms used by ssh2. One of the connect options provided by the ssh2 module is `algorithm`, which is an object that allows you to explicitly set the key exchange, ciphers, hmac and compression algorithms as well as server host key used to establish the initial secure connection. See the SSH2 documentation for details. Getting these parameters correct usually resolves the issue.
|
|
1168
1211
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
I have started collecting example scripts in the example directory of the repository. These are mainly scripts I have put together in order to investigate issues or provide samples for users. They are not robust, lack adequate error handling and may contain errors. However, I think they are still useful for helping developers see how the module and API can be used.
|
|
1172
|
-
|
|
1173
|
-
# Change Log<a id="sec-8"></a>
|
|
1174
|
-
|
|
1175
|
-
## v5.2.1 (Prod Version)<a id="sec-8-1"></a>
|
|
1176
|
-
|
|
1177
|
-
- Move some dependencies into dev-Dependencies
|
|
1178
|
-
|
|
1179
|
-
## v5.2.0<a id="sec-8-2"></a>
|
|
1180
|
-
|
|
1181
|
-
- Add new method posixRename() which uses the openSSH POSIX rename extension.
|
|
1182
|
-
|
|
1183
|
-
## v5.1.3<a id="sec-8-3"></a>
|
|
1184
|
-
|
|
1185
|
-
- Fix bug when writing to root directory and failure due to not being able to determine parent
|
|
1186
|
-
- Refactor some tests to eliminate need to have artificial delays between tests
|
|
1187
|
-
- Bumped some dependency versions to latest version
|
|
1188
|
-
|
|
1189
|
-
## v5.1.2<a id="sec-8-4"></a>
|
|
1190
|
-
|
|
1191
|
-
- Added back global close handler
|
|
1192
|
-
- Added dumpListeners() method
|
|
1193
|
-
|
|
1194
|
-
## v5.1.1<a id="sec-8-5"></a>
|
|
1195
|
-
|
|
1196
|
-
- Added separate close handlers to each method.
|
|
1197
|
-
- Added missing return statement in connect method
|
|
1198
|
-
- Added additional troubleshooting documentation for common errors.
|
|
1199
|
-
|
|
1200
|
-
## v5.1.0<a id="sec-8-6"></a>
|
|
1201
|
-
|
|
1202
|
-
- Fix bug in checkRemotePath() relating to handling of badly specified paths (issue #213)
|
|
1203
|
-
- Added additional debugging support
|
|
1204
|
-
- Add missing test for valid connection in end() method.
|
|
1205
|
-
- Bump ssh2 version to v0.8.8
|
|
1206
|
-
|
|
1207
|
-
## v5.0.2<a id="sec-8-7"></a>
|
|
1208
|
-
|
|
1209
|
-
- Fix bugs related to win32 platform and local tests for valid directories
|
|
1210
|
-
- Fix problem with parsing of file paths
|
|
1211
|
-
|
|
1212
|
-
## v5.0.1<a id="sec-8-8"></a>
|
|
1213
|
-
|
|
1214
|
-
- Turn down error checking to be less stringent and handle situations where user does not have read permission on parent directory.
|
|
1215
|
-
|
|
1216
|
-
## v5.0.0<a id="sec-8-9"></a>
|
|
1217
|
-
|
|
1218
|
-
- Added two new methods `uploadDir()` and `downloadDir()`
|
|
1219
|
-
- Removed deprecated `auxList()` method
|
|
1220
|
-
- Improved error message consistency
|
|
1221
|
-
- Added additional error checking to enable more accurate and useful error messages.
|
|
1222
|
-
- Added default error handler to deal with event errors which fire outside of active SftpClient methods (i.e. connection unexpectedly reset by remote host).
|
|
1223
|
-
- Modified event handlers to ensure that only event handlers added by the module are removed by the module (users now responsible for removing any custom event handlers they add).
|
|
1224
|
-
- Module error handlers added using `prependListener` to ensure they are called before any additional custom handlers added by client code.
|
|
1225
|
-
- Any error events fired during an `end()` call are now ignored.
|
|
1226
|
-
|
|
1227
|
-
## v4.3.1<a id="sec-8-10"></a>
|
|
1228
|
-
|
|
1229
|
-
- Updated end() method to resolve once close event fires
|
|
1230
|
-
- Added errorListener to error event in each promise to catch error events and reject the promise. This should resolve the issue of some error events causing uncaughtException erros and causing the process to exit.
|
|
1231
|
-
|
|
1232
|
-
## v4.3.0<a id="sec-8-11"></a>
|
|
1233
|
-
|
|
1234
|
-
- Ensure errors include an err.code property and pass through the error code from the originating error
|
|
1235
|
-
- Change tests for error type to use `error.code` instead of matching on `error.message`.
|
|
1236
|
-
|
|
1237
|
-
## v4.2.4<a id="sec-8-12"></a>
|
|
1238
|
-
|
|
1239
|
-
- Bumped ssh2 to v0.8.6
|
|
1240
|
-
- Added exists() usage example to examples directory
|
|
1241
|
-
- Clarify documentation on get() method
|
|
1242
|
-
|
|
1243
|
-
## v4.2.3<a id="sec-8-13"></a>
|
|
1244
|
-
|
|
1245
|
-
- Fix bug in `exist()` where tests on root directory returned false
|
|
1246
|
-
- Minor documentation fixes
|
|
1247
|
-
- Clean up mkdir example
|
|
1248
|
-
|
|
1249
|
-
## v4.2.2<a id="sec-8-14"></a>
|
|
1250
|
-
|
|
1251
|
-
- Minor documentation fixes
|
|
1252
|
-
- Added additional examples in the `example` directory
|
|
1253
|
-
|
|
1254
|
-
## v4.2.1<a id="sec-8-15"></a>
|
|
1255
|
-
|
|
1256
|
-
- Remove default close listener. changes in ssh2 API removed the utility of a default close listener
|
|
1257
|
-
- Fix path handling. Under mixed environments (where client platform and server platform were different i.e. one windows the other unix), path handling was broken due tot he use of path.join().
|
|
1258
|
-
- Ensure error messages include path details. Instead of errors such as "No such file" now report "No such file /path/to/missing/file" to help with debugging
|
|
1212
|
+
## How can I limit upload/download speed<a id="sec-7-6"></a>
|
|
1259
1213
|
|
|
1260
|
-
|
|
1214
|
+
If you want to limit the amount of bandwidth used during upload/download of data, you can use a stream to limit throughput. The following example was provided by *kennylbj*. Note that there is a caveat that we must set the `autoClose` flag to false to avoid calling an extra `_read()` on a closed stream that may cause \_get Permission Denied error in ssh2-streams.
|
|
1261
1215
|
|
|
1262
|
-
|
|
1263
|
-
- Added ability to set client name in constructor method
|
|
1264
|
-
- Added additional error checking to prevent `connect()` being called on already connected client
|
|
1265
|
-
- Added additional examples in `example` directory
|
|
1266
|
-
|
|
1267
|
-
## v4.1.0<a id="sec-8-17"></a>
|
|
1268
|
-
|
|
1269
|
-
- move `end()` call to resolve into close hook
|
|
1270
|
-
- Prevent `put()` and `get()` from creating empty files in destination when unable to read source
|
|
1271
|
-
- Expand tests for operations when lacking required permissions
|
|
1272
|
-
- Add additional data checks for `append()`
|
|
1273
|
-
- Verify file exists
|
|
1274
|
-
- Verify file is writeable
|
|
1275
|
-
- Verify file is a regular file
|
|
1276
|
-
- Fix handling of relative paths
|
|
1277
|
-
- Add `realPath()` method
|
|
1278
|
-
- Add `cwd()` method
|
|
1279
|
-
|
|
1280
|
-
## v4.0.4<a id="sec-8-18"></a>
|
|
1281
|
-
|
|
1282
|
-
- Minor documentation fix
|
|
1283
|
-
- Fix return value from `get()`
|
|
1284
|
-
|
|
1285
|
-
## v4.0.3<a id="sec-8-19"></a>
|
|
1286
|
-
|
|
1287
|
-
- Fix bug in mkdir() relating to handling of relative paths
|
|
1288
|
-
- Modify exists() to always return 'd' if path is '.'
|
|
1289
|
-
|
|
1290
|
-
## v4.0.2<a id="sec-8-20"></a>
|
|
1291
|
-
|
|
1292
|
-
- Fix some minor packaging issues
|
|
1293
|
-
|
|
1294
|
-
## v4.0.0<a id="sec-8-21"></a>
|
|
1295
|
-
|
|
1296
|
-
- Remove support for node < 8.x
|
|
1297
|
-
- Fix connection retry feature
|
|
1298
|
-
- sftp connection object set to null when 'end' signal is raised
|
|
1299
|
-
- Removed 'connectMethod' argument from connect method.
|
|
1300
|
-
- Refined adding/removing of listeners in connect() and end() methods to enable errors to be adequately caught and reported.
|
|
1301
|
-
- Deprecate auxList() and add pattern/regexp filter option to list()
|
|
1302
|
-
- Refactored handling of event signals to provide better feedback to clients
|
|
1303
|
-
- Removed pointless 'permissions' property from objects returned by `stat()` (same as mode property). Added additional properties describing the type of object.
|
|
1304
|
-
- Added the `removeListener()` method to compliment the existing `on()` method.
|
|
1305
|
-
|
|
1306
|
-
## Older Versions<a id="sec-8-22"></a>
|
|
1307
|
-
|
|
1308
|
-
### v2.5.2<a id="sec-8-22-1"></a>
|
|
1309
|
-
|
|
1310
|
-
- Repository transferred to theophilusx
|
|
1311
|
-
- Fix error in package.json pointing to wrong repository
|
|
1312
|
-
|
|
1313
|
-
### v2.5.1<a id="sec-8-22-2"></a>
|
|
1314
|
-
|
|
1315
|
-
- Apply 4 pull requests to address minor issues prior to transfer
|
|
1316
|
-
|
|
1317
|
-
### v2.5.0<a id="sec-8-22-3"></a>
|
|
1318
|
-
|
|
1319
|
-
- ???
|
|
1320
|
-
|
|
1321
|
-
### v2.4.3<a id="sec-8-22-4"></a>
|
|
1322
|
-
|
|
1323
|
-
- merge #108, #110
|
|
1324
|
-
- fix connect promise if connection ends
|
|
1325
|
-
|
|
1326
|
-
### v2.4.2<a id="sec-8-22-5"></a>
|
|
1327
|
-
|
|
1328
|
-
- merge #105
|
|
1329
|
-
- fix windows path
|
|
1330
|
-
|
|
1331
|
-
### v2.4.1<a id="sec-8-22-6"></a>
|
|
1332
|
-
|
|
1333
|
-
- merge pr #99, #100
|
|
1334
|
-
- bug fix
|
|
1335
|
-
|
|
1336
|
-
### v2.4.0<a id="sec-8-22-7"></a>
|
|
1337
|
-
|
|
1338
|
-
- Requires node.js v7.5.0 or above.
|
|
1339
|
-
- merge pr #97, thanks for @theophilusx
|
|
1340
|
-
- Remove emitter.maxListener warnings
|
|
1341
|
-
- Upgraded ssh2 dependency from 0.5.5 to 0.6.1
|
|
1342
|
-
- Enhanced error messages to provide more context and to be more consistent
|
|
1343
|
-
- re-factored test
|
|
1344
|
-
- Added new 'exists' method and re-factored mkdir/rmdir
|
|
1345
|
-
|
|
1346
|
-
### v2.3.0<a id="sec-8-22-8"></a>
|
|
1347
|
-
|
|
1348
|
-
- add: `stat` method
|
|
1349
|
-
- add `fastGet` and `fastPut` method.
|
|
1350
|
-
- fix: `mkdir` file exists decision logic
|
|
1351
|
-
|
|
1352
|
-
### v3.0.0 – deprecate this version<a id="sec-8-22-9"></a>
|
|
1216
|
+
```javascript
|
|
1353
1217
|
|
|
1354
|
-
- change: `sftp.get` will return chunk not stream anymore
|
|
1355
|
-
- fix: get readable not emitting data events in node 10.0.0
|
|
1356
1218
|
|
|
1357
|
-
|
|
1219
|
+
const Throttle = require('throttle');
|
|
1220
|
+
const progress = require('progress-stream');
|
|
1358
1221
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1222
|
+
// limit download speed
|
|
1223
|
+
const throttleStream = new Throttle(config.throttle);
|
|
1361
1224
|
|
|
1362
|
-
|
|
1225
|
+
// download progress stream
|
|
1226
|
+
const progressStream = progress({
|
|
1227
|
+
length: fileSize,
|
|
1228
|
+
time: 500,
|
|
1229
|
+
});
|
|
1230
|
+
progressStream.on('progress', (progress) => {
|
|
1231
|
+
console.log(progress.percentage.toFixed(2));
|
|
1232
|
+
});
|
|
1363
1233
|
|
|
1364
|
-
|
|
1365
|
-
- update: upgrade ssh2 to V0.5.0 [pr#30](https://github.com/jyu213/ssh2-sftp-client/pull/30)
|
|
1366
|
-
- fix: get method stream error reject unwork [#22](https://github.com/jyu213/ssh2-sftp-client/issues/22)
|
|
1367
|
-
- fix: return Error object on promise rejection [pr#20](https://github.com/jyu213/ssh2-sftp-client/pull/20)
|
|
1234
|
+
const outStream = createWriteStream(localPath);
|
|
1368
1235
|
|
|
1369
|
-
|
|
1236
|
+
// pipe streams together
|
|
1237
|
+
throttleStream.pipe(progressStream).pipe(outStream);
|
|
1370
1238
|
|
|
1371
|
-
|
|
1239
|
+
try {
|
|
1240
|
+
// set autoClose to false
|
|
1241
|
+
await client.get(remotePath, throttleStream, { autoClose: false });
|
|
1242
|
+
} catch (e) {
|
|
1243
|
+
console.log('sftp error', e);
|
|
1244
|
+
} finally {
|
|
1245
|
+
await client.end();
|
|
1246
|
+
}
|
|
1247
|
+
```
|
|
1372
1248
|
|
|
1373
|
-
|
|
1249
|
+
# Examples<a id="sec-8"></a>
|
|
1374
1250
|
|
|
1375
|
-
|
|
1376
|
-
- change: remove `this.client.sftp` to `connect` function
|
|
1251
|
+
I have started collecting example scripts in the example directory of the repository. These are mainly scripts I have put together in order to investigate issues or provide samples for users. They are not robust, lack adequate error handling and may contain errors. However, I think they are still useful for helping developers see how the module and API can be used.
|
|
1377
1252
|
|
|
1378
1253
|
# Troubleshooting<a id="sec-9"></a>
|
|
1379
1254
|
|
|
@@ -1407,7 +1282,7 @@ sftp.connect(config)
|
|
|
1407
1282
|
});
|
|
1408
1283
|
```
|
|
1409
1284
|
|
|
1410
|
-
In the above code, the `sftp.end()` method will almost certainly be called before `sftp.
|
|
1285
|
+
In the above code, the `sftp.end()` method will almost certainly be called before `sftp.fastGet()` has been fulfilled (unless the *foo.txt* file is really small!). In fact, the whole promise chain will complete and exit even before the `sftp.end()` call has been fulfilled. The correct code would be something like
|
|
1411
1286
|
|
|
1412
1287
|
```javascript
|
|
1413
1288
|
sftp.connect(config)
|
|
@@ -1508,6 +1383,18 @@ node script.js 2> debug.log
|
|
|
1508
1383
|
|
|
1509
1384
|
```
|
|
1510
1385
|
|
|
1386
|
+
If you just want to see debug messages from `ssh2-sftp-client` and exclude debug messages from the underlying `ssh2` and `ssh2-streams` modules, you can filter based on messages which start with 'CLIENT' e.g.
|
|
1387
|
+
|
|
1388
|
+
```javascript
|
|
1389
|
+
{
|
|
1390
|
+
debug: (msg) => {
|
|
1391
|
+
if (msg.startsWith('CLIENT')) {
|
|
1392
|
+
console.error(msg);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
```
|
|
1397
|
+
|
|
1511
1398
|
# Logging Issues<a id="sec-10"></a>
|
|
1512
1399
|
|
|
1513
1400
|
Please log an issue for all bugs, questions, feature and enhancement requests. Please ensure you include the module version, node version and platform.
|
|
@@ -1544,3 +1431,6 @@ Thanks to the following for their contributions -
|
|
|
1544
1431
|
- **waldyrious:** Documentation fixes
|
|
1545
1432
|
- **james-pellow:** Cleanup and fix for connect method logic
|
|
1546
1433
|
- **jhorbulyk:** Contributed posixRename() functionality
|
|
1434
|
+
- **teenangst:** Contributed fix for error code 4 in stat() method
|
|
1435
|
+
- **kennylbj:** Contributed example of using a throttle stream to limit upload/download bandwidth.
|
|
1436
|
+
- **anton-erofeev:** Documentation fix
|