UrgentcareCLI 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (317) hide show
  1. checksums.yaml +4 -4
  2. data/lib/UrgentCare/CLI.rb +1 -2
  3. data/lib/UrgentCare/Scraper.rb +65 -0
  4. data/lib/UrgentCare/version.rb +2 -2
  5. data/lib/UrgentCare.rb +1 -0
  6. metadata +3 -313
  7. data/.gitignore +0 -11
  8. data/.rspec +0 -3
  9. data/.travis.yml +0 -5
  10. data/CODE_OF_CONDUCT.md +0 -74
  11. data/Gemfile +0 -12
  12. data/Gemfile.lock +0 -84
  13. data/LICENSE.txt +0 -21
  14. data/Notes +0 -41
  15. data/README.md +0 -41
  16. data/Rakefile +0 -8
  17. data/UrgentCare.gemspec +0 -39
  18. data/background.jpg +0 -0
  19. data/data.txt +0 -4
  20. data/lib/Urgentcare/Scraper.rb +0 -78
  21. data/node_modules/.bin/rimraf +0 -1
  22. data/node_modules/.package-lock.json +0 -250
  23. data/node_modules/balanced-match/.github/FUNDING.yml +0 -2
  24. data/node_modules/balanced-match/LICENSE.md +0 -21
  25. data/node_modules/balanced-match/README.md +0 -97
  26. data/node_modules/balanced-match/index.js +0 -62
  27. data/node_modules/balanced-match/package.json +0 -48
  28. data/node_modules/brace-expansion/LICENSE +0 -21
  29. data/node_modules/brace-expansion/README.md +0 -129
  30. data/node_modules/brace-expansion/index.js +0 -201
  31. data/node_modules/brace-expansion/package.json +0 -47
  32. data/node_modules/concat-map/.travis.yml +0 -4
  33. data/node_modules/concat-map/LICENSE +0 -18
  34. data/node_modules/concat-map/README.markdown +0 -62
  35. data/node_modules/concat-map/example/map.js +0 -6
  36. data/node_modules/concat-map/index.js +0 -13
  37. data/node_modules/concat-map/package.json +0 -43
  38. data/node_modules/concat-map/test/map.js +0 -39
  39. data/node_modules/core-util-is/LICENSE +0 -19
  40. data/node_modules/core-util-is/README.md +0 -3
  41. data/node_modules/core-util-is/float.patch +0 -604
  42. data/node_modules/core-util-is/lib/util.js +0 -107
  43. data/node_modules/core-util-is/package.json +0 -32
  44. data/node_modules/core-util-is/test.js +0 -68
  45. data/node_modules/fs.realpath/LICENSE +0 -43
  46. data/node_modules/fs.realpath/README.md +0 -33
  47. data/node_modules/fs.realpath/index.js +0 -66
  48. data/node_modules/fs.realpath/old.js +0 -303
  49. data/node_modules/fs.realpath/package.json +0 -26
  50. data/node_modules/glob/LICENSE +0 -21
  51. data/node_modules/glob/README.md +0 -375
  52. data/node_modules/glob/changelog.md +0 -67
  53. data/node_modules/glob/common.js +0 -234
  54. data/node_modules/glob/glob.js +0 -788
  55. data/node_modules/glob/package.json +0 -51
  56. data/node_modules/glob/sync.js +0 -484
  57. data/node_modules/immediate/LICENSE.txt +0 -20
  58. data/node_modules/immediate/README.md +0 -93
  59. data/node_modules/immediate/dist/immediate.js +0 -75
  60. data/node_modules/immediate/dist/immediate.min.js +0 -1
  61. data/node_modules/immediate/lib/browser.js +0 -69
  62. data/node_modules/immediate/lib/index.js +0 -73
  63. data/node_modules/immediate/package.json +0 -42
  64. data/node_modules/inflight/LICENSE +0 -15
  65. data/node_modules/inflight/README.md +0 -37
  66. data/node_modules/inflight/inflight.js +0 -54
  67. data/node_modules/inflight/package.json +0 -29
  68. data/node_modules/inherits/LICENSE +0 -16
  69. data/node_modules/inherits/README.md +0 -42
  70. data/node_modules/inherits/inherits.js +0 -9
  71. data/node_modules/inherits/inherits_browser.js +0 -27
  72. data/node_modules/inherits/package.json +0 -29
  73. data/node_modules/isarray/.npmignore +0 -1
  74. data/node_modules/isarray/.travis.yml +0 -4
  75. data/node_modules/isarray/Makefile +0 -6
  76. data/node_modules/isarray/README.md +0 -60
  77. data/node_modules/isarray/component.json +0 -19
  78. data/node_modules/isarray/index.js +0 -5
  79. data/node_modules/isarray/package.json +0 -45
  80. data/node_modules/isarray/test.js +0 -20
  81. data/node_modules/jszip/.codeclimate.yml +0 -16
  82. data/node_modules/jszip/.editorconfig +0 -8
  83. data/node_modules/jszip/.jshintignore +0 -1
  84. data/node_modules/jszip/.jshintrc +0 -21
  85. data/node_modules/jszip/.travis.yml +0 -17
  86. data/node_modules/jszip/CHANGES.md +0 -163
  87. data/node_modules/jszip/LICENSE.markdown +0 -651
  88. data/node_modules/jszip/README.markdown +0 -35
  89. data/node_modules/jszip/dist/jszip.js +0 -30
  90. data/node_modules/jszip/dist/jszip.min.js +0 -13
  91. data/node_modules/jszip/index.d.ts +0 -270
  92. data/node_modules/jszip/lib/base64.js +0 -106
  93. data/node_modules/jszip/lib/compressedObject.js +0 -74
  94. data/node_modules/jszip/lib/compressions.js +0 -14
  95. data/node_modules/jszip/lib/crc32.js +0 -77
  96. data/node_modules/jszip/lib/defaults.js +0 -11
  97. data/node_modules/jszip/lib/external.js +0 -19
  98. data/node_modules/jszip/lib/flate.js +0 -85
  99. data/node_modules/jszip/lib/generate/ZipFileWorker.js +0 -540
  100. data/node_modules/jszip/lib/generate/index.js +0 -57
  101. data/node_modules/jszip/lib/index.js +0 -52
  102. data/node_modules/jszip/lib/license_header.js +0 -11
  103. data/node_modules/jszip/lib/load.js +0 -81
  104. data/node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js +0 -74
  105. data/node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js +0 -42
  106. data/node_modules/jszip/lib/nodejsUtils.js +0 -57
  107. data/node_modules/jszip/lib/object.js +0 -389
  108. data/node_modules/jszip/lib/readable-stream-browser.js +0 -9
  109. data/node_modules/jszip/lib/reader/ArrayReader.js +0 -57
  110. data/node_modules/jszip/lib/reader/DataReader.js +0 -116
  111. data/node_modules/jszip/lib/reader/NodeBufferReader.js +0 -19
  112. data/node_modules/jszip/lib/reader/StringReader.js +0 -38
  113. data/node_modules/jszip/lib/reader/Uint8ArrayReader.js +0 -22
  114. data/node_modules/jszip/lib/reader/readerFor.js +0 -28
  115. data/node_modules/jszip/lib/signature.js +0 -7
  116. data/node_modules/jszip/lib/stream/ConvertWorker.js +0 -26
  117. data/node_modules/jszip/lib/stream/Crc32Probe.js +0 -24
  118. data/node_modules/jszip/lib/stream/DataLengthProbe.js +0 -29
  119. data/node_modules/jszip/lib/stream/DataWorker.js +0 -116
  120. data/node_modules/jszip/lib/stream/GenericWorker.js +0 -263
  121. data/node_modules/jszip/lib/stream/StreamHelper.js +0 -212
  122. data/node_modules/jszip/lib/support.js +0 -38
  123. data/node_modules/jszip/lib/utf8.js +0 -275
  124. data/node_modules/jszip/lib/utils.js +0 -476
  125. data/node_modules/jszip/lib/zipEntries.js +0 -262
  126. data/node_modules/jszip/lib/zipEntry.js +0 -294
  127. data/node_modules/jszip/lib/zipObject.js +0 -133
  128. data/node_modules/jszip/package.json +0 -63
  129. data/node_modules/jszip/vendor/FileSaver.js +0 -247
  130. data/node_modules/lie/README.md +0 -62
  131. data/node_modules/lie/dist/lie.js +0 -350
  132. data/node_modules/lie/dist/lie.min.js +0 -1
  133. data/node_modules/lie/dist/lie.polyfill.js +0 -358
  134. data/node_modules/lie/dist/lie.polyfill.min.js +0 -1
  135. data/node_modules/lie/lib/browser.js +0 -273
  136. data/node_modules/lie/lib/index.js +0 -298
  137. data/node_modules/lie/license.md +0 -7
  138. data/node_modules/lie/lie.d.ts +0 -244
  139. data/node_modules/lie/package.json +0 -69
  140. data/node_modules/lie/polyfill.js +0 -4
  141. data/node_modules/minimatch/LICENSE +0 -15
  142. data/node_modules/minimatch/README.md +0 -209
  143. data/node_modules/minimatch/minimatch.js +0 -923
  144. data/node_modules/minimatch/package.json +0 -30
  145. data/node_modules/once/LICENSE +0 -15
  146. data/node_modules/once/README.md +0 -79
  147. data/node_modules/once/once.js +0 -42
  148. data/node_modules/once/package.json +0 -33
  149. data/node_modules/pako/CHANGELOG.md +0 -164
  150. data/node_modules/pako/LICENSE +0 -21
  151. data/node_modules/pako/README.md +0 -191
  152. data/node_modules/pako/dist/pako.js +0 -6818
  153. data/node_modules/pako/dist/pako.min.js +0 -1
  154. data/node_modules/pako/dist/pako_deflate.js +0 -3997
  155. data/node_modules/pako/dist/pako_deflate.min.js +0 -1
  156. data/node_modules/pako/dist/pako_inflate.js +0 -3300
  157. data/node_modules/pako/dist/pako_inflate.min.js +0 -1
  158. data/node_modules/pako/index.js +0 -14
  159. data/node_modules/pako/lib/deflate.js +0 -400
  160. data/node_modules/pako/lib/inflate.js +0 -423
  161. data/node_modules/pako/lib/utils/common.js +0 -105
  162. data/node_modules/pako/lib/utils/strings.js +0 -187
  163. data/node_modules/pako/lib/zlib/README +0 -59
  164. data/node_modules/pako/lib/zlib/adler32.js +0 -51
  165. data/node_modules/pako/lib/zlib/constants.js +0 -68
  166. data/node_modules/pako/lib/zlib/crc32.js +0 -59
  167. data/node_modules/pako/lib/zlib/deflate.js +0 -1874
  168. data/node_modules/pako/lib/zlib/gzheader.js +0 -58
  169. data/node_modules/pako/lib/zlib/inffast.js +0 -345
  170. data/node_modules/pako/lib/zlib/inflate.js +0 -1556
  171. data/node_modules/pako/lib/zlib/inftrees.js +0 -343
  172. data/node_modules/pako/lib/zlib/messages.js +0 -32
  173. data/node_modules/pako/lib/zlib/trees.js +0 -1222
  174. data/node_modules/pako/lib/zlib/zstream.js +0 -47
  175. data/node_modules/pako/package.json +0 -44
  176. data/node_modules/path-is-absolute/index.js +0 -20
  177. data/node_modules/path-is-absolute/license +0 -21
  178. data/node_modules/path-is-absolute/package.json +0 -43
  179. data/node_modules/path-is-absolute/readme.md +0 -59
  180. data/node_modules/process-nextick-args/index.js +0 -45
  181. data/node_modules/process-nextick-args/license.md +0 -19
  182. data/node_modules/process-nextick-args/package.json +0 -25
  183. data/node_modules/process-nextick-args/readme.md +0 -18
  184. data/node_modules/readable-stream/.travis.yml +0 -34
  185. data/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  186. data/node_modules/readable-stream/GOVERNANCE.md +0 -136
  187. data/node_modules/readable-stream/LICENSE +0 -47
  188. data/node_modules/readable-stream/README.md +0 -58
  189. data/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +0 -60
  190. data/node_modules/readable-stream/duplex-browser.js +0 -1
  191. data/node_modules/readable-stream/duplex.js +0 -1
  192. data/node_modules/readable-stream/lib/_stream_duplex.js +0 -131
  193. data/node_modules/readable-stream/lib/_stream_passthrough.js +0 -47
  194. data/node_modules/readable-stream/lib/_stream_readable.js +0 -1019
  195. data/node_modules/readable-stream/lib/_stream_transform.js +0 -214
  196. data/node_modules/readable-stream/lib/_stream_writable.js +0 -687
  197. data/node_modules/readable-stream/lib/internal/streams/BufferList.js +0 -79
  198. data/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -74
  199. data/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  200. data/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  201. data/node_modules/readable-stream/package.json +0 -52
  202. data/node_modules/readable-stream/passthrough.js +0 -1
  203. data/node_modules/readable-stream/readable-browser.js +0 -7
  204. data/node_modules/readable-stream/readable.js +0 -19
  205. data/node_modules/readable-stream/transform.js +0 -1
  206. data/node_modules/readable-stream/writable-browser.js +0 -1
  207. data/node_modules/readable-stream/writable.js +0 -8
  208. data/node_modules/rimraf/LICENSE +0 -15
  209. data/node_modules/rimraf/README.md +0 -101
  210. data/node_modules/rimraf/bin.js +0 -50
  211. data/node_modules/rimraf/package.json +0 -29
  212. data/node_modules/rimraf/rimraf.js +0 -372
  213. data/node_modules/safe-buffer/LICENSE +0 -21
  214. data/node_modules/safe-buffer/README.md +0 -584
  215. data/node_modules/safe-buffer/index.d.ts +0 -187
  216. data/node_modules/safe-buffer/index.js +0 -62
  217. data/node_modules/safe-buffer/package.json +0 -37
  218. data/node_modules/selenium-webdriver/CHANGES.md +0 -1114
  219. data/node_modules/selenium-webdriver/LICENSE +0 -202
  220. data/node_modules/selenium-webdriver/NOTICE +0 -2
  221. data/node_modules/selenium-webdriver/README.md +0 -229
  222. data/node_modules/selenium-webdriver/chrome.js +0 -295
  223. data/node_modules/selenium-webdriver/chromium.js +0 -829
  224. data/node_modules/selenium-webdriver/devtools/CDPConnection.js +0 -35
  225. data/node_modules/selenium-webdriver/edge.js +0 -224
  226. data/node_modules/selenium-webdriver/example/chrome_android.js +0 -45
  227. data/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js +0 -46
  228. data/node_modules/selenium-webdriver/example/firefox_channels.js +0 -84
  229. data/node_modules/selenium-webdriver/example/google_search.js +0 -50
  230. data/node_modules/selenium-webdriver/example/google_search_test.js +0 -70
  231. data/node_modules/selenium-webdriver/example/headless.js +0 -63
  232. data/node_modules/selenium-webdriver/example/logging.js +0 -64
  233. data/node_modules/selenium-webdriver/firefox.js +0 -789
  234. data/node_modules/selenium-webdriver/http/index.js +0 -324
  235. data/node_modules/selenium-webdriver/http/util.js +0 -172
  236. data/node_modules/selenium-webdriver/ie.js +0 -503
  237. data/node_modules/selenium-webdriver/index.js +0 -825
  238. data/node_modules/selenium-webdriver/io/exec.js +0 -162
  239. data/node_modules/selenium-webdriver/io/index.js +0 -348
  240. data/node_modules/selenium-webdriver/io/zip.js +0 -223
  241. data/node_modules/selenium-webdriver/lib/atoms/find-elements.js +0 -123
  242. data/node_modules/selenium-webdriver/lib/atoms/get-attribute.js +0 -101
  243. data/node_modules/selenium-webdriver/lib/atoms/is-displayed.js +0 -101
  244. data/node_modules/selenium-webdriver/lib/atoms/mutation-listener.js +0 -55
  245. data/node_modules/selenium-webdriver/lib/by.js +0 -415
  246. data/node_modules/selenium-webdriver/lib/capabilities.js +0 -553
  247. data/node_modules/selenium-webdriver/lib/command.js +0 -206
  248. data/node_modules/selenium-webdriver/lib/error.js +0 -605
  249. data/node_modules/selenium-webdriver/lib/http.js +0 -704
  250. data/node_modules/selenium-webdriver/lib/input.js +0 -946
  251. data/node_modules/selenium-webdriver/lib/logging.js +0 -661
  252. data/node_modules/selenium-webdriver/lib/promise.js +0 -285
  253. data/node_modules/selenium-webdriver/lib/proxy.js +0 -212
  254. data/node_modules/selenium-webdriver/lib/session.js +0 -77
  255. data/node_modules/selenium-webdriver/lib/symbols.js +0 -37
  256. data/node_modules/selenium-webdriver/lib/until.js +0 -429
  257. data/node_modules/selenium-webdriver/lib/webdriver.js +0 -2919
  258. data/node_modules/selenium-webdriver/net/index.js +0 -107
  259. data/node_modules/selenium-webdriver/net/portprober.js +0 -75
  260. data/node_modules/selenium-webdriver/opera.js +0 -406
  261. data/node_modules/selenium-webdriver/package.json +0 -54
  262. data/node_modules/selenium-webdriver/proxy.js +0 -32
  263. data/node_modules/selenium-webdriver/remote/index.js +0 -624
  264. data/node_modules/selenium-webdriver/safari.js +0 -168
  265. data/node_modules/selenium-webdriver/testing/index.js +0 -504
  266. data/node_modules/set-immediate-shim/index.js +0 -7
  267. data/node_modules/set-immediate-shim/package.json +0 -34
  268. data/node_modules/set-immediate-shim/readme.md +0 -31
  269. data/node_modules/string_decoder/.travis.yml +0 -50
  270. data/node_modules/string_decoder/LICENSE +0 -48
  271. data/node_modules/string_decoder/README.md +0 -47
  272. data/node_modules/string_decoder/lib/string_decoder.js +0 -296
  273. data/node_modules/string_decoder/package.json +0 -31
  274. data/node_modules/tmp/CHANGELOG.md +0 -288
  275. data/node_modules/tmp/LICENSE +0 -21
  276. data/node_modules/tmp/README.md +0 -365
  277. data/node_modules/tmp/lib/tmp.js +0 -780
  278. data/node_modules/tmp/node_modules/.bin/rimraf +0 -1
  279. data/node_modules/tmp/node_modules/rimraf/CHANGELOG.md +0 -65
  280. data/node_modules/tmp/node_modules/rimraf/LICENSE +0 -15
  281. data/node_modules/tmp/node_modules/rimraf/README.md +0 -101
  282. data/node_modules/tmp/node_modules/rimraf/bin.js +0 -68
  283. data/node_modules/tmp/node_modules/rimraf/package.json +0 -32
  284. data/node_modules/tmp/node_modules/rimraf/rimraf.js +0 -360
  285. data/node_modules/tmp/package.json +0 -58
  286. data/node_modules/util-deprecate/History.md +0 -16
  287. data/node_modules/util-deprecate/LICENSE +0 -24
  288. data/node_modules/util-deprecate/README.md +0 -53
  289. data/node_modules/util-deprecate/browser.js +0 -67
  290. data/node_modules/util-deprecate/node.js +0 -6
  291. data/node_modules/util-deprecate/package.json +0 -27
  292. data/node_modules/wrappy/LICENSE +0 -15
  293. data/node_modules/wrappy/README.md +0 -36
  294. data/node_modules/wrappy/package.json +0 -29
  295. data/node_modules/wrappy/wrappy.js +0 -33
  296. data/node_modules/ws/LICENSE +0 -21
  297. data/node_modules/ws/README.md +0 -496
  298. data/node_modules/ws/browser.js +0 -8
  299. data/node_modules/ws/index.js +0 -10
  300. data/node_modules/ws/lib/buffer-util.js +0 -129
  301. data/node_modules/ws/lib/constants.js +0 -10
  302. data/node_modules/ws/lib/event-target.js +0 -184
  303. data/node_modules/ws/lib/extension.js +0 -223
  304. data/node_modules/ws/lib/limiter.js +0 -55
  305. data/node_modules/ws/lib/permessage-deflate.js +0 -517
  306. data/node_modules/ws/lib/receiver.js +0 -507
  307. data/node_modules/ws/lib/sender.js +0 -405
  308. data/node_modules/ws/lib/stream.js +0 -165
  309. data/node_modules/ws/lib/validation.js +0 -104
  310. data/node_modules/ws/lib/websocket-server.js +0 -418
  311. data/node_modules/ws/lib/websocket.js +0 -942
  312. data/node_modules/ws/package.json +0 -56
  313. data/package-lock.json +0 -458
  314. data/package.json +0 -5
  315. data/selenium.log +0 -1
  316. data/spec.md +0 -6
  317. data/test.data +0 -2110
