ssh2-sftp-client 9.0.1 → 9.0.4
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/README.md +368 -432
- package/README.org +69 -44
- package/package.json +2 -2
- package/src/index.js +50 -122
- package/src/utils.js +38 -25
package/README.org
CHANGED
|
@@ -9,13 +9,35 @@ convenience abstraction as well as a Promise based API.
|
|
|
9
9
|
Documentation on the methods and available options in the underlying modules can
|
|
10
10
|
be found on the [[https://github.com/mscdex/ssh2][SSH2]] project pages.
|
|
11
11
|
|
|
12
|
-
Current stable release is *v9.0.
|
|
12
|
+
Current stable release is *v9.0.4*.
|
|
13
13
|
|
|
14
|
-
Code has been tested against Node versions 14.
|
|
14
|
+
Code has been tested against Node versions 14.20.0, 16.17.2 and 18.8.0
|
|
15
15
|
|
|
16
16
|
Node versions < 14.x are not supported.
|
|
17
17
|
|
|
18
18
|
** Version 9.x Changes
|
|
19
|
+
- Fix bug in ~connect()~ method when private key data was corrupted. The method was not
|
|
20
|
+
handling errors fro corrupted ssh private keys and would hang indefinitely without
|
|
21
|
+
reporting any error. Now reports that it was unable to parse the private key.
|
|
22
|
+
- Fix bug in ~end()~ method where it was possible for the module to attempt calling
|
|
23
|
+
the underlying ssh2 ~end()~ method when ssh2 has not been initialised. This could
|
|
24
|
+
lead to undefined reference errors.
|
|
25
|
+
- Fix bug in ~get()~ method where supplied destination streams were not close, creating
|
|
26
|
+
a possible resource leak. If the remote file did not exist, the method would return
|
|
27
|
+
an error, but failed to close any passed in stream supplied as the destination for
|
|
28
|
+
the data in the ~get()~ call.
|
|
29
|
+
- Change the default end and close handlers not to throw error or reject
|
|
30
|
+
promises. Previously, an end or close event would cause an error to be raised or a
|
|
31
|
+
promise to be rejected if the event was deemed to be /unexpected/. However,
|
|
32
|
+
classification of events as being unexpected was unreliable and didn't add much real
|
|
33
|
+
value. Both these handlers will now invalidate the SFTP connection object and log that
|
|
34
|
+
the event fired and nothing else.
|
|
35
|
+
- Changed when event handled flags are reset. Now they are reset after a new set of
|
|
36
|
+
temporary listeners are added.
|
|
37
|
+
- Don't throw an error when calling end() if there is no active SFTP connection. It does
|
|
38
|
+
no harm to call end() when there is no connection, so no need to raise an error.
|
|
39
|
+
- Use nullish coalescing when setting retry parameters instead of or'ing with
|
|
40
|
+
defaults. Allows setting values to 0.
|
|
19
41
|
- *Breaking Change*: This version uses syntax not supported in node versions
|
|
20
42
|
prior to v14. Therefore, node versions less than v14 will not work.
|
|
21
43
|
- *Breaking Change*: This ~list()~ method no longer accepts a regular expression
|
|
@@ -38,20 +60,20 @@ Node versions < 14.x are not supported.
|
|
|
38
60
|
select which directories and files to be transferred. The 3rd argument is
|
|
39
61
|
now an options object with two supported properties, ~filter~ and ~useFastput~
|
|
40
62
|
(for ~uploadDir()~) or ~useFastget~ (for ~downloadDir()~). If ~useFastput~ is true,
|
|
41
|
-
the ~fastPut()~ method will be
|
|
63
|
+
the ~fastPut()~ method will be used to upload files. If ~false~ or missing, the
|
|
42
64
|
slower, but better supported, ~put()~ method will be used. Likewise, the
|
|
43
65
|
~useFastget~ options can be set to ~true~ to use the ~fastGet()~ method for
|
|
44
|
-
|
|
66
|
+
downloading files, otherwise the slower, but more reliable, ~get()~ method
|
|
45
67
|
will be used.
|
|
46
|
-
- The ~uploadDir()~ and ~downloadDir()~ methods now use
|
|
68
|
+
- The ~uploadDir()~ and ~downloadDir()~ methods now use asynchronous processes to
|
|
47
69
|
upload/download files. This should result in improved performance for these
|
|
48
70
|
two methods.
|
|
49
71
|
- New Methods: Two new methods, ~createWriteStream()~ and ~createReadStream()~
|
|
50
72
|
have been added. These methods will return a stream object connected to a
|
|
51
|
-
remote file on the ~
|
|
73
|
+
remote file on the ~SFTP~ server. Client code is responsible for managing
|
|
52
74
|
these stream objects. This includes adding any necessary event listeners and
|
|
53
75
|
disposing of the objects once finished with them.
|
|
54
|
-
-
|
|
76
|
+
- Re-factoring of Listeners: The library manages temporary listeners in order
|
|
55
77
|
to provide a way to catch events and processes them inside a ~Promise~
|
|
56
78
|
context. Previously, every method added its own set of temporary listeners.
|
|
57
79
|
However, this could result in multiple sets of listeners being added,
|
|
@@ -65,7 +87,7 @@ Node versions < 14.x are not supported.
|
|
|
65
87
|
* Installation
|
|
66
88
|
|
|
67
89
|
#+begin_src shell
|
|
68
|
-
npm install ssh2-sftp-client
|
|
90
|
+
npm install ssh2-sftp-client
|
|
69
91
|
#+end_src
|
|
70
92
|
|
|
71
93
|
* Basic Usage
|
|
@@ -132,7 +154,7 @@ All the methods will return a Promise, except for ~on()~ and
|
|
|
132
154
|
more robust.
|
|
133
155
|
|
|
134
156
|
When specifying file paths, ensure to include a full path i.e. include the
|
|
135
|
-
remote
|
|
157
|
+
remote file name. Don't expect the module to append the local file name to the
|
|
136
158
|
path you provide. For example, the following will not work
|
|
137
159
|
|
|
138
160
|
#+begin_src javascript
|
|
@@ -140,7 +162,7 @@ All the methods will return a Promise, except for ~on()~ and
|
|
|
140
162
|
#+end_src
|
|
141
163
|
|
|
142
164
|
will not result in the file ~test.txt~ being copied to
|
|
143
|
-
~/remote/dir/test.txt~. You need to specify the target
|
|
165
|
+
~/remote/dir/test.txt~. You need to specify the target file name as well e.g.
|
|
144
166
|
|
|
145
167
|
#+begin_src javascript
|
|
146
168
|
client.put('/home/fred/test.txt', '/remote/dir/test.txt');
|
|
@@ -330,21 +352,6 @@ The objects in the array returned by ~list()~ have the following properties;
|
|
|
330
352
|
}
|
|
331
353
|
#+end_src
|
|
332
354
|
|
|
333
|
-
**** Pattern Filter
|
|
334
|
-
|
|
335
|
-
The filter options can be a regular expression (most powerful option) or a
|
|
336
|
-
simple /glob/-like string where * will match any number of characters, e.g.
|
|
337
|
-
|
|
338
|
-
#+begin_example
|
|
339
|
-
foo* => foo, foobar, foobaz
|
|
340
|
-
,*bar => bar, foobar, tabbar
|
|
341
|
-
,*oo* => foo, foobar, look, book
|
|
342
|
-
#+end_example
|
|
343
|
-
|
|
344
|
-
The /glob/-style matching is very simple. In most cases, you are best off using
|
|
345
|
-
a real regular expression which will allow you to do more powerful matching and
|
|
346
|
-
anchor matches to the beginning/end of the string etc.
|
|
347
|
-
|
|
348
355
|
*** exists(path) ==> boolean
|
|
349
356
|
|
|
350
357
|
Tests to see if remote file or directory exists. Returns type of remote object
|
|
@@ -820,11 +827,11 @@ necessary permissions to modify the remote file.
|
|
|
820
827
|
This method uses the openssh POSIX rename extension introduced in OpenSSH 4.8.
|
|
821
828
|
The advantage of this version of rename over standard SFTP rename is that it is
|
|
822
829
|
an atomic operation and will allow renaming a resource where the destination
|
|
823
|
-
name exists. The POSIX rename will also work on some
|
|
830
|
+
name exists. The POSIX rename will also work on some file systems which do not
|
|
824
831
|
support standard SFTP rename because they don't support the system hardlink()
|
|
825
832
|
call. The POSIX rename extension is available on all openSSH servers from 4.8
|
|
826
833
|
and some other implementations. This is an extension to the standard SFTP
|
|
827
|
-
protocol and therefore is not supported on all
|
|
834
|
+
protocol and therefore is not supported on all sftp servers.
|
|
828
835
|
|
|
829
836
|
- fromPath :: string. Path to existing file to be renamed.
|
|
830
837
|
- toPath :: string. Path for new name. If it already exists, it will be replaced
|
|
@@ -997,7 +1004,7 @@ required. All sub directories within ~srcDir~ will also be copied. Any existing
|
|
|
997
1004
|
files in the local path will be overwritten. No files in the local path will be
|
|
998
1005
|
deleted.
|
|
999
1006
|
|
|
1000
|
-
The method also
|
|
1007
|
+
The method also emits ~download~ events to provide a way to monitor download
|
|
1001
1008
|
progress. The download event listener is called with one argument, an object
|
|
1002
1009
|
with two properties, source and destination. The source property is the path to
|
|
1003
1010
|
the remote file that has been downloaded and the destination is the local path
|
|
@@ -1026,7 +1033,7 @@ services.
|
|
|
1026
1033
|
function is called for each item in the download path and should return true
|
|
1027
1034
|
to include the item and false to exclude it in the download. The ~useFastget~
|
|
1028
1035
|
property is a boolean. If true, the ~fastGet()~ method will be used to transfer
|
|
1029
|
-
files. If ~false~ (the default), the slower but better supported ~get()~
|
|
1036
|
+
files. If ~false~ (the default), the slower but better supported ~get()~ method is
|
|
1030
1037
|
used. .
|
|
1031
1038
|
|
|
1032
1039
|
**** Example
|
|
@@ -1077,7 +1084,6 @@ services.
|
|
|
1077
1084
|
|
|
1078
1085
|
#+end_src
|
|
1079
1086
|
|
|
1080
|
-
|
|
1081
1087
|
*** createReadStream(remotePath, options)) ==> stream object
|
|
1082
1088
|
|
|
1083
1089
|
Returns a read stream object which is attached to the remote file specified by
|
|
@@ -1095,19 +1101,19 @@ services.
|
|
|
1095
1101
|
- autoClose :: defaults to true. If set to false, client code is responsible
|
|
1096
1102
|
for closing file descriptors when finished
|
|
1097
1103
|
- start :: Default 0. Position to start reading bytes from (inclusive)
|
|
1098
|
-
- end ::
|
|
1104
|
+
- end :: Position to stop reading bytes (inclusive).
|
|
1099
1105
|
|
|
1100
1106
|
*** createWriteStream(remotePath, options) ==> stream object
|
|
1101
1107
|
|
|
1102
1108
|
Returns a write stream object which is attached to the remote file specified
|
|
1103
|
-
in the ~remotePath~ argument. This is a low
|
|
1109
|
+
in the ~remotePath~ argument. This is a low level function which just returns
|
|
1104
1110
|
the stream object. Client code is fully responsible for managing that object,
|
|
1105
|
-
including closing any file
|
|
1111
|
+
including closing any file descriptors and removing listeners etc.
|
|
1106
1112
|
|
|
1107
1113
|
- remotePath :: Path to the remote file specified as a string
|
|
1108
1114
|
- options :: An object containing stream options. Supported properties include
|
|
1109
1115
|
- flags :: default 'w'
|
|
1110
|
-
- encoding ::
|
|
1116
|
+
- encoding :: default null
|
|
1111
1117
|
- mode :: 0o666
|
|
1112
1118
|
- autoClose :: true
|
|
1113
1119
|
- start :: Byte position to start writing from (inclusive). May require
|
|
@@ -1115,13 +1121,13 @@ services.
|
|
|
1115
1121
|
|
|
1116
1122
|
*** rcopy(srcPath, dstPath) ==> string
|
|
1117
1123
|
|
|
1118
|
-
|
|
1124
|
+
Perform a remote file copy. The file identified by the ~srcPath~ argument will
|
|
1119
1125
|
be copied to the file specified as the ~dstPath~ argument. The directory where
|
|
1120
1126
|
~dstPath~ will be placed must exist, but the actual file must not i.e. no
|
|
1121
1127
|
overwrites allowed.
|
|
1122
1128
|
|
|
1123
1129
|
- srcPath :: Path to remote file to be copied specified as a string
|
|
1124
|
-
- dstPath :: Path to where the copy will be
|
|
1130
|
+
- dstPath :: Path to where the copy will be created specified as a string
|
|
1125
1131
|
|
|
1126
1132
|
*** end() ==> boolean
|
|
1127
1133
|
|
|
@@ -1175,7 +1181,7 @@ the ~end()~ method automatically removes all listeners from the client object.
|
|
|
1175
1181
|
All SFTP servers and platforms are not equal. Some facilities provided by
|
|
1176
1182
|
~ssh2-sftp-client~ either depend on capabilities of the remote server or the
|
|
1177
1183
|
underlying capabilities of the remote server platform. As an example,
|
|
1178
|
-
consider ~chmod()~. This command depends on a remote
|
|
1184
|
+
consider ~chmod()~. This command depends on a remote file system which
|
|
1179
1185
|
implements the 'nix' concept of users and groups. The /win32/ platform does
|
|
1180
1186
|
not have the same concept of users and groups, so ~chmod()~ will not behave
|
|
1181
1187
|
in the same way.
|
|
@@ -1190,6 +1196,25 @@ the ~end()~ method automatically removes all listeners from the client object.
|
|
|
1190
1196
|
additional steps to simulate missing functionality etc. You want to use a CLI
|
|
1191
1197
|
program which does as little as possible.
|
|
1192
1198
|
|
|
1199
|
+
** Issues with ~fastPut()~ and ~fastGet()~ Methods
|
|
1200
|
+
|
|
1201
|
+
The ~fastPut()~ and ~fastGet()~ methods are known to be somewhat dependent on
|
|
1202
|
+
SFTP server capabilities. Some SFTP servers just do not work correctly with
|
|
1203
|
+
concurrent connections and some are known to have issues with negotiating
|
|
1204
|
+
packet sizes. These issues can sometimes be resolved by tweaking the options
|
|
1205
|
+
supplied to the methods, such as setting number of concurrent connections or
|
|
1206
|
+
a specific packet size.
|
|
1207
|
+
|
|
1208
|
+
To see an example of the type of issues you can observe with ~fastPut()~ or
|
|
1209
|
+
~fastGet()~, have a look at [[https://github.com/theophilusx/ssh2-sftp-client/issues/407][issue 407]], which describes the experiences of one
|
|
1210
|
+
user. Bottom line, when it works, it tends to work well and be significantly
|
|
1211
|
+
faster than using just ~get()~ or ~put()~. However, when developing code to
|
|
1212
|
+
run against different SFTP servers, especially where you are unable to test
|
|
1213
|
+
against each server, you are likely better off just using ~get()~ and ~put()~
|
|
1214
|
+
or structuring your code so that users can select which method to use (this
|
|
1215
|
+
is what =ssh2-sftp-client= does - for example, see the ~!downloadDir()~ and
|
|
1216
|
+
~uploadDir()~ methods.
|
|
1217
|
+
|
|
1193
1218
|
** Promises, Events & Managing Exceptions
|
|
1194
1219
|
|
|
1195
1220
|
One of the challenges in providing a Promise based API over a module like
|
|
@@ -1204,7 +1229,7 @@ the ~end()~ method automatically removes all listeners from the client object.
|
|
|
1204
1229
|
=resolve= and =reject=. Only one can be called - once you call =resolve=, you
|
|
1205
1230
|
cannot call =reject= (well, you can call it, but it won't have any impact on
|
|
1206
1231
|
the fulfilment status of the promise). The problem arises when an event, for
|
|
1207
|
-
|
|
1232
|
+
example an =error= event is fired either after you have resolved a promise or
|
|
1208
1233
|
possibly in-between promises. If you don't catch the =error= event, your
|
|
1209
1234
|
script will likely crash with an =uncaught exception= error.
|
|
1210
1235
|
|
|
@@ -1226,7 +1251,7 @@ the ~end()~ method automatically removes all listeners from the client object.
|
|
|
1226
1251
|
|
|
1227
1252
|
To handle this, =ssh2-sftp-client= implements a couple of strategies.
|
|
1228
1253
|
Firstly, when you call one of the module's methods, it adds =error=, =end=
|
|
1229
|
-
and =close= event listeners which will call the =reject=
|
|
1254
|
+
and =close= event listeners which will call the =reject= method on the
|
|
1230
1255
|
enclosing promise. It also keeps track of whether an error has been handled
|
|
1231
1256
|
and if it has, it ignores any subsequent errors until the promise ends.
|
|
1232
1257
|
Typically, the first error caught has the most relevant information and any
|
|
@@ -1243,7 +1268,7 @@ the ~end()~ method automatically removes all listeners from the client object.
|
|
|
1243
1268
|
until all events have been caught.
|
|
1244
1269
|
|
|
1245
1270
|
The other area where additional events are fired is during the end() call. To
|
|
1246
|
-
deal with these events, the =end()= method
|
|
1271
|
+
deal with these events, the =end()= method sets up listeners which will
|
|
1247
1272
|
simply ignore additional =error=, =end= and =close= events. It is assumed
|
|
1248
1273
|
that once you have called =end()= you really only care about any main error
|
|
1249
1274
|
which occurs and no longer care about other errors that may be raised as the
|
|
@@ -1328,7 +1353,7 @@ openSSH is =10:30:60=, so you really just need to have enough delay to ensure
|
|
|
1328
1353
|
that the 1st connection has completed authentication before the 11th connection
|
|
1329
1354
|
is attempted.
|
|
1330
1355
|
|
|
1331
|
-
** How can I pass
|
|
1356
|
+
** How can I pass writeable stream as dst for get method?
|
|
1332
1357
|
|
|
1333
1358
|
If the dst argument passed to the get method is a writeable stream, the remote
|
|
1334
1359
|
file will be piped into that writeable. If the writeable you pass in is a
|
|
@@ -1473,7 +1498,7 @@ documentation for details. Getting these parameters correct usually resolves the
|
|
|
1473
1498
|
issue.
|
|
1474
1499
|
|
|
1475
1500
|
When encountering this type of problem, one worthwhile approach is to use
|
|
1476
|
-
openSSH's CLI sftp program with the =-v= switch to raise
|
|
1501
|
+
openSSH's CLI sftp program with the =-v= switch to raise logging levels. This
|
|
1477
1502
|
will show you what algorithms the CLI is using. You can then use this
|
|
1478
1503
|
information to match the names with the accepted algorithm names documented in
|
|
1479
1504
|
the =ssh2= README to set the properties in the =algorithms= object.
|
|
@@ -1581,7 +1606,7 @@ the ~ssh2-sftp-client~ wrapper module.
|
|
|
1581
1606
|
** Common Errors
|
|
1582
1607
|
|
|
1583
1608
|
There are some common errors people tend to make when using Promises or
|
|
1584
|
-
|
|
1609
|
+
Async/Await. These are by far the most common problem found in issues logged
|
|
1585
1610
|
against this module. Please check for some of these before logging your
|
|
1586
1611
|
issue.
|
|
1587
1612
|
|
|
@@ -1721,7 +1746,7 @@ the ~ssh2-sftp-client~ wrapper module.
|
|
|
1721
1746
|
|
|
1722
1747
|
The basic problem is that the try/catch block will have completed execution
|
|
1723
1748
|
before the asynchronous code has completed. If the asynchronous code has not
|
|
1724
|
-
|
|
1749
|
+
completed, then there is a potential for it to raise an error. However, as
|
|
1725
1750
|
the try/catch block has already completed, there is no /catch/ waiting to
|
|
1726
1751
|
catch the error. It will bubble up and probably result in your script
|
|
1727
1752
|
exiting with an uncaught exception error.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ssh2-sftp-client",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.4",
|
|
4
4
|
"description": "ssh2 sftp client for node",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"eslint-plugin-mocha": "^10.0.3",
|
|
41
41
|
"eslint-plugin-node": "^11.1.0",
|
|
42
42
|
"eslint-plugin-promise": "^6.0.0",
|
|
43
|
-
"eslint-plugin-unicorn": "^
|
|
43
|
+
"eslint-plugin-unicorn": "^43.0.2",
|
|
44
44
|
"mocha": "^10.0.0",
|
|
45
45
|
"moment": "^2.29.1",
|
|
46
46
|
"nyc": "^15.1.0",
|