bare-http1 3.6.3 → 3.8.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/index.js +18 -2
- package/lib/agent.js +87 -1
- package/lib/client-connection.js +41 -8
- package/lib/client-request.js +6 -9
- package/lib/constants.js +11 -0
- package/lib/incoming-message.js +8 -0
- package/lib/outgoing-message.js +8 -0
- package/lib/server-connection.js +44 -4
- package/lib/server.js +26 -0
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -27,14 +27,18 @@ exports.request = function request (url, opts, onresponse) {
|
|
|
27
27
|
|
|
28
28
|
if (typeof url === 'string') url = new URL(url)
|
|
29
29
|
|
|
30
|
-
if (
|
|
30
|
+
if (isURL(url)) {
|
|
31
31
|
opts = opts ? { ...opts } : {}
|
|
32
32
|
|
|
33
33
|
opts.host = url.hostname
|
|
34
34
|
opts.path = url.pathname + url.search
|
|
35
35
|
opts.port = url.port ? parseInt(url.port, 10) : defaultPort(url)
|
|
36
36
|
} else {
|
|
37
|
-
opts = url
|
|
37
|
+
opts = url ? { ...url } : {}
|
|
38
|
+
|
|
39
|
+
// For Node.js compatibility
|
|
40
|
+
opts.host = opts.hostname || opts.host
|
|
41
|
+
opts.port = typeof opts.port === 'string' ? parseInt(opts.port, 10) : opts.port
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
return new Request(opts, onresponse)
|
|
@@ -52,3 +56,15 @@ function defaultPort (url) {
|
|
|
52
56
|
|
|
53
57
|
return null
|
|
54
58
|
}
|
|
59
|
+
|
|
60
|
+
// https://url.spec.whatwg.org/#api
|
|
61
|
+
function isURL (url) {
|
|
62
|
+
return (
|
|
63
|
+
url !== null &&
|
|
64
|
+
typeof url === 'object' &&
|
|
65
|
+
typeof url.protocol === 'string' &&
|
|
66
|
+
typeof url.hostname === 'string' &&
|
|
67
|
+
typeof url.pathname === 'string' &&
|
|
68
|
+
typeof url.search === 'string'
|
|
69
|
+
)
|
|
70
|
+
}
|
package/lib/agent.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const tcp = require('bare-tcp')
|
|
2
|
+
const HTTPClientConnection = require('./client-connection')
|
|
2
3
|
|
|
3
4
|
module.exports = class HTTPAgent {
|
|
4
5
|
constructor (opts = {}) {
|
|
@@ -11,7 +12,12 @@ module.exports = class HTTPAgent {
|
|
|
11
12
|
timeout = -1
|
|
12
13
|
} = opts
|
|
13
14
|
|
|
15
|
+
this._sockets = new Map()
|
|
16
|
+
this._freeSockets = new Map()
|
|
17
|
+
|
|
14
18
|
this._keepAlive = typeof keepAlive === 'number' ? keepAlive : keepAlive ? keepAliveMsecs : -1
|
|
19
|
+
|
|
20
|
+
this._opts = { ...opts }
|
|
15
21
|
this._maxSockets = maxSockets
|
|
16
22
|
this._maxTotalSockets = maxTotalSockets
|
|
17
23
|
this._maxFreeSockets = maxFreeSockets
|
|
@@ -27,7 +33,87 @@ module.exports = class HTTPAgent {
|
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
keepSocketAlive (socket) {
|
|
30
|
-
return false
|
|
36
|
+
if (this._keepAlive === -1) return false
|
|
37
|
+
|
|
38
|
+
socket.setKeepAlive(true, this._keepAlive)
|
|
39
|
+
socket.unref()
|
|
40
|
+
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getName (opts) {
|
|
45
|
+
return `${opts.host}:${opts.port}`
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
addRequest (req, opts) {
|
|
49
|
+
opts = { ...opts, ...this._opts }
|
|
50
|
+
|
|
51
|
+
const name = this.getName(opts)
|
|
52
|
+
|
|
53
|
+
let socket
|
|
54
|
+
|
|
55
|
+
if (this._freeSockets.has(name)) {
|
|
56
|
+
const sockets = this._freeSockets.get(name)
|
|
57
|
+
socket = sockets.values().next().value
|
|
58
|
+
sockets.delete(socket)
|
|
59
|
+
if (sockets.size === 0) this._freeSockets.delete(name)
|
|
60
|
+
|
|
61
|
+
this.reuseSocket(socket, req)
|
|
62
|
+
} else {
|
|
63
|
+
socket = this.createConnection(opts)
|
|
64
|
+
|
|
65
|
+
socket
|
|
66
|
+
.on('free', () => this._onfree(socket, name))
|
|
67
|
+
.on('close', () => this._onremove(socket, name))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let sockets = this._sockets.get(name)
|
|
71
|
+
if (sockets === undefined) {
|
|
72
|
+
sockets = new Set()
|
|
73
|
+
this._sockets.set(name, sockets)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
sockets.add(socket)
|
|
77
|
+
|
|
78
|
+
req.socket = socket
|
|
79
|
+
|
|
80
|
+
const connection = HTTPClientConnection.from(socket, opts)
|
|
81
|
+
|
|
82
|
+
connection.req = req
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
destroy () {
|
|
86
|
+
for (const set of [this._sockets, this._freeSockets]) {
|
|
87
|
+
for (const [, sockets] of set) {
|
|
88
|
+
for (const socket of sockets) socket.destroy()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_onfree (socket, name) {
|
|
94
|
+
if (this.keepSocketAlive(socket)) {
|
|
95
|
+
this._onremove(socket, name, false)
|
|
96
|
+
|
|
97
|
+
let sockets = this._freeSockets.get(name)
|
|
98
|
+
if (sockets === undefined) {
|
|
99
|
+
sockets = new Set()
|
|
100
|
+
this._freeSockets.set(name, sockets)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
sockets.add(socket)
|
|
104
|
+
} else {
|
|
105
|
+
socket.end()
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
_onremove (socket, name, all = true) {
|
|
110
|
+
for (const set of all ? [this._sockets, this._freeSockets] : [this._sockets]) {
|
|
111
|
+
const sockets = set.get(name)
|
|
112
|
+
if (sockets === undefined) continue
|
|
113
|
+
|
|
114
|
+
sockets.delete(socket)
|
|
115
|
+
if (sockets.size === 0) set.delete(name)
|
|
116
|
+
}
|
|
31
117
|
}
|
|
32
118
|
|
|
33
119
|
static global = new this({ keepAlive: 1000, timeout: 5000 })
|
package/lib/client-connection.js
CHANGED
|
@@ -5,6 +5,16 @@ const errors = require('./errors')
|
|
|
5
5
|
const empty = Buffer.alloc(0)
|
|
6
6
|
|
|
7
7
|
module.exports = class HTTPClientConnection {
|
|
8
|
+
static _connections = new WeakMap()
|
|
9
|
+
|
|
10
|
+
static for (socket) {
|
|
11
|
+
return this._connections.get(socket) || null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static from (socket, opts) {
|
|
15
|
+
return this.for(socket) || new this(socket, opts)
|
|
16
|
+
}
|
|
17
|
+
|
|
8
18
|
constructor (socket, opts = {}) {
|
|
9
19
|
const {
|
|
10
20
|
IncomingMessage = HTTPIncomingMessage
|
|
@@ -21,12 +31,14 @@ module.exports = class HTTPClientConnection {
|
|
|
21
31
|
this._length = -1
|
|
22
32
|
this._read = 0
|
|
23
33
|
this._buffer = null
|
|
34
|
+
this._idle = true
|
|
24
35
|
|
|
25
36
|
this._onerror = this._onerror.bind(this)
|
|
26
37
|
this._onclose = this._onclose.bind(this)
|
|
27
38
|
this._onend = this._onend.bind(this)
|
|
28
39
|
this._ondata = this._ondata.bind(this)
|
|
29
40
|
this._ondrain = this._ondrain.bind(this)
|
|
41
|
+
this._ontimeout = this._ontimeout.bind(this)
|
|
30
42
|
|
|
31
43
|
socket
|
|
32
44
|
.on('error', this._onerror)
|
|
@@ -34,6 +46,13 @@ module.exports = class HTTPClientConnection {
|
|
|
34
46
|
.on('end', this._onend)
|
|
35
47
|
.on('data', this._ondata)
|
|
36
48
|
.on('drain', this._ondrain)
|
|
49
|
+
.on('timeout', this._ontimeout)
|
|
50
|
+
|
|
51
|
+
HTTPClientConnection._connections.set(socket, this)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get idle () {
|
|
55
|
+
return this._idle
|
|
37
56
|
}
|
|
38
57
|
|
|
39
58
|
_onerror (err) {
|
|
@@ -49,6 +68,8 @@ module.exports = class HTTPClientConnection {
|
|
|
49
68
|
}
|
|
50
69
|
|
|
51
70
|
_ondata (data) {
|
|
71
|
+
this._idle = false
|
|
72
|
+
|
|
52
73
|
if (this._state === constants.state.IN_BODY) return this._onbody(data)
|
|
53
74
|
|
|
54
75
|
if (this._buffer !== null) {
|
|
@@ -179,12 +200,7 @@ module.exports = class HTTPClientConnection {
|
|
|
179
200
|
}
|
|
180
201
|
|
|
181
202
|
_onupgrade (head) {
|
|
182
|
-
this.
|
|
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)
|
|
203
|
+
this._ondetach()
|
|
188
204
|
|
|
189
205
|
const req = this.req
|
|
190
206
|
|
|
@@ -196,11 +212,13 @@ module.exports = class HTTPClientConnection {
|
|
|
196
212
|
this.socket.destroy()
|
|
197
213
|
}
|
|
198
214
|
|
|
215
|
+
_ontimeout () {
|
|
216
|
+
if (this.req) this.req.emit('timeout')
|
|
217
|
+
}
|
|
218
|
+
|
|
199
219
|
_onfinished () {
|
|
200
220
|
if (this.res) this.res.push(null)
|
|
201
221
|
if (this.req) this.req._continueFinal()
|
|
202
|
-
|
|
203
|
-
this.socket.end()
|
|
204
222
|
}
|
|
205
223
|
|
|
206
224
|
_onreset () {
|
|
@@ -208,9 +226,24 @@ module.exports = class HTTPClientConnection {
|
|
|
208
226
|
this._length = -1
|
|
209
227
|
this._read = 0
|
|
210
228
|
this._buffer = null
|
|
229
|
+
this._idle = true
|
|
230
|
+
|
|
231
|
+
this.socket.emit('free')
|
|
211
232
|
}
|
|
212
233
|
|
|
213
234
|
_ondrain () {
|
|
214
235
|
if (this.req) this.req._continueWrite()
|
|
215
236
|
}
|
|
237
|
+
|
|
238
|
+
_ondetach () {
|
|
239
|
+
this.socket
|
|
240
|
+
.off('error', this._onerror)
|
|
241
|
+
.off('close', this._onclose)
|
|
242
|
+
.off('end', this._onend)
|
|
243
|
+
.off('data', this._ondata)
|
|
244
|
+
.off('drain', this._ondrain)
|
|
245
|
+
.off('timeout', this._ontimeout)
|
|
246
|
+
|
|
247
|
+
HTTPClientConnection._connections.delete(this.socket)
|
|
248
|
+
}
|
|
216
249
|
}
|
package/lib/client-request.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const HTTPAgent = require('./agent')
|
|
2
2
|
const HTTPOutgoingMessage = require('./outgoing-message')
|
|
3
|
-
const HTTPClientConnection = require('./client-connection')
|
|
4
3
|
|
|
5
4
|
module.exports = class HTTPClientRequest extends HTTPOutgoingMessage {
|
|
6
5
|
constructor (opts = {}, onresponse = null) {
|
|
@@ -11,25 +10,23 @@ module.exports = class HTTPClientRequest extends HTTPOutgoingMessage {
|
|
|
11
10
|
|
|
12
11
|
opts = opts ? { ...opts } : {}
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
// TODO: Renable the default global agent when tests have been sorted
|
|
14
|
+
// const agent = opts.agent === false ? new HTTPAgent() : opts.agent || HTTPAgent.global
|
|
15
|
+
|
|
16
|
+
const agent = opts.agent || new HTTPAgent()
|
|
15
17
|
const method = opts.method || 'GET'
|
|
16
18
|
const path = opts.path || '/'
|
|
17
19
|
const host = opts.host = opts.host || 'localhost'
|
|
18
20
|
const port = opts.port = opts.port || 80
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
connection = new HTTPClientConnection(agent.createConnection(opts), opts)
|
|
22
|
-
} = opts
|
|
23
|
-
|
|
24
|
-
super(connection.socket)
|
|
22
|
+
super()
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
agent.addRequest(this, opts)
|
|
27
25
|
|
|
28
26
|
this.method = method
|
|
29
27
|
this.path = path
|
|
30
28
|
this.headers = { host: host + ':' + port, ...opts.headers }
|
|
31
29
|
|
|
32
|
-
this._connection = connection
|
|
33
30
|
this._chunked = method !== 'GET' && method !== 'HEAD'
|
|
34
31
|
|
|
35
32
|
this._pendingFinal = null
|
package/lib/constants.js
CHANGED
|
@@ -6,6 +6,17 @@ module.exports = {
|
|
|
6
6
|
BEFORE_CHUNK: 4,
|
|
7
7
|
IN_CHUNK: 5
|
|
8
8
|
},
|
|
9
|
+
method: {
|
|
10
|
+
GET: 'GET',
|
|
11
|
+
HEAD: 'HEAD',
|
|
12
|
+
POST: 'POST',
|
|
13
|
+
PUT: 'PUT',
|
|
14
|
+
DELETE: 'DELETE',
|
|
15
|
+
CONNECT: 'CONNECT',
|
|
16
|
+
OPTIONS: 'OPTIONS',
|
|
17
|
+
TRACE: 'TRACE',
|
|
18
|
+
PATCH: 'PATCH'
|
|
19
|
+
},
|
|
9
20
|
status: {
|
|
10
21
|
100: 'Continue',
|
|
11
22
|
101: 'Switching Protocols',
|
package/lib/incoming-message.js
CHANGED
|
@@ -33,6 +33,14 @@ module.exports = class HTTPIncomingMessage extends Readable {
|
|
|
33
33
|
return name.toLowerCase() in this.headers
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
setTimeout (ms, ontimeout) {
|
|
37
|
+
if (ontimeout) this.once('timeout', ontimeout)
|
|
38
|
+
|
|
39
|
+
this.socket.setTimeout(ms)
|
|
40
|
+
|
|
41
|
+
return this
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
_predestroy () {
|
|
37
45
|
if (this.upgrade === false && this.socket !== null) this.socket.destroy()
|
|
38
46
|
}
|
package/lib/outgoing-message.js
CHANGED
|
@@ -34,6 +34,14 @@ module.exports = class HTTPOutgoingMessage extends Writable {
|
|
|
34
34
|
this.headersSent = true
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
setTimeout (ms, ontimeout) {
|
|
38
|
+
if (ontimeout) this.once('timeout', ontimeout)
|
|
39
|
+
|
|
40
|
+
this.socket.setTimeout(ms)
|
|
41
|
+
|
|
42
|
+
return this
|
|
43
|
+
}
|
|
44
|
+
|
|
37
45
|
_header () {
|
|
38
46
|
throw errors.NOT_IMPLEMENTED()
|
|
39
47
|
}
|
package/lib/server-connection.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const tcp = require('bare-tcp')
|
|
1
2
|
const HTTPIncomingMessage = require('./incoming-message')
|
|
2
3
|
const HTTPServerResponse = require('./server-response')
|
|
3
4
|
const constants = require('./constants')
|
|
@@ -5,6 +6,12 @@ const constants = require('./constants')
|
|
|
5
6
|
const empty = Buffer.alloc(0)
|
|
6
7
|
|
|
7
8
|
module.exports = class HTTPServerConnection {
|
|
9
|
+
static _connections = new WeakMap()
|
|
10
|
+
|
|
11
|
+
static for (socket) {
|
|
12
|
+
return this._connections.get(socket) || null
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
constructor (server, socket, opts = {}) {
|
|
9
16
|
const {
|
|
10
17
|
IncomingMessage = HTTPIncomingMessage,
|
|
@@ -24,15 +31,26 @@ module.exports = class HTTPServerConnection {
|
|
|
24
31
|
this._length = -1
|
|
25
32
|
this._read = 0
|
|
26
33
|
this._buffer = null
|
|
34
|
+
this._idle = true
|
|
27
35
|
|
|
28
36
|
this._onerror = this._onerror.bind(this)
|
|
29
37
|
this._ondata = this._ondata.bind(this)
|
|
30
38
|
this._ondrain = this._ondrain.bind(this)
|
|
39
|
+
this._ontimeout = this._ontimeout.bind(this)
|
|
31
40
|
|
|
32
41
|
socket
|
|
33
42
|
.on('error', this._onerror)
|
|
34
43
|
.on('data', this._ondata)
|
|
35
44
|
.on('drain', this._ondrain)
|
|
45
|
+
.on('timeout', this._ontimeout)
|
|
46
|
+
|
|
47
|
+
HTTPServerConnection._connections.set(socket, this)
|
|
48
|
+
|
|
49
|
+
if (this.server.timeout) socket.setTimeout(this.server.timeout)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get idle () {
|
|
53
|
+
return this._idle
|
|
36
54
|
}
|
|
37
55
|
|
|
38
56
|
_onerror (err) {
|
|
@@ -40,6 +58,8 @@ module.exports = class HTTPServerConnection {
|
|
|
40
58
|
}
|
|
41
59
|
|
|
42
60
|
_ondata (data) {
|
|
61
|
+
this._idle = false
|
|
62
|
+
|
|
43
63
|
if (this._state === constants.state.IN_BODY) return this._onbody(data)
|
|
44
64
|
|
|
45
65
|
if (this._buffer !== null) {
|
|
@@ -172,10 +192,7 @@ module.exports = class HTTPServerConnection {
|
|
|
172
192
|
}
|
|
173
193
|
|
|
174
194
|
_onupgrade (head) {
|
|
175
|
-
this.
|
|
176
|
-
.off('error', this._onerror)
|
|
177
|
-
.off('data', this._ondata)
|
|
178
|
-
.off('drain', this._ondrain)
|
|
195
|
+
this._ondetach()
|
|
179
196
|
|
|
180
197
|
const req = this.req
|
|
181
198
|
|
|
@@ -185,6 +202,14 @@ module.exports = class HTTPServerConnection {
|
|
|
185
202
|
this.server.emit('upgrade', req, this.socket, head || empty)
|
|
186
203
|
}
|
|
187
204
|
|
|
205
|
+
_ontimeout () {
|
|
206
|
+
const reqTimeout = this.req && this.req.emit('timeout')
|
|
207
|
+
const resTimeout = this.res && this.res.emit('timeout')
|
|
208
|
+
const serverTimeout = this.server.emit('timeout', this.socket)
|
|
209
|
+
|
|
210
|
+
if (!reqTimeout && !resTimeout && !serverTimeout) this.socket.destroy()
|
|
211
|
+
}
|
|
212
|
+
|
|
188
213
|
_onfinished () {
|
|
189
214
|
if (this.req) this.req.push(null)
|
|
190
215
|
}
|
|
@@ -194,9 +219,24 @@ module.exports = class HTTPServerConnection {
|
|
|
194
219
|
this._length = -1
|
|
195
220
|
this._read = 0
|
|
196
221
|
this._buffer = null
|
|
222
|
+
this._idle = true
|
|
223
|
+
|
|
224
|
+
if (this.server._state & tcp.constants.state.CLOSING) {
|
|
225
|
+
this.socket.destroy()
|
|
226
|
+
}
|
|
197
227
|
}
|
|
198
228
|
|
|
199
229
|
_ondrain () {
|
|
200
230
|
if (this.res) this.res._continueWrite()
|
|
201
231
|
}
|
|
232
|
+
|
|
233
|
+
_ondetach () {
|
|
234
|
+
this.socket
|
|
235
|
+
.off('error', this._onerror)
|
|
236
|
+
.off('data', this._ondata)
|
|
237
|
+
.off('drain', this._ondrain)
|
|
238
|
+
.off('timeout', this._ontimeout)
|
|
239
|
+
|
|
240
|
+
HTTPServerConnection._connections.delete(this.socket)
|
|
241
|
+
}
|
|
202
242
|
}
|
package/lib/server.js
CHANGED
|
@@ -10,8 +10,34 @@ module.exports = class HTTPServer extends TCPServer {
|
|
|
10
10
|
|
|
11
11
|
super({ allowHalfOpen: false })
|
|
12
12
|
|
|
13
|
+
this._timeout = 0
|
|
14
|
+
|
|
13
15
|
this.on('connection', (socket) => new HTTPServerConnection(this, socket, opts))
|
|
14
16
|
|
|
15
17
|
if (onrequest) this.on('request', onrequest)
|
|
16
18
|
}
|
|
19
|
+
|
|
20
|
+
get timeout () {
|
|
21
|
+
return this._timeout || undefined // For Node.js compatibility
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setTimeout (ms = 0, ontimeout) {
|
|
25
|
+
if (ontimeout) this.on('timeout', ontimeout)
|
|
26
|
+
|
|
27
|
+
this._timeout = ms
|
|
28
|
+
|
|
29
|
+
return this
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
close (onclose) {
|
|
33
|
+
super.close(onclose)
|
|
34
|
+
|
|
35
|
+
for (const socket of this._connections) {
|
|
36
|
+
const connection = HTTPServerConnection.for(socket)
|
|
37
|
+
|
|
38
|
+
if (connection && connection.idle) {
|
|
39
|
+
socket.destroy()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
17
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bare-http1",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"description": "Native HTTP/1 library for JavaScript",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"bare-events": "^2.0.0",
|
|
29
29
|
"bare-stream": "^2.0.0",
|
|
30
|
-
"bare-tcp": "^1.
|
|
30
|
+
"bare-tcp": "^1.8.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"brittle": "^3.3.0",
|