bare-http1 3.4.0 → 3.5.1

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.
@@ -2,6 +2,8 @@ const HTTPIncomingMessage = require('./incoming-message')
2
2
  const constants = require('./constants')
3
3
  const errors = require('./errors')
4
4
 
5
+ const empty = Buffer.alloc(0)
6
+
5
7
  module.exports = class HTTPClientConnection {
6
8
  constructor (socket, opts = {}) {
7
9
  const {
@@ -20,12 +22,18 @@ module.exports = class HTTPClientConnection {
20
22
  this._read = 0
21
23
  this._buffer = null
22
24
 
25
+ this._onerror = this._onerror.bind(this)
26
+ this._onclose = this._onclose.bind(this)
27
+ this._onend = this._onend.bind(this)
28
+ this._ondata = this._ondata.bind(this)
29
+ this._ondrain = this._ondrain.bind(this)
30
+
23
31
  socket
24
- .on('error', this._onerror.bind(this))
25
- .on('close', this._onclose.bind(this))
26
- .on('end', this._onend.bind(this))
27
- .on('data', this._ondata.bind(this))
28
- .on('drain', this._ondrain.bind(this))
32
+ .on('error', this._onerror)
33
+ .on('close', this._onclose)
34
+ .on('end', this._onend)
35
+ .on('data', this._ondata)
36
+ .on('drain', this._ondrain)
29
37
  }
30
38
 
31
39
  _onerror (err) {
@@ -106,7 +114,7 @@ module.exports = class HTTPClientConnection {
106
114
  const r = data.toString().split('\r\n')
107
115
  if (r.length === 0) return this.socket.destroy()
108
116
 
109
- const [, statusCode, statusMessage] = r[0].split(' ')
117
+ const [, statusCode, ...statusMessage] = r[0].split(' ')
110
118
  if (!statusCode || !statusMessage) return this.socket.destroy()
111
119
 
112
120
  const headers = {}
@@ -116,11 +124,18 @@ module.exports = class HTTPClientConnection {
116
124
  headers[name.toLowerCase()] = value
117
125
  }
118
126
 
119
- this.res = new this._IncomingMessage(this.socket, headers, { statusCode: parseInt(statusCode, 10), statusMessage })
120
-
121
127
  this.req.on('close', () => { this.req = null })
128
+
129
+ this.res = new this._IncomingMessage(this.socket, headers, { statusCode: parseInt(statusCode, 10), statusMessage: statusMessage.join(' ') })
130
+
122
131
  this.res.on('close', () => { this.res = null; this._onreset() })
123
132
 
133
+ if (headers.connection && headers.connection.toLowerCase() === 'upgrade') {
134
+ const head = this._buffer
135
+ this._buffer = null
136
+ return this._onupgrade(head)
137
+ }
138
+
124
139
  this.req.emit('response', this.res)
125
140
 
126
141
  if (headers['transfer-encoding'] === 'chunked') {
@@ -163,6 +178,24 @@ module.exports = class HTTPClientConnection {
163
178
  if (this._read === this._length) this._onfinished()
164
179
  }
165
180
 
181
+ _onupgrade (head) {
182
+ this.socket
183
+ .off('error', this._onerror)
184
+ .off('close', this._onclose)
185
+ .off('end', this._onend)
186
+ .off('data', this._ondata)
187
+ .off('drain', this._ondrain)
188
+
189
+ const req = this.req
190
+
191
+ req.upgrade = true
192
+ req.destroy()
193
+
194
+ if (req.emit('upgrade', this.res, this.socket, head || empty)) return
195
+
196
+ this.socket.destroy()
197
+ }
198
+
166
199
  _onfinished () {
167
200
  if (this.res) this.res.push(null)
168
201
  if (this.req) this.req._continueFinal()
@@ -35,15 +35,20 @@ module.exports = class HTTPClientRequest extends HTTPOutgoingMessage {
35
35
  _header () {
36
36
  let h = `${this.method} ${this.path} HTTP/1.1\r\n`
37
37
 
38
+ let upgrade = false
39
+
38
40
  for (const name of Object.keys(this.headers)) {
39
41
  const n = name.toLowerCase()
40
42
  const v = this.headers[name]
41
43
 
42
44
  if (n === 'content-length') this._chunked = false
45
+ if (n === 'connection' && v && v.toLowerCase() === 'upgrade') upgrade = true
43
46
 
44
47
  h += `${httpCase(n)}: ${v}\r\n`
45
48
  }
46
49
 
50
+ if (upgrade) this._chunked = false
51
+
47
52
  if (this._chunked) h += 'Transfer-Encoding: chunked\r\n'
48
53
 
49
54
  h += '\r\n'
@@ -74,6 +79,12 @@ module.exports = class HTTPClientRequest extends HTTPOutgoingMessage {
74
79
  this._pendingFinal = cb
75
80
  }
76
81
 
82
+ _predestroy () {
83
+ if (this.upgrade) return this._continueFinal()
84
+
85
+ this.socket.destroy()
86
+ }
87
+
77
88
  _continueWrite () {
78
89
  if (this._pendingWrite === null) return
79
90
  const cb = this._pendingWrite
@@ -6,6 +6,7 @@ module.exports = class HTTPIncomingMessage extends Readable {
6
6
 
7
7
  this.socket = socket
8
8
  this.headers = headers
9
+ this.upgrade = false
9
10
 
10
11
  // Server arguments
11
12
  this.method = args.method || ''
@@ -33,6 +34,6 @@ module.exports = class HTTPIncomingMessage extends Readable {
33
34
  }
34
35
 
35
36
  _predestroy () {
36
- this.socket.destroy()
37
+ if (this.upgrade === false) this.socket.destroy()
37
38
  }
38
39
  }
@@ -8,6 +8,7 @@ module.exports = class HTTPOutgoingMessage extends Writable {
8
8
  this.socket = socket
9
9
  this.headers = {}
10
10
  this.headersSent = false
11
+ this.upgrade = false
11
12
  }
12
13
 
13
14
  getHeader (name) {
@@ -38,7 +39,7 @@ module.exports = class HTTPOutgoingMessage extends Writable {
38
39
  }
39
40
 
40
41
  _predestroy () {
41
- this.socket.destroy()
42
+ if (this.upgrade === false) this.socket.destroy()
42
43
  }
43
44
  }
44
45
 
@@ -2,6 +2,8 @@ const HTTPIncomingMessage = require('./incoming-message')
2
2
  const HTTPServerResponse = require('./server-response')
3
3
  const constants = require('./constants')
4
4
 
5
+ const empty = Buffer.alloc(0)
6
+
5
7
  module.exports = class HTTPServerConnection {
6
8
  constructor (server, socket, opts = {}) {
7
9
  const {
@@ -23,10 +25,14 @@ module.exports = class HTTPServerConnection {
23
25
  this._read = 0
24
26
  this._buffer = null
25
27
 
28
+ this._onerror = this._onerror.bind(this)
29
+ this._ondata = this._ondata.bind(this)
30
+ this._ondrain = this._ondrain.bind(this)
31
+
26
32
  socket
27
- .on('error', this._onerror.bind(this))
28
- .on('data', this._ondata.bind(this))
29
- .on('drain', this._ondrain.bind(this))
33
+ .on('error', this._onerror)
34
+ .on('data', this._ondata)
35
+ .on('drain', this._ondrain)
30
36
  }
31
37
 
32
38
  _onerror (err) {
@@ -110,10 +116,18 @@ module.exports = class HTTPServerConnection {
110
116
  }
111
117
 
112
118
  this.req = new this._IncomingMessage(this.socket, headers, { method, url })
119
+
120
+ this.req.on('close', () => { this.req = null; this._onreset() })
121
+
122
+ if (headers.connection && headers.connection.toLowerCase() === 'upgrade') {
123
+ const head = this._buffer
124
+ this._buffer = null
125
+ return this._onupgrade(head)
126
+ }
127
+
113
128
  this.res = new this._ServerResponse(this.socket, this.req, headers.connection === 'close')
114
129
 
115
130
  this.res.on('close', () => { this.res = null })
116
- this.req.on('close', () => { this.req = null; this._onreset() })
117
131
 
118
132
  this.server.emit('request', this.req, this.res)
119
133
 
@@ -157,6 +171,20 @@ module.exports = class HTTPServerConnection {
157
171
  if (this._read === this._length) this._onfinished()
158
172
  }
159
173
 
174
+ _onupgrade (head) {
175
+ this.socket
176
+ .off('error', this._onerror)
177
+ .off('data', this._ondata)
178
+ .off('drain', this._ondrain)
179
+
180
+ const req = this.req
181
+
182
+ req.upgrade = true
183
+ req.destroy()
184
+
185
+ this.server.emit('upgrade', req, this.socket, head || empty)
186
+ }
187
+
160
188
  _onfinished () {
161
189
  if (this.req) this.req.push(null)
162
190
  }
@@ -42,7 +42,7 @@ module.exports = class HTTPServerResponse extends HTTPOutgoingMessage {
42
42
  const v = this.headers[name]
43
43
 
44
44
  if (n === 'content-length') this._chunked = false
45
- if (n === 'connection' && v === 'close') this._close = true
45
+ if (n === 'connection' && v && v.toLowerCase() === 'close') this._close = true
46
46
 
47
47
  h += httpCase(n) + ': ' + v + '\r\n'
48
48
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-http1",
3
- "version": "3.4.0",
3
+ "version": "3.5.1",
4
4
  "description": "Native HTTP/1 library for JavaScript",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -31,9 +31,6 @@
31
31
  },
32
32
  "devDependencies": {
33
33
  "brittle": "^3.3.0",
34
- "mime-types": "^2.1.35",
35
- "pump": "^3.0.0",
36
- "range-parser": "^1.2.1",
37
34
  "standard": "^17.0.0"
38
35
  }
39
36
  }