undici 7.0.0-alpha.9 → 7.0.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.
|
@@ -27,7 +27,8 @@ const {
|
|
|
27
27
|
kResume,
|
|
28
28
|
kSize,
|
|
29
29
|
kHTTPContext,
|
|
30
|
-
kClosed
|
|
30
|
+
kClosed,
|
|
31
|
+
kBodyTimeout
|
|
31
32
|
} = require('../core/symbols.js')
|
|
32
33
|
|
|
33
34
|
const kOpenStreams = Symbol('open streams')
|
|
@@ -90,7 +91,11 @@ async function connectH2 (client, socket) {
|
|
|
90
91
|
|
|
91
92
|
const session = http2.connect(client[kUrl], {
|
|
92
93
|
createConnection: () => socket,
|
|
93
|
-
peerMaxConcurrentStreams: client[kMaxConcurrentStreams]
|
|
94
|
+
peerMaxConcurrentStreams: client[kMaxConcurrentStreams],
|
|
95
|
+
settings: {
|
|
96
|
+
// TODO(metcoder95): add support for PUSH
|
|
97
|
+
enablePush: false
|
|
98
|
+
}
|
|
94
99
|
})
|
|
95
100
|
|
|
96
101
|
session[kOpenStreams] = 0
|
|
@@ -129,7 +134,6 @@ async function connectH2 (client, socket) {
|
|
|
129
134
|
if (socket[kClosed]) {
|
|
130
135
|
queueMicrotask(callback)
|
|
131
136
|
} else {
|
|
132
|
-
// Destroying the socket will trigger the session close
|
|
133
137
|
socket.destroy(err).on('close', callback)
|
|
134
138
|
}
|
|
135
139
|
},
|
|
@@ -281,6 +285,7 @@ function shouldSendContentLength (method) {
|
|
|
281
285
|
}
|
|
282
286
|
|
|
283
287
|
function writeH2 (client, request) {
|
|
288
|
+
const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout]
|
|
284
289
|
const session = client[kHTTP2Session]
|
|
285
290
|
const { method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request
|
|
286
291
|
let { body } = request
|
|
@@ -379,6 +384,7 @@ function writeH2 (client, request) {
|
|
|
379
384
|
session[kOpenStreams] -= 1
|
|
380
385
|
if (session[kOpenStreams] === 0) session.unref()
|
|
381
386
|
})
|
|
387
|
+
stream.setTimeout(requestTimeout)
|
|
382
388
|
|
|
383
389
|
return true
|
|
384
390
|
}
|
|
@@ -452,6 +458,7 @@ function writeH2 (client, request) {
|
|
|
452
458
|
|
|
453
459
|
session.ref()
|
|
454
460
|
|
|
461
|
+
// TODO(metcoder95): add support for sending trailers
|
|
455
462
|
const shouldEndStream = method === 'GET' || method === 'HEAD' || body === null
|
|
456
463
|
if (expectContinue) {
|
|
457
464
|
headers[HTTP2_HEADER_EXPECT] = '100-continue'
|
|
@@ -469,6 +476,7 @@ function writeH2 (client, request) {
|
|
|
469
476
|
|
|
470
477
|
// Increment counter as we have new streams open
|
|
471
478
|
++session[kOpenStreams]
|
|
479
|
+
stream.setTimeout(requestTimeout)
|
|
472
480
|
|
|
473
481
|
stream.once('response', headers => {
|
|
474
482
|
const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers
|
|
@@ -502,8 +510,9 @@ function writeH2 (client, request) {
|
|
|
502
510
|
// Present specially when using pipeline or stream
|
|
503
511
|
if (stream.state?.state == null || stream.state.state < 6) {
|
|
504
512
|
// Do not complete the request if it was aborted
|
|
505
|
-
|
|
506
|
-
|
|
513
|
+
// Not prone to happen for as safety net to avoid race conditions with 'trailers'
|
|
514
|
+
if (!request.aborted && !request.completed) {
|
|
515
|
+
request.onComplete({})
|
|
507
516
|
}
|
|
508
517
|
|
|
509
518
|
client[kQueue][client[kRunningIdx]++] = null
|
|
@@ -546,17 +555,25 @@ function writeH2 (client, request) {
|
|
|
546
555
|
stream.removeAllListeners('data')
|
|
547
556
|
})
|
|
548
557
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
558
|
+
stream.on('timeout', () => {
|
|
559
|
+
const err = new InformationalError(`HTTP/2: "stream timeout after ${requestTimeout}"`)
|
|
560
|
+
stream.removeAllListeners('data')
|
|
561
|
+
session[kOpenStreams] -= 1
|
|
562
|
+
|
|
563
|
+
if (session[kOpenStreams] === 0) {
|
|
564
|
+
session.unref()
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
abort(err)
|
|
568
|
+
})
|
|
552
569
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
570
|
+
stream.once('trailers', trailers => {
|
|
571
|
+
if (request.aborted || request.completed) {
|
|
572
|
+
return
|
|
573
|
+
}
|
|
556
574
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
// })
|
|
575
|
+
request.onComplete(trailers)
|
|
576
|
+
})
|
|
560
577
|
|
|
561
578
|
return true
|
|
562
579
|
|
|
@@ -27,6 +27,10 @@ class ResponseErrorHandler extends DecoratorHandler {
|
|
|
27
27
|
return this.#handler.onConnect(abort)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
#checkContentType (contentType) {
|
|
31
|
+
return this.#contentType.indexOf(contentType) === 0
|
|
32
|
+
}
|
|
33
|
+
|
|
30
34
|
onHeaders (statusCode, rawHeaders, resume, statusMessage, headers = parseHeaders(rawHeaders)) {
|
|
31
35
|
this.#statusCode = statusCode
|
|
32
36
|
this.#headers = headers
|
|
@@ -36,7 +40,7 @@ class ResponseErrorHandler extends DecoratorHandler {
|
|
|
36
40
|
return this.#handler.onHeaders(statusCode, rawHeaders, resume, statusMessage, headers)
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
if (this.#
|
|
43
|
+
if (this.#checkContentType('application/json') || this.#checkContentType('text/plain')) {
|
|
40
44
|
this.#decoder = new TextDecoder('utf-8')
|
|
41
45
|
}
|
|
42
46
|
}
|
|
@@ -53,7 +57,7 @@ class ResponseErrorHandler extends DecoratorHandler {
|
|
|
53
57
|
if (this.#statusCode >= 400) {
|
|
54
58
|
this.#body += this.#decoder?.decode(undefined, { stream: false }) ?? ''
|
|
55
59
|
|
|
56
|
-
if (this.#
|
|
60
|
+
if (this.#checkContentType('application/json')) {
|
|
57
61
|
try {
|
|
58
62
|
this.#body = JSON.parse(this.#body)
|
|
59
63
|
} catch {
|