UrgentcareCLI 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (308) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +60 -25
  4. data/Notes +1 -1
  5. data/README.md +5 -5
  6. data/Rakefile +2 -0
  7. data/UrgentCare.gemspec +3 -3
  8. data/background.jpg +0 -0
  9. data/lib/UrgentCare.rb +3 -0
  10. data/lib/UrgentCare/CLI.rb +6 -2
  11. data/lib/UrgentCare/version.rb +1 -1
  12. data/lib/Urgentcare/Scraper.rb +65 -23
  13. data/node_modules/.bin/rimraf +1 -0
  14. data/node_modules/.package-lock.json +250 -0
  15. data/node_modules/balanced-match/.github/FUNDING.yml +2 -0
  16. data/node_modules/balanced-match/LICENSE.md +21 -0
  17. data/node_modules/balanced-match/README.md +97 -0
  18. data/node_modules/balanced-match/index.js +62 -0
  19. data/node_modules/balanced-match/package.json +48 -0
  20. data/node_modules/brace-expansion/LICENSE +21 -0
  21. data/node_modules/brace-expansion/README.md +129 -0
  22. data/node_modules/brace-expansion/index.js +201 -0
  23. data/node_modules/brace-expansion/package.json +47 -0
  24. data/node_modules/concat-map/.travis.yml +4 -0
  25. data/node_modules/concat-map/LICENSE +18 -0
  26. data/node_modules/concat-map/README.markdown +62 -0
  27. data/node_modules/concat-map/example/map.js +6 -0
  28. data/node_modules/concat-map/index.js +13 -0
  29. data/node_modules/concat-map/package.json +43 -0
  30. data/node_modules/concat-map/test/map.js +39 -0
  31. data/node_modules/core-util-is/LICENSE +19 -0
  32. data/node_modules/core-util-is/README.md +3 -0
  33. data/node_modules/core-util-is/float.patch +604 -0
  34. data/node_modules/core-util-is/lib/util.js +107 -0
  35. data/node_modules/core-util-is/package.json +32 -0
  36. data/node_modules/core-util-is/test.js +68 -0
  37. data/node_modules/fs.realpath/LICENSE +43 -0
  38. data/node_modules/fs.realpath/README.md +33 -0
  39. data/node_modules/fs.realpath/index.js +66 -0
  40. data/node_modules/fs.realpath/old.js +303 -0
  41. data/node_modules/fs.realpath/package.json +26 -0
  42. data/node_modules/glob/LICENSE +21 -0
  43. data/node_modules/glob/README.md +375 -0
  44. data/node_modules/glob/changelog.md +67 -0
  45. data/node_modules/glob/common.js +234 -0
  46. data/node_modules/glob/glob.js +788 -0
  47. data/node_modules/glob/package.json +51 -0
  48. data/node_modules/glob/sync.js +484 -0
  49. data/node_modules/immediate/LICENSE.txt +20 -0
  50. data/node_modules/immediate/README.md +93 -0
  51. data/node_modules/immediate/dist/immediate.js +75 -0
  52. data/node_modules/immediate/dist/immediate.min.js +1 -0
  53. data/node_modules/immediate/lib/browser.js +69 -0
  54. data/node_modules/immediate/lib/index.js +73 -0
  55. data/node_modules/immediate/package.json +42 -0
  56. data/node_modules/inflight/LICENSE +15 -0
  57. data/node_modules/inflight/README.md +37 -0
  58. data/node_modules/inflight/inflight.js +54 -0
  59. data/node_modules/inflight/package.json +29 -0
  60. data/node_modules/inherits/LICENSE +16 -0
  61. data/node_modules/inherits/README.md +42 -0
  62. data/node_modules/inherits/inherits.js +9 -0
  63. data/node_modules/inherits/inherits_browser.js +27 -0
  64. data/node_modules/inherits/package.json +29 -0
  65. data/node_modules/isarray/.npmignore +1 -0
  66. data/node_modules/isarray/.travis.yml +4 -0
  67. data/node_modules/isarray/Makefile +6 -0
  68. data/node_modules/isarray/README.md +60 -0
  69. data/node_modules/isarray/component.json +19 -0
  70. data/node_modules/isarray/index.js +5 -0
  71. data/node_modules/isarray/package.json +45 -0
  72. data/node_modules/isarray/test.js +20 -0
  73. data/node_modules/jszip/.codeclimate.yml +16 -0
  74. data/node_modules/jszip/.editorconfig +8 -0
  75. data/node_modules/jszip/.jshintignore +1 -0
  76. data/node_modules/jszip/.jshintrc +21 -0
  77. data/node_modules/jszip/.travis.yml +17 -0
  78. data/node_modules/jszip/CHANGES.md +163 -0
  79. data/node_modules/jszip/LICENSE.markdown +651 -0
  80. data/node_modules/jszip/README.markdown +35 -0
  81. data/node_modules/jszip/dist/jszip.js +30 -0
  82. data/node_modules/jszip/dist/jszip.min.js +13 -0
  83. data/node_modules/jszip/index.d.ts +270 -0
  84. data/node_modules/jszip/lib/base64.js +106 -0
  85. data/node_modules/jszip/lib/compressedObject.js +74 -0
  86. data/node_modules/jszip/lib/compressions.js +14 -0
  87. data/node_modules/jszip/lib/crc32.js +77 -0
  88. data/node_modules/jszip/lib/defaults.js +11 -0
  89. data/node_modules/jszip/lib/external.js +19 -0
  90. data/node_modules/jszip/lib/flate.js +85 -0
  91. data/node_modules/jszip/lib/generate/ZipFileWorker.js +540 -0
  92. data/node_modules/jszip/lib/generate/index.js +57 -0
  93. data/node_modules/jszip/lib/index.js +52 -0
  94. data/node_modules/jszip/lib/license_header.js +11 -0
  95. data/node_modules/jszip/lib/load.js +81 -0
  96. data/node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js +74 -0
  97. data/node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js +42 -0
  98. data/node_modules/jszip/lib/nodejsUtils.js +57 -0
  99. data/node_modules/jszip/lib/object.js +389 -0
  100. data/node_modules/jszip/lib/readable-stream-browser.js +9 -0
  101. data/node_modules/jszip/lib/reader/ArrayReader.js +57 -0
  102. data/node_modules/jszip/lib/reader/DataReader.js +116 -0
  103. data/node_modules/jszip/lib/reader/NodeBufferReader.js +19 -0
  104. data/node_modules/jszip/lib/reader/StringReader.js +38 -0
  105. data/node_modules/jszip/lib/reader/Uint8ArrayReader.js +22 -0
  106. data/node_modules/jszip/lib/reader/readerFor.js +28 -0
  107. data/node_modules/jszip/lib/signature.js +7 -0
  108. data/node_modules/jszip/lib/stream/ConvertWorker.js +26 -0
  109. data/node_modules/jszip/lib/stream/Crc32Probe.js +24 -0
  110. data/node_modules/jszip/lib/stream/DataLengthProbe.js +29 -0
  111. data/node_modules/jszip/lib/stream/DataWorker.js +116 -0
  112. data/node_modules/jszip/lib/stream/GenericWorker.js +263 -0
  113. data/node_modules/jszip/lib/stream/StreamHelper.js +212 -0
  114. data/node_modules/jszip/lib/support.js +38 -0
  115. data/node_modules/jszip/lib/utf8.js +275 -0
  116. data/node_modules/jszip/lib/utils.js +476 -0
  117. data/node_modules/jszip/lib/zipEntries.js +262 -0
  118. data/node_modules/jszip/lib/zipEntry.js +294 -0
  119. data/node_modules/jszip/lib/zipObject.js +133 -0
  120. data/node_modules/jszip/package.json +63 -0
  121. data/node_modules/jszip/vendor/FileSaver.js +247 -0
  122. data/node_modules/lie/README.md +62 -0
  123. data/node_modules/lie/dist/lie.js +350 -0
  124. data/node_modules/lie/dist/lie.min.js +1 -0
  125. data/node_modules/lie/dist/lie.polyfill.js +358 -0
  126. data/node_modules/lie/dist/lie.polyfill.min.js +1 -0
  127. data/node_modules/lie/lib/browser.js +273 -0
  128. data/node_modules/lie/lib/index.js +298 -0
  129. data/node_modules/lie/license.md +7 -0
  130. data/node_modules/lie/lie.d.ts +244 -0
  131. data/node_modules/lie/package.json +69 -0
  132. data/node_modules/lie/polyfill.js +4 -0
  133. data/node_modules/minimatch/LICENSE +15 -0
  134. data/node_modules/minimatch/README.md +209 -0
  135. data/node_modules/minimatch/minimatch.js +923 -0
  136. data/node_modules/minimatch/package.json +30 -0
  137. data/node_modules/once/LICENSE +15 -0
  138. data/node_modules/once/README.md +79 -0
  139. data/node_modules/once/once.js +42 -0
  140. data/node_modules/once/package.json +33 -0
  141. data/node_modules/pako/CHANGELOG.md +164 -0
  142. data/node_modules/pako/LICENSE +21 -0
  143. data/node_modules/pako/README.md +191 -0
  144. data/node_modules/pako/dist/pako.js +6818 -0
  145. data/node_modules/pako/dist/pako.min.js +1 -0
  146. data/node_modules/pako/dist/pako_deflate.js +3997 -0
  147. data/node_modules/pako/dist/pako_deflate.min.js +1 -0
  148. data/node_modules/pako/dist/pako_inflate.js +3300 -0
  149. data/node_modules/pako/dist/pako_inflate.min.js +1 -0
  150. data/node_modules/pako/index.js +14 -0
  151. data/node_modules/pako/lib/deflate.js +400 -0
  152. data/node_modules/pako/lib/inflate.js +423 -0
  153. data/node_modules/pako/lib/utils/common.js +105 -0
  154. data/node_modules/pako/lib/utils/strings.js +187 -0
  155. data/node_modules/pako/lib/zlib/README +59 -0
  156. data/node_modules/pako/lib/zlib/adler32.js +51 -0
  157. data/node_modules/pako/lib/zlib/constants.js +68 -0
  158. data/node_modules/pako/lib/zlib/crc32.js +59 -0
  159. data/node_modules/pako/lib/zlib/deflate.js +1874 -0
  160. data/node_modules/pako/lib/zlib/gzheader.js +58 -0
  161. data/node_modules/pako/lib/zlib/inffast.js +345 -0
  162. data/node_modules/pako/lib/zlib/inflate.js +1556 -0
  163. data/node_modules/pako/lib/zlib/inftrees.js +343 -0
  164. data/node_modules/pako/lib/zlib/messages.js +32 -0
  165. data/node_modules/pako/lib/zlib/trees.js +1222 -0
  166. data/node_modules/pako/lib/zlib/zstream.js +47 -0
  167. data/node_modules/pako/package.json +44 -0
  168. data/node_modules/path-is-absolute/index.js +20 -0
  169. data/node_modules/path-is-absolute/license +21 -0
  170. data/node_modules/path-is-absolute/package.json +43 -0
  171. data/node_modules/path-is-absolute/readme.md +59 -0
  172. data/node_modules/process-nextick-args/index.js +45 -0
  173. data/node_modules/process-nextick-args/license.md +19 -0
  174. data/node_modules/process-nextick-args/package.json +25 -0
  175. data/node_modules/process-nextick-args/readme.md +18 -0
  176. data/node_modules/readable-stream/.travis.yml +34 -0
  177. data/node_modules/readable-stream/CONTRIBUTING.md +38 -0
  178. data/node_modules/readable-stream/GOVERNANCE.md +136 -0
  179. data/node_modules/readable-stream/LICENSE +47 -0
  180. data/node_modules/readable-stream/README.md +58 -0
  181. data/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +60 -0
  182. data/node_modules/readable-stream/duplex-browser.js +1 -0
  183. data/node_modules/readable-stream/duplex.js +1 -0
  184. data/node_modules/readable-stream/lib/_stream_duplex.js +131 -0
  185. data/node_modules/readable-stream/lib/_stream_passthrough.js +47 -0
  186. data/node_modules/readable-stream/lib/_stream_readable.js +1019 -0
  187. data/node_modules/readable-stream/lib/_stream_transform.js +214 -0
  188. data/node_modules/readable-stream/lib/_stream_writable.js +687 -0
  189. data/node_modules/readable-stream/lib/internal/streams/BufferList.js +79 -0
  190. data/node_modules/readable-stream/lib/internal/streams/destroy.js +74 -0
  191. data/node_modules/readable-stream/lib/internal/streams/stream-browser.js +1 -0
  192. data/node_modules/readable-stream/lib/internal/streams/stream.js +1 -0
  193. data/node_modules/readable-stream/package.json +52 -0
  194. data/node_modules/readable-stream/passthrough.js +1 -0
  195. data/node_modules/readable-stream/readable-browser.js +7 -0
  196. data/node_modules/readable-stream/readable.js +19 -0
  197. data/node_modules/readable-stream/transform.js +1 -0
  198. data/node_modules/readable-stream/writable-browser.js +1 -0
  199. data/node_modules/readable-stream/writable.js +8 -0
  200. data/node_modules/rimraf/LICENSE +15 -0
  201. data/node_modules/rimraf/README.md +101 -0
  202. data/node_modules/rimraf/bin.js +50 -0
  203. data/node_modules/rimraf/package.json +29 -0
  204. data/node_modules/rimraf/rimraf.js +372 -0
  205. data/node_modules/safe-buffer/LICENSE +21 -0
  206. data/node_modules/safe-buffer/README.md +584 -0
  207. data/node_modules/safe-buffer/index.d.ts +187 -0
  208. data/node_modules/safe-buffer/index.js +62 -0
  209. data/node_modules/safe-buffer/package.json +37 -0
  210. data/node_modules/selenium-webdriver/CHANGES.md +1114 -0
  211. data/node_modules/selenium-webdriver/LICENSE +202 -0
  212. data/node_modules/selenium-webdriver/NOTICE +2 -0
  213. data/node_modules/selenium-webdriver/README.md +229 -0
  214. data/node_modules/selenium-webdriver/chrome.js +295 -0
  215. data/node_modules/selenium-webdriver/chromium.js +829 -0
  216. data/node_modules/selenium-webdriver/devtools/CDPConnection.js +35 -0
  217. data/node_modules/selenium-webdriver/edge.js +224 -0
  218. data/node_modules/selenium-webdriver/example/chrome_android.js +45 -0
  219. data/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js +46 -0
  220. data/node_modules/selenium-webdriver/example/firefox_channels.js +84 -0
  221. data/node_modules/selenium-webdriver/example/google_search.js +50 -0
  222. data/node_modules/selenium-webdriver/example/google_search_test.js +70 -0
  223. data/node_modules/selenium-webdriver/example/headless.js +63 -0
  224. data/node_modules/selenium-webdriver/example/logging.js +64 -0
  225. data/node_modules/selenium-webdriver/firefox.js +789 -0
  226. data/node_modules/selenium-webdriver/http/index.js +324 -0
  227. data/node_modules/selenium-webdriver/http/util.js +172 -0
  228. data/node_modules/selenium-webdriver/ie.js +503 -0
  229. data/node_modules/selenium-webdriver/index.js +825 -0
  230. data/node_modules/selenium-webdriver/io/exec.js +162 -0
  231. data/node_modules/selenium-webdriver/io/index.js +348 -0
  232. data/node_modules/selenium-webdriver/io/zip.js +223 -0
  233. data/node_modules/selenium-webdriver/lib/atoms/find-elements.js +123 -0
  234. data/node_modules/selenium-webdriver/lib/atoms/get-attribute.js +101 -0
  235. data/node_modules/selenium-webdriver/lib/atoms/is-displayed.js +101 -0
  236. data/node_modules/selenium-webdriver/lib/atoms/mutation-listener.js +55 -0
  237. data/node_modules/selenium-webdriver/lib/by.js +415 -0
  238. data/node_modules/selenium-webdriver/lib/capabilities.js +553 -0
  239. data/node_modules/selenium-webdriver/lib/command.js +206 -0
  240. data/node_modules/selenium-webdriver/lib/error.js +605 -0
  241. data/node_modules/selenium-webdriver/lib/http.js +704 -0
  242. data/node_modules/selenium-webdriver/lib/input.js +946 -0
  243. data/node_modules/selenium-webdriver/lib/logging.js +661 -0
  244. data/node_modules/selenium-webdriver/lib/promise.js +285 -0
  245. data/node_modules/selenium-webdriver/lib/proxy.js +212 -0
  246. data/node_modules/selenium-webdriver/lib/session.js +77 -0
  247. data/node_modules/selenium-webdriver/lib/symbols.js +37 -0
  248. data/node_modules/selenium-webdriver/lib/until.js +429 -0
  249. data/node_modules/selenium-webdriver/lib/webdriver.js +2919 -0
  250. data/node_modules/selenium-webdriver/net/index.js +107 -0
  251. data/node_modules/selenium-webdriver/net/portprober.js +75 -0
  252. data/node_modules/selenium-webdriver/opera.js +406 -0
  253. data/node_modules/selenium-webdriver/package.json +54 -0
  254. data/node_modules/selenium-webdriver/proxy.js +32 -0
  255. data/node_modules/selenium-webdriver/remote/index.js +624 -0
  256. data/node_modules/selenium-webdriver/safari.js +168 -0
  257. data/node_modules/selenium-webdriver/testing/index.js +504 -0
  258. data/node_modules/set-immediate-shim/index.js +7 -0
  259. data/node_modules/set-immediate-shim/package.json +34 -0
  260. data/node_modules/set-immediate-shim/readme.md +31 -0
  261. data/node_modules/string_decoder/.travis.yml +50 -0
  262. data/node_modules/string_decoder/LICENSE +48 -0
  263. data/node_modules/string_decoder/README.md +47 -0
  264. data/node_modules/string_decoder/lib/string_decoder.js +296 -0
  265. data/node_modules/string_decoder/package.json +31 -0
  266. data/node_modules/tmp/CHANGELOG.md +288 -0
  267. data/node_modules/tmp/LICENSE +21 -0
  268. data/node_modules/tmp/README.md +365 -0
  269. data/node_modules/tmp/lib/tmp.js +780 -0
  270. data/node_modules/tmp/node_modules/.bin/rimraf +1 -0
  271. data/node_modules/tmp/node_modules/rimraf/CHANGELOG.md +65 -0
  272. data/node_modules/tmp/node_modules/rimraf/LICENSE +15 -0
  273. data/node_modules/tmp/node_modules/rimraf/README.md +101 -0
  274. data/node_modules/tmp/node_modules/rimraf/bin.js +68 -0
  275. data/node_modules/tmp/node_modules/rimraf/package.json +32 -0
  276. data/node_modules/tmp/node_modules/rimraf/rimraf.js +360 -0
  277. data/node_modules/tmp/package.json +58 -0
  278. data/node_modules/util-deprecate/History.md +16 -0
  279. data/node_modules/util-deprecate/LICENSE +24 -0
  280. data/node_modules/util-deprecate/README.md +53 -0
  281. data/node_modules/util-deprecate/browser.js +67 -0
  282. data/node_modules/util-deprecate/node.js +6 -0
  283. data/node_modules/util-deprecate/package.json +27 -0
  284. data/node_modules/wrappy/LICENSE +15 -0
  285. data/node_modules/wrappy/README.md +36 -0
  286. data/node_modules/wrappy/package.json +29 -0
  287. data/node_modules/wrappy/wrappy.js +33 -0
  288. data/node_modules/ws/LICENSE +21 -0
  289. data/node_modules/ws/README.md +496 -0
  290. data/node_modules/ws/browser.js +8 -0
  291. data/node_modules/ws/index.js +10 -0
  292. data/node_modules/ws/lib/buffer-util.js +129 -0
  293. data/node_modules/ws/lib/constants.js +10 -0
  294. data/node_modules/ws/lib/event-target.js +184 -0
  295. data/node_modules/ws/lib/extension.js +223 -0
  296. data/node_modules/ws/lib/limiter.js +55 -0
  297. data/node_modules/ws/lib/permessage-deflate.js +517 -0
  298. data/node_modules/ws/lib/receiver.js +507 -0
  299. data/node_modules/ws/lib/sender.js +405 -0
  300. data/node_modules/ws/lib/stream.js +165 -0
  301. data/node_modules/ws/lib/validation.js +104 -0
  302. data/node_modules/ws/lib/websocket-server.js +418 -0
  303. data/node_modules/ws/lib/websocket.js +942 -0
  304. data/node_modules/ws/package.json +56 -0
  305. data/package-lock.json +458 -0
  306. data/package.json +5 -0
  307. data/selenium.log +1 -0
  308. metadata +314 -19
@@ -0,0 +1,942 @@
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
+ }