bare-http1 4.2.4 → 4.3.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.
- package/index.d.ts +4 -1
- package/lib/agent.js +108 -52
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -99,6 +99,9 @@ export interface HTTPAgentOptions {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
export interface HTTPAgent {
|
|
102
|
+
readonly sockets: IterableIterator<TCPSocket>
|
|
103
|
+
readonly freeSockets: IterableIterator<TCPSocket>
|
|
104
|
+
|
|
102
105
|
createConnection(opts?: TCPSocketOptions & TCPSocketConnectOptions): TCPSocket
|
|
103
106
|
|
|
104
107
|
reuseSocket(socket: TCPSocket, req?: HTTPClientRequest): void
|
|
@@ -115,7 +118,7 @@ export interface HTTPAgent {
|
|
|
115
118
|
class HTTPAgent {
|
|
116
119
|
constructor(opts?: HTTPAgentOptions & TCPSocketOptions & TCPSocketConnectOptions)
|
|
117
120
|
|
|
118
|
-
static global: HTTPAgent
|
|
121
|
+
static readonly global: HTTPAgent
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
export const globalAgent: HTTPAgent
|
package/lib/agent.js
CHANGED
|
@@ -2,20 +2,88 @@ const EventEmitter = require('bare-events')
|
|
|
2
2
|
const tcp = require('bare-tcp')
|
|
3
3
|
const HTTPClientConnection = require('./client-connection')
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
class HTTPSocketSet {
|
|
6
|
+
constructor() {
|
|
7
|
+
this._sockets = new Map()
|
|
8
|
+
this._size = 0
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get size() {
|
|
12
|
+
return this._size
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
add(name, socket) {
|
|
16
|
+
const sockets = this._sockets.get(name)
|
|
17
|
+
|
|
18
|
+
this._size++
|
|
19
|
+
|
|
20
|
+
if (sockets === undefined) this._sockets.set(name, [socket])
|
|
21
|
+
else sockets.push(socket)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
pop(name) {
|
|
25
|
+
const sockets = this._sockets.get(name)
|
|
26
|
+
if (sockets === undefined || sockets.length === 0) return null
|
|
27
|
+
|
|
28
|
+
this._size--
|
|
29
|
+
|
|
30
|
+
const last = sockets.pop()
|
|
31
|
+
|
|
32
|
+
if (sockets.length === 0) this._sockets.delete(name)
|
|
33
|
+
|
|
34
|
+
return last
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
delete(name, socket) {
|
|
38
|
+
const sockets = this._sockets.get(name)
|
|
39
|
+
if (sockets === undefined) return
|
|
40
|
+
|
|
41
|
+
const i = sockets.indexOf(socket)
|
|
42
|
+
if (i === -1) return
|
|
43
|
+
|
|
44
|
+
this._size--
|
|
45
|
+
|
|
46
|
+
const last = sockets.pop()
|
|
47
|
+
if (last !== socket) sockets[i] = last
|
|
48
|
+
|
|
49
|
+
if (sockets.length === 0) this._sockets.delete(name)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
*sockets() {
|
|
53
|
+
for (const sockets of this._sockets.values()) {
|
|
54
|
+
yield* sockets
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
*[Symbol.iterator]() {
|
|
59
|
+
for (const [name, sockets] of this._sockets) {
|
|
60
|
+
for (const socket of sockets) yield [name, socket]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
class HTTPAgent extends EventEmitter {
|
|
6
66
|
constructor(opts = {}) {
|
|
7
67
|
super()
|
|
8
68
|
|
|
9
69
|
const { keepAlive = false, keepAliveMsecs = 1000 } = opts
|
|
10
70
|
|
|
11
|
-
this._sockets = new
|
|
12
|
-
this._freeSockets = new
|
|
71
|
+
this._sockets = new HTTPSocketSet()
|
|
72
|
+
this._freeSockets = new HTTPSocketSet()
|
|
13
73
|
|
|
14
74
|
this._keepAlive = typeof keepAlive === 'number' ? keepAlive : keepAlive ? keepAliveMsecs : -1
|
|
15
75
|
|
|
16
76
|
this._opts = { ...opts }
|
|
17
77
|
}
|
|
18
78
|
|
|
79
|
+
get sockets() {
|
|
80
|
+
return this._sockets.sockets()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get freeSockets() {
|
|
84
|
+
return this._freeSockets.sockets()
|
|
85
|
+
}
|
|
86
|
+
|
|
19
87
|
createConnection(opts) {
|
|
20
88
|
return tcp.createConnection(opts)
|
|
21
89
|
}
|
|
@@ -42,33 +110,26 @@ module.exports = class HTTPAgent extends EventEmitter {
|
|
|
42
110
|
|
|
43
111
|
const name = this.getName(opts)
|
|
44
112
|
|
|
45
|
-
let socket
|
|
46
|
-
|
|
47
|
-
if (this._freeSockets.has(name)) {
|
|
48
|
-
const sockets = this._freeSockets.get(name)
|
|
113
|
+
let socket = this._freeSockets.pop(name)
|
|
49
114
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (sockets.length === 0) this._freeSockets.delete(name)
|
|
53
|
-
|
|
54
|
-
this.reuseSocket(socket, req)
|
|
55
|
-
} else {
|
|
115
|
+
if (socket) this.reuseSocket(socket, req)
|
|
116
|
+
else {
|
|
56
117
|
const agent = this
|
|
57
118
|
|
|
58
119
|
socket = this.createConnection(opts)
|
|
59
120
|
|
|
60
|
-
socket
|
|
121
|
+
socket
|
|
122
|
+
.on('free', onfree)
|
|
123
|
+
.on('timeout', ontimeout)
|
|
124
|
+
.on('end', onremove)
|
|
125
|
+
.on('finish', onremove)
|
|
126
|
+
.on('close', onremove)
|
|
61
127
|
|
|
62
128
|
function onfree() {
|
|
63
129
|
if (socket.destroyed) return
|
|
64
130
|
|
|
65
131
|
if (agent.keepSocketAlive(socket)) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const sockets = agent._freeSockets.get(name)
|
|
69
|
-
|
|
70
|
-
if (sockets === undefined) agent._freeSockets.set(name, [socket])
|
|
71
|
-
else sockets.push(socket)
|
|
132
|
+
agent._freeSockets.add(name, socket)
|
|
72
133
|
} else {
|
|
73
134
|
socket.end()
|
|
74
135
|
}
|
|
@@ -76,41 +137,25 @@ module.exports = class HTTPAgent extends EventEmitter {
|
|
|
76
137
|
agent.emit('free', socket)
|
|
77
138
|
}
|
|
78
139
|
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
for (const set of destroy ? [agent._sockets, agent._freeSockets] : [agent._sockets]) {
|
|
83
|
-
const sockets = set.get(name)
|
|
84
|
-
if (sockets === undefined) continue
|
|
85
|
-
|
|
86
|
-
const i = sockets.indexOf(socket)
|
|
87
|
-
if (i === -1) continue
|
|
88
|
-
|
|
89
|
-
const last = sockets.pop()
|
|
90
|
-
if (last !== socket) sockets[i] = last
|
|
140
|
+
function ontimeout() {
|
|
141
|
+
socket.destroy()
|
|
91
142
|
|
|
92
|
-
|
|
93
|
-
}
|
|
143
|
+
agent._freeSockets.delete(name, socket)
|
|
94
144
|
}
|
|
95
145
|
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
if (sockets === undefined) return
|
|
99
|
-
|
|
100
|
-
const i = sockets.indexOf(socket)
|
|
101
|
-
if (i === -1) return
|
|
146
|
+
function onremove() {
|
|
147
|
+
socket.off('free', onfree)
|
|
102
148
|
|
|
103
|
-
|
|
104
|
-
|
|
149
|
+
agent._sockets.delete(name, socket)
|
|
150
|
+
agent._freeSockets.delete(name, socket)
|
|
105
151
|
|
|
106
|
-
if (
|
|
152
|
+
if (agent._sockets.size === 0) HTTPAgent._agents.delete(agent)
|
|
107
153
|
}
|
|
108
154
|
}
|
|
109
155
|
|
|
110
|
-
|
|
156
|
+
if (this._sockets.size === 0) HTTPAgent._agents.add(this)
|
|
111
157
|
|
|
112
|
-
|
|
113
|
-
else sockets.push(socket)
|
|
158
|
+
this._sockets.add(name, socket)
|
|
114
159
|
|
|
115
160
|
req.socket = socket
|
|
116
161
|
|
|
@@ -120,12 +165,23 @@ module.exports = class HTTPAgent extends EventEmitter {
|
|
|
120
165
|
}
|
|
121
166
|
|
|
122
167
|
destroy() {
|
|
123
|
-
for (const
|
|
124
|
-
for (const [, sockets] of set) {
|
|
125
|
-
for (const socket of sockets) socket.destroy()
|
|
126
|
-
}
|
|
127
|
-
}
|
|
168
|
+
for (const socket of this._sockets.sockets()) socket.destroy()
|
|
128
169
|
}
|
|
129
170
|
|
|
130
|
-
static
|
|
171
|
+
static _global = new this({ keepAlive: 1000, timeout: 5000 })
|
|
172
|
+
static _agents = new Set()
|
|
173
|
+
|
|
174
|
+
static get global() {
|
|
175
|
+
return this._global
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static _onidle() {
|
|
179
|
+
for (const agent of this._agents) {
|
|
180
|
+
for (const socket of agent._sockets.sockets()) socket.destroy()
|
|
181
|
+
}
|
|
182
|
+
}
|
|
131
183
|
}
|
|
184
|
+
|
|
185
|
+
module.exports = HTTPAgent
|
|
186
|
+
|
|
187
|
+
Bare.on('idle', HTTPAgent._onidle.bind(HTTPAgent))
|