bare-http1 4.1.1 → 4.1.3

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/index.d.ts CHANGED
@@ -8,11 +8,7 @@ import {
8
8
  } from 'bare-tcp'
9
9
  import Buffer from 'bare-buffer'
10
10
  import URL from 'bare-url'
11
- import constants, {
12
- HTTPMethod,
13
- HTTPStatusCode,
14
- HTTPStatusMessage
15
- } from './lib/constants'
11
+ import constants, { HTTPMethod, HTTPStatusCode, HTTPStatusMessage } from './lib/constants'
16
12
  import HTTPError from './lib/errors'
17
13
 
18
14
  export {
@@ -111,18 +107,13 @@ export interface HTTPAgent {
111
107
 
112
108
  getName(opts: { host: string; port: number }): string
113
109
 
114
- addRequest(
115
- req: HTTPClientRequest,
116
- opts: TCPSocketOptions & TCPSocketConnectOptions
117
- ): void
110
+ addRequest(req: HTTPClientRequest, opts: TCPSocketOptions & TCPSocketConnectOptions): void
118
111
 
119
112
  destroy(): void
120
113
  }
121
114
 
122
115
  export class HTTPAgent {
123
- constructor(
124
- opts?: HTTPAgentOptions & TCPSocketOptions & TCPSocketConnectOptions
125
- )
116
+ constructor(opts?: HTTPAgentOptions & TCPSocketOptions & TCPSocketConnectOptions)
126
117
 
127
118
  static global: HTTPAgent
128
119
  }
@@ -137,8 +128,7 @@ export interface HTTPServerEvents extends TCPServerEvents {
137
128
  timeout: [socket: TCPSocket]
138
129
  }
139
130
 
140
- export interface HTTPServer<M extends HTTPServerEvents = HTTPServerEvents>
141
- extends TCPServer<M> {
131
+ export interface HTTPServer<M extends HTTPServerEvents = HTTPServerEvents> extends TCPServer<M> {
142
132
  readonly timeout: number | undefined
143
133
 
144
134
  setTimeout(ms: number, ontimeout?: () => void): this
@@ -150,9 +140,7 @@ export class HTTPServer {
150
140
  onrequest?: (req: HTTPIncomingMessage, res: HTTPServerResponse) => void
151
141
  )
152
142
 
153
- constructor(
154
- onrequest: (req: HTTPIncomingMessage, res: HTTPServerResponse) => void
155
- )
143
+ constructor(onrequest: (req: HTTPIncomingMessage, res: HTTPServerResponse) => void)
156
144
  }
157
145
 
158
146
  export { HTTPServer as Server }
@@ -168,10 +156,7 @@ export interface HTTPServerResponse extends HTTPOutgoingMessage {
168
156
  headers?: Record<string, string | number>
169
157
  ): void
170
158
 
171
- writeHead(
172
- statusCode: HTTPStatusCode,
173
- headers?: Record<string, string | number>
174
- ): void
159
+ writeHead(statusCode: HTTPStatusCode, headers?: Record<string, string | number>): void
175
160
  }
176
161
 
177
162
  export class HTTPServerResponse {
@@ -191,16 +176,10 @@ export interface HTTPServerConnection {
191
176
 
192
177
  readonly req: HTTPIncomingMessage | null
193
178
  readonly res: HTTPServerResponse | null
194
-
195
- readonly idle: boolean
196
179
  }
197
180
 
198
181
  export class HTTPServerConnection {
199
- constructor(
200
- server: HTTPServer,
201
- socket: TCPSocket,
202
- opts?: HTTPServerConnectionOptions
203
- )
182
+ constructor(server: HTTPServer, socket: TCPSocket, opts?: HTTPServerConnectionOptions)
204
183
 
205
184
  static for(socket: TCPSocket): HTTPServerConnection
206
185
  }
@@ -219,9 +198,8 @@ export interface HTTPClientRequestOptions extends TCPSocketConnectOptions {
219
198
  path?: string
220
199
  }
221
200
 
222
- export interface HTTPClientRequest<
223
- M extends HTTPClientRequestEvents = HTTPClientRequestEvents
224
- > extends HTTPOutgoingMessage<M> {
201
+ export interface HTTPClientRequest<M extends HTTPClientRequestEvents = HTTPClientRequestEvents>
202
+ extends HTTPOutgoingMessage<M> {
225
203
  readonly method: HTTPMethod
226
204
  readonly path: string
227
205
  readonly headers: Record<string, string | number>
@@ -253,10 +231,7 @@ export class HTTPClientConnection {
253
231
 
254
232
  static for(socket: TCPSocket): HTTPClientConnection | null
255
233
 
256
- static from(
257
- socket: TCPSocket,
258
- opts?: HTTPClientConnectionOptions
259
- ): HTTPClientConnection
234
+ static from(socket: TCPSocket, opts?: HTTPClientConnectionOptions): HTTPClientConnection
260
235
  }
261
236
 
262
237
  export { HTTPClientConnection as ClientConnection }
package/index.js CHANGED
@@ -40,10 +40,12 @@ exports.request = function request(url, opts, onresponse) {
40
40
 
41
41
  // For Node.js compatibility
42
42
  opts.host = opts.hostname || opts.host
43
- opts.port =
44
- typeof opts.port === 'string' ? parseInt(opts.port, 10) : opts.port
43
+ opts.port = typeof opts.port === 'string' ? parseInt(opts.port, 10) : opts.port
45
44
  }
46
45
 
46
+ // TODO: Renable the default global agent when hangs have been sorted
47
+ opts.agent = opts.agent || new exports.Agent()
48
+
47
49
  return new exports.ClientRequest(opts, onresponse)
48
50
  }
49
51
 
package/lib/agent.js CHANGED
@@ -12,12 +12,7 @@ module.exports = class HTTPAgent extends EventEmitter {
12
12
  this._sockets = new Map()
13
13
  this._freeSockets = new Map()
14
14
 
15
- this._keepAlive =
16
- typeof keepAlive === 'number'
17
- ? keepAlive
18
- : keepAlive
19
- ? keepAliveMsecs
20
- : -1
15
+ this._keepAlive = typeof keepAlive === 'number' ? keepAlive : keepAlive ? keepAliveMsecs : -1
21
16
 
22
17
  this._opts = { ...opts }
23
18
  }
@@ -108,9 +103,7 @@ module.exports = class HTTPAgent extends EventEmitter {
108
103
  }
109
104
 
110
105
  _onremove(socket, name, all = true) {
111
- for (const set of all
112
- ? [this._sockets, this._freeSockets]
113
- : [this._sockets]) {
106
+ for (const set of all ? [this._sockets, this._freeSockets] : [this._sockets]) {
114
107
  const sockets = set.get(name)
115
108
  if (sockets === undefined) continue
116
109
 
@@ -1,8 +1,12 @@
1
+ const HTTPParser = require('bare-http-parser')
1
2
  const HTTPIncomingMessage = require('./incoming-message')
2
- const constants = require('./constants')
3
3
  const errors = require('./errors')
4
4
 
5
- const empty = Buffer.alloc(0)
5
+ const {
6
+ constants: { RESPONSE, DATA, END }
7
+ } = HTTPParser
8
+
9
+ const EMPTY = Buffer.alloc(0)
6
10
 
7
11
  module.exports = class HTTPClientConnection {
8
12
  static _connections = new WeakMap()
@@ -25,10 +29,7 @@ module.exports = class HTTPClientConnection {
25
29
 
26
30
  this._IncomingMessage = IncomingMessage
27
31
 
28
- this._state = constants.state.BEFORE_HEAD
29
- this._length = -1
30
- this._read = 0
31
- this._buffer = null
32
+ this._parser = new HTTPParser()
32
33
  this._idle = true
33
34
 
34
35
  this._onerror = this._onerror.bind(this)
@@ -68,154 +69,50 @@ module.exports = class HTTPClientConnection {
68
69
  _ondata(data) {
69
70
  this._idle = false
70
71
 
71
- if (this._state === constants.state.IN_BODY) return this._onbody(data)
72
-
73
- if (this._buffer !== null) {
74
- this._buffer = Buffer.concat([this._buffer, data])
75
- } else {
76
- this._buffer = data
77
- }
78
-
79
- let hits = 0
80
-
81
- for (let i = 0; i < this._buffer.byteLength; i++) {
82
- const b = this._buffer[i]
83
-
84
- if (hits === 0 && b === 13) {
85
- hits++
86
- } else if (hits === 1 && b === 10) {
87
- hits++
88
-
89
- if (this._state === constants.state.BEFORE_CHUNK) {
90
- const head = this._buffer.subarray(0, i - 1)
91
- this._buffer =
92
- i + 1 === this._buffer.byteLength
93
- ? null
94
- : this._buffer.subarray(i + 1)
95
- i = 0
96
- hits = 0
97
- this._onchunklength(head)
98
-
99
- if (this._buffer === null) break
100
- } else if (this._state === constants.state.IN_CHUNK) {
101
- const chunk = this._buffer.subarray(0, i - 1)
102
-
103
- if (chunk.byteLength !== this._length) {
104
- hits = 0
105
- continue
106
- }
107
-
108
- this._buffer =
109
- i + 1 === this._buffer.byteLength
110
- ? null
111
- : this._buffer.subarray(i + 1)
112
- i = 0
113
- hits = 0
114
- this._onchunk(chunk)
115
-
116
- if (this._buffer === null) break
117
- }
118
- } else if (hits === 2 && b === 13) {
119
- hits++
120
- } else if (hits === 3 && b === 10) {
121
- if (this._state === constants.state.BEFORE_HEAD) {
122
- const head = this._buffer.subarray(0, i - 3)
123
- this._buffer =
124
- i + 1 === this._buffer.byteLength
125
- ? null
126
- : this._buffer.subarray(i + 1)
127
- i = 0
128
- hits = 0
129
- this._onhead(head)
130
-
131
- if (this._buffer === null) break
132
- }
133
- } else {
134
- hits = 0
135
- }
136
- }
137
- }
72
+ try {
73
+ for (const op of this._parser.push(data)) {
74
+ switch (op.type) {
75
+ case RESPONSE:
76
+ this.req.on('close', () => {
77
+ this.req = null
78
+ })
138
79
 
139
- _onhead(data) {
140
- this._state = constants.state.IN_HEAD
80
+ this.res = new this._IncomingMessage(this.socket, op.headers, {
81
+ statusCode: op.code,
82
+ statusMessage: op.reason
83
+ })
141
84
 
142
- const r = data.toString().split('\r\n')
143
- if (r.length === 0) return this.socket.destroy()
85
+ this.res.on('close', () => {
86
+ this.res = null
144
87
 
145
- const [, statusCode, ...statusMessage] = r[0].split(' ')
146
- if (!statusCode || !statusMessage.length) return this.socket.destroy()
88
+ this._idle = true
147
89
 
148
- const headers = {}
90
+ this.socket.emit('free')
91
+ })
149
92
 
150
- for (let i = 1; i < r.length; i++) {
151
- const [name, value] = splitHeader(r[i])
152
- if (name === null) return this.socket.destroy()
153
- headers[name.toLowerCase()] = value
154
- }
93
+ if (op.headers.connection && op.headers.connection.toLowerCase() === 'upgrade') {
94
+ return this._onupgrade(this._parser.end())
95
+ }
155
96
 
156
- this.req.on('close', () => {
157
- this.req = null
158
- })
97
+ this.req.emit('response', this.res)
98
+ break
159
99
 
160
- this.res = new this._IncomingMessage(this.socket, headers, {
161
- statusCode: parseInt(statusCode, 10),
162
- statusMessage: statusMessage.join(' ')
163
- })
100
+ case DATA:
101
+ this.res.push(op.data)
102
+ break
164
103
 
165
- this.res.on('close', () => {
166
- this.res = null
167
- this._onreset()
168
- })
169
-
170
- if (headers.connection && headers.connection.toLowerCase() === 'upgrade') {
171
- const head = this._buffer
172
- this._buffer = null
173
- return this._onupgrade(head)
174
- }
175
-
176
- this.req.emit('response', this.res)
177
-
178
- if (headers['transfer-encoding'] === 'chunked') {
179
- this._state = constants.state.BEFORE_CHUNK
180
- } else {
181
- this._length = parseInt(headers['content-length'], 10) || 0
182
-
183
- if (this._length === 0) return this._onfinished()
184
-
185
- this._state = constants.state.IN_BODY
186
-
187
- if (this._buffer) {
188
- const body = this._buffer
189
- this._buffer = null
190
- this._onbody(body)
104
+ case END:
105
+ if (this.res) this.res.push(null)
106
+ if (this.req) this.req._continueFinal()
107
+ break
108
+ }
191
109
  }
110
+ } catch (err) {
111
+ this.socket.destroy(err)
192
112
  }
193
113
  }
194
114
 
195
- _onchunklength(data) {
196
- this._length = parseInt(data.toString(), 16)
197
-
198
- if (this._length === 0) this._onfinished()
199
- else this._state = constants.state.IN_CHUNK
200
- }
201
-
202
- _onchunk(data) {
203
- this._read += data.byteLength
204
-
205
- this.res.push(data)
206
-
207
- this._state = constants.state.BEFORE_CHUNK
208
- }
209
-
210
- _onbody(data) {
211
- this._read += data.byteLength
212
-
213
- this.res.push(data)
214
-
215
- if (this._read === this._length) this._onfinished()
216
- }
217
-
218
- _onupgrade(head) {
115
+ _onupgrade(data) {
219
116
  this._ondetach()
220
117
 
221
118
  const req = this.req
@@ -223,7 +120,7 @@ module.exports = class HTTPClientConnection {
223
120
  req.upgrade = true
224
121
  req.destroy()
225
122
 
226
- if (req.emit('upgrade', this.res, this.socket, head || empty)) return
123
+ if (req.emit('upgrade', this.res, this.socket, data || EMPTY)) return
227
124
 
228
125
  this.socket.destroy()
229
126
  }
@@ -232,21 +129,6 @@ module.exports = class HTTPClientConnection {
232
129
  if (this.req) this.req.emit('timeout')
233
130
  }
234
131
 
235
- _onfinished() {
236
- if (this.res) this.res.push(null)
237
- if (this.req) this.req._continueFinal()
238
- }
239
-
240
- _onreset() {
241
- this._state = constants.state.BEFORE_HEAD
242
- this._length = -1
243
- this._read = 0
244
- this._buffer = null
245
- this._idle = true
246
-
247
- this.socket.emit('free')
248
- }
249
-
250
132
  _ondrain() {
251
133
  if (this.req) this.req._continueWrite()
252
134
  }
@@ -263,9 +145,3 @@ module.exports = class HTTPClientConnection {
263
145
  HTTPClientConnection._connections.delete(this.socket)
264
146
  }
265
147
  }
266
-
267
- function splitHeader(s) {
268
- const i = s.indexOf(': ')
269
- if (i === -1) return [null, null]
270
- return [s.slice(0, i), s.slice(i + 2)]
271
- }
@@ -13,8 +13,7 @@ module.exports = class HTTPClientRequest extends HTTPOutgoingMessage {
13
13
 
14
14
  opts = opts ? { ...opts } : {}
15
15
 
16
- const agent =
17
- opts.agent === false ? new HTTPAgent() : opts.agent || HTTPAgent.global
16
+ const agent = opts.agent === false ? new HTTPAgent() : opts.agent || HTTPAgent.global
18
17
  const method = opts.method || 'GET'
19
18
  const path = opts.path || '/'
20
19
  const host = (opts.host = opts.host || 'localhost')
@@ -50,8 +49,7 @@ module.exports = class HTTPClientRequest extends HTTPOutgoingMessage {
50
49
  const v = this.headers[name]
51
50
 
52
51
  if (n === 'content-length') this._chunked = false
53
- if (n === 'connection' && v && v.toLowerCase() === 'upgrade')
54
- upgrade = true
52
+ if (n === 'connection' && v && v.toLowerCase() === 'upgrade') upgrade = true
55
53
 
56
54
  h += `${httpCase(n)}: ${v}\r\n`
57
55
  }
@@ -1,11 +1,4 @@
1
1
  declare const constants: {
2
- state: {
3
- BEFORE_HEAD: number
4
- IN_HEAD: number
5
- IN_BODY: number
6
- BEFORE_CHUNK: number
7
- IN_CHUNK: number
8
- }
9
2
  method: {
10
3
  GET: 'GET'
11
4
  HEAD: 'HEAD'
package/lib/constants.js CHANGED
@@ -1,11 +1,4 @@
1
1
  module.exports = {
2
- state: {
3
- BEFORE_HEAD: 1,
4
- IN_HEAD: 2,
5
- IN_BODY: 3,
6
- BEFORE_CHUNK: 4,
7
- IN_CHUNK: 5
8
- },
9
2
  method: {
10
3
  GET: 'GET',
11
4
  HEAD: 'HEAD',
package/lib/errors.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  declare class HTTPError extends Error {
2
- constructor(msg: string, code: string, fn: Error)
2
+ private constructor()
3
3
 
4
4
  static NOT_IMPLEMENTED(msg?: string): HTTPError
5
5
  static CONNECTION_LOST(msg?: string): HTTPError
package/lib/errors.js CHANGED
@@ -1,5 +1,5 @@
1
1
  module.exports = class HTTPError extends Error {
2
- constructor(msg, code, fn = HTTPError) {
2
+ constructor(msg, fn = HTTPError, code = fn.name) {
3
3
  super(`${code}: ${msg}`)
4
4
  this.code = code
5
5
 
@@ -13,10 +13,10 @@ module.exports = class HTTPError extends Error {
13
13
  }
14
14
 
15
15
  static NOT_IMPLEMENTED(msg = 'Method not implemented') {
16
- return new HTTPError(msg, 'NOT_IMPLEMENTED', HTTPError.NOT_IMPLEMENTED)
16
+ return new HTTPError(msg, HTTPError.NOT_IMPLEMENTED)
17
17
  }
18
18
 
19
19
  static CONNECTION_LOST(msg = 'Socket hung up') {
20
- return new HTTPError(msg, 'CONNECTION_LOST', HTTPError.CONNECTION_LOST)
20
+ return new HTTPError(msg, HTTPError.CONNECTION_LOST)
21
21
  }
22
22
  }
@@ -1,10 +1,14 @@
1
1
  const tcp = require('bare-tcp')
2
2
  const { isEnded, isFinished, getStreamError } = require('bare-stream')
3
+ const HTTPParser = require('bare-http-parser')
3
4
  const HTTPIncomingMessage = require('./incoming-message')
4
5
  const HTTPServerResponse = require('./server-response')
5
- const constants = require('./constants')
6
6
 
7
- const empty = Buffer.alloc(0)
7
+ const {
8
+ constants: { REQUEST, DATA, END }
9
+ } = HTTPParser
10
+
11
+ const EMPTY = Buffer.alloc(0)
8
12
 
9
13
  module.exports = class HTTPServerConnection {
10
14
  static _connections = new WeakMap()
@@ -14,10 +18,7 @@ module.exports = class HTTPServerConnection {
14
18
  }
15
19
 
16
20
  constructor(server, socket, opts = {}) {
17
- const {
18
- IncomingMessage = HTTPIncomingMessage,
19
- ServerResponse = HTTPServerResponse
20
- } = opts
21
+ const { IncomingMessage = HTTPIncomingMessage, ServerResponse = HTTPServerResponse } = opts
21
22
 
22
23
  this.server = server
23
24
  this.socket = socket
@@ -28,10 +29,7 @@ module.exports = class HTTPServerConnection {
28
29
  this._IncomingMessage = IncomingMessage
29
30
  this._ServerResponse = ServerResponse
30
31
 
31
- this._state = constants.state.BEFORE_HEAD
32
- this._length = -1
33
- this._read = 0
34
- this._buffer = null
32
+ this._parser = new HTTPParser()
35
33
  this._idle = true
36
34
 
37
35
  this._onclose = this._onclose.bind(this)
@@ -65,161 +63,61 @@ module.exports = class HTTPServerConnection {
65
63
  _ondata(data) {
66
64
  this._idle = false
67
65
 
68
- if (this._state === constants.state.IN_BODY) return this._onbody(data)
69
-
70
- if (this._buffer !== null) {
71
- this._buffer = Buffer.concat([this._buffer, data])
72
- } else {
73
- this._buffer = data
74
- }
75
-
76
- let hits = 0
77
-
78
- for (let i = 0; i < this._buffer.byteLength; i++) {
79
- const b = this._buffer[i]
80
-
81
- if (hits === 0 && b === 13) {
82
- hits++
83
- } else if (hits === 1 && b === 10) {
84
- hits++
85
-
86
- if (this._state === constants.state.BEFORE_CHUNK) {
87
- const head = this._buffer.subarray(0, i - 1)
88
- this._buffer =
89
- i + 1 === this._buffer.byteLength
90
- ? null
91
- : this._buffer.subarray(i + 1)
92
- i = 0
93
- hits = 0
94
- this._onchunklength(head)
95
-
96
- if (this._buffer === null) break
97
- } else if (this._state === constants.state.IN_CHUNK) {
98
- const chunk = this._buffer.subarray(0, i - 1)
99
-
100
- if (chunk.byteLength !== this._length) {
101
- hits = 0
102
- continue
103
- }
104
-
105
- this._buffer =
106
- i + 1 === this._buffer.byteLength
107
- ? null
108
- : this._buffer.subarray(i + 1)
109
- i = 0
110
- hits = 0
111
- this._onchunk(chunk)
112
-
113
- if (this._buffer === null) break
114
- }
115
- } else if (hits === 2 && b === 13) {
116
- hits++
117
- } else if (hits === 3 && b === 10) {
118
- if (this._state === constants.state.BEFORE_HEAD) {
119
- const head = this._buffer.subarray(0, i - 3)
120
- this._buffer =
121
- i + 1 === this._buffer.byteLength
122
- ? null
123
- : this._buffer.subarray(i + 1)
124
- i = 0
125
- hits = 0
126
- this._onhead(head)
127
-
128
- if (this._buffer === null) break
66
+ try {
67
+ for (const op of this._parser.push(data)) {
68
+ switch (op.type) {
69
+ case REQUEST:
70
+ this.req = new this._IncomingMessage(this.socket, op.headers, {
71
+ method: op.method,
72
+ url: op.url
73
+ })
74
+
75
+ this.req.on('close', () => {
76
+ this.req = null
77
+
78
+ this._idle = true
79
+
80
+ if (this.server._state & tcp.constants.state.CLOSING) {
81
+ this.socket.destroy()
82
+ }
83
+ })
84
+
85
+ // Eagerly open the request stream
86
+ this.req.resume()
87
+ this.req.pause()
88
+
89
+ if (op.headers.connection && op.headers.connection.toLowerCase() === 'upgrade') {
90
+ return this._onupgrade(this._parser.end())
91
+ }
92
+
93
+ this.res = new this._ServerResponse(
94
+ this.socket,
95
+ this.req,
96
+ op.headers.connection === 'close'
97
+ )
98
+
99
+ this.res.on('close', () => {
100
+ this.res = null
101
+ })
102
+
103
+ this.server.emit('request', this.req, this.res)
104
+ break
105
+
106
+ case DATA:
107
+ this.req.push(op.data)
108
+ break
109
+
110
+ case END:
111
+ if (this.req) this.req.push(null)
112
+ break
129
113
  }
130
- } else {
131
- hits = 0
132
- }
133
- }
134
- }
135
-
136
- _onhead(data) {
137
- this._state = constants.state.IN_HEAD
138
-
139
- const r = data.toString().split('\r\n')
140
- if (r.length === 0) return this.socket.destroy()
141
-
142
- const [method, url] = r[0].split(' ')
143
- if (!method || !url) return this.socket.destroy()
144
-
145
- const headers = {}
146
-
147
- for (let i = 1; i < r.length; i++) {
148
- const [name, value] = splitHeader(r[i])
149
- if (name === null) return this.socket.destroy()
150
- headers[name.toLowerCase()] = value
151
- }
152
-
153
- this.req = new this._IncomingMessage(this.socket, headers, { method, url })
154
-
155
- this.req.on('close', () => {
156
- this.req = null
157
- this._onreset()
158
- })
159
-
160
- // Eagerly open the request stream
161
- this.req.resume()
162
- this.req.pause()
163
-
164
- if (headers.connection && headers.connection.toLowerCase() === 'upgrade') {
165
- const head = this._buffer
166
- this._buffer = null
167
- return this._onupgrade(head)
168
- }
169
-
170
- this.res = new this._ServerResponse(
171
- this.socket,
172
- this.req,
173
- headers.connection === 'close'
174
- )
175
-
176
- this.res.on('close', () => {
177
- this.res = null
178
- })
179
-
180
- this.server.emit('request', this.req, this.res)
181
-
182
- if (headers['transfer-encoding'] === 'chunked') {
183
- this._state = constants.state.BEFORE_CHUNK
184
- } else {
185
- this._length = parseInt(headers['content-length'], 10) || 0
186
-
187
- if (this._length === 0) return this._onfinished()
188
-
189
- this._state = constants.state.IN_BODY
190
-
191
- if (this._buffer) {
192
- const body = this._buffer
193
- this._buffer = null
194
- this._onbody(body)
195
114
  }
115
+ } catch (err) {
116
+ this.socket.destroy(err)
196
117
  }
197
118
  }
198
119
 
199
- _onchunklength(data) {
200
- this._length = parseInt(data.toString(), 16)
201
-
202
- if (this._length === 0) this._onfinished()
203
- else this._state = constants.state.IN_CHUNK
204
- }
205
-
206
- _onchunk(data) {
207
- this._read += data.byteLength
208
-
209
- this.req.push(data)
210
-
211
- this._state = constants.state.BEFORE_CHUNK
212
- }
213
-
214
- _onbody(data) {
215
- this._read += data.byteLength
216
-
217
- this.req.push(data)
218
-
219
- if (this._read === this._length) this._onfinished()
220
- }
221
-
222
- _onupgrade(head) {
120
+ _onupgrade(data) {
223
121
  this._ondetach()
224
122
 
225
123
  const req = this.req
@@ -227,7 +125,7 @@ module.exports = class HTTPServerConnection {
227
125
  req.upgrade = true
228
126
  req.destroy()
229
127
 
230
- this.server.emit('upgrade', req, this.socket, head || empty)
128
+ this.server.emit('upgrade', req, this.socket, data || EMPTY)
231
129
  }
232
130
 
233
131
  _ontimeout() {
@@ -238,22 +136,6 @@ module.exports = class HTTPServerConnection {
238
136
  if (!reqTimeout && !resTimeout && !serverTimeout) this.socket.destroy()
239
137
  }
240
138
 
241
- _onfinished() {
242
- if (this.req) this.req.push(null)
243
- }
244
-
245
- _onreset() {
246
- this._state = constants.state.BEFORE_HEAD
247
- this._length = -1
248
- this._read = 0
249
- this._buffer = null
250
- this._idle = true
251
-
252
- if (this.server._state & tcp.constants.state.CLOSING) {
253
- this.socket.destroy()
254
- }
255
- }
256
-
257
139
  _ondrain() {
258
140
  if (this.res) this.res._continueWrite()
259
141
  }
@@ -271,9 +153,3 @@ module.exports = class HTTPServerConnection {
271
153
  }
272
154
 
273
155
  function noop() {}
274
-
275
- function splitHeader(s) {
276
- const i = s.indexOf(': ')
277
- if (i === -1) return [null, null]
278
- return [s.slice(0, i), s.slice(i + 2)]
279
- }
@@ -42,9 +42,7 @@ module.exports = class HTTPServerResponse extends HTTPOutgoingMessage {
42
42
  'HTTP/1.1 ' +
43
43
  this.statusCode +
44
44
  ' ' +
45
- (this.statusMessage === null
46
- ? constants.status[this.statusCode]
47
- : this.statusMessage) +
45
+ (this.statusMessage === null ? constants.status[this.statusCode] : this.statusMessage) +
48
46
  '\r\n'
49
47
 
50
48
  for (const name of Object.keys(this.headers)) {
@@ -52,8 +50,7 @@ module.exports = class HTTPServerResponse extends HTTPOutgoingMessage {
52
50
  const v = this.headers[name]
53
51
 
54
52
  if (n === 'content-length') this._chunked = false
55
- if (n === 'connection' && v && v.toLowerCase() === 'close')
56
- this._close = true
53
+ if (n === 'connection' && v && v.toLowerCase() === 'close') this._close = true
57
54
 
58
55
  h += httpCase(n) + ': ' + v + '\r\n'
59
56
  }
package/lib/server.js CHANGED
@@ -12,10 +12,7 @@ module.exports = class HTTPServer extends TCPServer {
12
12
 
13
13
  this._timeout = 0
14
14
 
15
- this.on(
16
- 'connection',
17
- (socket) => new HTTPServerConnection(this, socket, opts)
18
- )
15
+ this.on('connection', (socket) => new HTTPServerConnection(this, socket, opts))
19
16
 
20
17
  if (onrequest) this.on('request', onrequest)
21
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-http1",
3
- "version": "4.1.1",
3
+ "version": "4.1.3",
4
4
  "description": "Native HTTP/1 library for JavaScript",
5
5
  "exports": {
6
6
  "./package": "./package.json",
@@ -37,6 +37,7 @@
37
37
  "homepage": "https://github.com/holepunchto/bare-http1#readme",
38
38
  "dependencies": {
39
39
  "bare-events": "^2.6.0",
40
+ "bare-http-parser": "^1.0.0",
40
41
  "bare-stream": "^2.3.0",
41
42
  "bare-tcp": "^2.0.3"
42
43
  },
@@ -45,7 +46,7 @@
45
46
  "bare-url": "^2.1.3",
46
47
  "brittle": "^3.3.0",
47
48
  "prettier": "^3.4.1",
48
- "prettier-config-standard": "^7.0.0"
49
+ "prettier-config-holepunch": "^2.0.0"
49
50
  },
50
51
  "peerDependencies": {
51
52
  "bare-buffer": "*",