bdy 1.23.6-dev → 1.23.7-dev

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 (205) hide show
  1. package/distTs/package.json +10 -2
  2. package/distTs/src/agent/linux.js +53 -3
  3. package/distTs/src/agent/manager.js +3 -6
  4. package/distTs/src/agent/osx.js +51 -3
  5. package/distTs/src/agent/system.js +400 -21
  6. package/distTs/src/agent/windows.js +4 -7
  7. package/distTs/src/command/agent/debug.js +2 -2
  8. package/distTs/src/command/agent/install.js +37 -10
  9. package/distTs/src/command/agent/restart.js +2 -2
  10. package/distTs/src/command/agent/run.js +3 -0
  11. package/distTs/src/command/agent/start.js +2 -2
  12. package/distTs/src/command/agent/status.js +19 -0
  13. package/distTs/src/command/agent/stop.js +2 -2
  14. package/distTs/src/command/agent/uninstall.js +5 -8
  15. package/distTs/src/command/agent/update.js +2 -2
  16. package/distTs/src/command/artifact/publish.js +3 -1
  17. package/distTs/src/command/version.js +13 -5
  18. package/distTs/src/logger.js +40 -4
  19. package/distTs/src/texts.js +35 -19
  20. package/distTs/src/utils.js +98 -3
  21. package/node_modules/asn1/Jenkinsfile +65 -0
  22. package/node_modules/asn1/LICENSE +19 -0
  23. package/node_modules/asn1/README.md +50 -0
  24. package/node_modules/asn1/lib/ber/errors.js +13 -0
  25. package/node_modules/asn1/lib/ber/index.js +27 -0
  26. package/node_modules/asn1/lib/ber/reader.js +262 -0
  27. package/node_modules/asn1/lib/ber/types.js +36 -0
  28. package/node_modules/asn1/lib/ber/writer.js +317 -0
  29. package/node_modules/asn1/lib/index.js +20 -0
  30. package/node_modules/asn1/package.json +31 -0
  31. package/node_modules/bcrypt-pbkdf/CONTRIBUTING.md +13 -0
  32. package/node_modules/bcrypt-pbkdf/LICENSE +66 -0
  33. package/node_modules/bcrypt-pbkdf/README.md +45 -0
  34. package/node_modules/bcrypt-pbkdf/index.js +556 -0
  35. package/node_modules/bcrypt-pbkdf/package.json +15 -0
  36. package/node_modules/safer-buffer/LICENSE +21 -0
  37. package/node_modules/safer-buffer/Porting-Buffer.md +268 -0
  38. package/node_modules/safer-buffer/Readme.md +156 -0
  39. package/node_modules/safer-buffer/dangerous.js +58 -0
  40. package/node_modules/safer-buffer/package.json +34 -0
  41. package/node_modules/safer-buffer/safer.js +77 -0
  42. package/node_modules/safer-buffer/tests.js +406 -0
  43. package/node_modules/ssh2/.eslintignore +4 -0
  44. package/node_modules/ssh2/.eslintrc.js +5 -0
  45. package/node_modules/ssh2/.github/workflows/ci.yml +110 -0
  46. package/node_modules/ssh2/.github/workflows/lint.yml +27 -0
  47. package/node_modules/ssh2/LICENSE +19 -0
  48. package/node_modules/ssh2/README.md +1529 -0
  49. package/node_modules/ssh2/SFTP.md +413 -0
  50. package/node_modules/ssh2/examples/server-chat.js +238 -0
  51. package/node_modules/ssh2/examples/sftp-server-download-only.js +134 -0
  52. package/node_modules/ssh2/install.js +27 -0
  53. package/node_modules/ssh2/lib/Channel.js +295 -0
  54. package/node_modules/ssh2/lib/agent.js +1123 -0
  55. package/node_modules/ssh2/lib/client.js +2176 -0
  56. package/node_modules/ssh2/lib/http-agents.js +84 -0
  57. package/node_modules/ssh2/lib/index.js +44 -0
  58. package/node_modules/ssh2/lib/keygen.js +582 -0
  59. package/node_modules/ssh2/lib/protocol/Protocol.js +2136 -0
  60. package/node_modules/ssh2/lib/protocol/SFTP.js +4052 -0
  61. package/node_modules/ssh2/lib/protocol/constants.js +356 -0
  62. package/node_modules/ssh2/lib/protocol/crypto/binding.gyp +23 -0
  63. package/node_modules/ssh2/lib/protocol/crypto/poly1305.js +43 -0
  64. package/node_modules/ssh2/lib/protocol/crypto/src/binding.cc +2300 -0
  65. package/node_modules/ssh2/lib/protocol/crypto.js +1602 -0
  66. package/node_modules/ssh2/lib/protocol/handlers.js +16 -0
  67. package/node_modules/ssh2/lib/protocol/handlers.misc.js +1285 -0
  68. package/node_modules/ssh2/lib/protocol/kex.js +1908 -0
  69. package/node_modules/ssh2/lib/protocol/keyParser.js +1484 -0
  70. package/node_modules/ssh2/lib/protocol/node-fs-compat.js +115 -0
  71. package/node_modules/ssh2/lib/protocol/utils.js +356 -0
  72. package/node_modules/ssh2/lib/protocol/zlib.js +255 -0
  73. package/node_modules/ssh2/lib/server.js +1380 -0
  74. package/node_modules/ssh2/lib/utils.js +336 -0
  75. package/node_modules/ssh2/package.json +49 -0
  76. package/node_modules/ssh2/test/common.js +316 -0
  77. package/node_modules/ssh2/test/fixtures/bad_rsa_private_key +26 -0
  78. package/node_modules/ssh2/test/fixtures/https_cert.pem +33 -0
  79. package/node_modules/ssh2/test/fixtures/https_key.pem +52 -0
  80. package/node_modules/ssh2/test/fixtures/id_dsa +12 -0
  81. package/node_modules/ssh2/test/fixtures/id_ecdsa +5 -0
  82. package/node_modules/ssh2/test/fixtures/id_rsa +15 -0
  83. package/node_modules/ssh2/test/fixtures/id_rsa.ppk +26 -0
  84. package/node_modules/ssh2/test/fixtures/id_rsa_enc +30 -0
  85. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa +21 -0
  86. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub +1 -0
  87. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub.result +7 -0
  88. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.result +7 -0
  89. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc +22 -0
  90. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub +1 -0
  91. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub.result +7 -0
  92. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.result +7 -0
  93. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm +23 -0
  94. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub +1 -0
  95. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub.result +7 -0
  96. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.result +7 -0
  97. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa +9 -0
  98. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub +1 -0
  99. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub.result +7 -0
  100. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.result +7 -0
  101. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc +10 -0
  102. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub +1 -0
  103. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub.result +8 -0
  104. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.result +7 -0
  105. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm +10 -0
  106. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub +1 -0
  107. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub.result +8 -0
  108. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.result +7 -0
  109. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519 +7 -0
  110. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub +1 -0
  111. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub.result +7 -0
  112. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.result +7 -0
  113. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa +27 -0
  114. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub +1 -0
  115. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub.result +7 -0
  116. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.result +7 -0
  117. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc +28 -0
  118. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub +1 -0
  119. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub.result +8 -0
  120. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.result +7 -0
  121. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm +29 -0
  122. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub +1 -0
  123. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub.result +8 -0
  124. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.result +7 -0
  125. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa +12 -0
  126. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub +1 -0
  127. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub.result +7 -0
  128. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.result +7 -0
  129. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc +15 -0
  130. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub +1 -0
  131. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub.result +8 -0
  132. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.result +7 -0
  133. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa +5 -0
  134. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub +1 -0
  135. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub.result +7 -0
  136. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.result +7 -0
  137. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc +8 -0
  138. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub +1 -0
  139. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub.result +8 -0
  140. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.result +7 -0
  141. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa +27 -0
  142. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub +1 -0
  143. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub.result +7 -0
  144. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.result +7 -0
  145. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc +30 -0
  146. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub +1 -0
  147. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub.result +8 -0
  148. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.result +7 -0
  149. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256 +54 -0
  150. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub +1 -0
  151. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub.result +6 -0
  152. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.result +6 -0
  153. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc +17 -0
  154. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc.result +7 -0
  155. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa +26 -0
  156. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa.result +7 -0
  157. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc +18 -0
  158. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc.result +7 -0
  159. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub +9 -0
  160. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub.result +7 -0
  161. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub +10 -0
  162. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub.result +7 -0
  163. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub +11 -0
  164. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub.result +7 -0
  165. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub +11 -0
  166. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub.result +7 -0
  167. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub +8 -0
  168. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub.result +7 -0
  169. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub +13 -0
  170. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub.result +7 -0
  171. package/node_modules/ssh2/test/fixtures/openssh_new_rsa +27 -0
  172. package/node_modules/ssh2/test/fixtures/ssh_host_dsa_key +12 -0
  173. package/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key +5 -0
  174. package/node_modules/ssh2/test/fixtures/ssh_host_rsa_key +15 -0
  175. package/node_modules/ssh2/test/test-exec.js +578 -0
  176. package/node_modules/ssh2/test/test-integration-openssh.js +486 -0
  177. package/node_modules/ssh2/test/test-keygen.js +60 -0
  178. package/node_modules/ssh2/test/test-misc-client-server.js +1460 -0
  179. package/node_modules/ssh2/test/test-openssh.js +261 -0
  180. package/node_modules/ssh2/test/test-protocol-crypto.js +631 -0
  181. package/node_modules/ssh2/test/test-protocol-keyparser.js +177 -0
  182. package/node_modules/ssh2/test/test-server-hostkeys.js +138 -0
  183. package/node_modules/ssh2/test/test-sftp.js +842 -0
  184. package/node_modules/ssh2/test/test-shell.js +109 -0
  185. package/node_modules/ssh2/test/test-userauth-agent-openssh.js +110 -0
  186. package/node_modules/ssh2/test/test-userauth-agent.js +171 -0
  187. package/node_modules/ssh2/test/test-userauth.js +611 -0
  188. package/node_modules/ssh2/test/test-worker-imports.js +25 -0
  189. package/node_modules/ssh2/test/test.js +20 -0
  190. package/node_modules/ssh2/util/build_pagent.bat +2 -0
  191. package/node_modules/ssh2/util/pagent.c +88 -0
  192. package/node_modules/ssh2/util/pagent.exe +0 -0
  193. package/node_modules/tweetnacl/.npmignore +4 -0
  194. package/node_modules/tweetnacl/AUTHORS.md +28 -0
  195. package/node_modules/tweetnacl/CHANGELOG.md +221 -0
  196. package/node_modules/tweetnacl/LICENSE +24 -0
  197. package/node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md +20 -0
  198. package/node_modules/tweetnacl/README.md +459 -0
  199. package/node_modules/tweetnacl/nacl-fast.js +2388 -0
  200. package/node_modules/tweetnacl/nacl-fast.min.js +2 -0
  201. package/node_modules/tweetnacl/nacl.d.ts +98 -0
  202. package/node_modules/tweetnacl/nacl.js +1175 -0
  203. package/node_modules/tweetnacl/nacl.min.js +1 -0
  204. package/node_modules/tweetnacl/package.json +58 -0
  205. package/package.json +10 -2
