bdy 1.22.83-stage → 1.22.84-dev
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/distTs/package.json
CHANGED
|
@@ -9,14 +9,14 @@ const http2_1 = __importDefault(require("http2"));
|
|
|
9
9
|
const uuid_1 = require("uuid");
|
|
10
10
|
const texts_1 = require("../texts");
|
|
11
11
|
const CONNECTION_TIMEOUT = 5000;
|
|
12
|
-
const HTTP2_MAX_POOL_SIZE =
|
|
12
|
+
const HTTP2_MAX_POOL_SIZE = 8;
|
|
13
13
|
const HTTP2_MAX_CONCURRENT_STREAMS = 100;
|
|
14
14
|
const HTTP2_MAX_LIFETIME_REQUESTS = 1000;
|
|
15
15
|
// noDelay is honored by net.createConnection but missing from AgentOptions in @types/node
|
|
16
16
|
const AGENT_OPTIONS = {
|
|
17
17
|
noDelay: true,
|
|
18
18
|
keepAlive: true,
|
|
19
|
-
maxSockets:
|
|
19
|
+
maxSockets: 200,
|
|
20
20
|
};
|
|
21
21
|
class TunnelAgent {
|
|
22
22
|
static httpAgent1;
|
|
@@ -41,6 +41,7 @@ class TunnelHttp extends events_1.default {
|
|
|
41
41
|
auth;
|
|
42
42
|
proxyRes;
|
|
43
43
|
proxyReq;
|
|
44
|
+
decrementConcurrent;
|
|
44
45
|
constructor({ req, res, proto, host, port, hostHeader, serve, timeout, httpIdentify, verify, noCache, httpLog, compression, headers, responseHeaders, auth = null, }) {
|
|
45
46
|
super();
|
|
46
47
|
this.id = (0, uuid_1.v4)();
|
|
@@ -402,6 +403,9 @@ class TunnelHttp extends events_1.default {
|
|
|
402
403
|
if (c.concurrent > 0)
|
|
403
404
|
c.concurrent -= 1;
|
|
404
405
|
};
|
|
406
|
+
// Exposed so the timeout / client-disconnect handlers in pipe() can release
|
|
407
|
+
// the http2 stream slot even after clear() has torn down the 'close' listener.
|
|
408
|
+
this.decrementConcurrent = decrementConcurrent;
|
|
405
409
|
let r;
|
|
406
410
|
try {
|
|
407
411
|
r = client.request(headers);
|
|
@@ -471,6 +475,9 @@ class TunnelHttp extends events_1.default {
|
|
|
471
475
|
this.proxyRes.removeAllListeners();
|
|
472
476
|
this.proxyRes = null;
|
|
473
477
|
}
|
|
478
|
+
if (this.decrementConcurrent) {
|
|
479
|
+
this.decrementConcurrent = null;
|
|
480
|
+
}
|
|
474
481
|
if (this.httpLog) {
|
|
475
482
|
this.httpLog = null;
|
|
476
483
|
}
|
|
@@ -577,8 +584,59 @@ class TunnelHttp extends events_1.default {
|
|
|
577
584
|
}
|
|
578
585
|
this.proxyReq.setTimeout(this.timeout * 1000);
|
|
579
586
|
this.proxyReq.on('timeout', () => {
|
|
587
|
+
// Node does NOT abort a request on 'timeout' -> without destroy() the
|
|
588
|
+
// request stays alive holding its socket out of the keepAlive pool
|
|
589
|
+
// (http1, maxSockets:20) or its stream slot (http2). output504() only
|
|
590
|
+
// ends the client-side response and clear() just detaches listeners, so
|
|
591
|
+
// the target-side socket would hang forever -> pool exhaustion + OOM.
|
|
592
|
+
const pr = this.proxyReq;
|
|
593
|
+
const dec = this.decrementConcurrent;
|
|
580
594
|
this.output504();
|
|
595
|
+
if (dec) {
|
|
596
|
+
try {
|
|
597
|
+
dec();
|
|
598
|
+
}
|
|
599
|
+
catch {
|
|
600
|
+
// do nothing
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (pr) {
|
|
604
|
+
try {
|
|
605
|
+
pr.destroy();
|
|
606
|
+
}
|
|
607
|
+
catch {
|
|
608
|
+
// do nothing
|
|
609
|
+
}
|
|
610
|
+
}
|
|
581
611
|
});
|
|
612
|
+
if (this.res) {
|
|
613
|
+
this.res.once('close', () => {
|
|
614
|
+
// Client disconnected before the target responded (e.g. a scraper
|
|
615
|
+
// that gave up). The upstream request is still queued/in-flight and
|
|
616
|
+
// would keep its pooled socket / stream slot forever. Once headers
|
|
617
|
+
// are sent the response is streaming and pipeline teardown handles it.
|
|
618
|
+
if (!this.proxyReq)
|
|
619
|
+
return;
|
|
620
|
+
if (this.res && this.res.headersSent)
|
|
621
|
+
return;
|
|
622
|
+
const pr = this.proxyReq;
|
|
623
|
+
const dec = this.decrementConcurrent;
|
|
624
|
+
if (dec) {
|
|
625
|
+
try {
|
|
626
|
+
dec();
|
|
627
|
+
}
|
|
628
|
+
catch {
|
|
629
|
+
// do nothing
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
try {
|
|
633
|
+
pr.destroy();
|
|
634
|
+
}
|
|
635
|
+
catch {
|
|
636
|
+
// do nothing
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
}
|
|
582
640
|
if (this.logRequest) {
|
|
583
641
|
(0, node_stream_1.pipeline)(this.req, this.logRequest.requestBody, this.proxyReq, (err) => {
|
|
584
642
|
if (err)
|