@e-mc/request 0.10.5 → 0.11.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/LICENSE +1 -1
- package/README.md +16 -12
- package/http/adapter/index.d.ts +5 -0
- package/http/adapter/index.js +554 -0
- package/http/host/index.js +2 -2
- package/index.js +160 -727
- package/package.json +4 -4
- package/util.d.ts +5 -3
- package/util.js +159 -7
package/index.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const crypto = require("crypto");
|
|
6
|
-
const child_process = require("child_process");
|
|
7
|
-
const http = require("http");
|
|
8
|
-
const https = require("https");
|
|
9
|
-
const http2 = require("http2");
|
|
10
|
-
const dns = require("dns");
|
|
11
|
-
const net = require("net");
|
|
12
|
-
const stream = require("stream");
|
|
13
|
-
const zlib = require("zlib");
|
|
2
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const fs = require("node:fs");
|
|
5
|
+
const crypto = require("node:crypto");
|
|
6
|
+
const child_process = require("node:child_process");
|
|
7
|
+
const http = require("node:http");
|
|
8
|
+
const https = require("node:https");
|
|
9
|
+
const http2 = require("node:http2");
|
|
10
|
+
const dns = require("node:dns");
|
|
11
|
+
const net = require("node:net");
|
|
12
|
+
const stream = require("node:stream");
|
|
13
|
+
const zlib = require("node:zlib");
|
|
14
14
|
const qs = require("node:querystring");
|
|
15
15
|
const combined = require("combined-stream");
|
|
16
16
|
const pm = require("picomatch");
|
|
17
|
-
const yaml = require("js-yaml");
|
|
18
17
|
const which = require("which");
|
|
19
18
|
const types_1 = require("@e-mc/types");
|
|
20
19
|
const module_1 = require("@e-mc/module");
|
|
21
20
|
const util_1 = require("@e-mc/request/util");
|
|
22
21
|
const host_1 = require("@e-mc/request/http/host");
|
|
22
|
+
const adapter_1 = require("@e-mc/request/http/adapter");
|
|
23
23
|
const kSession = Symbol('session');
|
|
24
24
|
const kHttpVersion = Symbol('httpVersion');
|
|
25
25
|
const kIpVersion = Symbol('ipVersion');
|
|
@@ -35,6 +35,7 @@ const kPendingDns = Symbol('pendingDns');
|
|
|
35
35
|
const kConnectHttp = Symbol('connectHttp');
|
|
36
36
|
const kStatusOn = Symbol('statusOn');
|
|
37
37
|
const kHeadersOn = Symbol('headersOn');
|
|
38
|
+
const kAdapter = Symbol('adapter');
|
|
38
39
|
const SUPPORTED_NODE20 = (0, types_1.supported)(20);
|
|
39
40
|
const REGEXP_PEMCERT = /^-{3,}[ \t]*BEGIN[ \t].+\n-{3,}[ \t]*END[ \t][^-]+-{3,}$/s;
|
|
40
41
|
const REGEXP_GLOBWITHIN = /\\\?|(?:(?<!\\)(?:\*|\[!?[^!\]]+\]|\{(?:[^,]+,)+[^}]+\}|[!?+*@]\((?:[^|]+\|)*[^)]+\)|\?.*\?|\?$))/;
|
|
@@ -75,14 +76,13 @@ const ARIA2 = {
|
|
|
75
76
|
FILE_ALLOCATION: 'none',
|
|
76
77
|
CONF_PATH: ''
|
|
77
78
|
};
|
|
79
|
+
let HTTP_ADAPTER = adapter_1;
|
|
78
80
|
let KEEP_ALIVE = null;
|
|
79
81
|
let ACCEPT_ENCODING = false;
|
|
80
82
|
let READ_TIMEOUT = 0;
|
|
81
83
|
let AGENT_TIMEOUT = 0;
|
|
82
84
|
let LOG_HTTP = false;
|
|
83
85
|
let LOG_TIMEPROCESS = true;
|
|
84
|
-
let LOG_STDOUT = true;
|
|
85
|
-
let LOG_TIMEFORMAT = 'readable';
|
|
86
86
|
let LIB_ZSTD = null;
|
|
87
87
|
try {
|
|
88
88
|
require('zstd-codec/lib/zstd-stream').run(codec => {
|
|
@@ -92,8 +92,8 @@ try {
|
|
|
92
92
|
catch {
|
|
93
93
|
}
|
|
94
94
|
function getBaseHeaders(uri, headers) {
|
|
95
|
-
uri = (0, util_1.trimPath)(uri);
|
|
96
95
|
let result;
|
|
96
|
+
uri = (0, util_1.trimPath)(uri);
|
|
97
97
|
for (const pathname in headers) {
|
|
98
98
|
if (pathname === uri || uri.startsWith(pathname + '/')) {
|
|
99
99
|
(result ||= []).push([pathname, headers[pathname]]);
|
|
@@ -331,8 +331,8 @@ function decompressEncoding(value, chunkSize) {
|
|
|
331
331
|
break;
|
|
332
332
|
}
|
|
333
333
|
}
|
|
334
|
-
function abortHeaders(href, request, options, statusCode = '') {
|
|
335
|
-
const reason = (0, types_1.errorMessage)(statusCode, "Aborted by client", href);
|
|
334
|
+
function abortHeaders(href, request, options, statusCode = '', message) {
|
|
335
|
+
const reason = (0, types_1.errorMessage)(statusCode, message || "Aborted by client", href);
|
|
336
336
|
const outAbort = options.outAbort;
|
|
337
337
|
if (outAbort) {
|
|
338
338
|
outAbort.abort(reason);
|
|
@@ -346,7 +346,7 @@ function resetAria2() {
|
|
|
346
346
|
}
|
|
347
347
|
function escapeShellQuote(value) {
|
|
348
348
|
value = value.replaceAll('"', '\\"');
|
|
349
|
-
return module_1.PLATFORM_WIN32 ? value : value.replace(/[
|
|
349
|
+
return module_1.PLATFORM_WIN32 ? value : value.replace(/[ $`;]/g, capture => (capture !== ' ' ? '\\' : '') + '\\' + capture);
|
|
350
350
|
}
|
|
351
351
|
function failedDns(err, pending) {
|
|
352
352
|
for (const cb of pending) {
|
|
@@ -375,523 +375,10 @@ function successDns(instance, value, pending, connected) {
|
|
|
375
375
|
}
|
|
376
376
|
pending.length = 0;
|
|
377
377
|
}
|
|
378
|
+
const isFunction = (value) => typeof value === 'function';
|
|
378
379
|
const configureDns = (family, options) => family === 0 ? options : { family, hints: family === 6 ? dns.V4MAPPED : 0 };
|
|
379
380
|
const ignoreOpt = (opts, ...values) => !opts?.some(item => values.includes(item));
|
|
380
381
|
const escapeQuote = (value) => value.replace(/[\\"]/g, capture => '\\' + capture);
|
|
381
|
-
class Fetch {
|
|
382
|
-
static isUnsupported(value) {
|
|
383
|
-
return value === 421 || value === 505;
|
|
384
|
-
}
|
|
385
|
-
static isDowngrade(err) {
|
|
386
|
-
return err instanceof Error && (err.code === 'ERR_HTTP2_ERROR' || this.isUnsupported(Math.abs(err.errno)));
|
|
387
|
-
}
|
|
388
|
-
static wasAborted(err) {
|
|
389
|
-
return err instanceof Error && err.message.startsWith("Aborted");
|
|
390
|
-
}
|
|
391
|
-
static isConnectionTimeout(err) {
|
|
392
|
-
switch (err instanceof Error && err.code) {
|
|
393
|
-
case 'ETIMEDOUT':
|
|
394
|
-
case 'ECONNRESET':
|
|
395
|
-
return true;
|
|
396
|
-
default:
|
|
397
|
-
return false;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
constructor(instance, uri, opts) {
|
|
401
|
-
this.instance = instance;
|
|
402
|
-
this.opts = opts;
|
|
403
|
-
this.retries = 0;
|
|
404
|
-
this.redirects = 0;
|
|
405
|
-
this.closed = false;
|
|
406
|
-
this.aborted = false;
|
|
407
|
-
this.timeout = null;
|
|
408
|
-
this.outStream = null;
|
|
409
|
-
this.status = opts.silent === false || !opts.silent && !instance[kSingleton];
|
|
410
|
-
this.log = this.status && LOG_HTTP && LOG_TIMEPROCESS;
|
|
411
|
-
this.startTime = this.log ? process.hrtime() : 0;
|
|
412
|
-
this.setConfig(uri);
|
|
413
|
-
}
|
|
414
|
-
async start() {
|
|
415
|
-
return new Promise((resolve, reject) => {
|
|
416
|
-
this.resolve = resolve;
|
|
417
|
-
this.reject = reject;
|
|
418
|
-
this.init();
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
init() {
|
|
422
|
-
this.aborted = false;
|
|
423
|
-
this.setWriteStream();
|
|
424
|
-
const config = this.config;
|
|
425
|
-
const client = this.instance.open(this.uri, config);
|
|
426
|
-
this.client = client;
|
|
427
|
-
if (config.httpVersion === 2) {
|
|
428
|
-
client
|
|
429
|
-
.on('response', (headers, flags) => {
|
|
430
|
-
if (this.destroyed) {
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
const statusCode = headers[':status'];
|
|
434
|
-
if (statusCode < 300) {
|
|
435
|
-
this.acceptResponse(headers);
|
|
436
|
-
}
|
|
437
|
-
else if (statusCode < 400) {
|
|
438
|
-
this.redirectResponse(statusCode, headers.location);
|
|
439
|
-
}
|
|
440
|
-
else if (statusCode === 401 ||
|
|
441
|
-
statusCode === 402 ||
|
|
442
|
-
statusCode === 403 ||
|
|
443
|
-
statusCode === 404 ||
|
|
444
|
-
statusCode === 407 ||
|
|
445
|
-
statusCode === 410) {
|
|
446
|
-
this.terminate(this.formatStatus(statusCode));
|
|
447
|
-
}
|
|
448
|
-
else if (this.isRetry(statusCode)) {
|
|
449
|
-
this.retryResponse(statusCode, headers['retry-after']);
|
|
450
|
-
}
|
|
451
|
-
else if (Fetch.isUnsupported(statusCode)) {
|
|
452
|
-
this.retryDownload(true, this.formatNgFlags(http2.constants.NGHTTP2_PROTOCOL_ERROR, statusCode));
|
|
453
|
-
}
|
|
454
|
-
else {
|
|
455
|
-
switch (flags) {
|
|
456
|
-
case http2.constants.NGHTTP2_PROTOCOL_ERROR:
|
|
457
|
-
case http2.constants.NGHTTP2_INADEQUATE_SECURITY:
|
|
458
|
-
case http2.constants.NGHTTP2_HTTP_1_1_REQUIRED:
|
|
459
|
-
this.retryDownload(true, this.formatNgFlags(flags, statusCode, headers.location));
|
|
460
|
-
break;
|
|
461
|
-
default:
|
|
462
|
-
this.retryDownload(false, this.formatStatus(statusCode));
|
|
463
|
-
break;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
})
|
|
467
|
-
.on('unknownProtocol', () => {
|
|
468
|
-
if (!this.aborted) {
|
|
469
|
-
this.retryDownload(true, 'Unknown protocol (HTTP/2)');
|
|
470
|
-
}
|
|
471
|
-
})
|
|
472
|
-
.on('aborted', () => {
|
|
473
|
-
this.aborted = true;
|
|
474
|
-
this.terminate((0, types_1.createAbortError)());
|
|
475
|
-
})
|
|
476
|
-
.on('error', async (err) => {
|
|
477
|
-
if (this.aborted) {
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
if (Fetch.wasAborted(err)) {
|
|
481
|
-
this.errorResponse(err);
|
|
482
|
-
}
|
|
483
|
-
else {
|
|
484
|
-
switch (!Fetch.isDowngrade(err) && await config.host.hasProtocol(2)) {
|
|
485
|
-
case 1:
|
|
486
|
-
this.errorResponse(err);
|
|
487
|
-
break;
|
|
488
|
-
case 2:
|
|
489
|
-
this.retryDownload(false, err);
|
|
490
|
-
break;
|
|
491
|
-
default:
|
|
492
|
-
this.retryDownload(true, err);
|
|
493
|
-
break;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
else {
|
|
499
|
-
client
|
|
500
|
-
.on('response', res => {
|
|
501
|
-
if (this.destroyed) {
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
const statusCode = res.statusCode;
|
|
505
|
-
if (statusCode < 300) {
|
|
506
|
-
this.acceptResponse(res.headers);
|
|
507
|
-
}
|
|
508
|
-
else if (statusCode < 400) {
|
|
509
|
-
this.redirectResponse(statusCode, res.headers.location);
|
|
510
|
-
}
|
|
511
|
-
else if (this.isRetry(statusCode)) {
|
|
512
|
-
this.retryResponse(statusCode, res.headers['retry-after']);
|
|
513
|
-
}
|
|
514
|
-
else {
|
|
515
|
-
this.terminate(this.formatStatus(statusCode));
|
|
516
|
-
}
|
|
517
|
-
})
|
|
518
|
-
.on('abort', () => {
|
|
519
|
-
this.aborted = true;
|
|
520
|
-
this.terminate((0, types_1.createAbortError)());
|
|
521
|
-
})
|
|
522
|
-
.on('error', err => {
|
|
523
|
-
if (!this.aborted) {
|
|
524
|
-
this.errorResponse(err);
|
|
525
|
-
}
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
client.on('timeout', () => {
|
|
529
|
-
if (this.aborted) {
|
|
530
|
-
return;
|
|
531
|
-
}
|
|
532
|
-
if (++this.retries <= this.retryLimit) {
|
|
533
|
-
this.abortResponse();
|
|
534
|
-
this.retryTimeout();
|
|
535
|
-
}
|
|
536
|
-
else {
|
|
537
|
-
this.terminate(this.formatStatus(408));
|
|
538
|
-
}
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
setConfig(uri) {
|
|
542
|
-
this.uri = uri;
|
|
543
|
-
this.config = this.instance.opts(uri, this.opts);
|
|
544
|
-
}
|
|
545
|
-
setWriteStream() {
|
|
546
|
-
const pipeTo = this.pipeTo;
|
|
547
|
-
if (typeof pipeTo === 'string') {
|
|
548
|
-
try {
|
|
549
|
-
this.outStream = fs.createWriteStream(pipeTo, { emitClose: false, highWaterMark: this.config.host.streamSize });
|
|
550
|
-
this.config.outStream = this.outStream;
|
|
551
|
-
}
|
|
552
|
-
catch (err) {
|
|
553
|
-
this.terminate(err);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
else {
|
|
557
|
-
this.config.outStream = pipeTo;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
abortResponse() {
|
|
561
|
-
if (this.closed) {
|
|
562
|
-
return;
|
|
563
|
-
}
|
|
564
|
-
if (this.timeout) {
|
|
565
|
-
clearTimeout(this.timeout);
|
|
566
|
-
}
|
|
567
|
-
this.aborted = true;
|
|
568
|
-
this.client.destroy();
|
|
569
|
-
this.cleanup();
|
|
570
|
-
}
|
|
571
|
-
retryDownload(downgrade, message) {
|
|
572
|
-
if (this.aborted) {
|
|
573
|
-
return;
|
|
574
|
-
}
|
|
575
|
-
this.abortResponse();
|
|
576
|
-
if (downgrade) {
|
|
577
|
-
const host = this.config.host;
|
|
578
|
-
host.failed(2);
|
|
579
|
-
if (host.version > 1) {
|
|
580
|
-
if (this.status) {
|
|
581
|
-
this.instance.formatMessage(1024, 'HTTP2', ["Unsupported protocol", host.origin], message, { failed: true });
|
|
582
|
-
}
|
|
583
|
-
host.version = 1;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
this.opts.httpVersion = 1;
|
|
587
|
-
this.init();
|
|
588
|
-
}
|
|
589
|
-
acceptResponse(headers) {
|
|
590
|
-
const { instance, config, client, opts, pipeTo } = this;
|
|
591
|
-
const parent = this.instance.host;
|
|
592
|
-
const progressId = config.progressId;
|
|
593
|
-
if ('outHeaders' in opts) {
|
|
594
|
-
opts.outHeaders = headers;
|
|
595
|
-
}
|
|
596
|
-
if ('outFilename' in opts) {
|
|
597
|
-
opts.outFilename = (0, util_1.parseHeader)(headers, 'content-disposition');
|
|
598
|
-
}
|
|
599
|
-
const pipeline = pipeTo ? !(0, types_1.isString)(pipeTo) : false;
|
|
600
|
-
const enabled = config.connected?.call(client, headers) !== false && !pipeline;
|
|
601
|
-
const maxBufferSize = config.maxBufferSize ? (0, types_1.alignSize)(config.maxBufferSize) : 0;
|
|
602
|
-
const contentLength = parent && progressId !== undefined ? parseInt(headers['content-length'] || '0') : 0;
|
|
603
|
-
let log = this.log, buffer = null, dataLength = 0, mibsTime, delayTime;
|
|
604
|
-
if (log || contentLength > 0 || instance.readTimeout > 0) {
|
|
605
|
-
client.once('readable', () => {
|
|
606
|
-
if (instance.readTimeout > 0) {
|
|
607
|
-
this.timeout = setTimeout(() => {
|
|
608
|
-
this.terminate((0, types_1.errorValue)("Timeout was exceeded", this.uri.toString()));
|
|
609
|
-
}, instance.readTimeout);
|
|
610
|
-
}
|
|
611
|
-
if (log) {
|
|
612
|
-
switch (instance.settings?.time_format || LOG_TIMEFORMAT) {
|
|
613
|
-
case 'readable':
|
|
614
|
-
delayTime = process.hrtime(this.startTime);
|
|
615
|
-
break;
|
|
616
|
-
case 'relative':
|
|
617
|
-
delayTime = Date.now() - instance.startTime;
|
|
618
|
-
break;
|
|
619
|
-
case 'none':
|
|
620
|
-
if (opts.silent !== false) {
|
|
621
|
-
log = false;
|
|
622
|
-
}
|
|
623
|
-
break;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
mibsTime = process.hrtime();
|
|
627
|
-
if (contentLength > 0) {
|
|
628
|
-
parent.updateProgress("request", progressId, 0, 0, mibsTime);
|
|
629
|
-
}
|
|
630
|
-
});
|
|
631
|
-
}
|
|
632
|
-
if (enabled) {
|
|
633
|
-
const encoding = opts.encoding;
|
|
634
|
-
client.on('data', (chunk) => {
|
|
635
|
-
if (buffer) {
|
|
636
|
-
if (typeof buffer === 'string') {
|
|
637
|
-
buffer += typeof chunk === 'string' ? chunk : chunk.toString(encoding);
|
|
638
|
-
}
|
|
639
|
-
else if (Array.isArray(buffer)) {
|
|
640
|
-
buffer.push(typeof chunk === 'string' ? Buffer.from(chunk, encoding) : chunk);
|
|
641
|
-
}
|
|
642
|
-
else {
|
|
643
|
-
buffer = Buffer.concat([buffer, typeof chunk === 'string' ? Buffer.from(chunk, encoding) : chunk]);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
else {
|
|
647
|
-
buffer = typeof chunk === 'string' ? chunk : [chunk];
|
|
648
|
-
}
|
|
649
|
-
if (contentLength > 0) {
|
|
650
|
-
dataLength += Buffer.byteLength(chunk, encoding);
|
|
651
|
-
parent.updateProgress("request", progressId, dataLength, contentLength);
|
|
652
|
-
}
|
|
653
|
-
if (maxBufferSize > 0) {
|
|
654
|
-
if (contentLength === 0) {
|
|
655
|
-
dataLength += Buffer.byteLength(chunk, encoding);
|
|
656
|
-
}
|
|
657
|
-
if (dataLength > maxBufferSize) {
|
|
658
|
-
this.terminate((0, types_1.errorValue)("Size limit was exceeded", this.uri.toString()));
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
|
-
client.once('end', () => {
|
|
664
|
-
if (this.closed || this.aborted) {
|
|
665
|
-
return;
|
|
666
|
-
}
|
|
667
|
-
this.close();
|
|
668
|
-
const encoding = opts.encoding;
|
|
669
|
-
let result, messageUnit, titleBgColor;
|
|
670
|
-
if (buffer) {
|
|
671
|
-
if (Array.isArray(buffer)) {
|
|
672
|
-
buffer = Buffer.concat(buffer);
|
|
673
|
-
if (encoding) {
|
|
674
|
-
buffer = buffer.toString(encoding);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
dataLength = Buffer.byteLength(buffer, encoding);
|
|
678
|
-
if (mibsTime) {
|
|
679
|
-
messageUnit = (0, util_1.getTransferRate)(dataLength, (0, types_1.convertTime)(process.hrtime(mibsTime), false) * 1000);
|
|
680
|
-
}
|
|
681
|
-
if (contentLength > 0) {
|
|
682
|
-
parent.updateProgress("request", progressId, dataLength, dataLength);
|
|
683
|
-
}
|
|
684
|
-
if (typeof buffer === 'string') {
|
|
685
|
-
if (buffer.startsWith('\uFEFF') && encoding !== 'utf16le' && encoding !== 'utf-16le') {
|
|
686
|
-
buffer = buffer.substring(1);
|
|
687
|
-
}
|
|
688
|
-
if (config.outFormat) {
|
|
689
|
-
const { out: format, parser } = config.outFormat;
|
|
690
|
-
let packageName;
|
|
691
|
-
try {
|
|
692
|
-
switch (format) {
|
|
693
|
-
case 'yaml':
|
|
694
|
-
result = yaml.load(buffer, parser);
|
|
695
|
-
break;
|
|
696
|
-
case 'json5':
|
|
697
|
-
result = require(packageName = 'json5').parse(buffer);
|
|
698
|
-
break;
|
|
699
|
-
case 'xml':
|
|
700
|
-
result = new (require(packageName = 'fast-xml-parser').XMLParser)(parser).parse(buffer);
|
|
701
|
-
break;
|
|
702
|
-
case 'toml':
|
|
703
|
-
result = require(packageName = 'toml').parse(buffer);
|
|
704
|
-
break;
|
|
705
|
-
default:
|
|
706
|
-
result = JSON.parse(buffer);
|
|
707
|
-
break;
|
|
708
|
-
}
|
|
709
|
-
if (!(0, types_1.isObject)(result)) {
|
|
710
|
-
result = null;
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
catch (err) {
|
|
714
|
-
if (this.status && !(packageName && instance.checkPackage(err, packageName))) {
|
|
715
|
-
instance.writeFail(["Unable to parse URI response", format], err, 1024);
|
|
716
|
-
}
|
|
717
|
-
result = null;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
if (result === undefined) {
|
|
722
|
-
result = buffer;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
else {
|
|
726
|
-
if (contentLength > 0) {
|
|
727
|
-
parent.updateProgress("request", progressId, 0, contentLength);
|
|
728
|
-
}
|
|
729
|
-
if (enabled && instance.readExpect === 'always') {
|
|
730
|
-
this.terminate("No data received");
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
result = encoding && !pipeline ? '' : null;
|
|
734
|
-
titleBgColor = 'bgBlue';
|
|
735
|
-
}
|
|
736
|
-
if (log) {
|
|
737
|
-
instance.writeTimeProcess('HTTP' + config.httpVersion, config.statusMessage || this.uri.toString(), this.startTime, { type: 1024, queue: !!parent, titleBgColor, messageUnit, messageUnitMinWidth: 9, delayTime, bypassLog: LOG_STDOUT });
|
|
738
|
-
}
|
|
739
|
-
this.resolve(result);
|
|
740
|
-
});
|
|
741
|
-
config.host.success(this.httpVersion);
|
|
742
|
-
}
|
|
743
|
-
redirectResponse(statusCode, location) {
|
|
744
|
-
if (location) {
|
|
745
|
-
if (this.config.follow_redirect === false || this.config.followRedirect === false) {
|
|
746
|
-
this.terminate(this.formatStatus(statusCode, "Follow redirect was disabled"));
|
|
747
|
-
}
|
|
748
|
-
else if (++this.redirects <= this.redirectLimit) {
|
|
749
|
-
this.abortResponse();
|
|
750
|
-
this.setConfig(Request.fromURL(this.config.url, location));
|
|
751
|
-
this.init();
|
|
752
|
-
}
|
|
753
|
-
else {
|
|
754
|
-
this.terminate(this.formatStatus(statusCode, "Exceeded redirect limit"));
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
else {
|
|
758
|
-
this.terminate(this.formatStatus(statusCode, "Missing redirect location"));
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
errorResponse(err) {
|
|
762
|
-
if (Fetch.wasAborted(err)) {
|
|
763
|
-
this.terminate(err);
|
|
764
|
-
}
|
|
765
|
-
else if ((0, util_1.checkRetryable)(err) && ++this.retries <= this.retryLimit) {
|
|
766
|
-
this.abortResponse();
|
|
767
|
-
if (Fetch.isConnectionTimeout(err)) {
|
|
768
|
-
this.retryTimeout();
|
|
769
|
-
}
|
|
770
|
-
else {
|
|
771
|
-
setTimeout(() => {
|
|
772
|
-
this.init();
|
|
773
|
-
}, this.retryWait);
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
else {
|
|
777
|
-
this.config.host.error(this.httpVersion);
|
|
778
|
-
this.terminate(err);
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
retryResponse(statusCode, retryAfter) {
|
|
782
|
-
this.abortResponse();
|
|
783
|
-
if (retryAfter && this.retryAfter > 0) {
|
|
784
|
-
let offset = +retryAfter || new Date(retryAfter);
|
|
785
|
-
if (offset instanceof Date) {
|
|
786
|
-
offset = Math.max(0, offset.getTime() - Date.now());
|
|
787
|
-
}
|
|
788
|
-
else {
|
|
789
|
-
offset *= 1000;
|
|
790
|
-
}
|
|
791
|
-
if (offset > 0) {
|
|
792
|
-
if (offset <= this.retryAfter) {
|
|
793
|
-
this.sendWarning(`Retry After (${retryAfter})`);
|
|
794
|
-
setTimeout(() => {
|
|
795
|
-
this.init();
|
|
796
|
-
}, offset);
|
|
797
|
-
}
|
|
798
|
-
else {
|
|
799
|
-
this.terminate(this.formatStatus(statusCode));
|
|
800
|
-
}
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
this.sendWarning(this.formatRetry(Request.fromStatusCode(statusCode)));
|
|
805
|
-
if ((0, util_1.isRetryable)(statusCode, true)) {
|
|
806
|
-
process.nextTick(this.init.bind(this));
|
|
807
|
-
}
|
|
808
|
-
else {
|
|
809
|
-
setTimeout(() => {
|
|
810
|
-
this.init();
|
|
811
|
-
}, this.retryWait);
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
isRetry(value) {
|
|
815
|
-
return (0, util_1.isRetryable)(value) && ++this.retries <= this.retryLimit;
|
|
816
|
-
}
|
|
817
|
-
retryTimeout() {
|
|
818
|
-
this.sendWarning(this.formatRetry("HTTP connection timeout"));
|
|
819
|
-
this.init();
|
|
820
|
-
}
|
|
821
|
-
terminate(err) {
|
|
822
|
-
if (this.timeout) {
|
|
823
|
-
clearTimeout(this.timeout);
|
|
824
|
-
}
|
|
825
|
-
if (!this.closed) {
|
|
826
|
-
this.cleanup();
|
|
827
|
-
this.close();
|
|
828
|
-
this.reject(typeof err === 'string' ? new Error(err) : err);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
sendWarning(message) {
|
|
832
|
-
if (this.status) {
|
|
833
|
-
const { host, url } = this.config;
|
|
834
|
-
this.instance.formatMessage(1024, 'HTTP' + this.httpVersion, [message, host.origin], url.toString(), { ...module_1.LOG_STYLE_WARN });
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
formatStatus(value, hint) {
|
|
838
|
-
return value + ': ' + (hint || Request.fromStatusCode(value)) + ` (${this.uri.toString()})`;
|
|
839
|
-
}
|
|
840
|
-
formatNgFlags(value, statusCode, location) {
|
|
841
|
-
return location ? `Using HTTP 1.1 for URL redirect (${location})` : this.formatStatus(statusCode, value ? 'NGHTTP2 Error ' + value : '');
|
|
842
|
-
}
|
|
843
|
-
formatRetry(message) {
|
|
844
|
-
return message + ` (${this.retries} / ${this.retryLimit})`;
|
|
845
|
-
}
|
|
846
|
-
close() {
|
|
847
|
-
if (this.timeout) {
|
|
848
|
-
clearTimeout(this.timeout);
|
|
849
|
-
}
|
|
850
|
-
this.closed = true;
|
|
851
|
-
if (this.aborted && !this.client.aborted && !this.client.destroyed) {
|
|
852
|
-
this.opts.outAbort?.abort();
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
cleanup() {
|
|
856
|
-
const outAbort = this.opts.outAbort;
|
|
857
|
-
if (outAbort) {
|
|
858
|
-
this.downloading.delete(outAbort);
|
|
859
|
-
}
|
|
860
|
-
if ((0, types_1.isString)(this.pipeTo) && this.outStream) {
|
|
861
|
-
(0, util_1.cleanupStream)(this.outStream, this.pipeTo);
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
get destroyed() {
|
|
865
|
-
return this.client.destroyed || this.httpVersion === 2 && this.client.aborted;
|
|
866
|
-
}
|
|
867
|
-
get downloading() {
|
|
868
|
-
return this.instance[kDownloading];
|
|
869
|
-
}
|
|
870
|
-
get httpVersion() {
|
|
871
|
-
return this.config.httpVersion;
|
|
872
|
-
}
|
|
873
|
-
get outAbort() {
|
|
874
|
-
return this.config.outAbort;
|
|
875
|
-
}
|
|
876
|
-
get pipeTo() {
|
|
877
|
-
return this.opts.pipeTo;
|
|
878
|
-
}
|
|
879
|
-
get retryLimit() {
|
|
880
|
-
return this.settings.retryLimit;
|
|
881
|
-
}
|
|
882
|
-
get retryWait() {
|
|
883
|
-
return this.settings.retryWait;
|
|
884
|
-
}
|
|
885
|
-
get retryAfter() {
|
|
886
|
-
return this.settings.retryAfter;
|
|
887
|
-
}
|
|
888
|
-
get redirectLimit() {
|
|
889
|
-
return this.settings.redirectLimit;
|
|
890
|
-
}
|
|
891
|
-
get settings() {
|
|
892
|
-
return this.instance['_config'];
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
382
|
class Request extends module_1 {
|
|
896
383
|
static async purgeMemory(percent = 1, limit = 0, parent) {
|
|
897
384
|
if (percent >= 1) {
|
|
@@ -985,9 +472,8 @@ class Request extends module_1 {
|
|
|
985
472
|
READ_TIMEOUT = read_timeout;
|
|
986
473
|
}
|
|
987
474
|
if ((0, types_1.isObject)(agent)) {
|
|
988
|
-
let keep_alive;
|
|
989
|
-
(
|
|
990
|
-
if ((agent_timeout = (0, util_1.fromSeconds)(agent_timeout)) > 0) {
|
|
475
|
+
let { keep_alive, timeout } = agent;
|
|
476
|
+
if ((agent_timeout = (0, util_1.fromSeconds)(timeout)) > 0) {
|
|
991
477
|
AGENT_TIMEOUT = agent_timeout;
|
|
992
478
|
}
|
|
993
479
|
else {
|
|
@@ -1020,19 +506,13 @@ class Request extends module_1 {
|
|
|
1020
506
|
[TLS.TEXT, TLS.FILE] = validateCerts(certs);
|
|
1021
507
|
}
|
|
1022
508
|
HTTP.PROXY = getProxySettings(request, agent_timeout);
|
|
1023
|
-
const time_format = request.settings?.time_format;
|
|
1024
|
-
switch (time_format) {
|
|
1025
|
-
case 'readable':
|
|
1026
|
-
case 'relative':
|
|
1027
|
-
case 'none':
|
|
1028
|
-
LOG_TIMEFORMAT = time_format;
|
|
1029
|
-
break;
|
|
1030
|
-
}
|
|
1031
509
|
host_1.defineHostConfig(request);
|
|
510
|
+
if ('defineHostConfig' in HTTP_ADAPTER) {
|
|
511
|
+
HTTP_ADAPTER.defineHostConfig(request);
|
|
512
|
+
}
|
|
1032
513
|
}
|
|
1033
514
|
LOG_HTTP = this.hasLogType(1024);
|
|
1034
515
|
LOG_TIMEPROCESS = this.hasLogType(256);
|
|
1035
|
-
LOG_STDOUT = module_1.hasLogType(32768);
|
|
1036
516
|
return true;
|
|
1037
517
|
}
|
|
1038
518
|
static readCACert(value, cache) {
|
|
@@ -1048,153 +528,10 @@ class Request extends module_1 {
|
|
|
1048
528
|
return typeof value === 'string' && (value = value.trim()).length > 0 && REGEXP_PEMCERT.test(value);
|
|
1049
529
|
}
|
|
1050
530
|
static fromURL(url, value) {
|
|
1051
|
-
|
|
1052
|
-
return value;
|
|
1053
|
-
}
|
|
1054
|
-
const auth = host_1.formatBasicAuth(url);
|
|
1055
|
-
return url.protocol + '//' + (auth && (auth + '@')) + url.hostname + (url.port ? ':' + url.port : '') + (value.startsWith('/') ? '' : '/') + value;
|
|
531
|
+
return (0, util_1.fromURL)(url, value);
|
|
1056
532
|
}
|
|
1057
533
|
static fromStatusCode(value) {
|
|
1058
|
-
|
|
1059
|
-
if (value < 200) {
|
|
1060
|
-
switch (value) {
|
|
1061
|
-
case 100:
|
|
1062
|
-
return 'Continue';
|
|
1063
|
-
case 101:
|
|
1064
|
-
return 'Switching Protocol';
|
|
1065
|
-
case 102:
|
|
1066
|
-
return 'Processing';
|
|
1067
|
-
case 103:
|
|
1068
|
-
return 'Early Hints';
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
else if (value < 300) {
|
|
1072
|
-
switch (value) {
|
|
1073
|
-
case 200:
|
|
1074
|
-
return 'OK';
|
|
1075
|
-
case 201:
|
|
1076
|
-
return 'Created';
|
|
1077
|
-
case 202:
|
|
1078
|
-
return 'Accepted';
|
|
1079
|
-
case 203:
|
|
1080
|
-
return 'Non-Authoritative Information';
|
|
1081
|
-
case 204:
|
|
1082
|
-
return 'No Content';
|
|
1083
|
-
case 205:
|
|
1084
|
-
return 'Reset Content';
|
|
1085
|
-
case 206:
|
|
1086
|
-
return 'Partial Content';
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
else if (value < 400) {
|
|
1090
|
-
switch (value) {
|
|
1091
|
-
case 300:
|
|
1092
|
-
return 'Multiple Choice';
|
|
1093
|
-
case 301:
|
|
1094
|
-
return 'Moved Permanently';
|
|
1095
|
-
case 302:
|
|
1096
|
-
return 'Found';
|
|
1097
|
-
case 303:
|
|
1098
|
-
return 'See Other';
|
|
1099
|
-
case 304:
|
|
1100
|
-
return 'Not Modified';
|
|
1101
|
-
case 305:
|
|
1102
|
-
return 'Use Proxy';
|
|
1103
|
-
case 307:
|
|
1104
|
-
return 'Temporary Redirect';
|
|
1105
|
-
case 308:
|
|
1106
|
-
return 'Permanent Redirect';
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
else if (value < 500) {
|
|
1110
|
-
switch (value) {
|
|
1111
|
-
case 400:
|
|
1112
|
-
return 'Bad Request';
|
|
1113
|
-
case 401:
|
|
1114
|
-
return 'Upgrade Required';
|
|
1115
|
-
case 402:
|
|
1116
|
-
return 'Payment Required';
|
|
1117
|
-
case 403:
|
|
1118
|
-
return 'Forbidden';
|
|
1119
|
-
case 404:
|
|
1120
|
-
return 'Not Found';
|
|
1121
|
-
case 405:
|
|
1122
|
-
return 'Method Not Allowed';
|
|
1123
|
-
case 406:
|
|
1124
|
-
return 'Not Acceptable';
|
|
1125
|
-
case 407:
|
|
1126
|
-
return 'Proxy Authentication Required';
|
|
1127
|
-
case 408:
|
|
1128
|
-
return 'Request Timeout';
|
|
1129
|
-
case 409:
|
|
1130
|
-
return 'Conflict';
|
|
1131
|
-
case 410:
|
|
1132
|
-
return 'Gone';
|
|
1133
|
-
case 411:
|
|
1134
|
-
return 'Length Required';
|
|
1135
|
-
case 412:
|
|
1136
|
-
return 'Precondition Failed';
|
|
1137
|
-
case 413:
|
|
1138
|
-
return 'Payload Too Large';
|
|
1139
|
-
case 414:
|
|
1140
|
-
return 'URI Too Long';
|
|
1141
|
-
case 415:
|
|
1142
|
-
return 'Unsupported Media Type';
|
|
1143
|
-
case 416:
|
|
1144
|
-
return 'Range Not Satisfiable';
|
|
1145
|
-
case 417:
|
|
1146
|
-
return 'Expectation Failed';
|
|
1147
|
-
case 421:
|
|
1148
|
-
return 'Misdirected Request';
|
|
1149
|
-
case 422:
|
|
1150
|
-
return 'Unprocessable Entity';
|
|
1151
|
-
case 423:
|
|
1152
|
-
return 'Locked';
|
|
1153
|
-
case 424:
|
|
1154
|
-
return 'Failed Dependency';
|
|
1155
|
-
case 425:
|
|
1156
|
-
return 'Too Early';
|
|
1157
|
-
case 426:
|
|
1158
|
-
return 'Upgrade Required';
|
|
1159
|
-
case 428:
|
|
1160
|
-
return 'Precondition Required';
|
|
1161
|
-
case 429:
|
|
1162
|
-
return 'Too Many Requests';
|
|
1163
|
-
case 431:
|
|
1164
|
-
return 'Request Header Fields Too Large';
|
|
1165
|
-
case 451:
|
|
1166
|
-
return 'Unavailable For Legal Reasons';
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
else {
|
|
1170
|
-
switch (value) {
|
|
1171
|
-
case 500:
|
|
1172
|
-
return 'Internal Server Error';
|
|
1173
|
-
case 501:
|
|
1174
|
-
return 'Not Implemented';
|
|
1175
|
-
case 502:
|
|
1176
|
-
return 'Bad Gateway';
|
|
1177
|
-
case 503:
|
|
1178
|
-
return 'Service Unavailable';
|
|
1179
|
-
case 504:
|
|
1180
|
-
return 'Gateway Timeout';
|
|
1181
|
-
case 505:
|
|
1182
|
-
return 'HTTP Version Not Supported';
|
|
1183
|
-
case 506:
|
|
1184
|
-
return 'Variant Also Negotiates';
|
|
1185
|
-
case 507:
|
|
1186
|
-
return 'Insufficient Storage';
|
|
1187
|
-
case 508:
|
|
1188
|
-
return 'Loop Detected';
|
|
1189
|
-
case 509:
|
|
1190
|
-
return 'Bandwidth Limit Exceeded';
|
|
1191
|
-
case 510:
|
|
1192
|
-
return 'Not Extended';
|
|
1193
|
-
case 511:
|
|
1194
|
-
return 'Network Authentication Required';
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
return "Unknown";
|
|
534
|
+
return (0, util_1.fromStatusCode)(value);
|
|
1198
535
|
}
|
|
1199
536
|
static defineHttpAgent(options) {
|
|
1200
537
|
const { keepAlive, timeout = 0 } = options;
|
|
@@ -1243,6 +580,11 @@ class Request extends module_1 {
|
|
|
1243
580
|
}
|
|
1244
581
|
}
|
|
1245
582
|
}
|
|
583
|
+
static defineHttpAdapter(module) {
|
|
584
|
+
if (isFunction(module) && module.prototype instanceof adapter_1) {
|
|
585
|
+
HTTP_ADAPTER = module;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
1246
588
|
static getAria2Path() {
|
|
1247
589
|
return ARIA2.BIN;
|
|
1248
590
|
}
|
|
@@ -1271,9 +613,10 @@ class Request extends module_1 {
|
|
|
1271
613
|
this[_h] = [{}, {}];
|
|
1272
614
|
this[_j] = null;
|
|
1273
615
|
this[_k] = null;
|
|
1274
|
-
this[_l] =
|
|
1275
|
-
this[_m] =
|
|
1276
|
-
this[_o] =
|
|
616
|
+
this[_l] = HTTP_ADAPTER;
|
|
617
|
+
this[_m] = new Set();
|
|
618
|
+
this[_o] = {};
|
|
619
|
+
this[_p] = [Object.create(null)];
|
|
1277
620
|
if ((0, types_1.isPlainObject)(data)) {
|
|
1278
621
|
const { headers, read_timeout, agent, use, connect, certs } = data;
|
|
1279
622
|
const timeout = (0, util_1.fromSeconds)(data.timeout);
|
|
@@ -1355,7 +698,7 @@ class Request extends module_1 {
|
|
|
1355
698
|
count = Math.max(count, value);
|
|
1356
699
|
}
|
|
1357
700
|
});
|
|
1358
|
-
if (
|
|
701
|
+
if (module_1.hasLogType(32768)) {
|
|
1359
702
|
output.sort((a, b) => {
|
|
1360
703
|
if (a[2] === b[2]) {
|
|
1361
704
|
return a[1] < b[1] ? -1 : 1;
|
|
@@ -1556,7 +899,24 @@ class Request extends module_1 {
|
|
|
1556
899
|
if (!include && !exclude && !localhost) {
|
|
1557
900
|
return proxy;
|
|
1558
901
|
}
|
|
1559
|
-
if (
|
|
902
|
+
if (exclude) {
|
|
903
|
+
let valid = true;
|
|
904
|
+
for (const value of exclude) {
|
|
905
|
+
if (value.startsWith('!')) {
|
|
906
|
+
if (REGEXP_GLOBWITHIN.test(value.substring(1))) {
|
|
907
|
+
valid = true;
|
|
908
|
+
break;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
else if (valid && (REGEXP_GLOBWITHIN.test(value) ? pm.isMatch(uri, value) : uri.startsWith(value))) {
|
|
912
|
+
valid = false;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
if (!valid) {
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if ((0, types_1.isArray)(include) && !include.some(value => REGEXP_GLOBWITHIN.test(value) ? pm.isMatch(uri, value) : uri.startsWith(value))) {
|
|
1560
920
|
return;
|
|
1561
921
|
}
|
|
1562
922
|
return proxy;
|
|
@@ -1848,7 +1208,7 @@ class Request extends module_1 {
|
|
|
1848
1208
|
opts.push(`"${escapeShellQuote(uri)}"`);
|
|
1849
1209
|
args = args.concat(init, opts);
|
|
1850
1210
|
const startTime = Date.now();
|
|
1851
|
-
let out = '', message = '', aborted;
|
|
1211
|
+
let out = '', message = '', aborted = false;
|
|
1852
1212
|
const errorResponse = (pid, err) => {
|
|
1853
1213
|
aborted = true;
|
|
1854
1214
|
closeTorrent(pid);
|
|
@@ -1983,7 +1343,7 @@ class Request extends module_1 {
|
|
|
1983
1343
|
return { ...options, host, url };
|
|
1984
1344
|
}
|
|
1985
1345
|
open(uri, options) {
|
|
1986
|
-
let { host, url, httpVersion, method = 'GET', search, encoding, format, headers: outgoing,
|
|
1346
|
+
let { host, url, httpVersion, method = 'GET', search, encoding, format, headers: outgoing, socketPath, expectContinue = false, timeout = this._config.connectTimeout, outStream } = options, headers = (0, util_1.parseOutgoingHeaders)(outgoing), getting = false, posting = false;
|
|
1987
1347
|
switch (method = method.toUpperCase()) {
|
|
1988
1348
|
case 'GET':
|
|
1989
1349
|
case 'DELETE':
|
|
@@ -2066,10 +1426,29 @@ class Request extends module_1 {
|
|
|
2066
1426
|
const pathname = url.pathname + (socketPath ? '' : url.search);
|
|
2067
1427
|
const proxy = this.proxyOf(uri, host.localhost);
|
|
2068
1428
|
const version = this.httpVersion;
|
|
2069
|
-
|
|
1429
|
+
const baseHeaders = this.headersOf(uri);
|
|
1430
|
+
let request, ca, cert, key, ciphers, minVersion;
|
|
2070
1431
|
if (getting && this.acceptEncoding && !host.localhost && !baseHeaders?.['accept-encoding']) {
|
|
2071
1432
|
(headers ||= {})['accept-encoding'] ||= 'gzip, deflate, br' + (LIB_ZSTD ? ', zstd' : '');
|
|
2072
1433
|
}
|
|
1434
|
+
if (posting && options.postData) {
|
|
1435
|
+
if (expectContinue) {
|
|
1436
|
+
(headers ||= {}).expect = '100-continue';
|
|
1437
|
+
}
|
|
1438
|
+
else {
|
|
1439
|
+
let expect;
|
|
1440
|
+
if (headers && 'expect' in headers) {
|
|
1441
|
+
expect = headers.expect;
|
|
1442
|
+
}
|
|
1443
|
+
else if (baseHeaders) {
|
|
1444
|
+
expect = baseHeaders.expect;
|
|
1445
|
+
}
|
|
1446
|
+
expectContinue = expect === '100-continue';
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
else {
|
|
1450
|
+
expectContinue = false;
|
|
1451
|
+
}
|
|
2073
1452
|
if (secure) {
|
|
2074
1453
|
const certs = this[kCerts]?.[0][origin] || this.host && TLS.TEXT[origin];
|
|
2075
1454
|
if (certs) {
|
|
@@ -2082,10 +1461,14 @@ class Request extends module_1 {
|
|
|
2082
1461
|
const listenerMap = {};
|
|
2083
1462
|
const onEvent = request.on.bind(request);
|
|
2084
1463
|
const onceEvent = request.once.bind(request);
|
|
2085
|
-
let connected, emitter;
|
|
1464
|
+
let connected = false, emitter;
|
|
2086
1465
|
request.on('response', response => {
|
|
2087
|
-
connected = true;
|
|
2088
1466
|
const statusCode = response[':status'];
|
|
1467
|
+
if (expectContinue) {
|
|
1468
|
+
abortHeaders.call(this, url.href, request, options, statusCode, "Did not receive continue acknowledgment");
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
connected = true;
|
|
2089
1472
|
if (this.matchStatus(statusCode, url, response, request, options) && statusCode >= 200 && statusCode < 300) {
|
|
2090
1473
|
if (emitter = checkEncoding(request, request, statusCode, outStream, response['content-encoding'])) {
|
|
2091
1474
|
for (const event in listenerMap) {
|
|
@@ -2114,8 +1497,8 @@ class Request extends module_1 {
|
|
|
2114
1497
|
this[kConnectHttp][1][origin] = (this[kConnectHttp][1][origin] || 0) + 1;
|
|
2115
1498
|
}
|
|
2116
1499
|
}
|
|
2117
|
-
request.setTimeout(this._config.timeout);
|
|
2118
1500
|
this.matchHeaders(url, response, request, options);
|
|
1501
|
+
request.setTimeout(this._config.timeout);
|
|
2119
1502
|
});
|
|
2120
1503
|
request.on = function (event, listener) {
|
|
2121
1504
|
switch (event) {
|
|
@@ -2159,16 +1542,14 @@ class Request extends module_1 {
|
|
|
2159
1542
|
else {
|
|
2160
1543
|
let agent;
|
|
2161
1544
|
if (!socketPath) {
|
|
1545
|
+
let { keepAlive, agentTimeout } = options;
|
|
2162
1546
|
if (proxy) {
|
|
2163
1547
|
const pkg = secure ? 'https-proxy-agent' : 'http-proxy-agent';
|
|
2164
1548
|
try {
|
|
2165
1549
|
keepAlive ??= proxy.keepAlive;
|
|
2166
1550
|
agentTimeout ??= proxy.agentTimeout;
|
|
2167
1551
|
const proxyHeaders = this[kHeaders] && getBaseHeaders(proxy.host.href, this[kHeaders]) || getBaseHeaders(proxy.host.href, HTTP.HEADERS);
|
|
2168
|
-
agent = require(pkg)(proxy.host, typeof keepAlive === 'boolean' || agentTimeout > 0
|
|
2169
|
-
if (proxyHeaders) {
|
|
2170
|
-
baseHeaders = { ...baseHeaders, ...proxyHeaders };
|
|
2171
|
-
}
|
|
1552
|
+
agent = require(pkg)(proxy.host, (typeof keepAlive === 'boolean' || agentTimeout > 0) && agentTimeout !== 0 ? { keepAlive: keepAlive ?? true, timeout: agentTimeout, headers: proxyHeaders } : { headers: proxyHeaders });
|
|
2172
1553
|
}
|
|
2173
1554
|
catch (err) {
|
|
2174
1555
|
this.checkPackage(err, pkg, "Unknown");
|
|
@@ -2208,10 +1589,12 @@ class Request extends module_1 {
|
|
|
2208
1589
|
}, response => {
|
|
2209
1590
|
const statusCode = response.statusCode;
|
|
2210
1591
|
const incoming = response.headers;
|
|
2211
|
-
if (this.matchStatus(statusCode, url, incoming, request, options) && (getting || posting) && statusCode >= 200 && statusCode < 300) {
|
|
1592
|
+
if (!expectContinue && this.matchStatus(statusCode, url, incoming, request, options) && (getting || posting) && statusCode >= 200 && statusCode < 300) {
|
|
2212
1593
|
let source = checkEncoding(request, response, statusCode, outStream, incoming['content-encoding']);
|
|
2213
1594
|
if (source) {
|
|
2214
|
-
source.once('finish', () =>
|
|
1595
|
+
source.once('finish', () => {
|
|
1596
|
+
request.emit('end');
|
|
1597
|
+
});
|
|
2215
1598
|
}
|
|
2216
1599
|
else {
|
|
2217
1600
|
if (encoding) {
|
|
@@ -2228,7 +1611,9 @@ class Request extends module_1 {
|
|
|
2228
1611
|
});
|
|
2229
1612
|
}
|
|
2230
1613
|
else {
|
|
2231
|
-
response.once('end', () =>
|
|
1614
|
+
response.once('end', () => {
|
|
1615
|
+
request.emit('end');
|
|
1616
|
+
});
|
|
2232
1617
|
}
|
|
2233
1618
|
source = response;
|
|
2234
1619
|
}
|
|
@@ -2273,9 +1658,15 @@ class Request extends module_1 {
|
|
|
2273
1658
|
.once('end', () => {
|
|
2274
1659
|
request.emit('end');
|
|
2275
1660
|
});
|
|
1661
|
+
if (expectContinue) {
|
|
1662
|
+
abortHeaders.call(this, url.href, request, options, statusCode, "Did not receive continue acknowledgment");
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
2276
1665
|
}
|
|
2277
1666
|
if (this._config.timeout) {
|
|
2278
|
-
response.setTimeout(this._config.timeout, () =>
|
|
1667
|
+
response.setTimeout(this._config.timeout, () => {
|
|
1668
|
+
request.emit('timeout');
|
|
1669
|
+
});
|
|
2279
1670
|
}
|
|
2280
1671
|
this.matchHeaders(url, incoming, request, options);
|
|
2281
1672
|
});
|
|
@@ -2295,15 +1686,32 @@ class Request extends module_1 {
|
|
|
2295
1686
|
ac.abort(new Error("Aborted by process"));
|
|
2296
1687
|
}, { once: true });
|
|
2297
1688
|
}
|
|
2298
|
-
|
|
2299
|
-
if (
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
1689
|
+
const sendBody = () => {
|
|
1690
|
+
if (posting) {
|
|
1691
|
+
const postData = options.postData;
|
|
1692
|
+
if ((0, types_1.isString)(postData) || Buffer.isBuffer(postData)) {
|
|
1693
|
+
request.write(postData);
|
|
1694
|
+
}
|
|
1695
|
+
else if (postData instanceof stream.Stream) {
|
|
1696
|
+
postData.pipe(request);
|
|
1697
|
+
}
|
|
2304
1698
|
}
|
|
1699
|
+
};
|
|
1700
|
+
if (expectContinue) {
|
|
1701
|
+
const pending = setTimeout(() => {
|
|
1702
|
+
request.end();
|
|
1703
|
+
}, options.expectTimeout || 5 * 1000);
|
|
1704
|
+
request.on('continue', () => {
|
|
1705
|
+
clearTimeout(pending);
|
|
1706
|
+
expectContinue = false;
|
|
1707
|
+
sendBody();
|
|
1708
|
+
request.end();
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1711
|
+
else {
|
|
1712
|
+
sendBody();
|
|
1713
|
+
request.end();
|
|
2305
1714
|
}
|
|
2306
|
-
request.end();
|
|
2307
1715
|
return request;
|
|
2308
1716
|
}
|
|
2309
1717
|
head(uri, options) {
|
|
@@ -2344,14 +1752,13 @@ class Request extends module_1 {
|
|
|
2344
1752
|
}
|
|
2345
1753
|
let dataEncoding;
|
|
2346
1754
|
if ((0, types_1.isPlainObject)(options)) {
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
if (!putting && formData) {
|
|
2350
|
-
(parts ||= []).push(...Array.isArray(formData) ? formData : [formData]);
|
|
1755
|
+
if (!putting && options.formData) {
|
|
1756
|
+
(parts ||= []).push(...Array.isArray(options.formData) ? options.formData : [options.formData]);
|
|
2351
1757
|
}
|
|
2352
1758
|
else {
|
|
2353
1759
|
contentType ||= options.contentType;
|
|
2354
1760
|
}
|
|
1761
|
+
dataEncoding = options.dataEncoding;
|
|
2355
1762
|
}
|
|
2356
1763
|
else {
|
|
2357
1764
|
options = {};
|
|
@@ -2364,7 +1771,7 @@ class Request extends module_1 {
|
|
|
2364
1771
|
}
|
|
2365
1772
|
}
|
|
2366
1773
|
if (!putting && (parts || contentType === "multipart/form-data" || contentType === 'form-data')) {
|
|
2367
|
-
let valid;
|
|
1774
|
+
let valid = false;
|
|
2368
1775
|
if ((0, types_1.isArray)(parts)) {
|
|
2369
1776
|
const write = combined.create();
|
|
2370
1777
|
const boundary = crypto.randomUUID().replaceAll('-', '');
|
|
@@ -2446,7 +1853,7 @@ class Request extends module_1 {
|
|
|
2446
1853
|
}
|
|
2447
1854
|
else {
|
|
2448
1855
|
if (contentType && !contentType.includes('/')) {
|
|
2449
|
-
contentType = 'application/' + contentType
|
|
1856
|
+
contentType = 'application/' + contentType;
|
|
2450
1857
|
}
|
|
2451
1858
|
if (!(0, types_1.isPlainObject)(data)) {
|
|
2452
1859
|
data = module_1.asString(data);
|
|
@@ -2468,14 +1875,35 @@ class Request extends module_1 {
|
|
|
2468
1875
|
headers['content-type'] = contentType || "text/plain";
|
|
2469
1876
|
return this.get(uri, options);
|
|
2470
1877
|
}
|
|
2471
|
-
async get(uri, options
|
|
2472
|
-
const opts = (typeof options === 'string' ? { format: options, encoding: 'utf-8' } : options);
|
|
1878
|
+
async get(uri, options) {
|
|
1879
|
+
const opts = (typeof options === 'string' ? { format: options, encoding: 'utf-8' } : options || {});
|
|
2473
1880
|
if (this.readExpect === 'string') {
|
|
2474
1881
|
opts.encoding = (0, types_1.getEncoding)(opts.encoding);
|
|
2475
1882
|
}
|
|
2476
|
-
|
|
1883
|
+
const singleton = this[kSingleton];
|
|
1884
|
+
const verbose = !opts.silent && !singleton || opts.silent === false;
|
|
1885
|
+
const log = verbose && LOG_HTTP && LOG_TIMEPROCESS;
|
|
1886
|
+
const state = Object.freeze({
|
|
1887
|
+
verbose,
|
|
1888
|
+
log,
|
|
1889
|
+
singleton,
|
|
1890
|
+
config: this._config
|
|
1891
|
+
});
|
|
1892
|
+
return new this[kAdapter](this, state, uri, opts).start();
|
|
2477
1893
|
}
|
|
2478
|
-
reset() {
|
|
1894
|
+
reset(adapter) {
|
|
1895
|
+
if (adapter) {
|
|
1896
|
+
if (adapter.timeout) {
|
|
1897
|
+
clearTimeout(adapter.timeout);
|
|
1898
|
+
adapter.timeout = null;
|
|
1899
|
+
}
|
|
1900
|
+
const ac = adapter.abortController;
|
|
1901
|
+
if (ac) {
|
|
1902
|
+
this[kDownloading].delete(ac);
|
|
1903
|
+
adapter.abortController = null;
|
|
1904
|
+
}
|
|
1905
|
+
return;
|
|
1906
|
+
}
|
|
2479
1907
|
this[kPendingDns] = Object.create(null);
|
|
2480
1908
|
this[kDownloading].clear();
|
|
2481
1909
|
}
|
|
@@ -2545,6 +1973,11 @@ class Request extends module_1 {
|
|
|
2545
1973
|
}
|
|
2546
1974
|
return true;
|
|
2547
1975
|
}
|
|
1976
|
+
set adapter(value) {
|
|
1977
|
+
if (isFunction(value) && value.prototype instanceof adapter_1) {
|
|
1978
|
+
this[kAdapter] = value;
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
2548
1981
|
set agentTimeout(value) {
|
|
2549
1982
|
if (value > 0) {
|
|
2550
1983
|
this[kAgentTimeout] = value;
|
|
@@ -2585,5 +2018,5 @@ class Request extends module_1 {
|
|
|
2585
2018
|
return this.module.settings ||= {};
|
|
2586
2019
|
}
|
|
2587
2020
|
}
|
|
2588
|
-
_a = kSingleton, _b = kHttpVersion, _c = kHeaders, _d = kCerts, _e = kBaseURL, _f = kConnectDns, _g = kPendingDns, _h = kConnectHttp, _j = kStatusOn, _k = kHeadersOn, _l =
|
|
2021
|
+
_a = kSingleton, _b = kHttpVersion, _c = kHeaders, _d = kCerts, _e = kBaseURL, _f = kConnectDns, _g = kPendingDns, _h = kConnectHttp, _j = kStatusOn, _k = kHeadersOn, _l = kAdapter, _m = kDownloading, _o = kHostInfo, _p = kSession;
|
|
2589
2022
|
module.exports = Request;
|