@@ -1,942 +0,0 @@
1
- 'use strict';
2
-
3
- const EventEmitter = require('events');
4
- const https = require('https');
5
- const http = require('http');
6
- const net = require('net');
7
- const tls = require('tls');
8
- const { randomBytes, createHash } = require('crypto');
9
- const { URL } = require('url');
10
-
11
- const PerMessageDeflate = require('./permessage-deflate');
12
- const Receiver = require('./receiver');
13
- const Sender = require('./sender');
14
- const {
15
- BINARY_TYPES,
16
- EMPTY_BUFFER,
17
- GUID,
18
- kStatusCode,
19
- kWebSocket,
20
- NOOP
21
- } = require('./constants');
22
- const { addEventListener, removeEventListener } = require('./event-target');
23
- const { format, parse } = require('./extension');
24
- const { toBuffer } = require('./buffer-util');
25
-
26
- const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];
27
- const protocolVersions = [8, 13];
28
- const closeTimeout = 30 * 1000;
29
-
30
- /**
31
- * Class representing a WebSocket.
32
- *
33
- * @extends EventEmitter
34
- */
35
- class WebSocket extends EventEmitter {
36
- /**
37
- * Create a new `WebSocket`.
38
- *
39
- * @param {(String|url.URL)} address The URL to which to connect
40
- * @param {(String|String[])} [protocols] The subprotocols
41
- * @param {Object} [options] Connection options
42
- */
43
- constructor(address, protocols, options) {
44
- super();
45
-
46
- this._binaryType = BINARY_TYPES[0];
47
- this._closeCode = 1006;
48
- this._closeFrameReceived = false;
49
- this._closeFrameSent = false;
50
- this._closeMessage = '';
51
- this._closeTimer = null;
52
- this._extensions = {};
53
- this._protocol = '';
54
- this._readyState = WebSocket.CONNECTING;
55
- this._receiver = null;
56
- this._sender = null;
57
- this._socket = null;
58
-
59
- if (address !== null) {
60
- this._bufferedAmount = 0;
61
- this._isServer = false;
62
- this._redirects = 0;
63
-
64
- if (Array.isArray(protocols)) {
65
- protocols = protocols.join(', ');
66
- } else if (typeof protocols === 'object' && protocols !== null) {
67
- options = protocols;
68
- protocols = undefined;
69
- }
70
-
71
- initAsClient(this, address, protocols, options);
72
- } else {
73
- this._isServer = true;
74
- }
75
- }
76
-
77
- /**
78
- * This deviates from the WHATWG interface since ws doesn't support the
79
- * required default "blob" type (instead we define a custom "nodebuffer"
80
- * type).
81
- *
82
- * @type {String}
83
- */
84
- get binaryType() {
85
- return this._binaryType;
86
- }
87
-
88
- set binaryType(type) {
89
- if (!BINARY_TYPES.includes(type)) return;
90
-
91
- this._binaryType = type;
92
-
93
- //
94
- // Allow to change `binaryType` on the fly.
95
- //
96
- if (this._receiver) this._receiver._binaryType = type;
97
- }
98
-
99
- /**
100
- * @type {Number}
101
- */
102
- get bufferedAmount() {
103
- if (!this._socket) return this._bufferedAmount;
104
-
105
- return this._socket._writableState.length + this._sender._bufferedBytes;
106
- }
107
-
108
- /**
109
- * @type {String}
110
- */
111
- get extensions() {
112
- return Object.keys(this._extensions).join();
113
- }
114
-
115
- /**
116
- * @type {String}
117
- */
118
- get protocol() {
119
- return this._protocol;
120
- }
121
-
122
- /**
123
- * @type {Number}
124
- */
125
- get readyState() {
126
- return this._readyState;
127
- }
128
-
129
- /**
130
- * @type {String}
131
- */
132
- get url() {
133
- return this._url;
134
- }
135
-
136
- /**
137
- * Set up the socket and the internal resources.
138
- *
139
- * @param {net.Socket} socket The network socket between the server and client
140
- * @param {Buffer} head The first packet of the upgraded stream
141
- * @param {Number} [maxPayload=0] The maximum allowed message size
142
- * @private
143
- */
144
- setSocket(socket, head, maxPayload) {
145
- const receiver = new Receiver(
146
- this.binaryType,
147
- this._extensions,
148
- this._isServer,
149
- maxPayload
150
- );
151
-
152
- this._sender = new Sender(socket, this._extensions);
153
- this._receiver = receiver;
154
- this._socket = socket;
155
-
156
- receiver[kWebSocket] = this;
157
- socket[kWebSocket] = this;
158
-
159
- receiver.on('conclude', receiverOnConclude);
160
- receiver.on('drain', receiverOnDrain);
161
- receiver.on('error', receiverOnError);
162
- receiver.on('message', receiverOnMessage);
163
- receiver.on('ping', receiverOnPing);
164
- receiver.on('pong', receiverOnPong);
165
-
166
- socket.setTimeout(0);
167
- socket.setNoDelay();
168
-
169
- if (head.length > 0) socket.unshift(head);
170
-
171
- socket.on('close', socketOnClose);
172
- socket.on('data', socketOnData);
173
- socket.on('end', socketOnEnd);
174
- socket.on('error', socketOnError);
175
-
176
- this._readyState = WebSocket.OPEN;
177
- this.emit('open');
178
- }
179
-
180
- /**
181
- * Emit the `'close'` event.
182
- *
183
- * @private
184
- */
185
- emitClose() {
186
- if (!this._socket) {
187
- this._readyState = WebSocket.CLOSED;
188
- this.emit('close', this._closeCode, this._closeMessage);
189
- return;
190
- }
191
-
192
- if (this._extensions[PerMessageDeflate.extensionName]) {
193
- this._extensions[PerMessageDeflate.extensionName].cleanup();
194
- }
195
-
196
- this._receiver.removeAllListeners();
197
- this._readyState = WebSocket.CLOSED;
198
- this.emit('close', this._closeCode, this._closeMessage);
199
- }
200
-
201
- /**
202
- * Start a closing handshake.
203
- *
204
- * +----------+ +-----------+ +----------+
205
- * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -
206
- * | +----------+ +-----------+ +----------+ |
207
- * +----------+ +-----------+ |
208
- * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING
209
- * +----------+ +-----------+ |
210
- * | | | +---+ |
211
- * +------------------------+-->|fin| - - - -
212
- * | +---+ | +---+
213
- * - - - - -|fin|<---------------------+
214
- * +---+
215
- *
216
- * @param {Number} [code] Status code explaining why the connection is closing
217
- * @param {String} [data] A string explaining why the connection is closing
218
- * @public
219
- */
220
- close(code, data) {
221
- if (this.readyState === WebSocket.CLOSED) return;
222
- if (this.readyState === WebSocket.CONNECTING) {
223
- const msg = 'WebSocket was closed before the connection was established';
224
- return abortHandshake(this, this._req, msg);
225
- }
226
-
227
- if (this.readyState === WebSocket.CLOSING) {
228
- if (this._closeFrameSent && this._closeFrameReceived) this._socket.end();
229
- return;
230
- }
231
-
232
- this._readyState = WebSocket.CLOSING;
233
- this._sender.close(code, data, !this._isServer, (err) => {
234
- //
235
- // This error is handled by the `'error'` listener on the socket. We only
236
- // want to know if the close frame has been sent here.
237
- //
238
- if (err) return;
239
-
240
- this._closeFrameSent = true;
241
- if (this._closeFrameReceived) this._socket.end();
242
- });
243
-
244
- //
245
- // Specify a timeout for the closing handshake to complete.
246
- //
247
- this._closeTimer = setTimeout(
248
- this._socket.destroy.bind(this._socket),
249
- closeTimeout
250
- );
251
- }
252
-
253
- /**
254
- * Send a ping.
255
- *
256
- * @param {*} [data] The data to send
257
- * @param {Boolean} [mask] Indicates whether or not to mask `data`
258
- * @param {Function} [cb] Callback which is executed when the ping is sent
259
- * @public
260
- */
261
- ping(data, mask, cb) {
262
- if (this.readyState === WebSocket.CONNECTING) {
263
- throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
264
- }
265
-
266
- if (typeof data === 'function') {
267
- cb = data;
268
- data = mask = undefined;
269
- } else if (typeof mask === 'function') {
270
- cb = mask;
271
- mask = undefined;
272
- }
273
-
274
- if (typeof data === 'number') data = data.toString();
275
-
276
- if (this.readyState !== WebSocket.OPEN) {
277
- sendAfterClose(this, data, cb);
278
- return;
279
- }
280
-
281
- if (mask === undefined) mask = !this._isServer;
282
- this._sender.ping(data || EMPTY_BUFFER, mask, cb);
283
- }
284
-
285
- /**
286
- * Send a pong.
287
- *
288
- * @param {*} [data] The data to send
289
- * @param {Boolean} [mask] Indicates whether or not to mask `data`
290
- * @param {Function} [cb] Callback which is executed when the pong is sent
291
- * @public
292
- */
293
- pong(data, mask, cb) {
294
- if (this.readyState === WebSocket.CONNECTING) {
295
- throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
296
- }
297
-
298
- if (typeof data === 'function') {
299
- cb = data;
300
- data = mask = undefined;
301
- } else if (typeof mask === 'function') {
302
- cb = mask;
303
- mask = undefined;
304
- }
305
-
306
- if (typeof data === 'number') data = data.toString();
307
-
308
- if (this.readyState !== WebSocket.OPEN) {
309
- sendAfterClose(this, data, cb);
310
- return;
311
- }
312
-
313
- if (mask === undefined) mask = !this._isServer;
314
- this._sender.pong(data || EMPTY_BUFFER, mask, cb);
315
- }
316
-
317
- /**
318
- * Send a data message.
319
- *
320
- * @param {*} data The message to send
321
- * @param {Object} [options] Options object
322
- * @param {Boolean} [options.compress] Specifies whether or not to compress
323
- * `data`
324
- * @param {Boolean} [options.binary] Specifies whether `data` is binary or
325
- * text
326
- * @param {Boolean} [options.fin=true] Specifies whether the fragment is the
327
- * last one
328
- * @param {Boolean} [options.mask] Specifies whether or not to mask `data`
329
- * @param {Function} [cb] Callback which is executed when data is written out
330
- * @public
331
- */
332
- send(data, options, cb) {
333
- if (this.readyState === WebSocket.CONNECTING) {
334
- throw new Error('WebSocket is not open: readyState 0 (CONNECTING)');
335
- }
336
-
337
- if (typeof options === 'function') {
338
- cb = options;
339
- options = {};
340
- }
341
-
342
- if (typeof data === 'number') data = data.toString();
343
-
344
- if (this.readyState !== WebSocket.OPEN) {
345
- sendAfterClose(this, data, cb);
346
- return;
347
- }
348
-
349
- const opts = {
350
- binary: typeof data !== 'string',
351
- mask: !this._isServer,
352
- compress: true,
353
- fin: true,
354
- ...options
355
- };
356
-
357
- if (!this._extensions[PerMessageDeflate.extensionName]) {
358
- opts.compress = false;
359
- }
360
-
361
- this._sender.send(data || EMPTY_BUFFER, opts, cb);
362
- }
363
-
364
- /**
365
- * Forcibly close the connection.
366
- *
367
- * @public
368
- */
369
- terminate() {
370
- if (this.readyState === WebSocket.CLOSED) return;
371
- if (this.readyState === WebSocket.CONNECTING) {
372
- const msg = 'WebSocket was closed before the connection was established';
373
- return abortHandshake(this, this._req, msg);
374
- }
375
-
376
- if (this._socket) {
377
- this._readyState = WebSocket.CLOSING;
378
- this._socket.destroy();
379
- }
380
- }
381
- }
382
-
383
- readyStates.forEach((readyState, i) => {
384
- const descriptor = { enumerable: true, value: i };
385
-
386
- Object.defineProperty(WebSocket.prototype, readyState, descriptor);
387
- Object.defineProperty(WebSocket, readyState, descriptor);
388
- });
389
-
390
- [
391
- 'binaryType',
392
- 'bufferedAmount',
393
- 'extensions',
394
- 'protocol',
395
- 'readyState',
396
- 'url'
397
- ].forEach((property) => {
398
- Object.defineProperty(WebSocket.prototype, property, { enumerable: true });
399
- });
400
-
401
- //
402
- // Add the `onopen`, `onerror`, `onclose`, and `onmessage` attributes.
403
- // See https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface
404
- //
405
- ['open', 'error', 'close', 'message'].forEach((method) => {
406
- Object.defineProperty(WebSocket.prototype, `on${method}`, {
407
- configurable: true,
408
- enumerable: true,
409
- /**
410
- * Return the listener of the event.
411
- *
412
- * @return {(Function|undefined)} The event listener or `undefined`
413
- * @public
414
- */
415
- get() {
416
- const listeners = this.listeners(method);
417
- for (let i = 0; i < listeners.length; i++) {
418
- if (listeners[i]._listener) return listeners[i]._listener;
419
- }
420
-
421
- return undefined;
422
- },
423
- /**
424
- * Add a listener for the event.
425
- *
426
- * @param {Function} listener The listener to add
427
- * @public
428
- */
429
- set(listener) {
430
- const listeners = this.listeners(method);
431
- for (let i = 0; i < listeners.length; i++) {
432
- //
433
- // Remove only the listeners added via `addEventListener`.
434
- //
435
- if (listeners[i]._listener) this.removeListener(method, listeners[i]);
436
- }
437
- this.addEventListener(method, listener);
438
- }
439
- });
440
- });
441
-
442
- WebSocket.prototype.addEventListener = addEventListener;
443
- WebSocket.prototype.removeEventListener = removeEventListener;
444
-
445
- module.exports = WebSocket;
446
-
447
- /**
448
- * Initialize a WebSocket client.
449
- *
450
- * @param {WebSocket} websocket The client to initialize
451
- * @param {(String|url.URL)} address The URL to which to connect
452
- * @param {String} [protocols] The subprotocols
453
- * @param {Object} [options] Connection options
454
- * @param {(Boolean|Object)} [options.perMessageDeflate=true] Enable/disable
455
- * permessage-deflate
456
- * @param {Number} [options.handshakeTimeout] Timeout in milliseconds for the
457
- * handshake request
458
- * @param {Number} [options.protocolVersion=13] Value of the
459
- * `Sec-WebSocket-Version` header
460
- * @param {String} [options.origin] Value of the `Origin` or
461
- * `Sec-WebSocket-Origin` header
462
- * @param {Number} [options.maxPayload=104857600] The maximum allowed message
463
- * size
464
- * @param {Boolean} [options.followRedirects=false] Whether or not to follow
465
- * redirects
466
- * @param {Number} [options.maxRedirects=10] The maximum number of redirects
467
- * allowed
468
- * @private
469
- */
470
- function initAsClient(websocket, address, protocols, options) {
471
- const opts = {
472
- protocolVersion: protocolVersions[1],
473
- maxPayload: 100 * 1024 * 1024,
474
- perMessageDeflate: true,
475
- followRedirects: false,
476
- maxRedirects: 10,
477
- ...options,
478
- createConnection: undefined,
479
- socketPath: undefined,
480
- hostname: undefined,
481
- protocol: undefined,
482
- timeout: undefined,
483
- method: undefined,
484
- host: undefined,
485
- path: undefined,
486
- port: undefined
487
- };
488
-
489
- if (!protocolVersions.includes(opts.protocolVersion)) {
490
- throw new RangeError(
491
- `Unsupported protocol version: ${opts.protocolVersion} ` +
492
- `(supported versions: ${protocolVersions.join(', ')})`
493
- );
494
- }
495
-
496
- let parsedUrl;
497
-
498
- if (address instanceof URL) {
499
- parsedUrl = address;
500
- websocket._url = address.href;
501
- } else {
502
- parsedUrl = new URL(address);
503
- websocket._url = address;
504
- }
505
-
506
- const isUnixSocket = parsedUrl.protocol === 'ws+unix:';
507
-
508
- if (!parsedUrl.host && (!isUnixSocket || !parsedUrl.pathname)) {
509
- throw new Error(`Invalid URL: ${websocket.url}`);
510
- }
511
-
512
- const isSecure =
513
- parsedUrl.protocol === 'wss:' || parsedUrl.protocol === 'https:';
514
- const defaultPort = isSecure ? 443 : 80;
515
- const key = randomBytes(16).toString('base64');
516
- const get = isSecure ? https.get : http.get;
517
- let perMessageDeflate;
518
-
519
- opts.createConnection = isSecure ? tlsConnect : netConnect;
520
- opts.defaultPort = opts.defaultPort || defaultPort;
521
- opts.port = parsedUrl.port || defaultPort;
522
- opts.host = parsedUrl.hostname.startsWith('[')
523
- ? parsedUrl.hostname.slice(1, -1)
524
- : parsedUrl.hostname;
525
- opts.headers = {
526
- 'Sec-WebSocket-Version': opts.protocolVersion,
527
- 'Sec-WebSocket-Key': key,
528
- Connection: 'Upgrade',
529
- Upgrade: 'websocket',
530
- ...opts.headers
531
- };
532
- opts.path = parsedUrl.pathname + parsedUrl.search;
533
- opts.timeout = opts.handshakeTimeout;
534
-
535
- if (opts.perMessageDeflate) {
536
- perMessageDeflate = new PerMessageDeflate(
537
- opts.perMessageDeflate !== true ? opts.perMessageDeflate : {},
538
- false,
539
- opts.maxPayload
540
- );
541
- opts.headers['Sec-WebSocket-Extensions'] = format({
542
- [PerMessageDeflate.extensionName]: perMessageDeflate.offer()
543
- });
544
- }
545
- if (protocols) {
546
- opts.headers['Sec-WebSocket-Protocol'] = protocols;
547
- }
548
- if (opts.origin) {
549
- if (opts.protocolVersion < 13) {
550
- opts.headers['Sec-WebSocket-Origin'] = opts.origin;
551
- } else {
552
- opts.headers.Origin = opts.origin;
553
- }
554
- }
555
- if (parsedUrl.username || parsedUrl.password) {
556
- opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
557
- }
558
-
559
- if (isUnixSocket) {
560
- const parts = opts.path.split(':');
561
-
562
- opts.socketPath = parts[0];
563
- opts.path = parts[1];
564
- }
565
-
566
- let req = (websocket._req = get(opts));
567
-
568
- if (opts.timeout) {
569
- req.on('timeout', () => {
570
- abortHandshake(websocket, req, 'Opening handshake has timed out');
571
- });
572
- }
573
-
574
- req.on('error', (err) => {
575
- if (req === null || req.aborted) return;
576
-
577
- req = websocket._req = null;
578
- websocket._readyState = WebSocket.CLOSING;
579
- websocket.emit('error', err);
580
- websocket.emitClose();
581
- });
582
-
583
- req.on('response', (res) => {
584
- const location = res.headers.location;
585
- const statusCode = res.statusCode;
586
-
587
- if (
588
- location &&
589
- opts.followRedirects &&
590
- statusCode >= 300 &&
591
- statusCode < 400
592
- ) {
593
- if (++websocket._redirects > opts.maxRedirects) {
594
- abortHandshake(websocket, req, 'Maximum redirects exceeded');
595
- return;
596
- }
597
-
598
- req.abort();
599
-
600
- const addr = new URL(location, address);
601
-
602
- initAsClient(websocket, addr, protocols, options);
603
- } else if (!websocket.emit('unexpected-response', req, res)) {
604
- abortHandshake(
605
- websocket,
606
- req,
607
- `Unexpected server response: ${res.statusCode}`
608
- );
609
- }
610
- });
611
-
612
- req.on('upgrade', (res, socket, head) => {
613
- websocket.emit('upgrade', res);
614
-
615
- //
616
- // The user may have closed the connection from a listener of the `upgrade`
617
- // event.
618
- //
619
- if (websocket.readyState !== WebSocket.CONNECTING) return;
620
-
621
- req = websocket._req = null;
622
-
623
- const digest = createHash('sha1')
624
- .update(key + GUID)
625
- .digest('base64');
626
-
627
- if (res.headers['sec-websocket-accept'] !== digest) {
628
- abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');
629
- return;
630
- }
631
-
632
- const serverProt = res.headers['sec-websocket-protocol'];
633
- const protList = (protocols || '').split(/, */);
634
- let protError;
635
-
636
- if (!protocols && serverProt) {
637
- protError = 'Server sent a subprotocol but none was requested';
638
- } else if (protocols && !serverProt) {
639
- protError = 'Server sent no subprotocol';
640
- } else if (serverProt && !protList.includes(serverProt)) {
641
- protError = 'Server sent an invalid subprotocol';
642
- }
643
-
644
- if (protError) {
645
- abortHandshake(websocket, socket, protError);
646
- return;
647
- }
648
-
649
- if (serverProt) websocket._protocol = serverProt;
650
-
651
- if (perMessageDeflate) {
652
- try {
653
- const extensions = parse(res.headers['sec-websocket-extensions']);
654
-
655
- if (extensions[PerMessageDeflate.extensionName]) {
656
- perMessageDeflate.accept(extensions[PerMessageDeflate.extensionName]);
657
- websocket._extensions[PerMessageDeflate.extensionName] =
658
- perMessageDeflate;
659
- }
660
- } catch (err) {
661
- abortHandshake(
662
- websocket,
663
- socket,
664
- 'Invalid Sec-WebSocket-Extensions header'
665
- );
666
- return;
667
- }
668
- }
669
-
670
- websocket.setSocket(socket, head, opts.maxPayload);
671
- });
672
- }
673
-
674
- /**
675
- * Create a `net.Socket` and initiate a connection.
676
- *
677
- * @param {Object} options Connection options
678
- * @return {net.Socket} The newly created socket used to start the connection
679
- * @private
680
- */
681
- function netConnect(options) {
682
- options.path = options.socketPath;
683
- return net.connect(options);
684
- }
685
-
686
- /**
687
- * Create a `tls.TLSSocket` and initiate a connection.
688
- *
689
- * @param {Object} options Connection options
690
- * @return {tls.TLSSocket} The newly created socket used to start the connection
691
- * @private
692
- */
693
- function tlsConnect(options) {
694
- options.path = undefined;
695
-
696
- if (!options.servername && options.servername !== '') {
697
- options.servername = net.isIP(options.host) ? '' : options.host;
698
- }
699
-
700
- return tls.connect(options);
701
- }
702
-
703
- /**
704
- * Abort the handshake and emit an error.
705
- *
706
- * @param {WebSocket} websocket The WebSocket instance
707
- * @param {(http.ClientRequest|net.Socket)} stream The request to abort or the
708
- * socket to destroy
709
- * @param {String} message The error message
710
- * @private
711
- */
712
- function abortHandshake(websocket, stream, message) {
713
- websocket._readyState = WebSocket.CLOSING;
714
-
715
- const err = new Error(message);
716
- Error.captureStackTrace(err, abortHandshake);
717
-
718
- if (stream.setHeader) {
719
- stream.abort();
720
-
721
- if (stream.socket && !stream.socket.destroyed) {
722
- //
723
- // On Node.js >= 14.3.0 `request.abort()` does not destroy the socket if
724
- // called after the request completed. See
725
- // https://github.com/websockets/ws/issues/1869.
726
- //
727
- stream.socket.destroy();
728
- }
729
-
730
- stream.once('abort', websocket.emitClose.bind(websocket));
731
- websocket.emit('error', err);
732
- } else {
733
- stream.destroy(err);
734
- stream.once('error', websocket.emit.bind(websocket, 'error'));
735
- stream.once('close', websocket.emitClose.bind(websocket));
736
- }
737
- }
738
-
739
- /**
740
- * Handle cases where the `ping()`, `pong()`, or `send()` methods are called
741
- * when the `readyState` attribute is `CLOSING` or `CLOSED`.
742
- *
743
- * @param {WebSocket} websocket The WebSocket instance
744
- * @param {*} [data] The data to send
745
- * @param {Function} [cb] Callback
746
- * @private
747
- */
748
- function sendAfterClose(websocket, data, cb) {
749
- if (data) {
750
- const length = toBuffer(data).length;
751
-
752
- //
753
- // The `_bufferedAmount` property is used only when the peer is a client and
754
- // the opening handshake fails. Under these circumstances, in fact, the
755
- // `setSocket()` method is not called, so the `_socket` and `_sender`
756
- // properties are set to `null`.
757
- //
758
- if (websocket._socket) websocket._sender._bufferedBytes += length;
759
- else websocket._bufferedAmount += length;
760
- }
761
-
762
- if (cb) {
763
- const err = new Error(
764
- `WebSocket is not open: readyState ${websocket.readyState} ` +
765
- `(${readyStates[websocket.readyState]})`
766
- );
767
- cb(err);
768
- }
769
- }
770
-
771
- /**
772
- * The listener of the `Receiver` `'conclude'` event.
773
- *
774
- * @param {Number} code The status code
775
- * @param {String} reason The reason for closing
776
- * @private
777
- */
778
- function receiverOnConclude(code, reason) {
779
- const websocket = this[kWebSocket];
780
-
781
- websocket._socket.removeListener('data', socketOnData);
782
- websocket._socket.resume();
783
-
784
- websocket._closeFrameReceived = true;
785
- websocket._closeMessage = reason;
786
- websocket._closeCode = code;
787
-
788
- if (code === 1005) websocket.close();
789
- else websocket.close(code, reason);
790
- }
791
-
792
- /**
793
- * The listener of the `Receiver` `'drain'` event.
794
- *
795
- * @private
796
- */
797
- function receiverOnDrain() {
798
- this[kWebSocket]._socket.resume();
799
- }
800
-
801
- /**
802
- * The listener of the `Receiver` `'error'` event.
803
- *
804
- * @param {(RangeError|Error)} err The emitted error
805
- * @private
806
- */
807
- function receiverOnError(err) {
808
- const websocket = this[kWebSocket];
809
-
810
- websocket._socket.removeListener('data', socketOnData);
811
-
812
- websocket._readyState = WebSocket.CLOSING;
813
- websocket._closeCode = err[kStatusCode];
814
- websocket.emit('error', err);
815
- websocket._socket.destroy();
816
- }
817
-
818
- /**
819
- * The listener of the `Receiver` `'finish'` event.
820
- *
821
- * @private
822
- */
823
- function receiverOnFinish() {
824
- this[kWebSocket].emitClose();
825
- }
826
-
827
- /**
828
- * The listener of the `Receiver` `'message'` event.
829
- *
830
- * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The message
831
- * @private
832
- */
833
- function receiverOnMessage(data) {
834
- this[kWebSocket].emit('message', data);
835
- }
836
-
837
- /**
838
- * The listener of the `Receiver` `'ping'` event.
839
- *
840
- * @param {Buffer} data The data included in the ping frame
841
- * @private
842
- */
843
- function receiverOnPing(data) {
844
- const websocket = this[kWebSocket];
845
-
846
- websocket.pong(data, !websocket._isServer, NOOP);
847
- websocket.emit('ping', data);
848
- }
849
-
850
- /**
851
- * The listener of the `Receiver` `'pong'` event.
852
- *
853
- * @param {Buffer} data The data included in the pong frame
854
- * @private
855
- */
856
- function receiverOnPong(data) {
857
- this[kWebSocket].emit('pong', data);
858
- }
859
-
860
- /**
861
- * The listener of the `net.Socket` `'close'` event.
862
- *
863
- * @private
864
- */
865
- function socketOnClose() {
866
- const websocket = this[kWebSocket];
867
-
868
- this.removeListener('close', socketOnClose);
869
- this.removeListener('end', socketOnEnd);
870
-
871
- websocket._readyState = WebSocket.CLOSING;
872
-
873
- //
874
- // The close frame might not have been received or the `'end'` event emitted,
875
- // for example, if the socket was destroyed due to an error. Ensure that the
876
- // `receiver` stream is closed after writing any remaining buffered data to
877
- // it. If the readable side of the socket is in flowing mode then there is no
878
- // buffered data as everything has been already written and `readable.read()`
879
- // will return `null`. If instead, the socket is paused, any possible buffered
880
- // data will be read as a single chunk and emitted synchronously in a single
881
- // `'data'` event.
882
- //
883
- websocket._socket.read();
884
- websocket._receiver.end();
885
-
886
- this.removeListener('data', socketOnData);
887
- this[kWebSocket] = undefined;
888
-
889
- clearTimeout(websocket._closeTimer);
890
-
891
- if (
892
- websocket._receiver._writableState.finished ||
893
- websocket._receiver._writableState.errorEmitted
894
- ) {
895
- websocket.emitClose();
896
- } else {
897
- websocket._receiver.on('error', receiverOnFinish);
898
- websocket._receiver.on('finish', receiverOnFinish);
899
- }
900
- }
901
-
902
- /**
903
- * The listener of the `net.Socket` `'data'` event.
904
- *
905
- * @param {Buffer} chunk A chunk of data
906
- * @private
907
- */
908
- function socketOnData(chunk) {
909
- if (!this[kWebSocket]._receiver.write(chunk)) {
910
- this.pause();
911
- }
912
- }
913
-
914
- /**
915
- * The listener of the `net.Socket` `'end'` event.
916
- *
917
- * @private
918
- */
919
- function socketOnEnd() {
920
- const websocket = this[kWebSocket];
921
-
922
- websocket._readyState = WebSocket.CLOSING;
923
- websocket._receiver.end();
924
- this.end();
925
- }
926
-
927
- /**
928
- * The listener of the `net.Socket` `'error'` event.
929
- *
930
- * @private
931
- */
932
- function socketOnError() {
933
- const websocket = this[kWebSocket];
934
-
935
- this.removeListener('error', socketOnError);
936
- this.on('error', NOOP);
937
-
938
- if (websocket) {
939
- websocket._readyState = WebSocket.CLOSING;
940
- this.destroy();
941
- }
942
- }