bare-http1 4.1.3 → 4.1.5

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
@@ -56,7 +56,7 @@ export interface HTTPIncomingMessage<
56
56
  setTimeout(ms: number, ontimeout?: () => void): this
57
57
  }
58
58
 
59
- export class HTTPIncomingMessage {
59
+ class HTTPIncomingMessage extends Readable {
60
60
  constructor(
61
61
  socket?: TCPSocket,
62
62
  headers?: Record<string, string | number>,
@@ -87,7 +87,7 @@ export interface HTTPOutgoingMessage<
87
87
  setTimeout(ms: number, ontimeout?: () => void): this
88
88
  }
89
89
 
90
- export class HTTPOutgoingMessage {
90
+ class HTTPOutgoingMessage extends Writable {
91
91
  constructor(socket?: TCPSocket)
92
92
  }
93
93
 
@@ -112,7 +112,7 @@ export interface HTTPAgent {
112
112
  destroy(): void
113
113
  }
114
114
 
115
- export class HTTPAgent {
115
+ class HTTPAgent {
116
116
  constructor(opts?: HTTPAgentOptions & TCPSocketOptions & TCPSocketConnectOptions)
117
117
 
118
118
  static global: HTTPAgent
@@ -134,7 +134,7 @@ export interface HTTPServer<M extends HTTPServerEvents = HTTPServerEvents> exten
134
134
  setTimeout(ms: number, ontimeout?: () => void): this
135
135
  }
136
136
 
137
- export class HTTPServer {
137
+ class HTTPServer extends TCPServer {
138
138
  constructor(
139
139
  opts?: HTTPServerConnectionOptions,
140
140
  onrequest?: (req: HTTPIncomingMessage, res: HTTPServerResponse) => void
@@ -159,7 +159,7 @@ export interface HTTPServerResponse extends HTTPOutgoingMessage {
159
159
  writeHead(statusCode: HTTPStatusCode, headers?: Record<string, string | number>): void
160
160
  }
161
161
 
162
- export class HTTPServerResponse {
162
+ class HTTPServerResponse extends HTTPOutgoingMessage {
163
163
  constructor(socket: TCPSocket, req: HTTPIncomingMessage, close: boolean)
164
164
  }
165
165
 
@@ -176,9 +176,11 @@ export interface HTTPServerConnection {
176
176
 
177
177
  readonly req: HTTPIncomingMessage | null
178
178
  readonly res: HTTPServerResponse | null
179
+
180
+ readonly idle: boolean
179
181
  }
180
182
 
181
- export class HTTPServerConnection {
183
+ class HTTPServerConnection {
182
184
  constructor(server: HTTPServer, socket: TCPSocket, opts?: HTTPServerConnectionOptions)
183
185
 
184
186
  static for(socket: TCPSocket): HTTPServerConnection
@@ -205,7 +207,7 @@ export interface HTTPClientRequest<M extends HTTPClientRequestEvents = HTTPClien
205
207
  readonly headers: Record<string, string | number>
206
208
  }
207
209
 
208
- export class HTTPClientRequest {
210
+ class HTTPClientRequest extends HTTPOutgoingMessage {
209
211
  constructor(opts?: HTTPClientRequestOptions, onresponse?: () => void)
210
212
 
211
213
  constructor(onresponse: () => void)
@@ -226,7 +228,7 @@ export interface HTTPClientConnection {
226
228
  readonly idle: boolean
227
229
  }
228
230
 
229
- export class HTTPClientConnection {
231
+ class HTTPClientConnection {
230
232
  constructor(socket: TCPSocket, opts?: HTTPClientConnectionOptions)
231
233
 
232
234
  static for(socket: TCPSocket): HTTPClientConnection | null
package/index.js CHANGED
@@ -43,9 +43,6 @@ exports.request = function request(url, opts, onresponse) {
43
43
  opts.port = typeof opts.port === 'string' ? parseInt(opts.port, 10) : opts.port
44
44
  }
45
45
 
46
- // TODO: Renable the default global agent when hangs have been sorted
47
- opts.agent = opts.agent || new exports.Agent()
48
-
49
46
  return new exports.ClientRequest(opts, onresponse)
50
47
  }
51
48
 
package/lib/agent.js CHANGED
@@ -1,13 +1,12 @@
1
+ const EventEmitter = require('bare-events')
1
2
  const tcp = require('bare-tcp')
2
3
  const HTTPClientConnection = require('./client-connection')
3
- const EventEmitter = require('bare-events')
4
4
 
5
5
  module.exports = class HTTPAgent extends EventEmitter {
6
6
  constructor(opts = {}) {
7
7
  super()
8
8
 
9
9
  const { keepAlive = false, keepAliveMsecs = 1000 } = opts
10
- this.options = { keepAlive, keepAliveMsecs }
11
10
 
12
11
  this._sockets = new Map()
13
12
  this._freeSockets = new Map()
@@ -47,27 +46,67 @@ module.exports = class HTTPAgent extends EventEmitter {
47
46
 
48
47
  if (this._freeSockets.has(name)) {
49
48
  const sockets = this._freeSockets.get(name)
50
- socket = sockets.values().next().value
51
- sockets.delete(socket)
52
- if (sockets.size === 0) this._freeSockets.delete(name)
49
+
50
+ socket = sockets.pop()
51
+
52
+ if (sockets.length === 0) this._freeSockets.delete(name)
53
53
 
54
54
  this.reuseSocket(socket, req)
55
55
  } else {
56
+ const agent = this
57
+
56
58
  socket = this.createConnection(opts)
57
59
 
58
- socket
59
- .on('free', () => this._onfree(socket, name))
60
- .on('close', () => this._onremove(socket, name))
61
- .on('timeout', () => this._ontimeout(socket, name))
62
- }
60
+ socket.on('free', onfree).on('end', onremove).on('finish', onremove).on('timeout', ontimeout)
61
+
62
+ function onfree() {
63
+ if (agent.keepSocketAlive(socket)) {
64
+ onremove(false)
65
+
66
+ const sockets = agent._freeSockets.get(name)
67
+
68
+ if (sockets === undefined) agent._freeSockets.set(name, [socket])
69
+ else sockets.push(socket)
70
+ } else {
71
+ socket.end()
72
+ }
73
+
74
+ agent.emit('free', socket)
75
+ }
76
+
77
+ function onremove(destroy = true) {
78
+ for (const set of destroy ? [agent._sockets, agent._freeSockets] : [agent._sockets]) {
79
+ const sockets = set.get(name)
80
+ if (sockets === undefined) continue
81
+
82
+ const i = sockets.indexOf(socket)
83
+ if (i === -1) continue
84
+
85
+ const last = sockets.pop()
86
+ if (last !== socket) sockets[i] = last
87
+
88
+ if (sockets.length === 0) set.delete(name)
89
+ }
90
+ }
91
+
92
+ function ontimeout(socket, name) {
93
+ const sockets = agent._freeSockets.get(name)
94
+ if (sockets === undefined) return
95
+
96
+ const i = sockets.indexOf(socket)
97
+ if (i === -1) return
63
98
 
64
- let sockets = this._sockets.get(name)
65
- if (sockets === undefined) {
66
- sockets = new Set()
67
- this._sockets.set(name, sockets)
99
+ const last = sockets.pop()
100
+ if (last !== socket) sockets[i] = last
101
+
102
+ if (sockets.length === 0) agent._freeSockets.delete(name)
103
+ }
68
104
  }
69
105
 
70
- sockets.add(socket)
106
+ const sockets = this._sockets.get(name)
107
+
108
+ if (sockets === undefined) this._sockets.set(name, [socket])
109
+ else sockets.push(socket)
71
110
 
72
111
  req.socket = socket
73
112
 
@@ -84,41 +123,5 @@ module.exports = class HTTPAgent extends EventEmitter {
84
123
  }
85
124
  }
86
125
 
87
- _onfree(socket, name) {
88
- if (this.keepSocketAlive(socket)) {
89
- this._onremove(socket, name, false)
90
-
91
- let sockets = this._freeSockets.get(name)
92
- if (sockets === undefined) {
93
- sockets = new Set()
94
- this._freeSockets.set(name, sockets)
95
- }
96
-
97
- sockets.add(socket)
98
- } else {
99
- socket.end()
100
- }
101
-
102
- this.emit('free', socket)
103
- }
104
-
105
- _onremove(socket, name, all = true) {
106
- for (const set of all ? [this._sockets, this._freeSockets] : [this._sockets]) {
107
- const sockets = set.get(name)
108
- if (sockets === undefined) continue
109
-
110
- sockets.delete(socket)
111
- if (sockets.size === 0) set.delete(name)
112
- }
113
- }
114
-
115
- _ontimeout(socket, name) {
116
- const sockets = this._freeSockets.get(name)
117
- if (!sockets) return
118
-
119
- if (sockets.delete(socket)) socket.destroy()
120
- if (sockets.size === 0) this._freeSockets.delete(name)
121
- }
122
-
123
126
  static global = new this({ keepAlive: 1000, timeout: 5000 })
124
127
  }
package/lib/server.js CHANGED
@@ -12,7 +12,9 @@ module.exports = class HTTPServer extends TCPServer {
12
12
 
13
13
  this._timeout = 0
14
14
 
15
- this.on('connection', (socket) => new HTTPServerConnection(this, socket, opts))
15
+ this.on('connection', (socket) => {
16
+ new HTTPServerConnection(this, socket, opts)
17
+ })
16
18
 
17
19
  if (onrequest) this.on('request', onrequest)
18
20
  }
@@ -35,9 +37,11 @@ module.exports = class HTTPServer extends TCPServer {
35
37
  for (const socket of this._connections) {
36
38
  const connection = HTTPServerConnection.for(socket)
37
39
 
38
- if (connection && connection.idle) {
40
+ if (connection === null || connection.idle) {
39
41
  socket.destroy()
40
42
  }
41
43
  }
44
+
45
+ return this
42
46
  }
43
47
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-http1",
3
- "version": "4.1.3",
3
+ "version": "4.1.5",
4
4
  "description": "Native HTTP/1 library for JavaScript",
5
5
  "exports": {
6
6
  "./package": "./package.json",