ssh2-sftp-client 9.0.2 → 9.0.3

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.
Files changed (4) hide show
  1. package/README.md +123 -131
  2. package/README.org +7 -15
  3. package/package.json +2 -2
  4. package/src/index.js +14 -11
package/README.md CHANGED
@@ -1,66 +1,66 @@
1
- - [Overview](#org50de852)
2
- - [Version 9.x Changes](#orgaeda8f1)
3
- - [Installation](#orgf01877e)
4
- - [Basic Usage](#org5950004)
5
- - [Documentation](#org5057006)
6
- - [Specifying Paths](#org4ef62d6)
7
- - [Methods](#org197917e)
8
- - [new SftpClient(name) ===> SFTP client object](#orge668bfa)
9
- - [connect(config) ===> SFTP object](#orgcf80c45)
10
- - [list(path, filter) ==> Array[object]](#org329ff56)
11
- - [exists(path) ==> boolean](#orgc52d8a8)
12
- - [stat(path) ==> object](#orgcfa8682)
13
- - [get(path, dst, options) ==> String|Stream|Buffer](#orgbe46842)
14
- - [fastGet(remotePath, localPath, options) ===> string](#org740cf5c)
15
- - [put(src, remotePath, options) ==> string](#org429e96a)
16
- - [fastPut(localPath, remotePath, options) ==> string](#orgcab50c6)
17
- - [append(input, remotePath, options) ==> string](#orgc15d676)
18
- - [mkdir(path, recursive) ==> string](#org6fab860)
19
- - [rmdir(path, recursive) ==> string](#org520f6bc)
20
- - [delete(path, noErrorOK) ==> string](#org1be8ca9)
21
- - [rename(fromPath, toPath) ==> string](#org3d89131)
22
- - [posixRename(fromPath, toPath) ==> string](#org58dfee5)
23
- - [chmod(path, mode) ==> string](#orgb319965)
24
- - [realPath(path) ===> string](#orgf665476)
25
- - [cwd() ==> string](#org409acd1)
26
- - [uploadDir(srcDir, dstDir, options) ==> string](#org668b085)
27
- - [downloadDir(srcDir, dstDir, options) ==> string](#org395ac4e)
28
- - [createReadStream(remotePath, options)) ==> stream object](#org8a73b83)
29
- - [createWriteStream(remotePath, options) ==> stream object](#orgb71fb72)
30
- - [rcopy(srcPath, dstPath) ==> string](#org936f530)
31
- - [end() ==> boolean](#org62a8323)
32
- - [Add and Remove Listeners](#orgd1ebc36)
33
- - [Platform Quirks & Warnings](#orgdfff943)
34
- - [Server Capabilities](#org886fe2e)
35
- - [Issues with `fastPut()` and `fastGet()` Methods](#org1719a52)
36
- - [Promises, Events & Managing Exceptions](#org42a51fc)
37
- - [Adding Custom Handlers](#orgd50a35a)
38
- - [Windows Based Servers](#org7b0987f)
39
- - [Don't Re-use SftpClient Objects](#orgbe548c2)
40
- - [FAQ](#orgfddb94b)
41
- - [Remote server drops connections with only an end event](#orgbd2a31e)
42
- - [How can I pass writable stream as dst for get method?](#org9d72a61)
43
- - [How can I upload files without having to specify a password?](#org9fda086)
44
- - [How can I connect through a Socks Proxy](#org2ccc5e8)
45
- - [Timeout while waiting for handshake or handshake errors](#org5306b6f)
46
- - [How can I limit upload/download speed](#org3a77529)
47
- - [Connection hangs or fails for larger files](#org68eedc7)
48
- - [Examples](#orgd436fa7)
49
- - [Troubleshooting](#orge21d870)
50
- - [Common Errors](#org287b86f)
51
- - [Not returning the promise in a `then()` block](#org20a99bb)
52
- - [Mixing Promise Chains and Async/Await](#org51482b4)
53
- - [Try/catch and Error Handlers](#orgb9a556a)
54
- - [Server Differences](#org0d148f0)
55
- - [Avoid Concurrent Operations](#orgf115391)
56
- - [Debugging Support](#orgc7c437f)
57
- - [Logging Issues](#orgc79ef28)
58
- - [Pull Requests](#org64bd2a2)
59
- - [Contributors](#org709b0f9)
60
-
61
-
62
-
63
- <a id="org50de852"></a>
1
+ - [Overview](#orgd38e3db)
2
+ - [Version 9.x Changes](#orgbc6dbf7)
3
+ - [Installation](#org8538ac8)
4
+ - [Basic Usage](#org0e586d6)
5
+ - [Documentation](#org8b956c0)
6
+ - [Specifying Paths](#orge4d511d)
7
+ - [Methods](#org54a5a5f)
8
+ - [new SftpClient(name) ===> SFTP client object](#org7e1be88)
9
+ - [connect(config) ===> SFTP object](#org4d439ac)
10
+ - [list(path, filter) ==> Array[object]](#org1cdf979)
11
+ - [exists(path) ==> boolean](#org27dfbbb)
12
+ - [stat(path) ==> object](#org989df3b)
13
+ - [get(path, dst, options) ==> String|Stream|Buffer](#orgc4730e8)
14
+ - [fastGet(remotePath, localPath, options) ===> string](#org2f58141)
15
+ - [put(src, remotePath, options) ==> string](#org6859ddc)
16
+ - [fastPut(localPath, remotePath, options) ==> string](#org62993ea)
17
+ - [append(input, remotePath, options) ==> string](#orgbac60b5)
18
+ - [mkdir(path, recursive) ==> string](#orgf266033)
19
+ - [rmdir(path, recursive) ==> string](#orgcb249fd)
20
+ - [delete(path, noErrorOK) ==> string](#orgfef0bf5)
21
+ - [rename(fromPath, toPath) ==> string](#org916cc1f)
22
+ - [posixRename(fromPath, toPath) ==> string](#org590854d)
23
+ - [chmod(path, mode) ==> string](#orgf437cd4)
24
+ - [realPath(path) ===> string](#org22161d6)
25
+ - [cwd() ==> string](#orgdba7a3a)
26
+ - [uploadDir(srcDir, dstDir, options) ==> string](#org583c51e)
27
+ - [downloadDir(srcDir, dstDir, options) ==> string](#orgc06694a)
28
+ - [createReadStream(remotePath, options)) ==> stream object](#org5163593)
29
+ - [createWriteStream(remotePath, options) ==> stream object](#orgbeba46f)
30
+ - [rcopy(srcPath, dstPath) ==> string](#orgfab48e5)
31
+ - [end() ==> boolean](#org9ffad87)
32
+ - [Add and Remove Listeners](#org5c294b3)
33
+ - [Platform Quirks & Warnings](#org6e33ff1)
34
+ - [Server Capabilities](#org0b56fde)
35
+ - [Issues with `fastPut()` and `fastGet()` Methods](#org7c6eba4)
36
+ - [Promises, Events & Managing Exceptions](#org38e15f9)
37
+ - [Adding Custom Handlers](#org10f1f65)
38
+ - [Windows Based Servers](#org7057905)
39
+ - [Don't Re-use SftpClient Objects](#org1775ff2)
40
+ - [FAQ](#org683ae73)
41
+ - [Remote server drops connections with only an end event](#org7e12a90)
42
+ - [How can I pass writable stream as dst for get method?](#org7f93e7e)
43
+ - [How can I upload files without having to specify a password?](#org6f24d1a)
44
+ - [How can I connect through a Socks Proxy](#org59a22c0)
45
+ - [Timeout while waiting for handshake or handshake errors](#org0439a3c)
46
+ - [How can I limit upload/download speed](#orge773153)
47
+ - [Connection hangs or fails for larger files](#orgf14374e)
48
+ - [Examples](#orge58bfb0)
49
+ - [Troubleshooting](#org5c3ee29)
50
+ - [Common Errors](#orgd46a3a1)
51
+ - [Not returning the promise in a `then()` block](#org41486a0)
52
+ - [Mixing Promise Chains and Async/Await](#org36f96d6)
53
+ - [Try/catch and Error Handlers](#org367d856)
54
+ - [Server Differences](#org180dea0)
55
+ - [Avoid Concurrent Operations](#org2bfd976)
56
+ - [Debugging Support](#org9590bf5)
57
+ - [Logging Issues](#orga4f395e)
58
+ - [Pull Requests](#orgbed06d9)
59
+ - [Contributors](#org7b575e4)
60
+
61
+
62
+
63
+ <a id="orgd38e3db"></a>
64
64
 
65
65
  # Overview
66
66
 
@@ -75,10 +75,12 @@ Code has been tested against Node versions 14.19.1, 16.15.0 and 18.1.0
75
75
  Node versions < 14.x are not supported.
76
76
 
77
77
 
78
- <a id="orgaeda8f1"></a>
78
+ <a id="orgbc6dbf7"></a>
79
79
 
80
80
  ## Version 9.x Changes
81
81
 
82
+ - Fix bug in `end()` method where it was possible for the module to attempt calling the underlying ssh2 `end()` method when ssh2 has not been initialised. This could lead to undefined reference errors.
83
+ - Fix bug in `get()` method where supplied destination streams were not close, creating a possible resource leak. If the remote file did not exist, the method would return an error, but failed to close any passed in stream supplied as the destination for the data in the `get()` call.
82
84
  - Change the default end and close handlers not to throw error or reject promises. Previously, an end or close event would cause an error to be raised or a promise to be rejected if the event was deemed to be *unexpected*. However, classification of events as being unexpected was unreliable and didn't add much real value. Both these handlers will now invalidate the sftp connection object and log that the event fired and nothing else.
83
85
  - Changed when event handled flags are reset. Now they are reset after a new set of temporary listeners are added.
84
86
  - Don't throw an error when calling end() if there is no active sftp connection. It does no harm to call end() when there is no connection, so no need to raise an error.
@@ -94,7 +96,7 @@ Node versions < 14.x are not supported.
94
96
  - Bumped ssh2 version to 1.11.0
95
97
 
96
98
 
97
- <a id="orgf01877e"></a>
99
+ <a id="org8538ac8"></a>
98
100
 
99
101
  # Installation
100
102
 
@@ -103,7 +105,7 @@ npm install ssh2-sftp-client
103
105
  ```
104
106
 
105
107
 
106
- <a id="org5950004"></a>
108
+ <a id="org0e586d6"></a>
107
109
 
108
110
  # Basic Usage
109
111
 
@@ -126,7 +128,7 @@ sftp.connect({
126
128
  ```
127
129
 
128
130
 
129
- <a id="org5057006"></a>
131
+ <a id="org8b956c0"></a>
130
132
 
131
133
  # Documentation
132
134
 
@@ -135,7 +137,7 @@ The connection options are the same as those offered by the underlying SSH2 modu
135
137
  All the methods will return a Promise, except for `on()` and `removeListener()`, which are typically only used in special use cases.
136
138
 
137
139
 
138
- <a id="org4ef62d6"></a>
140
+ <a id="orge4d511d"></a>
139
141
 
140
142
  ## Specifying Paths
141
143
 
@@ -168,12 +170,12 @@ client.put('/home/fred/test.txt', '/remote/dir/test-copy.txt');
168
170
  This will copy the local file `test.txt` to the remote file `test-copy.txt` in the directory `/remote/dir`.
169
171
 
170
172
 
171
- <a id="org197917e"></a>
173
+ <a id="org54a5a5f"></a>
172
174
 
173
175
  ## Methods
174
176
 
175
177
 
176
- <a id="orge668bfa"></a>
178
+ <a id="org7e1be88"></a>
177
179
 
178
180
  ### new SftpClient(name) ===> SFTP client object
179
181
 
@@ -212,7 +214,7 @@ Constructor to create a new `ssh2-sftp-client` object. An optional `name` string
212
214
  ```
213
215
 
214
216
 
215
- <a id="orgcf80c45"></a>
217
+ <a id="org4d439ac"></a>
216
218
 
217
219
  ### connect(config) ===> SFTP object
218
220
 
@@ -278,7 +280,7 @@ Connect to an sftp server. Full documentation for connection options is availabl
278
280
  ```
279
281
 
280
282
 
281
- <a id="org329ff56"></a>
283
+ <a id="org1cdf979"></a>
282
284
 
283
285
  ### list(path, filter) ==> Array[object]
284
286
 
@@ -338,18 +340,8 @@ Retrieves a directory listing. This method returns a Promise, which once realise
338
340
  }
339
341
  ```
340
342
 
341
- 3. Pattern Filter
342
343
 
343
- 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.
344
-
345
- foo* => foo, foobar, foobaz
346
- *bar => bar, foobar, tabbar
347
- *oo* => foo, foobar, look, book
348
-
349
- 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.
350
-
351
-
352
- <a id="orgc52d8a8"></a>
344
+ <a id="org27dfbbb"></a>
353
345
 
354
346
  ### exists(path) ==> boolean
355
347
 
@@ -385,7 +377,7 @@ Tests to see if remote file or directory exists. Returns type of remote object i
385
377
  ```
386
378
 
387
379
 
388
- <a id="orgcfa8682"></a>
380
+ <a id="org989df3b"></a>
389
381
 
390
382
  ### stat(path) ==> object
391
383
 
@@ -436,7 +428,7 @@ Returns the attributes associated with the object pointed to by `path`.
436
428
  ```
437
429
 
438
430
 
439
- <a id="orgbe46842"></a>
431
+ <a id="orgc4730e8"></a>
440
432
 
441
433
  ### get(path, dst, options) ==> String|Stream|Buffer
442
434
 
@@ -492,7 +484,7 @@ In general, if you're going to pass in a string as the destination, you are bett
492
484
  - **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'.
493
485
 
494
486
 
495
- <a id="org740cf5c"></a>
487
+ <a id="org2f58141"></a>
496
488
 
497
489
  ### fastGet(remotePath, localPath, options) ===> string
498
490
 
@@ -535,7 +527,7 @@ Downloads a file at remotePath to localPath using parallel reads for faster thro
535
527
  ```
536
528
 
537
529
 
538
- <a id="org429e96a"></a>
530
+ <a id="org6859ddc"></a>
539
531
 
540
532
  ### put(src, remotePath, options) ==> string
541
533
 
@@ -585,7 +577,7 @@ Upload data from local system to remote server. If the `src` argument is a strin
585
577
  - **Tip:** If the src argument is a path string, consider just using `fastPut()`.
586
578
 
587
579
 
588
- <a id="orgcab50c6"></a>
580
+ <a id="org62993ea"></a>
589
581
 
590
582
  ### fastPut(localPath, remotePath, options) ==> string
591
583
 
@@ -629,7 +621,7 @@ Uploads the data in file at `localPath` to a new file on remote server at `remot
629
621
  ```
630
622
 
631
623
 
632
- <a id="orgc15d676"></a>
624
+ <a id="orgbac60b5"></a>
633
625
 
634
626
  ### append(input, remotePath, options) ==> string
635
627
 
@@ -673,7 +665,7 @@ Append the `input` data to an existing remote file. There is no integrity checki
673
665
  ```
674
666
 
675
667
 
676
- <a id="org6fab860"></a>
668
+ <a id="orgf266033"></a>
677
669
 
678
670
  ### mkdir(path, recursive) ==> string
679
671
 
@@ -701,7 +693,7 @@ Create a new directory. If the recursive flag is set to true, the method will cr
701
693
  ```
702
694
 
703
695
 
704
- <a id="org520f6bc"></a>
696
+ <a id="orgcb249fd"></a>
705
697
 
706
698
  ### rmdir(path, recursive) ==> string
707
699
 
@@ -731,7 +723,7 @@ Remove a directory. If removing a directory and recursive flag is set to `true`,
731
723
  ```
732
724
 
733
725
 
734
- <a id="org1be8ca9"></a>
726
+ <a id="orgfef0bf5"></a>
735
727
 
736
728
  ### delete(path, noErrorOK) ==> string
737
729
 
@@ -760,7 +752,7 @@ Delete a file on the remote server.
760
752
  ```
761
753
 
762
754
 
763
- <a id="org3d89131"></a>
755
+ <a id="org916cc1f"></a>
764
756
 
765
757
  ### rename(fromPath, toPath) ==> string
766
758
 
@@ -789,7 +781,7 @@ Rename a file or directory from `fromPath` to `toPath`. You must have the necess
789
781
  ```
790
782
 
791
783
 
792
- <a id="org58dfee5"></a>
784
+ <a id="org590854d"></a>
793
785
 
794
786
  ### posixRename(fromPath, toPath) ==> string
795
787
 
@@ -816,7 +808,7 @@ client.connect(config)
816
808
  ```
817
809
 
818
810
 
819
- <a id="orgb319965"></a>
811
+ <a id="orgf437cd4"></a>
820
812
 
821
813
  ### chmod(path, mode) ==> string
822
814
 
@@ -845,7 +837,7 @@ Change the mode (read, write or execute permissions) of a remote file or directo
845
837
  ```
846
838
 
847
839
 
848
- <a id="orgf665476"></a>
840
+ <a id="org22161d6"></a>
849
841
 
850
842
  ### realPath(path) ===> string
851
843
 
@@ -856,14 +848,14 @@ Converts a relative path to an absolute path on the remote server. This method i
856
848
  - **path:** A file path, either relative or absolute. Can handle '.' and '..', but does not expand '~'.
857
849
 
858
850
 
859
- <a id="org409acd1"></a>
851
+ <a id="orgdba7a3a"></a>
860
852
 
861
853
  ### cwd() ==> string
862
854
 
863
855
  Returns what the server believes is the current remote working directory.
864
856
 
865
857
 
866
- <a id="org668b085"></a>
858
+ <a id="org583c51e"></a>
867
859
 
868
860
  ### uploadDir(srcDir, dstDir, options) ==> string
869
861
 
@@ -932,7 +924,7 @@ The `useFastput` option is a boolean option. If `true`, the method will use the
932
924
  ```
933
925
 
934
926
 
935
- <a id="org395ac4e"></a>
927
+ <a id="orgc06694a"></a>
936
928
 
937
929
  ### downloadDir(srcDir, dstDir, options) ==> string
938
930
 
@@ -997,7 +989,7 @@ If the `useFastget` property is set to `true`, the method will use `fastGet()` t
997
989
  ```
998
990
 
999
991
 
1000
- <a id="org8a73b83"></a>
992
+ <a id="org5163593"></a>
1001
993
 
1002
994
  ### createReadStream(remotePath, options)) ==> stream object
1003
995
 
@@ -1014,7 +1006,7 @@ Returns a read stream object which is attached to the remote file specified by t
1014
1006
  - **end:** Postion to stop reading bytes (inclusive).
1015
1007
 
1016
1008
 
1017
- <a id="orgb71fb72"></a>
1009
+ <a id="orgbeba46f"></a>
1018
1010
 
1019
1011
  ### createWriteStream(remotePath, options) ==> stream object
1020
1012
 
@@ -1029,7 +1021,7 @@ Returns a write stream object which is attached to the remote file specified in
1029
1021
  - **start:** Byte position to start writing from (inclusive). May require changing flag to 'r+'.
1030
1022
 
1031
1023
 
1032
- <a id="org936f530"></a>
1024
+ <a id="orgfab48e5"></a>
1033
1025
 
1034
1026
  ### rcopy(srcPath, dstPath) ==> string
1035
1027
 
@@ -1039,7 +1031,7 @@ Perfrom a remote file copy. The file identified by the `srcPath` argument will b
1039
1031
  - **dstPath:** Path to where the copy will be creaeted specified as a string
1040
1032
 
1041
1033
 
1042
- <a id="org62a8323"></a>
1034
+ <a id="org9ffad87"></a>
1043
1035
 
1044
1036
  ### end() ==> boolean
1045
1037
 
@@ -1063,7 +1055,7 @@ Ends the current client session, releasing the client socket and associated reso
1063
1055
  ```
1064
1056
 
1065
1057
 
1066
- <a id="orgd1ebc36"></a>
1058
+ <a id="org5c294b3"></a>
1067
1059
 
1068
1060
  ### Add and Remove Listeners
1069
1061
 
@@ -1084,12 +1076,12 @@ Although normally not required, you can add and remove custom listeners on the s
1084
1076
  Removes the specified listener from the event specified in eventType. Note that the `end()` method automatically removes all listeners from the client object.
1085
1077
 
1086
1078
 
1087
- <a id="orgdfff943"></a>
1079
+ <a id="org6e33ff1"></a>
1088
1080
 
1089
1081
  # Platform Quirks & Warnings
1090
1082
 
1091
1083
 
1092
- <a id="org886fe2e"></a>
1084
+ <a id="org0b56fde"></a>
1093
1085
 
1094
1086
  ## Server Capabilities
1095
1087
 
@@ -1098,7 +1090,7 @@ All SFTP servers and platforms are not equal. Some facilities provided by `ssh2-
1098
1090
  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.
1099
1091
 
1100
1092
 
1101
- <a id="org1719a52"></a>
1093
+ <a id="org7c6eba4"></a>
1102
1094
 
1103
1095
  ## Issues with `fastPut()` and `fastGet()` Methods
1104
1096
 
@@ -1107,7 +1099,7 @@ The `fastPut()` and `fastGet()` methods are known to be somewhat dependent on SF
1107
1099
  To see an example of the type of issues you can observe with `fastPut()` or `fastGet()`, have a look at [issue 407](https://github.com/theophilusx/ssh2-sftp-client/issues/407), which describes the experiences of one user. Bottom line, when it works, it tends to work well and be significantly faster than using just `get()` or `put()`. However, when developing code to run against different SFTP servers, especially where you are unable to test against each server, you are likely better off just using `get()` and `put()` or structuring your code so that users can select which method to use (this is what `ssh2-sftp-client` does - for example, see the `!downloadDir()` and `uploadDir()` methods.
1108
1100
 
1109
1101
 
1110
- <a id="org42a51fc"></a>
1102
+ <a id="org38e15f9"></a>
1111
1103
 
1112
1104
  ## Promises, Events & Managing Exceptions
1113
1105
 
@@ -1126,14 +1118,14 @@ The other area where additional events are fired is during the end() call. To de
1126
1118
  In addition to the promise based event handlers, `ssh2-sftp-client` also implements global event handlers which will catch any `error`, `end` or `close` events. Essentially, these global handlers only reset the `sftp` property of the client object, effectively ensuring any subsequent calls are rejected and in the case of an error, send the error to the console.
1127
1119
 
1128
1120
 
1129
- <a id="orgd50a35a"></a>
1121
+ <a id="org10f1f65"></a>
1130
1122
 
1131
1123
  ### Adding Custom Handlers
1132
1124
 
1133
1125
  While the above strategies appear to work for the majority of use cases, there are always going to be edge cases which require more flexible or powerful event handling. To support this, the `on()` and `removeListener()` methods are provided. Any event listener added using the `on()` method will be added at the beginning of the list of handlers for that event, ensuring it will be called before any global or promise local events. See the documentation for the `on()` method for details.
1134
1126
 
1135
1127
 
1136
- <a id="org7b0987f"></a>
1128
+ <a id="org7057905"></a>
1137
1129
 
1138
1130
  ## Windows Based Servers
1139
1131
 
@@ -1142,7 +1134,7 @@ It appears that when the sftp server is running on Windows, a *ECONNRESET* error
1142
1134
  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.
1143
1135
 
1144
1136
 
1145
- <a id="orgbe548c2"></a>
1137
+ <a id="org1775ff2"></a>
1146
1138
 
1147
1139
  ## Don't Re-use SftpClient Objects
1148
1140
 
@@ -1151,12 +1143,12 @@ Due to an issue with *ECONNRESET* error signals when connecting to Windows based
1151
1143
  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.
1152
1144
 
1153
1145
 
1154
- <a id="orgfddb94b"></a>
1146
+ <a id="org683ae73"></a>
1155
1147
 
1156
1148
  # FAQ
1157
1149
 
1158
1150
 
1159
- <a id="orgbd2a31e"></a>
1151
+ <a id="org7e12a90"></a>
1160
1152
 
1161
1153
  ## Remote server drops connections with only an end event
1162
1154
 
@@ -1167,7 +1159,7 @@ Clients first make an unauthenticated connection to the SFTP server to begin neg
1167
1159
  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.
1168
1160
 
1169
1161
 
1170
- <a id="org9d72a61"></a>
1162
+ <a id="org7f93e7e"></a>
1171
1163
 
1172
1164
  ## How can I pass writable stream as dst for get method?
1173
1165
 
@@ -1226,7 +1218,7 @@ sftp
1226
1218
  ```
1227
1219
 
1228
1220
 
1229
- <a id="org9fda086"></a>
1221
+ <a id="org6f24d1a"></a>
1230
1222
 
1231
1223
  ## How can I upload files without having to specify a password?
1232
1224
 
@@ -1261,7 +1253,7 @@ sftp.connect({
1261
1253
  ```
1262
1254
 
1263
1255
 
1264
- <a id="org2ccc5e8"></a>
1256
+ <a id="org59a22c0"></a>
1265
1257
 
1266
1258
  ## How can I connect through a Socks Proxy
1267
1259
 
@@ -1297,7 +1289,7 @@ client.connect({
1297
1289
  ```
1298
1290
 
1299
1291
 
1300
- <a id="org5306b6f"></a>
1292
+ <a id="org0439a3c"></a>
1301
1293
 
1302
1294
  ## Timeout while waiting for handshake or handshake errors
1303
1295
 
@@ -1306,7 +1298,7 @@ Some users have encountered the error 'Timeout while waiting for handshake' or '
1306
1298
  When encountering this type of problem, one worthwhile approach is to use openSSH's CLI sftp program with the `-v` switch to raise loggin levels. This will show you what algorithms the CLI is using. You can then use this information to match the names with the accepted algorithm names documented in the `ssh2` README to set the properties in the `algorithms` object.
1307
1299
 
1308
1300
 
1309
- <a id="org3a77529"></a>
1301
+ <a id="orge773153"></a>
1310
1302
 
1311
1303
  ## How can I limit upload/download speed
1312
1304
 
@@ -1346,7 +1338,7 @@ try {
1346
1338
  ```
1347
1339
 
1348
1340
 
1349
- <a id="org68eedc7"></a>
1341
+ <a id="orgf14374e"></a>
1350
1342
 
1351
1343
  ## Connection hangs or fails for larger files
1352
1344
 
@@ -1357,14 +1349,14 @@ A symptom of this issue is that you are able to upload small files, but uploadin
1357
1349
  For more explanation, see [issue #342](https://github.com/theophilusx/ssh2-sftp-client/issues/342).
1358
1350
 
1359
1351
 
1360
- <a id="orgd436fa7"></a>
1352
+ <a id="orge58bfb0"></a>
1361
1353
 
1362
1354
  # Examples
1363
1355
 
1364
1356
  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.
1365
1357
 
1366
1358
 
1367
- <a id="orge21d870"></a>
1359
+ <a id="org5c3ee29"></a>
1368
1360
 
1369
1361
  # Troubleshooting
1370
1362
 
@@ -1379,14 +1371,14 @@ Note also that in the repository there are two useful directories. The first is
1379
1371
  The second directory is the validation directory. I have some very simple scripts in this directory which perform basic tasks using only the `ssh2` modules (no `ssh2-sftp-client` module). These can be useful when trying to determine if the issue is with the underlying `ssh2` module or the `ssh2-sftp-client` wrapper module.
1380
1372
 
1381
1373
 
1382
- <a id="org287b86f"></a>
1374
+ <a id="orgd46a3a1"></a>
1383
1375
 
1384
1376
  ## Common Errors
1385
1377
 
1386
1378
  There are some common errors people tend to make when using Promises or Asyc/Await. These are by far the most common problem found in issues logged against this module. Please check for some of these before logging your issue.
1387
1379
 
1388
1380
 
1389
- <a id="org20a99bb"></a>
1381
+ <a id="org41486a0"></a>
1390
1382
 
1391
1383
  ### Not returning the promise in a `then()` block
1392
1384
 
@@ -1423,7 +1415,7 @@ Note the `return` statements. These ensure that the Promise returned by the clie
1423
1415
  A common symptom of this type of error is for file uploads or download to fail to complete or for data in those files to be truncated. What is happening is that the connection is being ended before the transfer has completed.
1424
1416
 
1425
1417
 
1426
- <a id="org51482b4"></a>
1418
+ <a id="org36f96d6"></a>
1427
1419
 
1428
1420
  ### Mixing Promise Chains and Async/Await
1429
1421
 
@@ -1483,7 +1475,7 @@ async function doSftp() {
1483
1475
  ```
1484
1476
 
1485
1477
 
1486
- <a id="orgb9a556a"></a>
1478
+ <a id="org367d856"></a>
1487
1479
 
1488
1480
  ### Try/catch and Error Handlers
1489
1481
 
@@ -1494,14 +1486,14 @@ The basic problem is that the try/catch block will have completed execution befo
1494
1486
  Error events are essentially asynchronous code. You don't know when such events will fire. Therefore, you cannot use a try/catch block to catch such event errors. Even creating an error handler which then throws an exception won't help as the key problem is that your try/catch block has already executed. There are a number of alternative ways to deal with this situation. However, the key symptom is that you see occasional uncaught error exceptions that cause your script to exit abnormally despite having try/catch blocks in your script. What you need to do is look at your code and find where errors are raised asynchronously and use an event handler or some other mechanism to manage any errors raised.
1495
1487
 
1496
1488
 
1497
- <a id="org0d148f0"></a>
1489
+ <a id="org180dea0"></a>
1498
1490
 
1499
1491
  ### Server Differences
1500
1492
 
1501
1493
  Not all SFTP servers are the same. Like most standards, the SFTP protocol has some level of interpretation and allows different levels of compliance. This means there can be differences in behaviour between different servers and code which works with one server will not work the same with another. For example, the value returned by *realpath* for non-existent objects can differ significantly. Some servers will throw an error for a particular operation while others will just return null, some servers support concurrent operations (such as used by fastGet/fastPut) while others will not and of course, the text of error messages can vary significantly. In particular, we have noticed significant differences across different platforms. It is therefore advisable to do comprehensive testing when the SFTP server is moved to a new platform. This includes moving from to a cloud based service even if the underlying platform remains the same. I have noticed that some cloud platforms can generate unexpected events, possibly related to additional functionality or features associated with the cloud implementation. For example, it appears SFTP servers running under Azure will generate an error event when the connection is closed even when the client has requested the connection be terminated. The same SFTP server running natively on Windows does not appear to exhibit such behaviour.
1502
1494
 
1503
1495
 
1504
- <a id="orgf115391"></a>
1496
+ <a id="org2bfd976"></a>
1505
1497
 
1506
1498
  ### Avoid Concurrent Operations
1507
1499
 
@@ -1510,7 +1502,7 @@ Technically, SFTP should be able to perform multiple operations concurrently. As
1510
1502
  If you are going to try and perform concurrent operations, you need to test extensively and ensure you are using data which is large enough that context switching does occur (i.e. the request is not completed in a single run). Some SFTP servers will handle concurrent operations better than others.
1511
1503
 
1512
1504
 
1513
- <a id="orgc7c437f"></a>
1505
+ <a id="org9590bf5"></a>
1514
1506
 
1515
1507
  ## Debugging Support
1516
1508
 
@@ -1543,7 +1535,7 @@ If you just want to see debug messages from `ssh2-sftp-client` and exclude debug
1543
1535
  ```
1544
1536
 
1545
1537
 
1546
- <a id="orgc79ef28"></a>
1538
+ <a id="orga4f395e"></a>
1547
1539
 
1548
1540
  # Logging Issues
1549
1541
 
@@ -1560,7 +1552,7 @@ I am happy to try and help diagnose and fix any issues you encounter while using
1560
1552
  Perhaps the best assistance is a minimal reproducible example of the issue. Once the issue can be readily reproduced, it can usually be fixed very quickly.
1561
1553
 
1562
1554
 
1563
- <a id="org64bd2a2"></a>
1555
+ <a id="orgbed06d9"></a>
1564
1556
 
1565
1557
  # Pull Requests
1566
1558
 
@@ -1575,7 +1567,7 @@ This module will adopt a standard semantic versioning policy. Please indicate in
1575
1567
  - **Bug Fix:** No change to functionality or features. Simple fix of an existing bug.
1576
1568
 
1577
1569
 
1578
- <a id="org709b0f9"></a>
1570
+ <a id="org7b575e4"></a>
1579
1571
 
1580
1572
  # Contributors
1581
1573
 
package/README.org CHANGED
@@ -16,6 +16,13 @@ Code has been tested against Node versions 14.19.1, 16.15.0 and 18.1.0
16
16
  Node versions < 14.x are not supported.
17
17
 
18
18
  ** Version 9.x Changes
19
+ - Fix bug in ~end()~ method where it was possible for the module to attempt calling
20
+ the underlying ssh2 ~end()~ method when ssh2 has not been initialised. This could
21
+ lead to undefined reference errors.
22
+ - Fix bug in ~get()~ method where supplied destination streams were not close, creating
23
+ a possible resource leak. If the remote file did not exist, the method would return
24
+ an error, but failed to close any passed in stream supplied as the destination for
25
+ the data in the ~get()~ call.
19
26
  - Change the default end and close handlers not to throw error or reject
20
27
  promises. Previously, an end or close event would cause an error to be raised or a
21
28
  promise to be rejected if the event was deemed to be /unexpected/. However,
@@ -342,21 +349,6 @@ The objects in the array returned by ~list()~ have the following properties;
342
349
  }
343
350
  #+end_src
344
351
 
345
- **** Pattern Filter
346
-
347
- The filter options can be a regular expression (most powerful option) or a
348
- simple /glob/-like string where * will match any number of characters, e.g.
349
-
350
- #+begin_example
351
- foo* => foo, foobar, foobaz
352
- ,*bar => bar, foobar, tabbar
353
- ,*oo* => foo, foobar, look, book
354
- #+end_example
355
-
356
- The /glob/-style matching is very simple. In most cases, you are best off using
357
- a real regular expression which will allow you to do more powerful matching and
358
- anchor matches to the beginning/end of the string etc.
359
-
360
352
  *** exists(path) ==> boolean
361
353
 
362
354
  Tests to see if remote file or directory exists. Returns type of remote object
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ssh2-sftp-client",
3
- "version": "9.0.2",
3
+ "version": "9.0.3",
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": "^42.0.0",
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",
package/src/index.js CHANGED
@@ -221,16 +221,16 @@ class SftpClient {
221
221
  case 'ENOTFOUND':
222
222
  case 'ECONNREFUSED':
223
223
  case 'ERR_SOCKET_BAD_PORT':
224
- throw err;
225
- case undefined: {
226
- if (err.message.endsWith('All configured authentication methods failed')) {
227
- throw this.fmtError(err.message, 'getConnection', errorCode.badAuth);
224
+ throw err;
225
+ case undefined: {
226
+ if (err.message.endsWith('All configured authentication methods failed')) {
227
+ throw this.fmtError(err.message, 'getConnection', errorCode.badAuth);
228
+ }
229
+ retry(err);
230
+ break;
228
231
  }
229
- retry(err);
230
- break;
231
- }
232
- default:
233
- retry(err);
232
+ default:
233
+ retry(err);
234
234
  }
235
235
  }
236
236
  });
@@ -414,7 +414,7 @@ class SftpClient {
414
414
  * List contents of a remote directory. If a pattern is provided,
415
415
  * filter the results to only include files with names that match
416
416
  * the supplied pattern. Return value is an array of file entry
417
- * objects that include properties for type, name, size, modifiyTime,
417
+ * objects that include properties for type, name, size, modifyTime,
418
418
  * accessTime, rights {user, group other}, owner and group.
419
419
  *
420
420
  * @param {String} remotePath - path to remote directory
@@ -498,6 +498,9 @@ class SftpClient {
498
498
  };
499
499
  rdr = this.sftp.createReadStream(rPath, opts.readStreamOptions);
500
500
  rdr.once('error', (err) => {
501
+ if (dst && typeof dst !== 'string' && !dst.destroyed) {
502
+ dst.destroy();
503
+ }
501
504
  reject(this.fmtError(`${err.message} ${rPath}`, '_get', err.code));
502
505
  });
503
506
  if (dst === undefined) {
@@ -1443,7 +1446,7 @@ class SftpClient {
1443
1446
  resolve(true);
1444
1447
  };
1445
1448
  this.on('close', endCloseHandler);
1446
- if (this.client) {
1449
+ if (this.client.sftp) {
1447
1450
  this.client.end();
1448
1451
  } else {
1449
1452
  // no actual connection exists - just resolve