bare-ws 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- const EOL = exports.EOL = '\r\n'
1
+ const EOL = (exports.EOL = '\r\n')
2
2
 
3
3
  exports.EOF = EOL.repeat(2)
4
4
 
package/lib/errors.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { status } = require('./constants')
2
2
 
3
3
  module.exports = class WebSocketError extends Error {
4
- constructor (msg, code, status, fn = WebSocketError) {
4
+ constructor(msg, code, status, fn = WebSocketError) {
5
5
  super(`${code}: ${msg}`)
6
6
  this.code = code
7
7
  this.status = status
@@ -11,71 +11,151 @@ module.exports = class WebSocketError extends Error {
11
11
  }
12
12
  }
13
13
 
14
- get name () {
14
+ get name() {
15
15
  return 'WebSocketError'
16
16
  }
17
17
 
18
- static NOT_CONNECTED (msg = 'Socket is not connected') {
19
- return new WebSocketError(msg, 'NOT_CONNECTED', 0, WebSocketError.NOT_CONNECTED)
20
- }
21
-
22
- static UNEXPECTED_RSV1 (msg = 'RSV1 must be unset') {
23
- return new WebSocketError(msg, 'UNEXPECTED_RSV1', status.PROTOCOL_ERROR, WebSocketError.UNEXPECTED_RSV1)
24
- }
25
-
26
- static UNEXPECTED_RSV2 (msg = 'RSV2 must be unset') {
27
- return new WebSocketError(msg, 'UNEXPECTED_RSV2', status.PROTOCOL_ERROR, WebSocketError.UNEXPECTED_RSV2)
28
- }
29
-
30
- static UNEXPECTED_RSV3 (msg = 'RSV3 must be unset') {
31
- return new WebSocketError(msg, 'UNEXPECTED_RSV3', status.PROTOCOL_ERROR, WebSocketError.UNEXPECTED_RSV3)
32
- }
33
-
34
- static EXPECTED_MASK (msg = 'MASK must be set') {
35
- return new WebSocketError(msg, 'EXPECTED_MASK', status.PROTOCOL_ERROR, WebSocketError.EXPECTED_MASK)
36
- }
37
-
38
- static UNEXPECTED_MASK (msg = 'MASK must be unset') {
39
- return new WebSocketError(msg, 'UNEXPECTED_MASK', status.PROTOCOL_ERROR, WebSocketError.UNEXPECTED_MASK)
40
- }
41
-
42
- static EXPECTED_CONTINUATION (msg = 'Expected a continuation frame') {
43
- return new WebSocketError(msg, 'EXPECTED_CONTINUATION', status.PROTOCOL_ERROR, WebSocketError.EXPECTED_CONTINUATION)
44
- }
45
-
46
- static UNEXPECTED_CONTINUATION (msg = 'Unexpected continuation frame') {
47
- return new WebSocketError(msg, 'UNEXPECTED_CONTINUATION', status.PROTOCOL_ERROR, WebSocketError.UNEXPECTED_CONTINUATION)
48
- }
49
-
50
- static UNEXPECTED_CONTROL (msg = 'Unexpected control frame') {
51
- return new WebSocketError(msg, 'UNEXPECTED_CONTROL', status.PROTOCOL_ERROR, WebSocketError.UNEXPECTED_CONTROL)
52
- }
53
-
54
- static INVALID_ENCODING (msg = 'Invalid encoding') {
55
- return new WebSocketError(msg, 'INVALID_ENCODING', status.PROTOCOL_ERROR, WebSocketError.INVALID_ENCODING)
56
- }
57
-
58
- static INVALID_UPGRADE_HEADER (msg = 'Invalid Upgrade header') {
59
- return new WebSocketError(msg, 'INVALID_UPGRADE_HEADER', status.PROTOCOL_ERROR, WebSocketError.INVALID_UPGRADE_HEADER)
60
- }
61
-
62
- static INVALID_VERSION_HEADER (msg = 'Invalid Sec-WebSocket-Version header') {
63
- return new WebSocketError(msg, 'INVALID_VERSION_HEADER', status.PROTOCOL_ERROR, WebSocketError.INVALID_VERSION_HEADER)
64
- }
65
-
66
- static INVALID_KEY_HEADER (msg = 'Invalid Sec-WebSocket-Key header') {
67
- return new WebSocketError(msg, 'INVALID_KEY_HEADER', status.PROTOCOL_ERROR, WebSocketError.INVALID_KEY_HEADER)
68
- }
69
-
70
- static INVALID_ACCEPT_HEADER (msg = 'Invalid Sec-WebSocket-Accept header') {
71
- return new WebSocketError(msg, 'INVALID_ACCEPT_HEADER', status.PROTOCOL_ERROR, WebSocketError.INVALID_ACCEPT_HEADER)
72
- }
73
-
74
- static INVALID_OPCODE (msg = 'Invalid opcode') {
75
- return new WebSocketError(msg, 'INVALID_OPCODE', status.PROTOCOL_ERROR, WebSocketError.INVALID_OPCODE)
76
- }
77
-
78
- static INVALID_PAYLOAD_LENGTH (msg = 'Invalid payload length') {
79
- return new WebSocketError(msg, 'INVALID_PAYLOAD_LENGTH', status.MESSAGE_TOO_LARGE, WebSocketError.INVALID_PAYLOAD_LENGTH)
18
+ static NOT_CONNECTED(msg = 'Socket is not connected') {
19
+ return new WebSocketError(
20
+ msg,
21
+ 'NOT_CONNECTED',
22
+ 0,
23
+ WebSocketError.NOT_CONNECTED
24
+ )
25
+ }
26
+
27
+ static UNEXPECTED_RSV1(msg = 'RSV1 must be unset') {
28
+ return new WebSocketError(
29
+ msg,
30
+ 'UNEXPECTED_RSV1',
31
+ status.PROTOCOL_ERROR,
32
+ WebSocketError.UNEXPECTED_RSV1
33
+ )
34
+ }
35
+
36
+ static UNEXPECTED_RSV2(msg = 'RSV2 must be unset') {
37
+ return new WebSocketError(
38
+ msg,
39
+ 'UNEXPECTED_RSV2',
40
+ status.PROTOCOL_ERROR,
41
+ WebSocketError.UNEXPECTED_RSV2
42
+ )
43
+ }
44
+
45
+ static UNEXPECTED_RSV3(msg = 'RSV3 must be unset') {
46
+ return new WebSocketError(
47
+ msg,
48
+ 'UNEXPECTED_RSV3',
49
+ status.PROTOCOL_ERROR,
50
+ WebSocketError.UNEXPECTED_RSV3
51
+ )
52
+ }
53
+
54
+ static EXPECTED_MASK(msg = 'MASK must be set') {
55
+ return new WebSocketError(
56
+ msg,
57
+ 'EXPECTED_MASK',
58
+ status.PROTOCOL_ERROR,
59
+ WebSocketError.EXPECTED_MASK
60
+ )
61
+ }
62
+
63
+ static UNEXPECTED_MASK(msg = 'MASK must be unset') {
64
+ return new WebSocketError(
65
+ msg,
66
+ 'UNEXPECTED_MASK',
67
+ status.PROTOCOL_ERROR,
68
+ WebSocketError.UNEXPECTED_MASK
69
+ )
70
+ }
71
+
72
+ static EXPECTED_CONTINUATION(msg = 'Expected a continuation frame') {
73
+ return new WebSocketError(
74
+ msg,
75
+ 'EXPECTED_CONTINUATION',
76
+ status.PROTOCOL_ERROR,
77
+ WebSocketError.EXPECTED_CONTINUATION
78
+ )
79
+ }
80
+
81
+ static UNEXPECTED_CONTINUATION(msg = 'Unexpected continuation frame') {
82
+ return new WebSocketError(
83
+ msg,
84
+ 'UNEXPECTED_CONTINUATION',
85
+ status.PROTOCOL_ERROR,
86
+ WebSocketError.UNEXPECTED_CONTINUATION
87
+ )
88
+ }
89
+
90
+ static UNEXPECTED_CONTROL(msg = 'Unexpected control frame') {
91
+ return new WebSocketError(
92
+ msg,
93
+ 'UNEXPECTED_CONTROL',
94
+ status.PROTOCOL_ERROR,
95
+ WebSocketError.UNEXPECTED_CONTROL
96
+ )
97
+ }
98
+
99
+ static INVALID_ENCODING(msg = 'Invalid encoding') {
100
+ return new WebSocketError(
101
+ msg,
102
+ 'INVALID_ENCODING',
103
+ status.PROTOCOL_ERROR,
104
+ WebSocketError.INVALID_ENCODING
105
+ )
106
+ }
107
+
108
+ static INVALID_UPGRADE_HEADER(msg = 'Invalid Upgrade header') {
109
+ return new WebSocketError(
110
+ msg,
111
+ 'INVALID_UPGRADE_HEADER',
112
+ status.PROTOCOL_ERROR,
113
+ WebSocketError.INVALID_UPGRADE_HEADER
114
+ )
115
+ }
116
+
117
+ static INVALID_VERSION_HEADER(msg = 'Invalid Sec-WebSocket-Version header') {
118
+ return new WebSocketError(
119
+ msg,
120
+ 'INVALID_VERSION_HEADER',
121
+ status.PROTOCOL_ERROR,
122
+ WebSocketError.INVALID_VERSION_HEADER
123
+ )
124
+ }
125
+
126
+ static INVALID_KEY_HEADER(msg = 'Invalid Sec-WebSocket-Key header') {
127
+ return new WebSocketError(
128
+ msg,
129
+ 'INVALID_KEY_HEADER',
130
+ status.PROTOCOL_ERROR,
131
+ WebSocketError.INVALID_KEY_HEADER
132
+ )
133
+ }
134
+
135
+ static INVALID_ACCEPT_HEADER(msg = 'Invalid Sec-WebSocket-Accept header') {
136
+ return new WebSocketError(
137
+ msg,
138
+ 'INVALID_ACCEPT_HEADER',
139
+ status.PROTOCOL_ERROR,
140
+ WebSocketError.INVALID_ACCEPT_HEADER
141
+ )
142
+ }
143
+
144
+ static INVALID_OPCODE(msg = 'Invalid opcode') {
145
+ return new WebSocketError(
146
+ msg,
147
+ 'INVALID_OPCODE',
148
+ status.PROTOCOL_ERROR,
149
+ WebSocketError.INVALID_OPCODE
150
+ )
151
+ }
152
+
153
+ static INVALID_PAYLOAD_LENGTH(msg = 'Invalid payload length') {
154
+ return new WebSocketError(
155
+ msg,
156
+ 'INVALID_PAYLOAD_LENGTH',
157
+ status.MESSAGE_TOO_LARGE,
158
+ WebSocketError.INVALID_PAYLOAD_LENGTH
159
+ )
80
160
  }
81
161
  }
package/lib/frame.js CHANGED
@@ -12,8 +12,8 @@ const MASK = 0b10000000
12
12
  const LENGTH = 0b01111111
13
13
 
14
14
  // https://datatracker.ietf.org/doc/html/rfc6455#section-5
15
- const Frame = module.exports = exports = class Frame {
16
- constructor (opcode, payload = EMPTY, opts = {}) {
15
+ module.exports = exports = class Frame {
16
+ constructor(opcode, payload = EMPTY, opts = {}) {
17
17
  if (payload && !Buffer.isBuffer(payload)) {
18
18
  opts = payload
19
19
  payload = EMPTY
@@ -36,7 +36,7 @@ const Frame = module.exports = exports = class Frame {
36
36
  this.payload = payload
37
37
  }
38
38
 
39
- toBuffer () {
39
+ toBuffer() {
40
40
  const state = { start: 0, end: 0, buffer: null }
41
41
 
42
42
  Frame.preencode(state, this)
@@ -49,7 +49,9 @@ const Frame = module.exports = exports = class Frame {
49
49
  }
50
50
  }
51
51
 
52
- exports.preencode = function preencode (state, f) {
52
+ const Frame = exports
53
+
54
+ exports.preencode = function preencode(state, f) {
53
55
  let i = state.end
54
56
 
55
57
  i++
@@ -69,7 +71,7 @@ exports.preencode = function preencode (state, f) {
69
71
  state.end = i
70
72
  }
71
73
 
72
- exports.encode = function encode (state, f) {
74
+ exports.encode = function encode(state, f) {
73
75
  const b = state.buffer
74
76
 
75
77
  let i = state.start
@@ -133,7 +135,7 @@ exports.encode = function encode (state, f) {
133
135
  state.start = i
134
136
  }
135
137
 
136
- exports.decode = function decode (state) {
138
+ exports.decode = function decode(state) {
137
139
  const b = state.buffer
138
140
 
139
141
  let i = state.start
package/lib/server.js CHANGED
@@ -11,7 +11,7 @@ const EMPTY = Buffer.alloc(0)
11
11
  const KEY = /^[+/0-9A-Za-z]{22}==$/
12
12
 
13
13
  module.exports = exports = class WebSocketServer extends EventEmitter {
14
- constructor (opts = {}, onconnection) {
14
+ constructor(opts = {}, onconnection) {
15
15
  if (typeof opts === 'function') {
16
16
  onconnection = opts
17
17
  opts = {}
@@ -22,7 +22,10 @@ module.exports = exports = class WebSocketServer extends EventEmitter {
22
22
  const createServer = opts.secure ? https.createServer : http.createServer
23
23
 
24
24
  const {
25
- server = createServer(opts, this._onrequest.bind(this)).listen(opts, this._onlistening.bind(this))
25
+ server = createServer(opts, this._onrequest.bind(this)).listen(
26
+ opts,
27
+ this._onlistening.bind(this)
28
+ )
26
29
  } = opts
27
30
 
28
31
  this._server = server
@@ -32,31 +35,31 @@ module.exports = exports = class WebSocketServer extends EventEmitter {
32
35
  if (onconnection) this.on('connection', onconnection)
33
36
  }
34
37
 
35
- get listening () {
38
+ get listening() {
36
39
  return this._server.listening
37
40
  }
38
41
 
39
- address () {
42
+ address() {
40
43
  return this._server.address()
41
44
  }
42
45
 
43
- close (cb) {
46
+ close(cb) {
44
47
  return this._server.close(cb)
45
48
  }
46
49
 
47
- ref () {
50
+ ref() {
48
51
  this._server.ref()
49
52
  }
50
53
 
51
- unref () {
54
+ unref() {
52
55
  this._server.unref()
53
56
  }
54
57
 
55
- _onlistening () {
58
+ _onlistening() {
56
59
  this.emit('listening')
57
60
  }
58
61
 
59
- _onrequest (req, res) {
62
+ _onrequest(req, res) {
60
63
  const body = http.constants.status[426]
61
64
 
62
65
  res.writeHead(426, {
@@ -67,7 +70,7 @@ module.exports = exports = class WebSocketServer extends EventEmitter {
67
70
  res.end(body)
68
71
  }
69
72
 
70
- _onupgrade (req, socket, head) {
73
+ _onupgrade(req, socket, head) {
71
74
  handshake(req, socket, head, (err) => {
72
75
  if (err) return socket.destroy(err)
73
76
 
@@ -77,7 +80,12 @@ module.exports = exports = class WebSocketServer extends EventEmitter {
77
80
  }
78
81
 
79
82
  // https://datatracker.ietf.org/doc/html/rfc6455#section-4.2
80
- const handshake = exports.handshake = function handshake (req, socket = req.socket, head = EMPTY, cb) {
83
+ const handshake = (exports.handshake = function handshake(
84
+ req,
85
+ socket = req.socket,
86
+ head = EMPTY,
87
+ cb
88
+ ) {
81
89
  if (typeof socket === 'function') {
82
90
  cb = socket
83
91
  socket = req.socket
@@ -103,19 +111,24 @@ const handshake = exports.handshake = function handshake (req, socket = req.sock
103
111
  return cb(errors.INVALID_KEY_HEADER())
104
112
  }
105
113
 
106
- const digest = crypto.createHash('sha1')
114
+ const digest = crypto
115
+ .createHash('sha1')
107
116
  .update(key)
108
117
  .update(GUID)
109
118
  .digest('base64')
110
119
 
111
120
  socket.write(
112
- 'HTTP/1.1 101 Web Socket Protocol Handshake' + EOL +
113
- 'Upgrade: WebSocket' + EOL +
114
- 'Connection: Upgrade' + EOL +
115
- `Sec-WebSocket-Accept: ${digest}` + EOF
121
+ 'HTTP/1.1 101 Web Socket Protocol Handshake' +
122
+ EOL +
123
+ 'Upgrade: WebSocket' +
124
+ EOL +
125
+ 'Connection: Upgrade' +
126
+ EOL +
127
+ `Sec-WebSocket-Accept: ${digest}` +
128
+ EOF
116
129
  )
117
130
 
118
131
  if (head.byteLength) socket.unshift(head)
119
132
 
120
133
  cb(null)
121
- }
134
+ })
package/lib/socket.js CHANGED
@@ -9,10 +9,10 @@ const Frame = require('./frame')
9
9
  const CLOSE = new Frame(opcode.CLOSE).toBuffer()
10
10
 
11
11
  module.exports = exports = class WebSocket extends Duplex {
12
- constructor (url, opts = {}) {
12
+ constructor(url, opts = {}) {
13
13
  if (typeof url === 'string') url = new URL(url)
14
14
 
15
- if (URL.isURL(url)) {
15
+ if (isURL(url)) {
16
16
  opts = opts ? { ...opts } : {}
17
17
 
18
18
  opts.host = url.hostname
@@ -21,12 +21,14 @@ module.exports = exports = class WebSocket extends Duplex {
21
21
  opts.secure = url.protocol === 'https:' || url.protocol === 'wss:'
22
22
  } else {
23
23
  opts = url ? { ...url } : {}
24
+
25
+ // For Node.js compatibility
26
+ opts.host = opts.hostname || opts.host
27
+ opts.port =
28
+ typeof opts.port === 'string' ? parseInt(opts.port, 10) : opts.port
24
29
  }
25
30
 
26
- const {
27
- isServer = false,
28
- socket = null
29
- } = opts
31
+ const { isServer = false, socket = null } = opts
30
32
 
31
33
  super({ eagerOpen: true })
32
34
 
@@ -44,23 +46,27 @@ module.exports = exports = class WebSocket extends Duplex {
44
46
  else this._connect(opts)
45
47
  }
46
48
 
47
- ping (data) {
49
+ ping(data) {
48
50
  if (this._socket === null) throw errors.NOT_CONNECTED()
49
51
 
50
52
  if (typeof data === 'string') data = Buffer.from(data)
51
53
 
52
- this._socket.write(new Frame(opcode.PING, data, { mask: this._mask }).toBuffer())
54
+ this._socket.write(
55
+ new Frame(opcode.PING, data, { mask: this._mask }).toBuffer()
56
+ )
53
57
  }
54
58
 
55
- pong (data) {
59
+ pong(data) {
56
60
  if (this._socket === null) throw errors.NOT_CONNECTED()
57
61
 
58
62
  if (typeof data === 'string') data = Buffer.from(data)
59
63
 
60
- this._socket.write(new Frame(opcode.PONG, data, { mask: this._mask }).toBuffer())
64
+ this._socket.write(
65
+ new Frame(opcode.PONG, data, { mask: this._mask }).toBuffer()
66
+ )
61
67
  }
62
68
 
63
- _attach (socket) {
69
+ _attach(socket) {
64
70
  this._socket = socket
65
71
 
66
72
  this._socket
@@ -70,7 +76,7 @@ module.exports = exports = class WebSocket extends Duplex {
70
76
  .on('drain', this._ondrain.bind(this))
71
77
  }
72
78
 
73
- _connect (opts) {
79
+ _connect(opts) {
74
80
  const request = opts.secure ? https.request : http.request
75
81
 
76
82
  const req = request(opts)
@@ -86,15 +92,15 @@ module.exports = exports = class WebSocket extends Duplex {
86
92
  })
87
93
  }
88
94
 
89
- _onerror (err) {
95
+ _onerror(err) {
90
96
  this.destroy(err)
91
97
  }
92
98
 
93
- _onclose () {
99
+ _onclose() {
94
100
  this.destroy()
95
101
  }
96
102
 
97
- _ondata (data) {
103
+ _ondata(data) {
98
104
  if (this._buffer === null) this._buffer = data
99
105
  else this._buffer = Buffer.concat([this._buffer, data])
100
106
 
@@ -110,7 +116,8 @@ module.exports = exports = class WebSocket extends Duplex {
110
116
 
111
117
  if (frame === null) return
112
118
 
113
- this._buffer = state.start === state.end ? null : this._buffer.subarray(state.start)
119
+ this._buffer =
120
+ state.start === state.end ? null : this._buffer.subarray(state.start)
114
121
 
115
122
  try {
116
123
  this._onframe(frame)
@@ -120,7 +127,7 @@ module.exports = exports = class WebSocket extends Duplex {
120
127
  }
121
128
  }
122
129
 
123
- _onframe (frame) {
130
+ _onframe(frame) {
124
131
  if (frame.rsv1) throw errors.UNEXPECTED_RSV1()
125
132
 
126
133
  if (frame.rsv2) throw errors.UNEXPECTED_RSV2()
@@ -132,15 +139,18 @@ module.exports = exports = class WebSocket extends Duplex {
132
139
  }
133
140
 
134
141
  if (frame.fin === false) {
135
- if (this._fragments.push(frame) === 1) { // First frame
136
- if (frame.opcode === opcode.CONTINUATION) throw errors.UNEXPECTED_CONTINUATION()
142
+ if (this._fragments.push(frame) === 1) {
143
+ // First frame
144
+ if (frame.opcode === opcode.CONTINUATION)
145
+ throw errors.UNEXPECTED_CONTINUATION()
137
146
 
138
147
  if (frame.opcode >= opcode.CLOSE) throw errors.UNEXPECTED_CONTROL()
139
148
 
140
149
  return
141
150
  }
142
151
 
143
- if (frame.opcode !== opcode.CONTINUATION) throw errors.EXPECTED_CONTINUATION()
152
+ if (frame.opcode !== opcode.CONTINUATION)
153
+ throw errors.EXPECTED_CONTINUATION()
144
154
 
145
155
  return
146
156
  }
@@ -165,7 +175,7 @@ module.exports = exports = class WebSocket extends Duplex {
165
175
 
166
176
  frame.opcode = this._fragments[0].opcode
167
177
 
168
- const payloads = this._fragments.map(frame => frame.payload)
178
+ const payloads = this._fragments.map((frame) => frame.payload)
169
179
 
170
180
  payloads.push(frame.payload)
171
181
 
@@ -191,41 +201,45 @@ module.exports = exports = class WebSocket extends Duplex {
191
201
  }
192
202
  }
193
203
 
194
- _ondrain () {
204
+ _ondrain() {
195
205
  if (this._pendingWrite === null) return
196
206
  const cb = this._pendingWrite
197
207
  this._pendingWrite = null
198
208
  cb(null)
199
209
  }
200
210
 
201
- _open (cb) {
211
+ _open(cb) {
202
212
  if (this._socket === null) this._pendingOpen = cb
203
213
  else cb(null)
204
214
  }
205
215
 
206
- _write (data, encoding, cb) {
216
+ _write(data, encoding, cb) {
207
217
  if (encoding !== 'buffer' && encoding !== 'utf8') {
208
218
  return cb(errors.INVALID_ENCODING())
209
219
  }
210
220
 
211
- const frame = new Frame(encoding === 'buffer' ? opcode.BINARY : opcode.TEXT, data, { mask: this._mask })
221
+ const frame = new Frame(
222
+ encoding === 'buffer' ? opcode.BINARY : opcode.TEXT,
223
+ data,
224
+ { mask: this._mask }
225
+ )
212
226
 
213
227
  if (this._socket.write(frame.toBuffer())) cb(null)
214
228
  else this._pendingWrite = cb
215
229
  }
216
230
 
217
- _final (cb) {
231
+ _final(cb) {
218
232
  this._socket.end(CLOSE)
219
233
  cb(null)
220
234
  }
221
235
 
222
- _predestroy () {
236
+ _predestroy() {
223
237
  this._socket.destroy()
224
238
  }
225
239
  }
226
240
 
227
241
  // https://datatracker.ietf.org/doc/html/rfc6455#section-4.1
228
- const handshake = exports.handshake = function handshake (req, cb) {
242
+ const handshake = (exports.handshake = function handshake(req, cb) {
229
243
  const key = crypto.randomBytes(16).toString('base64')
230
244
 
231
245
  req.headers = {
@@ -241,7 +255,8 @@ const handshake = exports.handshake = function handshake (req, cb) {
241
255
  return cb(errors.INVALID_UPGRADE_HEADER())
242
256
  }
243
257
 
244
- const digest = crypto.createHash('sha1')
258
+ const digest = crypto
259
+ .createHash('sha1')
245
260
  .update(key)
246
261
  .update(GUID)
247
262
  .digest('base64')
@@ -256,17 +271,32 @@ const handshake = exports.handshake = function handshake (req, cb) {
256
271
  })
257
272
 
258
273
  req.end()
259
- }
274
+ })
260
275
 
261
276
  // https://url.spec.whatwg.org/#default-port
262
- function defaultPort (url) {
277
+ function defaultPort(url) {
263
278
  switch (url.protocol) {
264
- case 'ftp:': return 21
279
+ case 'ftp:':
280
+ return 21
265
281
  case 'http:':
266
- case 'ws:': return 80
282
+ case 'ws:':
283
+ return 80
267
284
  case 'https:':
268
- case 'wss:': return 443
285
+ case 'wss:':
286
+ return 443
269
287
  }
270
288
 
271
289
  return null
272
290
  }
291
+
292
+ // https://url.spec.whatwg.org/#api
293
+ function isURL(url) {
294
+ return (
295
+ url !== null &&
296
+ typeof url === 'object' &&
297
+ typeof url.protocol === 'string' &&
298
+ typeof url.hostname === 'string' &&
299
+ typeof url.pathname === 'string' &&
300
+ typeof url.search === 'string'
301
+ )
302
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-ws",
3
- "version": "1.3.0",
3
+ "version": "2.0.0",
4
4
  "description": "WebSocket library for JavaScript",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -13,7 +13,7 @@
13
13
  "lib"
14
14
  ],
15
15
  "scripts": {
16
- "test": "standard && bare test.js"
16
+ "test": "prettier . --check && bare test.js"
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",
@@ -28,13 +28,14 @@
28
28
  "dependencies": {
29
29
  "bare-crypto": "^1.2.0",
30
30
  "bare-events": "^2.3.1",
31
- "bare-http1": "^3.5.2",
32
- "bare-https": "^1.1.0",
31
+ "bare-http1": "^4.0.0",
32
+ "bare-https": "^2.0.0",
33
33
  "bare-stream": "^2.1.2"
34
34
  },
35
35
  "devDependencies": {
36
- "bare-fs": "^2.3.1",
36
+ "bare-fs": "^4.0.0",
37
37
  "brittle": "^3.3.0",
38
- "standard": "^17.0.0"
38
+ "prettier": "^3.4.1",
39
+ "prettier-config-standard": "^7.0.0"
39
40
  }
40
41
  }