@@ -0,0 +1,842 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+ const { constants } = require('fs');
5
+
6
+ const {
7
+ fixture,
8
+ mustCall,
9
+ mustCallAtLeast,
10
+ mustNotCall,
11
+ setup: setup_,
12
+ setupSimple
13
+ } = require('./common.js');
14
+
15
+ const { OPEN_MODE, Stats, STATUS_CODE } = require('../lib/protocol/SFTP.js');
16
+
17
+ const DEBUG = false;
18
+
19
+ setup('open', mustCall((client, server) => {
20
+ const path_ = '/tmp/foo.txt';
21
+ const handle_ = Buffer.from('node.js');
22
+ const pflags_ = (OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE);
23
+ server.on('OPEN', mustCall((id, path, pflags, attrs) => {
24
+ assert(id === 0, `Wrong request id: ${id}`);
25
+ assert(path === path_, `Wrong path: ${path}`);
26
+ assert(pflags === pflags_, `Wrong flags: ${flagsToHuman(pflags)}`);
27
+ server.handle(id, handle_);
28
+ server.end();
29
+ }));
30
+ client.open(path_, 'w', mustCall((err, handle) => {
31
+ assert(!err, `Unexpected open() error: ${err}`);
32
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
33
+ }));
34
+ }));
35
+
36
+ setup('close', mustCall((client, server) => {
37
+ const handle_ = Buffer.from('node.js');
38
+ server.on('CLOSE', mustCall((id, handle) => {
39
+ assert(id === 0, `Wrong request id: ${id}`);
40
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
41
+ server.status(id, STATUS_CODE.OK);
42
+ server.end();
43
+ }));
44
+ client.close(handle_, mustCall((err) => {
45
+ assert(!err, `Unexpected close() error: ${err}`);
46
+ }));
47
+ }));
48
+
49
+ setup('read', mustCall((client, server) => {
50
+ const expected = Buffer.from('node.jsnode.jsnode.jsnode.jsnode.jsnode.js');
51
+ const handle_ = Buffer.from('node.js');
52
+ const buf = Buffer.alloc(expected.length);
53
+ server.on('READ', mustCall((id, handle, offset, len) => {
54
+ assert(id === 0, `Wrong request id: ${id}`);
55
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
56
+ assert(offset === 5, `Wrong read offset: ${offset}`);
57
+ assert(len === buf.length, `Wrong read len: ${len}`);
58
+ server.data(id, expected);
59
+ server.end();
60
+ }));
61
+ client.read(handle_, buf, 0, buf.length, 5, mustCall((err, nb) => {
62
+ assert(!err, `Unexpected read() error: ${err}`);
63
+ assert.deepStrictEqual(buf, expected, 'read data mismatch');
64
+ }));
65
+ }));
66
+
67
+ setup('read (partial)', mustCall((client, server) => {
68
+ const expected = Buffer.from('blargh');
69
+ const handle_ = Buffer.from('node.js');
70
+ const buf = Buffer.alloc(256);
71
+ server.on('READ', mustCall((id, handle, offset, len) => {
72
+ assert(id === 0, `Wrong request id: ${id}`);
73
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
74
+ assert(offset === 0, `Wrong read offset: ${offset}`);
75
+ assert(len === buf.length, `Wrong read len: ${len}`);
76
+ server.data(id, expected);
77
+ server.end();
78
+ }));
79
+ client.read(handle_, buf, 0, buf.length, 0, mustCall((err, nb, data) => {
80
+ assert(!err, `Unexpected read() error: ${err}`);
81
+ assert.strictEqual(nb, expected.length, 'nb count mismatch');
82
+ assert.deepStrictEqual(
83
+ buf.slice(0, expected.length),
84
+ expected,
85
+ 'read data mismatch'
86
+ );
87
+ assert.deepStrictEqual(data, expected, 'read data mismatch');
88
+ }));
89
+ }));
90
+
91
+ setup('read (overflow)', mustCall((client, server) => {
92
+ const maxChunk = client._maxReadLen;
93
+ const expected = Buffer.alloc(3 * maxChunk, 'Q');
94
+ const handle_ = Buffer.from('node.js');
95
+ const buf = Buffer.alloc(expected.length, 0);
96
+ let reqs = 0;
97
+ server.on('READ', mustCall((id, handle, offset, len) => {
98
+ ++reqs;
99
+ assert.strictEqual(id, reqs - 1, `Wrong request id: ${id}`);
100
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
101
+ assert.strictEqual(offset,
102
+ (reqs - 1) * maxChunk,
103
+ `Wrong read offset: ${offset}`);
104
+ server.data(id, expected.slice(offset, offset + len));
105
+ if (reqs === 3)
106
+ server.end();
107
+ }, 3));
108
+ client.read(handle_, buf, 0, buf.length, 0, mustCall((err, nb) => {
109
+ assert(!err, `Unexpected read() error: ${err}`);
110
+ assert.deepStrictEqual(buf, expected);
111
+ assert.strictEqual(nb, buf.length, 'read nb mismatch');
112
+ }));
113
+ }));
114
+
115
+ setup('write', mustCall((client, server) => {
116
+ const handle_ = Buffer.from('node.js');
117
+ const buf = Buffer.from('node.jsnode.jsnode.jsnode.jsnode.jsnode.js');
118
+ server.on('WRITE', mustCall((id, handle, offset, data) => {
119
+ assert(id === 0, `Wrong request id: ${id}`);
120
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
121
+ assert(offset === 5, `Wrong write offset: ${offset}`);
122
+ assert.deepStrictEqual(data, buf, 'write data mismatch');
123
+ server.status(id, STATUS_CODE.OK);
124
+ server.end();
125
+ }));
126
+ client.write(handle_, buf, 0, buf.length, 5, mustCall((err, nb) => {
127
+ assert(!err, `Unexpected write() error: ${err}`);
128
+ assert.strictEqual(nb, buf.length, 'wrong bytes written');
129
+ }));
130
+ }));
131
+
132
+ setup('write (overflow)', mustCall((client, server) => {
133
+ const maxChunk = client._maxWriteLen;
134
+ const handle_ = Buffer.from('node.js');
135
+ const buf = Buffer.allocUnsafe(3 * maxChunk);
136
+ let reqs = 0;
137
+ server.on('WRITE', mustCall((id, handle, offset, data) => {
138
+ ++reqs;
139
+ assert.strictEqual(id, reqs - 1, `Wrong request id: ${id}`);
140
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
141
+ assert.strictEqual(offset,
142
+ (reqs - 1) * maxChunk,
143
+ `Wrong write offset: ${offset}`);
144
+ assert((offset + data.length) <= buf.length, 'bad offset');
145
+ assert.deepStrictEqual(data,
146
+ buf.slice(offset, offset + data.length),
147
+ 'write data mismatch');
148
+ server.status(id, STATUS_CODE.OK);
149
+ if (reqs === 3)
150
+ server.end();
151
+ }, 3));
152
+ client.write(handle_, buf, 0, buf.length, 0, mustCall((err, nb) => {
153
+ assert(!err, `Unexpected write() error: ${err}`);
154
+ assert.strictEqual(nb, buf.length, 'wrote bytes written');
155
+ }));
156
+ }));
157
+
158
+ setup('lstat', mustCall((client, server) => {
159
+ const path_ = '/foo/bar/baz';
160
+ const attrs_ = new Stats({
161
+ size: 10 * 1024,
162
+ uid: 9001,
163
+ gid: 9001,
164
+ atime: (Date.now() / 1000) | 0,
165
+ mtime: (Date.now() / 1000) | 0
166
+ });
167
+ server.on('LSTAT', mustCall((id, path) => {
168
+ assert(id === 0, `Wrong request id: ${id}`);
169
+ assert(path === path_, `Wrong path: ${path}`);
170
+ server.attrs(id, attrs_);
171
+ server.end();
172
+ }));
173
+ client.lstat(path_, mustCall((err, attrs) => {
174
+ assert(!err, `Unexpected lstat() error: ${err}`);
175
+ assert.deepStrictEqual(attrs, attrs_, 'attrs mismatch');
176
+ }));
177
+ }));
178
+
179
+ setup('fstat', mustCall((client, server) => {
180
+ const handle_ = Buffer.from('node.js');
181
+ const attrs_ = new Stats({
182
+ size: 10 * 1024,
183
+ uid: 9001,
184
+ gid: 9001,
185
+ atime: (Date.now() / 1000) | 0,
186
+ mtime: (Date.now() / 1000) | 0
187
+ });
188
+ server.on('FSTAT', mustCall((id, handle) => {
189
+ assert(id === 0, `Wrong request id: ${id}`);
190
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
191
+ server.attrs(id, attrs_);
192
+ server.end();
193
+ }));
194
+ client.fstat(handle_, mustCall((err, attrs) => {
195
+ assert(!err, `Unexpected fstat() error: ${err}`);
196
+ assert.deepStrictEqual(attrs, attrs_, 'attrs mismatch');
197
+ }));
198
+ }));
199
+
200
+ setup('setstat', mustCall((client, server) => {
201
+ const path_ = '/foo/bar/baz';
202
+ const attrs_ = new Stats({
203
+ uid: 9001,
204
+ gid: 9001,
205
+ atime: (Date.now() / 1000) | 0,
206
+ mtime: (Date.now() / 1000) | 0
207
+ });
208
+ server.on('SETSTAT', mustCall((id, path, attrs) => {
209
+ assert(id === 0, `Wrong request id: ${id}`);
210
+ assert(path === path_, `Wrong path: ${path}`);
211
+ assert.deepStrictEqual(attrs, attrs_, 'attrs mismatch');
212
+ server.status(id, STATUS_CODE.OK);
213
+ server.end();
214
+ }));
215
+ client.setstat(path_, attrs_, mustCall((err) => {
216
+ assert(!err, `Unexpected setstat() error: ${err}`);
217
+ }));
218
+ }));
219
+
220
+ setup('fsetstat', mustCall((client, server) => {
221
+ const handle_ = Buffer.from('node.js');
222
+ const attrs_ = new Stats({
223
+ uid: 9001,
224
+ gid: 9001,
225
+ atime: (Date.now() / 1000) | 0,
226
+ mtime: (Date.now() / 1000) | 0
227
+ });
228
+ server.on('FSETSTAT', mustCall((id, handle, attrs) => {
229
+ assert(id === 0, `Wrong request id: ${id}`);
230
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
231
+ assert.deepStrictEqual(attrs, attrs_, 'attrs mismatch');
232
+ server.status(id, STATUS_CODE.OK);
233
+ server.end();
234
+ }));
235
+ client.fsetstat(handle_, attrs_, mustCall((err) => {
236
+ assert(!err, `Unexpected fsetstat() error: ${err}`);
237
+ }));
238
+ }));
239
+
240
+ setup('opendir', mustCall((client, server) => {
241
+ const handle_ = Buffer.from('node.js');
242
+ const path_ = '/tmp';
243
+ server.on('OPENDIR', mustCall((id, path) => {
244
+ assert(id === 0, `Wrong request id: ${id}`);
245
+ assert(path === path_, `Wrong path: ${path}`);
246
+ server.handle(id, handle_);
247
+ server.end();
248
+ }));
249
+ client.opendir(path_, mustCall((err, handle) => {
250
+ assert(!err, `Unexpected opendir() error: ${err}`);
251
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
252
+ }));
253
+ }));
254
+
255
+ setup('readdir', mustCall((client, server) => {
256
+ const handle_ = Buffer.from('node.js');
257
+ const list_ = [
258
+ { filename: '.',
259
+ longname: 'drwxr-xr-x 56 nodejs nodejs 4096 Nov 10 01:05 .',
260
+ attrs: new Stats({
261
+ mode: 0o755 | constants.S_IFDIR,
262
+ size: 4096,
263
+ uid: 9001,
264
+ gid: 8001,
265
+ atime: 1415599549,
266
+ mtime: 1415599590
267
+ })
268
+ },
269
+ { filename: '..',
270
+ longname: 'drwxr-xr-x 4 root root 4096 May 16 2013 ..',
271
+ attrs: new Stats({
272
+ mode: 0o755 | constants.S_IFDIR,
273
+ size: 4096,
274
+ uid: 0,
275
+ gid: 0,
276
+ atime: 1368729954,
277
+ mtime: 1368729999
278
+ })
279
+ },
280
+ { filename: 'foo',
281
+ longname: 'drwxrwxrwx 2 nodejs nodejs 4096 Mar 8 2009 foo',
282
+ attrs: new Stats({
283
+ mode: 0o777 | constants.S_IFDIR,
284
+ size: 4096,
285
+ uid: 9001,
286
+ gid: 8001,
287
+ atime: 1368729954,
288
+ mtime: 1368729999
289
+ })
290
+ },
291
+ { filename: 'bar',
292
+ longname: '-rw-r--r-- 1 nodejs nodejs 513901992 Dec 4 2009 bar',
293
+ attrs: new Stats({
294
+ mode: 0o644 | constants.S_IFREG,
295
+ size: 513901992,
296
+ uid: 9001,
297
+ gid: 8001,
298
+ atime: 1259972199,
299
+ mtime: 1259972199
300
+ })
301
+ }
302
+ ];
303
+ server.on('READDIR', mustCall((id, handle) => {
304
+ assert(id === 0, `Wrong request id: ${id}`);
305
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
306
+ server.name(id, list_);
307
+ server.end();
308
+ }));
309
+ client.readdir(handle_, mustCall((err, list) => {
310
+ assert(!err, `Unexpected readdir() error: ${err}`);
311
+ assert.deepStrictEqual(list,
312
+ list_.slice(2),
313
+ 'dir list mismatch');
314
+ }));
315
+ }));
316
+
317
+ setup('readdir (full)', mustCall((client, server) => {
318
+ const handle_ = Buffer.from('node.js');
319
+ const list_ = [
320
+ { filename: '.',
321
+ longname: 'drwxr-xr-x 56 nodejs nodejs 4096 Nov 10 01:05 .',
322
+ attrs: new Stats({
323
+ mode: 0o755 | constants.S_IFDIR,
324
+ size: 4096,
325
+ uid: 9001,
326
+ gid: 8001,
327
+ atime: 1415599549,
328
+ mtime: 1415599590
329
+ })
330
+ },
331
+ { filename: '..',
332
+ longname: 'drwxr-xr-x 4 root root 4096 May 16 2013 ..',
333
+ attrs: new Stats({
334
+ mode: 0o755 | constants.S_IFDIR,
335
+ size: 4096,
336
+ uid: 0,
337
+ gid: 0,
338
+ atime: 1368729954,
339
+ mtime: 1368729999
340
+ })
341
+ },
342
+ { filename: 'foo',
343
+ longname: 'drwxrwxrwx 2 nodejs nodejs 4096 Mar 8 2009 foo',
344
+ attrs: new Stats({
345
+ mode: 0o777 | constants.S_IFDIR,
346
+ size: 4096,
347
+ uid: 9001,
348
+ gid: 8001,
349
+ atime: 1368729954,
350
+ mtime: 1368729999
351
+ })
352
+ },
353
+ { filename: 'bar',
354
+ longname: '-rw-r--r-- 1 nodejs nodejs 513901992 Dec 4 2009 bar',
355
+ attrs: new Stats({
356
+ mode: 0o644 | constants.S_IFREG,
357
+ size: 513901992,
358
+ uid: 9001,
359
+ gid: 8001,
360
+ atime: 1259972199,
361
+ mtime: 1259972199
362
+ })
363
+ }
364
+ ];
365
+ server.on('READDIR', mustCall((id, handle) => {
366
+ assert(id === 0, `Wrong request id: ${id}`);
367
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
368
+ server.name(id, list_);
369
+ server.end();
370
+ }));
371
+ client.readdir(handle_, { full: true }, mustCall((err, list) => {
372
+ assert(!err, `Unexpected readdir() error: ${err}`);
373
+ assert.deepStrictEqual(list, list_, 'dir list mismatch');
374
+ }));
375
+ }));
376
+
377
+ setup('readdir (EOF)', mustCall((client, server) => {
378
+ const handle_ = Buffer.from('node.js');
379
+ server.on('READDIR', mustCall((id, handle) => {
380
+ assert(id === 0, `Wrong request id: ${id}`);
381
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
382
+ server.status(id, STATUS_CODE.EOF);
383
+ server.end();
384
+ }));
385
+ client.readdir(handle_, mustCall((err, list) => {
386
+ assert(err && err.code === STATUS_CODE.EOF,
387
+ `Expected EOF, got: ${err}`);
388
+ }));
389
+ }));
390
+
391
+ setup('unlink', mustCall((client, server) => {
392
+ const path_ = '/foo/bar/baz';
393
+ server.on('REMOVE', mustCall((id, path) => {
394
+ assert(id === 0, `Wrong request id: ${id}`);
395
+ assert(path === path_, `Wrong path: ${path}`);
396
+ server.status(id, STATUS_CODE.OK);
397
+ server.end();
398
+ }));
399
+ client.unlink(path_, mustCall((err) => {
400
+ assert(!err, `Unexpected unlink() error: ${err}`);
401
+ }));
402
+ }));
403
+
404
+ setup('mkdir', mustCall((client, server) => {
405
+ const path_ = '/foo/bar/baz';
406
+ server.on('MKDIR', mustCall((id, path) => {
407
+ assert(id === 0, `Wrong request id: ${id}`);
408
+ assert(path === path_, `Wrong path: ${path}`);
409
+ server.status(id, STATUS_CODE.OK);
410
+ server.end();
411
+ }));
412
+ client.mkdir(path_, mustCall((err) => {
413
+ assert(!err, `Unexpected mkdir() error: ${err}`);
414
+ }));
415
+ }));
416
+
417
+ setup('rmdir', mustCall((client, server) => {
418
+ const path_ = '/foo/bar/baz';
419
+ server.on('RMDIR', mustCall((id, path) => {
420
+ assert(id === 0, `Wrong request id: ${id}`);
421
+ assert(path === path_, `Wrong path: ${path}`);
422
+ server.status(id, STATUS_CODE.OK);
423
+ server.end();
424
+ }));
425
+ client.rmdir(path_, mustCall((err) => {
426
+ assert(!err, `Unexpected rmdir() error: ${err}`);
427
+ }));
428
+ }));
429
+
430
+ setup('realpath', mustCall((client, server) => {
431
+ const path_ = '/foo/bar/baz';
432
+ const name_ = { filename: '/tmp/foo' };
433
+ server.on('REALPATH', mustCall((id, path) => {
434
+ assert(id === 0, `Wrong request id: ${id}`);
435
+ assert(path === path_, `Wrong path: ${path}`);
436
+ server.name(id, name_);
437
+ server.end();
438
+ }));
439
+ client.realpath(path_, mustCall((err, name) => {
440
+ assert(!err, `Unexpected realpath() error: ${err}`);
441
+ assert.deepStrictEqual(name, name_.filename, 'name mismatch');
442
+ }));
443
+ }));
444
+
445
+ setup('stat', mustCall((client, server) => {
446
+ const path_ = '/foo/bar/baz';
447
+ const attrs_ = new Stats({
448
+ mode: 0o644 | constants.S_IFREG,
449
+ size: 10 * 1024,
450
+ uid: 9001,
451
+ gid: 9001,
452
+ atime: (Date.now() / 1000) | 0,
453
+ mtime: (Date.now() / 1000) | 0
454
+ });
455
+ server.on('STAT', mustCall((id, path) => {
456
+ assert(id === 0, `Wrong request id: ${id}`);
457
+ assert(path === path_, `Wrong path: ${path}`);
458
+ server.attrs(id, attrs_);
459
+ server.end();
460
+ }));
461
+ client.stat(path_, mustCall((err, attrs) => {
462
+ assert(!err, `Unexpected stat() error: ${err}`);
463
+ assert.deepStrictEqual(attrs, attrs_, 'attrs mismatch');
464
+ const expectedTypes = {
465
+ isDirectory: false,
466
+ isFile: true,
467
+ isBlockDevice: false,
468
+ isCharacterDevice: false,
469
+ isSymbolicLink: false,
470
+ isFIFO: false,
471
+ isSocket: false
472
+ };
473
+ for (const [fn, expect] of Object.entries(expectedTypes))
474
+ assert(attrs[fn]() === expect, `attrs.${fn}() failed`);
475
+ }));
476
+ }));
477
+
478
+ setup('rename', mustCall((client, server) => {
479
+ const oldPath_ = '/foo/bar/baz';
480
+ const newPath_ = '/tmp/foo';
481
+ server.on('RENAME', mustCall((id, oldPath, newPath) => {
482
+ assert(id === 0, `Wrong request id: ${id}`);
483
+ assert(oldPath === oldPath_, `Wrong old path: ${oldPath}`);
484
+ assert(newPath === newPath_, `Wrong new path: ${newPath}`);
485
+ server.status(id, STATUS_CODE.OK);
486
+ server.end();
487
+ }));
488
+ client.rename(oldPath_, newPath_, mustCall((err) => {
489
+ assert(!err, `Unexpected rename() error: ${err}`);
490
+ }));
491
+ }));
492
+
493
+ setup('readlink', mustCall((client, server) => {
494
+ const linkPath_ = '/foo/bar/baz';
495
+ const name = { filename: '/tmp/foo' };
496
+ server.on('READLINK', mustCall((id, linkPath) => {
497
+ assert(id === 0, `Wrong request id: ${id}`);
498
+ assert(linkPath === linkPath_, `Wrong link path: ${linkPath}`);
499
+ server.name(id, name);
500
+ server.end();
501
+ }));
502
+ client.readlink(linkPath_, mustCall((err, targetPath) => {
503
+ assert(!err, `Unexpected readlink() error: ${err}`);
504
+ assert(targetPath === name.filename,
505
+ `Wrong target path: ${targetPath}`);
506
+ }));
507
+ }));
508
+
509
+ setup('symlink', mustCall((client, server) => {
510
+ const linkPath_ = '/foo/bar/baz';
511
+ const targetPath_ = '/tmp/foo';
512
+ server.on('SYMLINK', mustCall((id, linkPath, targetPath) => {
513
+ assert(id === 0, `Wrong request id: ${id}`);
514
+ assert(linkPath === linkPath_, `Wrong link path: ${linkPath}`);
515
+ assert(targetPath === targetPath_, `Wrong target path: ${targetPath}`);
516
+ server.status(id, STATUS_CODE.OK);
517
+ server.end();
518
+ }));
519
+ client.symlink(targetPath_, linkPath_, mustCall((err) => {
520
+ assert(!err, `Unexpected symlink() error: ${err}`);
521
+ }));
522
+ }));
523
+
524
+ setup('readFile', mustCall((client, server) => {
525
+ const path_ = '/foo/bar/baz';
526
+ const handle_ = Buffer.from('hi mom!');
527
+ const data_ = Buffer.from('hello world');
528
+ server.on('OPEN', mustCall((id, path, pflags, attrs) => {
529
+ assert(id === 0, `Wrong request id: ${id}`);
530
+ assert(path === path_, `Wrong path: ${path}`);
531
+ assert(pflags === OPEN_MODE.READ, `Wrong flags: ${flagsToHuman(pflags)}`);
532
+ server.handle(id, handle_);
533
+ })).on('FSTAT', mustCall((id, handle) => {
534
+ assert(id === 1, `Wrong request id: ${id}`);
535
+ const attrs = new Stats({
536
+ size: data_.length,
537
+ uid: 9001,
538
+ gid: 9001,
539
+ atime: (Date.now() / 1000) | 0,
540
+ mtime: (Date.now() / 1000) | 0
541
+ });
542
+ server.attrs(id, attrs);
543
+ })).on('READ', mustCall((id, handle, offset, len) => {
544
+ assert(id === 2, `Wrong request id: ${id}`);
545
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
546
+ assert(offset === 0, `Wrong read offset: ${offset}`);
547
+ server.data(id, data_);
548
+ })).on('CLOSE', mustCall((id, handle) => {
549
+ assert(id === 3, `Wrong request id: ${id}`);
550
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
551
+ server.status(id, STATUS_CODE.OK);
552
+ server.end();
553
+ }));
554
+ client.readFile(path_, mustCall((err, buf) => {
555
+ assert(!err, `Unexpected error: ${err}`);
556
+ assert.deepStrictEqual(buf, data_, 'data mismatch');
557
+ }));
558
+ }));
559
+
560
+ setup('readFile (no size from fstat)', mustCall((client, server) => {
561
+ const path_ = '/foo/bar/baz';
562
+ const handle_ = Buffer.from('hi mom!');
563
+ const data_ = Buffer.from('hello world');
564
+ let reads = 0;
565
+ server.on('OPEN', mustCall((id, path, pflags, attrs) => {
566
+ assert(id === 0, `Wrong request id: ${id}`);
567
+ assert(path === path_, `Wrong path: ${path}`);
568
+ assert(pflags === OPEN_MODE.READ, `Wrong flags: ${flagsToHuman(pflags)}`);
569
+ server.handle(id, handle_);
570
+ })).on('FSTAT', mustCall((id, handle) => {
571
+ assert(id === 1, `Wrong request id: ${id}`);
572
+ const attrs = new Stats({
573
+ uid: 9001,
574
+ gid: 9001,
575
+ atime: (Date.now() / 1000) | 0,
576
+ mtime: (Date.now() / 1000) | 0
577
+ });
578
+ server.attrs(id, attrs);
579
+ })).on('READ', mustCall((id, handle, offset, len) => {
580
+ assert(++reads + 1 === id, `Wrong request id: ${id}`);
581
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
582
+ switch (id) {
583
+ case 2:
584
+ assert(offset === 0, `Wrong read offset for first read: ${offset}`);
585
+ server.data(id, data_);
586
+ break;
587
+ case 3:
588
+ assert(offset === data_.length,
589
+ `Wrong read offset for second read: ${offset}`);
590
+ server.status(id, STATUS_CODE.EOF);
591
+ break;
592
+ }
593
+ }, 2)).on('CLOSE', mustCall((id, handle) => {
594
+ assert(id === 4, `Wrong request id: ${id}`);
595
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
596
+ server.status(id, STATUS_CODE.OK);
597
+ server.end();
598
+ }));
599
+ client.readFile(path_, mustCall((err, buf) => {
600
+ assert(!err, `Unexpected error: ${err}`);
601
+ assert.deepStrictEqual(buf, data_, 'data mismatch');
602
+ }));
603
+ }));
604
+
605
+ setup('ReadStream', mustCall((client, server) => {
606
+ let reads = 0;
607
+ const path_ = '/foo/bar/baz';
608
+ const handle_ = Buffer.from('hi mom!');
609
+ const data_ = Buffer.from('hello world');
610
+ server.on('OPEN', mustCall((id, path, pflags, attrs) => {
611
+ assert(id === 0, `Wrong request id: ${id}`);
612
+ assert(path === path_, `Wrong path: ${path}`);
613
+ assert(pflags === OPEN_MODE.READ, `Wrong flags: ${flagsToHuman(pflags)}`);
614
+ server.handle(id, handle_);
615
+ })).on('READ', mustCall((id, handle, offset, len) => {
616
+ assert(id === ++reads, `Wrong request id: ${id}`);
617
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
618
+ if (reads === 1) {
619
+ assert(offset === 0, `Wrong read offset: ${offset}`);
620
+ server.data(id, data_);
621
+ } else {
622
+ server.status(id, STATUS_CODE.EOF);
623
+ }
624
+ }, 2)).on('CLOSE', mustCall((id, handle) => {
625
+ assert(id === 3, `Wrong request id: ${id}`);
626
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
627
+ server.status(id, STATUS_CODE.OK);
628
+ server.end();
629
+ }));
630
+ let buf = [];
631
+ client.createReadStream(path_).on('readable', mustCallAtLeast(function() {
632
+ let chunk;
633
+ while ((chunk = this.read()) !== null)
634
+ buf.push(chunk);
635
+ })).on('end', mustCall(() => {
636
+ buf = Buffer.concat(buf);
637
+ assert.deepStrictEqual(buf, data_, 'data mismatch');
638
+ }));
639
+ }));
640
+
641
+ setup('ReadStream (fewer bytes than requested)', mustCall((client, server) => {
642
+ const path_ = '/foo/bar/baz';
643
+ const handle_ = Buffer.from('hi mom!');
644
+ const data_ = Buffer.from('hello world');
645
+ server.on('OPEN', mustCall((id, path, pflags, attrs) => {
646
+ server.handle(id, handle_);
647
+ })).on('READ', mustCallAtLeast((id, handle, offset, len) => {
648
+ if (offset > data_.length) {
649
+ server.status(id, STATUS_CODE.EOF);
650
+ } else {
651
+ // Only read 4 bytes at a time
652
+ server.data(id, data_.slice(offset, offset + 4));
653
+ }
654
+ })).on('CLOSE', mustCall((id, handle) => {
655
+ server.status(id, STATUS_CODE.OK);
656
+ server.end();
657
+ }));
658
+ let buf = [];
659
+ client.createReadStream(path_).on('readable', mustCallAtLeast(function() {
660
+ let chunk;
661
+ while ((chunk = this.read()) !== null)
662
+ buf.push(chunk);
663
+ })).on('end', mustCall(() => {
664
+ buf = Buffer.concat(buf);
665
+ assert.deepStrictEqual(buf, data_, 'data mismatch');
666
+ }));
667
+ }));
668
+
669
+ setup('ReadStream (error)', mustCall((client, server) => {
670
+ const path_ = '/foo/bar/baz';
671
+ server.on('OPEN', mustCall((id, path, pflags, attrs) => {
672
+ assert(id === 0, `Wrong request id: ${id}`);
673
+ assert(path === path_, `Wrong path: ${path}`);
674
+ assert(pflags === OPEN_MODE.READ, `Wrong flags: ${flagsToHuman(pflags)}`);
675
+ server.status(id, STATUS_CODE.NO_SUCH_FILE);
676
+ server.end();
677
+ }));
678
+ client.createReadStream(path_).on('error', mustCall((err) => {
679
+ assert(err.code === STATUS_CODE.NO_SUCH_FILE);
680
+ }));
681
+ }));
682
+
683
+ setup('WriteStream', mustCall((client, server) => {
684
+ let writes = 0;
685
+ const path_ = '/foo/bar/baz';
686
+ const handle_ = Buffer.from('hi mom!');
687
+ const data_ = Buffer.from('hello world');
688
+ const pflags_ = OPEN_MODE.TRUNC | OPEN_MODE.CREAT | OPEN_MODE.WRITE;
689
+ server.on('OPEN', mustCall((id, path, pflags, attrs) => {
690
+ assert(id === 0, `Wrong request id: ${id}`);
691
+ assert(path === path_, `Wrong path: ${path}`);
692
+ assert(pflags === pflags_, `Wrong flags: ${flagsToHuman(pflags)}`);
693
+ server.handle(id, handle_);
694
+ })).on('FSETSTAT', mustCall((id, handle, attrs) => {
695
+ assert(id === 1, `Wrong request id: ${id}`);
696
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
697
+ assert.strictEqual(attrs.mode, 0o666, 'Wrong file mode');
698
+ server.status(id, STATUS_CODE.OK);
699
+ })).on('WRITE', mustCall((id, handle, offset, data) => {
700
+ assert(id === ++writes + 1, `Wrong request id: ${id}`);
701
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
702
+ assert(offset === ((writes - 1) * data_.length),
703
+ `Wrong write offset: ${offset}`);
704
+ assert.deepStrictEqual(data, data_, 'Wrong data');
705
+ server.status(id, STATUS_CODE.OK);
706
+ }, 3)).on('CLOSE', mustCall((id, handle) => {
707
+ assert(id === 5, `Wrong request id: ${id}`);
708
+ assert.deepStrictEqual(handle, handle_, 'handle mismatch');
709
+ server.status(id, STATUS_CODE.OK);
710
+ server.end();
711
+ }));
712
+
713
+ const writer = client.createWriteStream(path_);
714
+ writer.cork && writer.cork();
715
+ writer.write(data_);
716
+ writer.write(data_);
717
+ writer.write(data_);
718
+ writer.uncork && writer.uncork();
719
+ writer.end();
720
+ }));
721
+
722
+ {
723
+ const { client, server } = setup_(
724
+ 'SFTP server aborts with exit-status',
725
+ {
726
+ client: { username: 'foo', password: 'bar' },
727
+ server: { hostKeys: [ fixture('ssh_host_rsa_key') ] },
728
+ },
729
+ );
730
+
731
+ server.on('connection', mustCall((conn) => {
732
+ conn.on('authentication', mustCall((ctx) => {
733
+ ctx.accept();
734
+ })).on('ready', mustCall(() => {
735
+ conn.on('session', mustCall((accept, reject) => {
736
+ accept().on('sftp', mustCall((accept, reject) => {
737
+ const sftp = accept();
738
+
739
+ // XXX: hack
740
+ sftp._protocol.exitStatus(sftp.outgoing.id, 127);
741
+ sftp._protocol.channelClose(sftp.outgoing.id);
742
+ }));
743
+ }));
744
+ }));
745
+ }));
746
+
747
+ client.on('ready', mustCall(() => {
748
+ const timeout = setTimeout(mustNotCall(), 1000);
749
+ client.sftp(mustCall((err, sftp) => {
750
+ clearTimeout(timeout);
751
+ assert(err, 'Expected error');
752
+ assert(err.code === 127, `Expected exit code 127, saw: ${err.code}`);
753
+ client.end();
754
+ }));
755
+ }));
756
+ }
757
+
758
+ {
759
+ const { client, server } = setup_(
760
+ 'SFTP client sets environment',
761
+ {
762
+ client: { username: 'foo', password: 'bar' },
763
+ server: { hostKeys: [ fixture('ssh_host_rsa_key') ] },
764
+ },
765
+ );
766
+
767
+ const env = { SSH2NODETEST: 'foo' };
768
+
769
+ server.on('connection', mustCall((conn) => {
770
+ conn.on('authentication', mustCall((ctx) => {
771
+ ctx.accept();
772
+ })).on('ready', mustCall(() => {
773
+ conn.on('session', mustCall((accept, reject) => {
774
+ accept().on('env', mustCall((accept, reject, info) => {
775
+ accept && accept();
776
+ assert(info.key === Object.keys(env)[0], 'Wrong env key');
777
+ assert(info.val === Object.values(env)[0], 'Wrong env value');
778
+ })).on('sftp', mustCall((accept, reject) => {
779
+ accept();
780
+ }));
781
+ }));
782
+ }));
783
+ }));
784
+
785
+ client.on('ready', mustCall(() => {
786
+ const timeout = setTimeout(mustNotCall(), 1000);
787
+ client.sftp(env, mustCall((err, sftp) => {
788
+ clearTimeout(timeout);
789
+ assert(!err, `Unexpected exec error: ${err}`);
790
+ client.end();
791
+ }));
792
+ }));
793
+ }
794
+
795
+ // =============================================================================
796
+ function setup(title, cb) {
797
+ const { client, server } = setupSimple(DEBUG, title);
798
+ let clientSFTP;
799
+ let serverSFTP;
800
+
801
+ const onSFTP = mustCall(() => {
802
+ if (clientSFTP && serverSFTP)
803
+ cb(clientSFTP, serverSFTP);
804
+ }, 2);
805
+
806
+ client.on('ready', mustCall(() => {
807
+ client.sftp(mustCall((err, sftp) => {
808
+ assert(!err, `[${title}] Unexpected client sftp start error: ${err}`);
809
+ sftp.on('close', mustCall(() => {
810
+ client.end();
811
+ }));
812
+ clientSFTP = sftp;
813
+ onSFTP();
814
+ }));
815
+ }));
816
+
817
+ server.on('connection', mustCall((conn) => {
818
+ conn.on('ready', mustCall(() => {
819
+ conn.on('session', mustCall((accept, reject) => {
820
+ accept().on('sftp', mustCall((accept, reject) => {
821
+ const sftp = accept();
822
+ sftp.on('close', mustCall(() => {
823
+ conn.end();
824
+ }));
825
+ serverSFTP = sftp;
826
+ onSFTP();
827
+ }));
828
+ }));
829
+ }));
830
+ }));
831
+ }
832
+
833
+ function flagsToHuman(flags) {
834
+ const ret = [];
835
+
836
+ for (const [name, value] of Object.entries(OPEN_MODE)) {
837
+ if (flags & value)
838
+ ret.push(name);
839
+ }
840
+
841
+ return ret.join(' | ');
842
+ }