@e-mc/request 0.11.8 → 0.12.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/README.md +53 -9
- package/http/adapter/index.js +28 -23
- package/http/host/index.js +57 -62
- package/index.js +720 -281
- package/package.json +3 -3
- package/util.js +29 -28
package/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
3
2
|
const path = require("node:path");
|
|
4
3
|
const fs = require("node:fs");
|
|
5
4
|
const crypto = require("node:crypto");
|
|
@@ -20,22 +19,7 @@ const module_1 = require("@e-mc/module");
|
|
|
20
19
|
const util_1 = require("@e-mc/request/util");
|
|
21
20
|
const host_1 = require("@e-mc/request/http/host");
|
|
22
21
|
const adapter_1 = require("@e-mc/request/http/adapter");
|
|
23
|
-
const
|
|
24
|
-
const kHttpVersion = Symbol('httpVersion');
|
|
25
|
-
const kIpVersion = Symbol('ipVersion');
|
|
26
|
-
const kAgentTimeout = Symbol('agentTimeout');
|
|
27
|
-
const kHeaders = Symbol('headers');
|
|
28
|
-
const kCerts = Symbol('certs');
|
|
29
|
-
const kBaseURL = Symbol('baseURL');
|
|
30
|
-
const kDownloading = Symbol('downloading');
|
|
31
|
-
const kSingleton = Symbol('singleton');
|
|
32
|
-
const kHostInfo = Symbol('hostInfo');
|
|
33
|
-
const kConnectDns = Symbol('connectDns');
|
|
34
|
-
const kPendingDns = Symbol('pendingDns');
|
|
35
|
-
const kConnectHttp = Symbol('connectHttp');
|
|
36
|
-
const kStatusOn = Symbol('statusOn');
|
|
37
|
-
const kHeadersOn = Symbol('headersOn');
|
|
38
|
-
const kAdapter = Symbol('adapter');
|
|
22
|
+
const kRequest = Symbol.for('request:constructor');
|
|
39
23
|
const SUPPORTED_NODE20 = (0, types_1.supported)(20);
|
|
40
24
|
const SUPPORTED_ZSTD = (0, types_1.supported)(23, 8) && typeof zlib.createZstdDecompress === 'function';
|
|
41
25
|
const REGEXP_PEMCERT = /^-{3,}[ \t]*BEGIN[ \t].+\n-{3,}[ \t]*END[ \t][^-]+-{3,}$/s;
|
|
@@ -75,8 +59,46 @@ const ARIA2 = {
|
|
|
75
59
|
LOWEST_SPEED_LIMIT: null,
|
|
76
60
|
ALWAYS_RESUME: false,
|
|
77
61
|
FILE_ALLOCATION: 'none',
|
|
62
|
+
PROXY: {},
|
|
63
|
+
NO_PROXY: '',
|
|
78
64
|
CONF_PATH: ''
|
|
79
65
|
};
|
|
66
|
+
const RCLONE = {
|
|
67
|
+
BIN: which.sync(module_1.PLATFORM_WIN32 ? 'rclone.exe' : 'rclone', { nothrow: true }) || '',
|
|
68
|
+
EXEC_UID: undefined,
|
|
69
|
+
EXEC_GID: undefined,
|
|
70
|
+
CHECK_FIRST: false,
|
|
71
|
+
CHECKSUM: false,
|
|
72
|
+
CUTOFF_MODE: '',
|
|
73
|
+
IGNORE_CASE_SYNC: false,
|
|
74
|
+
IGNORE_CHECKSUM: false,
|
|
75
|
+
IGNORE_EXISTING: false,
|
|
76
|
+
IGNORE_SIZE: false,
|
|
77
|
+
IGNORE_TIMES: false,
|
|
78
|
+
IMMUTABLE: false,
|
|
79
|
+
INPLACE: false,
|
|
80
|
+
MAX_BACKLOG: 0,
|
|
81
|
+
MAX_DURATION: '',
|
|
82
|
+
MAX_TRANSFER: '',
|
|
83
|
+
METADATA: false,
|
|
84
|
+
MODIFY_WINDOW: '',
|
|
85
|
+
MULTI_THREAD_CHUNK_SIZE: '',
|
|
86
|
+
MULTI_THREAD_CUTOFF: '',
|
|
87
|
+
MULTI_THREAD_STREAMS: 0,
|
|
88
|
+
MULTI_THREAD_WRITE_BUFFER_SIZE: '',
|
|
89
|
+
NO_CHECK_DEST: false,
|
|
90
|
+
NO_TRAVERSE: false,
|
|
91
|
+
NO_UPDATE_DIR_MODTIME: false,
|
|
92
|
+
REFRESH_TIMES: false,
|
|
93
|
+
SIZE_ONLY: false,
|
|
94
|
+
UPDATE: false,
|
|
95
|
+
FAST_LIST: false,
|
|
96
|
+
BIND: '',
|
|
97
|
+
CONTIMEOUT: '',
|
|
98
|
+
DISABLE_HTTP2: false,
|
|
99
|
+
TIMEOUT: '',
|
|
100
|
+
CONFIG: ''
|
|
101
|
+
};
|
|
80
102
|
let HTTP_ADAPTER = adapter_1;
|
|
81
103
|
let KEEP_ALIVE = null;
|
|
82
104
|
let ACCEPT_ENCODING = false;
|
|
@@ -335,15 +357,6 @@ function decompressEncoding(value, chunkSize) {
|
|
|
335
357
|
break;
|
|
336
358
|
}
|
|
337
359
|
}
|
|
338
|
-
function abortHeaders(href, request, options, statusCode = '', message) {
|
|
339
|
-
const reason = (0, types_1.errorMessage)(statusCode, message || "Aborted by client", href);
|
|
340
|
-
const outAbort = options.outAbort;
|
|
341
|
-
if (outAbort) {
|
|
342
|
-
outAbort.abort(reason);
|
|
343
|
-
this[kDownloading].delete(outAbort);
|
|
344
|
-
}
|
|
345
|
-
request.destroy(reason);
|
|
346
|
-
}
|
|
347
360
|
function resetAria2() {
|
|
348
361
|
clearInterval(ARIA2.PID_TIMER);
|
|
349
362
|
ARIA2.PID_TIMER = null;
|
|
@@ -363,27 +376,187 @@ function failedDns(err, pending) {
|
|
|
363
376
|
}
|
|
364
377
|
pending.length = 0;
|
|
365
378
|
}
|
|
366
|
-
function
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
379
|
+
function setBinExec(settings, target) {
|
|
380
|
+
let { bin, exec } = settings;
|
|
381
|
+
if (bin === false) {
|
|
382
|
+
target.BIN = '';
|
|
383
|
+
}
|
|
384
|
+
else if (bin && module_1.isPath(bin = path.resolve(bin), true)) {
|
|
385
|
+
target.BIN = bin;
|
|
386
|
+
}
|
|
387
|
+
if ((0, types_1.isPlainObject)(exec)) {
|
|
388
|
+
let { uid, gid } = exec;
|
|
389
|
+
target.EXEC_UID = (uid = (0, util_1.asInt)(uid)) >= 0 ? uid : undefined;
|
|
390
|
+
target.EXEC_GID = (gid = (0, util_1.asInt)(gid)) >= 0 ? gid : undefined;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
function parseBinOpts(instance, options, ignore, skip) {
|
|
394
|
+
let pathname = options.pathname, binOpts;
|
|
395
|
+
if (!(0, types_1.isString)(pathname)) {
|
|
396
|
+
if (!instance.host) {
|
|
397
|
+
return [];
|
|
398
|
+
}
|
|
399
|
+
pathname = process.cwd();
|
|
400
|
+
}
|
|
401
|
+
if ((0, types_1.isArray)(options.binOpts)) {
|
|
402
|
+
let next = false;
|
|
403
|
+
binOpts = options.binOpts.filter(opt => !((0, types_1.isString)(opt) && /^-[a-z].*$/i.test(opt.trim()))).map((opt) => {
|
|
404
|
+
if (next) {
|
|
405
|
+
if (!module_1.asString(opt).startsWith('--')) {
|
|
406
|
+
return [];
|
|
407
|
+
}
|
|
408
|
+
next = false;
|
|
409
|
+
}
|
|
410
|
+
switch (typeof opt) {
|
|
411
|
+
case 'string': {
|
|
412
|
+
const value = opt.trim();
|
|
413
|
+
if (value.startsWith('--')) {
|
|
414
|
+
const match = /^(--[a-z]+[a-z0-9-]*)(=)?\s*(.*)$/s.exec(value);
|
|
415
|
+
if (match) {
|
|
416
|
+
if (ignore.includes(match[1])) {
|
|
417
|
+
return [];
|
|
418
|
+
}
|
|
419
|
+
if (skip.includes(match[1])) {
|
|
420
|
+
if (!match[2]) {
|
|
421
|
+
next = true;
|
|
422
|
+
}
|
|
423
|
+
return [];
|
|
424
|
+
}
|
|
425
|
+
switch (match[1]) {
|
|
426
|
+
case '--version':
|
|
427
|
+
case '--help':
|
|
428
|
+
return [];
|
|
429
|
+
default:
|
|
430
|
+
return match[3] ? [match[1], (0, types_1.sanitizeArgs)(match[3])] : [match[1]];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
else if (value) {
|
|
435
|
+
return [(0, types_1.sanitizeArgs)(value)];
|
|
436
|
+
}
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
case 'number':
|
|
440
|
+
case 'boolean':
|
|
441
|
+
return [opt.toString()];
|
|
442
|
+
default:
|
|
443
|
+
if ((0, types_1.isArray)(opt)) {
|
|
444
|
+
return opt.filter(item => (0, types_1.isString)(item)).map(item => (0, types_1.sanitizeArgs)(item));
|
|
445
|
+
}
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
return [];
|
|
449
|
+
}).flat();
|
|
450
|
+
}
|
|
451
|
+
return [pathname, (0, util_1.parseOutgoingHeaders)(options.headers), binOpts];
|
|
452
|
+
}
|
|
453
|
+
function checkBinTarget(instance, name, uri, pathname, command, binOpts) {
|
|
454
|
+
if (!(0, types_1.isString)(pathname)) {
|
|
455
|
+
throw (0, types_1.errorMessage)(name, "Invalid parameters", 'pathname');
|
|
456
|
+
}
|
|
457
|
+
pathname = path.resolve(pathname);
|
|
458
|
+
if ((instance.host || instance.hasPermission('fs') || process.permission) && !instance.canWrite(pathname)) {
|
|
459
|
+
throw (0, types_1.errorMessage)(name, "Unsupported access", pathname);
|
|
460
|
+
}
|
|
461
|
+
let target;
|
|
462
|
+
switch (command) {
|
|
463
|
+
case 'copyurl':
|
|
464
|
+
if (module_1.isDir(pathname) || isDirEnd(pathname)) {
|
|
465
|
+
target = pathname;
|
|
466
|
+
if (!binOpts || !binOpts.includes('--auto-filename') && !binOpts.includes('--header-filename')) {
|
|
467
|
+
pathname = path.join(pathname, path.basename(new URL(uri).pathname));
|
|
468
|
+
}
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
case 'copyto':
|
|
472
|
+
target = isDirEnd(pathname) ? pathname : path.dirname(pathname);
|
|
473
|
+
break;
|
|
474
|
+
default:
|
|
475
|
+
target = pathname;
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
if (!module_1.createDir(target)) {
|
|
479
|
+
throw (0, types_1.errorMessage)(name, "Path is not a directory", target);
|
|
480
|
+
}
|
|
481
|
+
return pathname;
|
|
482
|
+
}
|
|
483
|
+
function checkBinOpts(init, binOpts) {
|
|
484
|
+
if ((0, types_1.isArray)(binOpts)) {
|
|
485
|
+
for (let i = 0; i < binOpts.length; ++i) {
|
|
486
|
+
const leading = binOpts[i] + '=';
|
|
487
|
+
for (const arg of init) {
|
|
488
|
+
if (arg.startsWith(leading)) {
|
|
489
|
+
const items = [];
|
|
490
|
+
for (let k = i + 1; k < binOpts.length; ++k) {
|
|
491
|
+
const next = binOpts[k];
|
|
492
|
+
if (next.startsWith('--')) {
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
items.push(next);
|
|
496
|
+
}
|
|
497
|
+
const l = items.length + 1;
|
|
498
|
+
binOpts.splice(i, l);
|
|
499
|
+
i += l;
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
372
503
|
}
|
|
373
504
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
505
|
+
}
|
|
506
|
+
function setBinHeaders(args, headers) {
|
|
507
|
+
for (const name in headers) {
|
|
508
|
+
let items = headers[name];
|
|
509
|
+
if (!Array.isArray(items)) {
|
|
510
|
+
items = [items.toString()];
|
|
378
511
|
}
|
|
512
|
+
args.push(...items.map(value => `--header="${name}: ${escapeShellQuote(value)}"`));
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
function finalizeBinArgs(instance, name, bin, args, opts, binOpts, cmd = []) {
|
|
516
|
+
if ((0, types_1.isArray)(binOpts)) {
|
|
517
|
+
for (const leading of binOpts) {
|
|
518
|
+
if (leading.startsWith('-')) {
|
|
519
|
+
const pattern = new RegExp(`^${leading}(?:=|$)`);
|
|
520
|
+
for (let i = 0; i < opts.length; ++i) {
|
|
521
|
+
if (pattern.test(opts[i])) {
|
|
522
|
+
opts.splice(i--, i);
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
args = binOpts.concat(args);
|
|
529
|
+
}
|
|
530
|
+
if (args.length > 0) {
|
|
531
|
+
if (module_1.hasLogType(32768)) {
|
|
532
|
+
instance.formatMessage(32768, name.toUpperCase(), [bin].concat(cmd).join(' '), args.join(' '), { ...module_1.LOG_STYLE_WARN });
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
instance.addLog(types_1.STATUS_TYPE.INFO, path.basename(bin) + ' ' + args.join(' '), name);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return args;
|
|
539
|
+
}
|
|
540
|
+
function addAria2Proxy(args, protocol, host) {
|
|
541
|
+
const { origin, username, password } = host;
|
|
542
|
+
args.push(`--${protocol}-proxy="${origin}"`);
|
|
543
|
+
if (username) {
|
|
544
|
+
args.push(`--${protocol}-proxy-user="${escapeShellQuote(decodeURIComponent(username))}"`);
|
|
545
|
+
}
|
|
546
|
+
if (password) {
|
|
547
|
+
args.push(`--${protocol}-proxy-passwd="${escapeShellQuote(decodeURIComponent(password))}"`);
|
|
379
548
|
}
|
|
380
|
-
pending.length = 0;
|
|
381
549
|
}
|
|
382
|
-
const
|
|
550
|
+
const isConstructor = (value) => typeof value === 'function';
|
|
551
|
+
const isDirEnd = (value) => value.endsWith('/') || value.endsWith(path.sep);
|
|
552
|
+
const trimCharEnd = (value) => value.substring(0, value.length - 1);
|
|
383
553
|
const configureDns = (family, options) => family === 0 ? options : { family, hints: family === 6 ? dns.V4MAPPED : 0 };
|
|
384
|
-
const ignoreOpt = (opts, ...values) => !opts?.some(
|
|
554
|
+
const ignoreOpt = (opts, ...values) => !opts?.some(opt => values.some(value => opt === value || opt.startsWith(value + '=')));
|
|
385
555
|
const escapeQuote = (value) => value.replace(/[\\"]/g, capture => '\\' + capture);
|
|
556
|
+
const rcloneSize = (value) => (0, types_1.isString)(value) ? /^\d+(?:B|K|M|G|T|P)$/.exec(value)?.[0] : undefined;
|
|
557
|
+
const rcloneDuration = (value) => (0, types_1.isString)(value) ? /^\d+(?:h|m|s|ms|ns)$/.exec(value)?.[0] : undefined;
|
|
386
558
|
class Request extends module_1 {
|
|
559
|
+
static [kRequest] = true;
|
|
387
560
|
static async purgeMemory(percent = 1, limit = 0, parent) {
|
|
388
561
|
if (percent >= 1) {
|
|
389
562
|
resetHttpHost(0);
|
|
@@ -403,18 +576,8 @@ class Request extends module_1 {
|
|
|
403
576
|
}
|
|
404
577
|
const { request, download } = settings;
|
|
405
578
|
if (download?.aria2) {
|
|
406
|
-
let {
|
|
407
|
-
|
|
408
|
-
ARIA2.BIN = '';
|
|
409
|
-
}
|
|
410
|
-
else if (bin && this.isPath(bin = path.resolve(bin), true)) {
|
|
411
|
-
ARIA2.BIN = bin;
|
|
412
|
-
}
|
|
413
|
-
if ((0, types_1.isPlainObject)(exec)) {
|
|
414
|
-
let { uid, gid } = exec;
|
|
415
|
-
ARIA2.EXEC_UID = (uid = (0, util_1.asInt)(uid)) >= 0 ? uid : undefined;
|
|
416
|
-
ARIA2.EXEC_GID = (gid = (0, util_1.asInt)(gid)) >= 0 ? gid : undefined;
|
|
417
|
-
}
|
|
579
|
+
let { update_status, max_concurrent_downloads, max_connection_per_server, check_integrity, bt_stop_timeout, bt_tracker_connect_timeout, bt_tracker_timeout, min_split_size, disk_cache, lowest_speed_limit, always_resume, file_allocation, proxy, no_proxy, conf_path } = download.aria2;
|
|
580
|
+
setBinExec(download.aria2, ARIA2);
|
|
418
581
|
if ((0, types_1.isPlainObject)(update_status)) {
|
|
419
582
|
const { interval, broadcast_only } = update_status;
|
|
420
583
|
if (typeof broadcast_only === 'boolean') {
|
|
@@ -425,12 +588,12 @@ class Request extends module_1 {
|
|
|
425
588
|
if ((update_status = (0, util_1.asInt)(update_status)) >= 0) {
|
|
426
589
|
ARIA2.UPDATE_STATUS = update_status;
|
|
427
590
|
}
|
|
428
|
-
if ((max_concurrent_downloads = (0, util_1.asInt)(max_concurrent_downloads)) > 0) {
|
|
429
|
-
ARIA2.MAX_CONCURRENT_DOWNLOADS = max_concurrent_downloads;
|
|
430
|
-
}
|
|
431
591
|
if (typeof check_integrity === 'boolean') {
|
|
432
592
|
ARIA2.CHECK_INTEGRITY = check_integrity;
|
|
433
593
|
}
|
|
594
|
+
if ((max_concurrent_downloads = (0, util_1.asInt)(max_concurrent_downloads)) > 0) {
|
|
595
|
+
ARIA2.MAX_CONCURRENT_DOWNLOADS = max_concurrent_downloads;
|
|
596
|
+
}
|
|
434
597
|
if ((max_connection_per_server = (0, util_1.asInt)(max_connection_per_server)) > 0) {
|
|
435
598
|
ARIA2.MAX_CONNECTION_PER_SERVER = max_connection_per_server;
|
|
436
599
|
}
|
|
@@ -466,10 +629,130 @@ class Request extends module_1 {
|
|
|
466
629
|
break;
|
|
467
630
|
}
|
|
468
631
|
}
|
|
632
|
+
if (proxy) {
|
|
633
|
+
try {
|
|
634
|
+
for (const uri in proxy) {
|
|
635
|
+
const host = new URL(uri);
|
|
636
|
+
ARIA2.PROXY[trimCharEnd(host.protocol)] = { host };
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
catch {
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
else if (proxy === false) {
|
|
643
|
+
ARIA2.PROXY = {};
|
|
644
|
+
}
|
|
645
|
+
if (no_proxy === '' || (0, types_1.isString)(no_proxy)) {
|
|
646
|
+
ARIA2.NO_PROXY = no_proxy;
|
|
647
|
+
}
|
|
469
648
|
if (conf_path === '' || (0, types_1.isString)(conf_path) && this.isPath(conf_path = path.resolve(conf_path))) {
|
|
470
649
|
ARIA2.CONF_PATH = conf_path;
|
|
471
650
|
}
|
|
472
651
|
}
|
|
652
|
+
if (download?.rclone) {
|
|
653
|
+
let { check_first, checksum, cutoff_mode, ignore_case_sync, ignore_checksum, ignore_existing, ignore_size, ignore_times, immutable, inplace, max_backlog, max_duration, max_transfer, metadata, modify_window, multi_thread_chunk_size, multi_thread_cutoff, multi_thread_streams, multi_thread_write_buffer_size, no_check_dest, no_traverse, no_update_dir_modtime, refresh_times, size_only, update, fast_list, bind, contimeout, disable_http2, timeout, config } = download.rclone;
|
|
654
|
+
setBinExec(download.rclone, RCLONE);
|
|
655
|
+
if (typeof check_first === 'boolean') {
|
|
656
|
+
RCLONE.CHECK_FIRST = check_first;
|
|
657
|
+
}
|
|
658
|
+
if (typeof checksum === 'boolean') {
|
|
659
|
+
RCLONE.CHECKSUM = checksum;
|
|
660
|
+
}
|
|
661
|
+
if ((0, types_1.isString)(cutoff_mode)) {
|
|
662
|
+
const value = cutoff_mode.toUpperCase();
|
|
663
|
+
switch (value) {
|
|
664
|
+
case 'HARD':
|
|
665
|
+
case 'SOFT':
|
|
666
|
+
case 'CAUTIOUS':
|
|
667
|
+
RCLONE.CUTOFF_MODE = value;
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if (typeof ignore_case_sync === 'boolean') {
|
|
672
|
+
RCLONE.IGNORE_CASE_SYNC = ignore_case_sync;
|
|
673
|
+
}
|
|
674
|
+
if (typeof ignore_checksum === 'boolean') {
|
|
675
|
+
RCLONE.IGNORE_CHECKSUM = ignore_checksum;
|
|
676
|
+
}
|
|
677
|
+
if (typeof ignore_existing === 'boolean') {
|
|
678
|
+
RCLONE.IGNORE_EXISTING = ignore_existing;
|
|
679
|
+
}
|
|
680
|
+
if (typeof ignore_size === 'boolean') {
|
|
681
|
+
RCLONE.IGNORE_SIZE = ignore_size;
|
|
682
|
+
}
|
|
683
|
+
if (typeof ignore_times === 'boolean') {
|
|
684
|
+
RCLONE.IGNORE_TIMES = ignore_times;
|
|
685
|
+
}
|
|
686
|
+
if (typeof immutable === 'boolean') {
|
|
687
|
+
RCLONE.IMMUTABLE = immutable;
|
|
688
|
+
}
|
|
689
|
+
if (typeof inplace === 'boolean') {
|
|
690
|
+
RCLONE.INPLACE = inplace;
|
|
691
|
+
}
|
|
692
|
+
if ((max_backlog = (0, util_1.asInt)(max_backlog)) > 0) {
|
|
693
|
+
RCLONE.MAX_BACKLOG = max_backlog;
|
|
694
|
+
}
|
|
695
|
+
if (max_duration = rcloneDuration(max_duration)) {
|
|
696
|
+
RCLONE.MAX_DURATION = max_duration;
|
|
697
|
+
}
|
|
698
|
+
if (max_transfer = rcloneSize(max_transfer)) {
|
|
699
|
+
RCLONE.MAX_TRANSFER = max_transfer;
|
|
700
|
+
}
|
|
701
|
+
if (typeof metadata === 'boolean') {
|
|
702
|
+
RCLONE.METADATA = metadata;
|
|
703
|
+
}
|
|
704
|
+
if (modify_window = rcloneDuration(modify_window)) {
|
|
705
|
+
RCLONE.MODIFY_WINDOW = modify_window;
|
|
706
|
+
}
|
|
707
|
+
if (multi_thread_chunk_size = rcloneSize(multi_thread_chunk_size)) {
|
|
708
|
+
RCLONE.MULTI_THREAD_CHUNK_SIZE = multi_thread_chunk_size;
|
|
709
|
+
}
|
|
710
|
+
if (multi_thread_cutoff = rcloneSize(multi_thread_cutoff)) {
|
|
711
|
+
RCLONE.MULTI_THREAD_CUTOFF = multi_thread_cutoff;
|
|
712
|
+
}
|
|
713
|
+
if ((multi_thread_streams = (0, util_1.asInt)(multi_thread_streams)) > 0) {
|
|
714
|
+
RCLONE.MULTI_THREAD_STREAMS = multi_thread_streams;
|
|
715
|
+
}
|
|
716
|
+
if (multi_thread_write_buffer_size = rcloneSize(multi_thread_write_buffer_size)) {
|
|
717
|
+
RCLONE.MULTI_THREAD_WRITE_BUFFER_SIZE = multi_thread_write_buffer_size;
|
|
718
|
+
}
|
|
719
|
+
if (typeof no_check_dest === 'boolean') {
|
|
720
|
+
RCLONE.NO_CHECK_DEST = no_check_dest;
|
|
721
|
+
}
|
|
722
|
+
if (typeof no_traverse === 'boolean') {
|
|
723
|
+
RCLONE.NO_TRAVERSE = no_traverse;
|
|
724
|
+
}
|
|
725
|
+
if (typeof no_update_dir_modtime === 'boolean') {
|
|
726
|
+
RCLONE.NO_UPDATE_DIR_MODTIME = no_update_dir_modtime;
|
|
727
|
+
}
|
|
728
|
+
if (typeof refresh_times === 'boolean') {
|
|
729
|
+
RCLONE.REFRESH_TIMES = refresh_times;
|
|
730
|
+
}
|
|
731
|
+
if (typeof size_only === 'boolean') {
|
|
732
|
+
RCLONE.SIZE_ONLY = size_only;
|
|
733
|
+
}
|
|
734
|
+
if (typeof update === 'boolean') {
|
|
735
|
+
RCLONE.UPDATE = update;
|
|
736
|
+
}
|
|
737
|
+
if (typeof fast_list === 'boolean') {
|
|
738
|
+
RCLONE.FAST_LIST = fast_list;
|
|
739
|
+
}
|
|
740
|
+
if (contimeout = rcloneDuration(contimeout)) {
|
|
741
|
+
RCLONE.CONTIMEOUT = contimeout;
|
|
742
|
+
}
|
|
743
|
+
if (typeof bind === 'string') {
|
|
744
|
+
RCLONE.BIND = bind;
|
|
745
|
+
}
|
|
746
|
+
if (typeof disable_http2 === 'boolean') {
|
|
747
|
+
RCLONE.DISABLE_HTTP2 = disable_http2;
|
|
748
|
+
}
|
|
749
|
+
if (timeout = rcloneDuration(timeout)) {
|
|
750
|
+
RCLONE.TIMEOUT = timeout;
|
|
751
|
+
}
|
|
752
|
+
if (config === '' || (0, types_1.isString)(config) && this.isPath(config = path.resolve(config), true)) {
|
|
753
|
+
RCLONE.CONFIG = config;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
473
756
|
if (request) {
|
|
474
757
|
let { read_timeout, agent, use, headers, certs } = request, agent_timeout;
|
|
475
758
|
if ((read_timeout = (0, util_1.fromSeconds)(read_timeout)) >= 0) {
|
|
@@ -585,42 +868,51 @@ class Request extends module_1 {
|
|
|
585
868
|
}
|
|
586
869
|
}
|
|
587
870
|
static defineHttpAdapter(module) {
|
|
588
|
-
if (
|
|
871
|
+
if (isConstructor(module) && module.prototype instanceof adapter_1) {
|
|
589
872
|
HTTP_ADAPTER = module;
|
|
590
873
|
}
|
|
591
874
|
}
|
|
592
875
|
static getAria2Path() {
|
|
593
876
|
return ARIA2.BIN;
|
|
594
877
|
}
|
|
878
|
+
static getRclonePath() {
|
|
879
|
+
return RCLONE.BIN;
|
|
880
|
+
}
|
|
881
|
+
startTime = Date.now();
|
|
882
|
+
acceptEncoding;
|
|
883
|
+
keepAlive;
|
|
884
|
+
readExpect = 'none';
|
|
885
|
+
readTimeout;
|
|
886
|
+
proxy = null;
|
|
887
|
+
module;
|
|
888
|
+
_moduleName = "request";
|
|
889
|
+
_threadable = true;
|
|
890
|
+
_config = {
|
|
891
|
+
timeout: 60000,
|
|
892
|
+
connectTimeout: 20 * 1000,
|
|
893
|
+
redirectLimit: 10,
|
|
894
|
+
retryWait: 1000,
|
|
895
|
+
retryAfter: 30 * 1000,
|
|
896
|
+
retryLimit: 5
|
|
897
|
+
};
|
|
898
|
+
#singleton = false;
|
|
899
|
+
#httpVersion = null;
|
|
900
|
+
#ipVersion;
|
|
901
|
+
#agentTimeout;
|
|
902
|
+
#headers = null;
|
|
903
|
+
#certs = null;
|
|
904
|
+
#baseUrl = null;
|
|
905
|
+
#connectDns = Object.create(null);
|
|
906
|
+
#pendingDns = Object.create(null);
|
|
907
|
+
#connectHttp = [{}, {}];
|
|
908
|
+
#statusOn = null;
|
|
909
|
+
#headersOn = null;
|
|
910
|
+
#adapter = HTTP_ADAPTER;
|
|
911
|
+
#downloading = new Set();
|
|
912
|
+
#hostInfo = {};
|
|
913
|
+
#session = [Object.create(null)];
|
|
595
914
|
constructor(data) {
|
|
596
915
|
super();
|
|
597
|
-
this.startTime = Date.now();
|
|
598
|
-
this.readExpect = 'none';
|
|
599
|
-
this.proxy = null;
|
|
600
|
-
this._moduleName = "request";
|
|
601
|
-
this._threadable = true;
|
|
602
|
-
this._config = {
|
|
603
|
-
timeout: 60000,
|
|
604
|
-
connectTimeout: 20 * 1000,
|
|
605
|
-
redirectLimit: 10,
|
|
606
|
-
retryWait: 1000,
|
|
607
|
-
retryAfter: 30 * 1000,
|
|
608
|
-
retryLimit: 5
|
|
609
|
-
};
|
|
610
|
-
this[_a] = false;
|
|
611
|
-
this[_b] = null;
|
|
612
|
-
this[_c] = null;
|
|
613
|
-
this[_d] = null;
|
|
614
|
-
this[_e] = null;
|
|
615
|
-
this[_f] = Object.create(null);
|
|
616
|
-
this[_g] = Object.create(null);
|
|
617
|
-
this[_h] = [{}, {}];
|
|
618
|
-
this[_j] = null;
|
|
619
|
-
this[_k] = null;
|
|
620
|
-
this[_l] = HTTP_ADAPTER;
|
|
621
|
-
this[_m] = new Set();
|
|
622
|
-
this[_o] = {};
|
|
623
|
-
this[_p] = [Object.create(null)];
|
|
624
916
|
if ((0, types_1.isPlainObject)(data)) {
|
|
625
917
|
const { headers, read_timeout, agent, use, connect, certs } = data;
|
|
626
918
|
const timeout = (0, util_1.fromSeconds)(data.timeout);
|
|
@@ -629,14 +921,14 @@ class Request extends module_1 {
|
|
|
629
921
|
this.keepAlive = typeof (value = agent?.keep_alive) === 'boolean' ? value : KEEP_ALIVE;
|
|
630
922
|
this.acceptEncoding = typeof (value = use?.accept_encoding) === 'boolean' ? value : ACCEPT_ENCODING;
|
|
631
923
|
if ((value = (0, util_1.asInt)(use?.http_version)) === 1 || value === 2) {
|
|
632
|
-
this
|
|
924
|
+
this.#httpVersion = value;
|
|
633
925
|
}
|
|
634
|
-
this
|
|
926
|
+
this.#ipVersion = (value = (0, util_1.asInt)(data.dns?.family)) && (value === 4 || value === 6) ? value : 0;
|
|
635
927
|
if ((value = (0, util_1.fromSeconds)(agent?.timeout)) >= 0) {
|
|
636
|
-
this
|
|
928
|
+
this.#agentTimeout = value;
|
|
637
929
|
}
|
|
638
930
|
else {
|
|
639
|
-
this
|
|
931
|
+
this.#agentTimeout = AGENT_TIMEOUT;
|
|
640
932
|
value = undefined;
|
|
641
933
|
}
|
|
642
934
|
const proxy = getProxySettings(data, value);
|
|
@@ -644,10 +936,10 @@ class Request extends module_1 {
|
|
|
644
936
|
this.proxy = proxy;
|
|
645
937
|
}
|
|
646
938
|
if ((0, types_1.isObject)(headers)) {
|
|
647
|
-
setOutgoingHeaders(this
|
|
939
|
+
setOutgoingHeaders(this.#headers = {}, headers);
|
|
648
940
|
}
|
|
649
941
|
if ((0, types_1.isObject)(certs)) {
|
|
650
|
-
this
|
|
942
|
+
this.#certs = validateCerts(certs);
|
|
651
943
|
}
|
|
652
944
|
if ((0, types_1.isObject)(connect)) {
|
|
653
945
|
this.apply({ client: {
|
|
@@ -668,21 +960,21 @@ class Request extends module_1 {
|
|
|
668
960
|
this.readTimeout = READ_TIMEOUT;
|
|
669
961
|
this.keepAlive = KEEP_ALIVE;
|
|
670
962
|
this.acceptEncoding = ACCEPT_ENCODING;
|
|
671
|
-
this
|
|
672
|
-
this
|
|
963
|
+
this.#agentTimeout = AGENT_TIMEOUT;
|
|
964
|
+
this.#ipVersion = DNS.FAMILY;
|
|
673
965
|
}
|
|
674
966
|
this.module = data;
|
|
675
967
|
}
|
|
676
968
|
flushLog() {
|
|
677
969
|
const log = this._logQueued;
|
|
678
|
-
if (this
|
|
970
|
+
if (this.#singleton) {
|
|
679
971
|
log.length = 0;
|
|
680
972
|
}
|
|
681
973
|
else {
|
|
682
974
|
if (log.length > 0 && !this.host?.aborted) {
|
|
683
975
|
const output = [];
|
|
684
976
|
let count = 0;
|
|
685
|
-
this
|
|
977
|
+
this.#connectHttp.forEach((protocol, index) => {
|
|
686
978
|
const title = 'HTTP' + (index + 1);
|
|
687
979
|
for (const origin in protocol) {
|
|
688
980
|
const value = protocol[origin];
|
|
@@ -731,22 +1023,22 @@ class Request extends module_1 {
|
|
|
731
1023
|
}
|
|
732
1024
|
super.flushLog();
|
|
733
1025
|
}
|
|
734
|
-
this
|
|
1026
|
+
this.#connectHttp = [{}, {}];
|
|
735
1027
|
}
|
|
736
1028
|
detach(singleton) {
|
|
737
1029
|
if (typeof singleton === 'boolean') {
|
|
738
|
-
this
|
|
1030
|
+
this.#singleton = singleton;
|
|
739
1031
|
}
|
|
740
1032
|
if (singleton !== false) {
|
|
741
1033
|
super.detach();
|
|
742
1034
|
}
|
|
743
1035
|
}
|
|
744
1036
|
abort(reason) {
|
|
745
|
-
for (const item of this
|
|
1037
|
+
for (const item of this.#downloading) {
|
|
746
1038
|
item.abort(reason);
|
|
747
1039
|
}
|
|
748
1040
|
this.close();
|
|
749
|
-
if (!this
|
|
1041
|
+
if (!this.#singleton) {
|
|
750
1042
|
super.abort(reason);
|
|
751
1043
|
}
|
|
752
1044
|
}
|
|
@@ -754,7 +1046,7 @@ class Request extends module_1 {
|
|
|
754
1046
|
if (config) {
|
|
755
1047
|
const { headers, httpVersion, ipVersion, readTimeout } = config;
|
|
756
1048
|
if ((0, types_1.isObject)(headers)) {
|
|
757
|
-
setOutgoingHeaders(this
|
|
1049
|
+
setOutgoingHeaders(this.#headers ||= {}, headers);
|
|
758
1050
|
}
|
|
759
1051
|
if (httpVersion !== undefined) {
|
|
760
1052
|
this.httpVersion = httpVersion;
|
|
@@ -841,10 +1133,10 @@ class Request extends module_1 {
|
|
|
841
1133
|
}
|
|
842
1134
|
break;
|
|
843
1135
|
}
|
|
844
|
-
setDnsCache(hostname, this[
|
|
1136
|
+
setDnsCache(hostname, this.#connectDns[hostname] = [{ address, family }], timeout);
|
|
845
1137
|
}
|
|
846
1138
|
lookupDns(hostname) {
|
|
847
|
-
const resolved = this[
|
|
1139
|
+
const resolved = this.#connectDns[hostname] || DNS.CACHE[hostname];
|
|
848
1140
|
if (resolved) {
|
|
849
1141
|
return (...args) => {
|
|
850
1142
|
if (SUPPORTED_NODE20) {
|
|
@@ -855,13 +1147,29 @@ class Request extends module_1 {
|
|
|
855
1147
|
}
|
|
856
1148
|
};
|
|
857
1149
|
}
|
|
858
|
-
const pending = this[
|
|
1150
|
+
const pending = this.#pendingDns[hostname] ||= [];
|
|
1151
|
+
const successDns = (value, connected) => {
|
|
1152
|
+
this.#connectDns[value] = connected;
|
|
1153
|
+
setDnsCache(value, connected, null);
|
|
1154
|
+
if (SUPPORTED_NODE20) {
|
|
1155
|
+
for (const cb of pending) {
|
|
1156
|
+
cb(null, connected);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
else {
|
|
1160
|
+
const { address, family } = connected[0];
|
|
1161
|
+
for (const cb of pending) {
|
|
1162
|
+
cb(null, address, family);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
pending.length = 0;
|
|
1166
|
+
};
|
|
859
1167
|
return (value, options, callback) => {
|
|
860
1168
|
if (pending.push(callback) === 1) {
|
|
861
1169
|
let ipVersion = this.ipVersion;
|
|
862
1170
|
dns.lookup(value, configureDns(ipVersion, options), (err, address, family) => {
|
|
863
1171
|
if (!err) {
|
|
864
|
-
successDns(
|
|
1172
|
+
successDns(value, typeof address === 'string' ? [{ address, family }] : address);
|
|
865
1173
|
return;
|
|
866
1174
|
}
|
|
867
1175
|
switch (err.code) {
|
|
@@ -886,7 +1194,7 @@ class Request extends module_1 {
|
|
|
886
1194
|
}
|
|
887
1195
|
dns.lookup(value, configureDns(ipVersion, options), (err, address, family) => {
|
|
888
1196
|
if (!err) {
|
|
889
|
-
successDns(
|
|
1197
|
+
successDns(value, typeof address === 'string' ? [{ address, family }] : address);
|
|
890
1198
|
}
|
|
891
1199
|
else {
|
|
892
1200
|
failedDns(err, pending);
|
|
@@ -932,7 +1240,7 @@ class Request extends module_1 {
|
|
|
932
1240
|
globUrl = '*';
|
|
933
1241
|
}
|
|
934
1242
|
if ((0, types_1.isString)(globUrl) && typeof callback === 'function') {
|
|
935
|
-
const on = this
|
|
1243
|
+
const on = this.#statusOn ||= new Map();
|
|
936
1244
|
for (const item of !Array.isArray(code) ? [code] : code) {
|
|
937
1245
|
let status = on.get(item);
|
|
938
1246
|
if (!status) {
|
|
@@ -948,7 +1256,7 @@ class Request extends module_1 {
|
|
|
948
1256
|
globUrl = '*';
|
|
949
1257
|
}
|
|
950
1258
|
if ((0, types_1.isString)(globUrl) && typeof callback === 'function') {
|
|
951
|
-
const on = this
|
|
1259
|
+
const on = this.#headersOn ||= new Map();
|
|
952
1260
|
for (const item of !Array.isArray(name) ? [name] : name) {
|
|
953
1261
|
let headers = on.get(item);
|
|
954
1262
|
if (!headers) {
|
|
@@ -959,86 +1267,31 @@ class Request extends module_1 {
|
|
|
959
1267
|
}
|
|
960
1268
|
}
|
|
961
1269
|
headersOf(uri) {
|
|
962
|
-
const headers = this
|
|
1270
|
+
const headers = this.#headers;
|
|
963
1271
|
return headers && getBaseHeaders(uri, headers) || (this.host ? getBaseHeaders(uri, HTTP.HEADERS) : undefined);
|
|
964
1272
|
}
|
|
965
|
-
async aria2c(uri, options) {
|
|
1273
|
+
async aria2c(uri, options = {}) {
|
|
966
1274
|
if (!ARIA2.BIN) {
|
|
967
1275
|
return Promise.reject((0, types_1.errorMessage)("aria2", "Binary not found"));
|
|
968
1276
|
}
|
|
969
|
-
if (typeof uri === 'string' && module_1.isURL(uri)) {
|
|
970
|
-
uri = new URL(uri);
|
|
971
|
-
}
|
|
972
1277
|
let pathname, headers, binOpts, signal, silent;
|
|
973
|
-
if (options) {
|
|
974
|
-
|
|
975
|
-
pathname = options;
|
|
976
|
-
}
|
|
977
|
-
else {
|
|
978
|
-
({ pathname, binOpts, signal, silent } = options);
|
|
979
|
-
headers = (0, util_1.parseOutgoingHeaders)(options.headers);
|
|
980
|
-
if ((0, types_1.isArray)(binOpts)) {
|
|
981
|
-
let next = false;
|
|
982
|
-
binOpts = binOpts.filter(opt => !((0, types_1.isString)(opt) && /^-[a-z].*$/i.test(opt.trim()))).map((opt) => {
|
|
983
|
-
if (next) {
|
|
984
|
-
if (!module_1.asString(opt).startsWith('--')) {
|
|
985
|
-
return [];
|
|
986
|
-
}
|
|
987
|
-
next = false;
|
|
988
|
-
}
|
|
989
|
-
switch (typeof opt) {
|
|
990
|
-
case 'string': {
|
|
991
|
-
const value = opt.trim();
|
|
992
|
-
if (value.startsWith('--')) {
|
|
993
|
-
const match = /^(--[a-z]+[a-z0-9-]*)(=)?\s*(.*)$/s.exec(value);
|
|
994
|
-
if (match) {
|
|
995
|
-
switch (match[1]) {
|
|
996
|
-
case '--daemon':
|
|
997
|
-
case '--version':
|
|
998
|
-
case '--help':
|
|
999
|
-
break;
|
|
1000
|
-
case '--input-file':
|
|
1001
|
-
if (!match[2]) {
|
|
1002
|
-
next = true;
|
|
1003
|
-
}
|
|
1004
|
-
break;
|
|
1005
|
-
default:
|
|
1006
|
-
return match[3] ? [match[1], module_1.sanitizeArgs(match[3])] : [match[1]];
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
else if (value) {
|
|
1011
|
-
return [module_1.sanitizeArgs(value)];
|
|
1012
|
-
}
|
|
1013
|
-
break;
|
|
1014
|
-
}
|
|
1015
|
-
case 'number':
|
|
1016
|
-
case 'boolean':
|
|
1017
|
-
return [opt.toString()];
|
|
1018
|
-
default:
|
|
1019
|
-
if ((0, types_1.isArray)(opt)) {
|
|
1020
|
-
return opt.filter(item => (0, types_1.isString)(item)).map(item => module_1.sanitizeArgs(item));
|
|
1021
|
-
}
|
|
1022
|
-
break;
|
|
1023
|
-
}
|
|
1024
|
-
return [];
|
|
1025
|
-
}).flat();
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1278
|
+
if ((0, types_1.isString)(options)) {
|
|
1279
|
+
pathname = options;
|
|
1028
1280
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
}
|
|
1033
|
-
pathname = process.cwd();
|
|
1281
|
+
else {
|
|
1282
|
+
({ signal, silent } = options);
|
|
1283
|
+
[pathname, headers, binOpts] = parseBinOpts(this, options, ['--daemon'], ['--input-file']);
|
|
1034
1284
|
}
|
|
1035
|
-
|
|
1036
|
-
|
|
1285
|
+
try {
|
|
1286
|
+
if (typeof uri === 'string' && module_1.isURL(uri)) {
|
|
1287
|
+
uri = new URL(uri);
|
|
1288
|
+
}
|
|
1289
|
+
pathname = checkBinTarget(this, "aria2", uri, pathname, 'aria2', binOpts);
|
|
1037
1290
|
}
|
|
1038
|
-
|
|
1039
|
-
return Promise.reject(
|
|
1291
|
+
catch (err) {
|
|
1292
|
+
return Promise.reject(err);
|
|
1040
1293
|
}
|
|
1041
|
-
silent ??= this
|
|
1294
|
+
silent ??= this.#singleton;
|
|
1042
1295
|
return new Promise((resolve, reject) => {
|
|
1043
1296
|
let protocol, origin, username, password;
|
|
1044
1297
|
if (uri instanceof URL) {
|
|
@@ -1059,31 +1312,7 @@ class Request extends module_1 {
|
|
|
1059
1312
|
'--stderr=false',
|
|
1060
1313
|
'--log=""'
|
|
1061
1314
|
];
|
|
1062
|
-
|
|
1063
|
-
if ((0, types_1.isArray)(binOpts)) {
|
|
1064
|
-
for (let i = 0; i < binOpts.length; ++i) {
|
|
1065
|
-
const leading = binOpts[i] + '=';
|
|
1066
|
-
for (const arg of init) {
|
|
1067
|
-
if (arg.startsWith(leading)) {
|
|
1068
|
-
const items = [];
|
|
1069
|
-
for (let k = i + 1; k < binOpts.length; ++k) {
|
|
1070
|
-
const next = binOpts[k];
|
|
1071
|
-
if (next.startsWith('--')) {
|
|
1072
|
-
break;
|
|
1073
|
-
}
|
|
1074
|
-
items.push(next);
|
|
1075
|
-
}
|
|
1076
|
-
const l = items.length + 1;
|
|
1077
|
-
binOpts.splice(i, l);
|
|
1078
|
-
i += l;
|
|
1079
|
-
break;
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
else {
|
|
1085
|
-
binOpts = undefined;
|
|
1086
|
-
}
|
|
1315
|
+
checkBinOpts(init, binOpts);
|
|
1087
1316
|
const { connectTimeout, timeout, retryWait, retryLimit } = this._config;
|
|
1088
1317
|
const opts = [
|
|
1089
1318
|
'--log-level=warn',
|
|
@@ -1093,6 +1322,7 @@ class Request extends module_1 {
|
|
|
1093
1322
|
'--file-allocation=' + ARIA2.FILE_ALLOCATION,
|
|
1094
1323
|
'--max-tries=' + (retryLimit + 1)
|
|
1095
1324
|
];
|
|
1325
|
+
let args = [];
|
|
1096
1326
|
if (ARIA2.MAX_CONCURRENT_DOWNLOADS) {
|
|
1097
1327
|
opts.push('--max-concurrent-downloads=' + ARIA2.MAX_CONCURRENT_DOWNLOADS);
|
|
1098
1328
|
}
|
|
@@ -1126,6 +1356,10 @@ class Request extends module_1 {
|
|
|
1126
1356
|
if (retryWait > 0) {
|
|
1127
1357
|
opts.push('--retry-wait=' + Math.min(Math.ceil(retryWait / 1000), 600));
|
|
1128
1358
|
}
|
|
1359
|
+
if (ARIA2.NO_PROXY) {
|
|
1360
|
+
opts.push(`--no-proxy="${ARIA2.NO_PROXY}"`);
|
|
1361
|
+
}
|
|
1362
|
+
let proxy;
|
|
1129
1363
|
if (protocol) {
|
|
1130
1364
|
if (this.agentTimeout === 0) {
|
|
1131
1365
|
opts.push('--enable-http-keep-alive=false');
|
|
@@ -1135,16 +1369,10 @@ class Request extends module_1 {
|
|
|
1135
1369
|
if (baseHeaders) {
|
|
1136
1370
|
headers = headers ? { ...baseHeaders, ...headers } : baseHeaders;
|
|
1137
1371
|
}
|
|
1138
|
-
|
|
1139
|
-
let items = headers[name];
|
|
1140
|
-
if (!Array.isArray(items)) {
|
|
1141
|
-
items = [items.toString()];
|
|
1142
|
-
}
|
|
1143
|
-
args.push(...items.map(value => `--header="${name}: ${escapeShellQuote(value)}"`));
|
|
1144
|
-
}
|
|
1372
|
+
setBinHeaders(args, headers);
|
|
1145
1373
|
}
|
|
1146
1374
|
if (origin) {
|
|
1147
|
-
const secure = this
|
|
1375
|
+
const secure = this.#certs?.[1][origin] || this.host && TLS.FILE[origin];
|
|
1148
1376
|
if (secure) {
|
|
1149
1377
|
if (secure.ca && ignoreOpt(binOpts, '--ca-certificate')) {
|
|
1150
1378
|
args.push(`--ca-certificate="${escapeShellQuote(secure.ca)}"`);
|
|
@@ -1157,7 +1385,7 @@ class Request extends module_1 {
|
|
|
1157
1385
|
}
|
|
1158
1386
|
}
|
|
1159
1387
|
}
|
|
1160
|
-
switch (protocol =
|
|
1388
|
+
switch (protocol = trimCharEnd(protocol)) {
|
|
1161
1389
|
case 'http':
|
|
1162
1390
|
case 'https':
|
|
1163
1391
|
if (ignoreOpt(binOpts, '--http-no-cache')) {
|
|
@@ -1173,54 +1401,33 @@ class Request extends module_1 {
|
|
|
1173
1401
|
args.push(`--${prefix}-passwd="${escapeShellQuote(decodeURIComponent(password))}"`);
|
|
1174
1402
|
}
|
|
1175
1403
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
({ origin, username, password } = proxy.host);
|
|
1179
|
-
if (ignoreOpt(binOpts, `--${protocol}-proxy`)) {
|
|
1180
|
-
args.push(`--${protocol}-proxy="${origin}"`);
|
|
1181
|
-
}
|
|
1182
|
-
if (username) {
|
|
1183
|
-
args.push(`--${protocol}-proxy-user="${escapeShellQuote(decodeURIComponent(username))}"`);
|
|
1184
|
-
}
|
|
1185
|
-
if (password) {
|
|
1186
|
-
args.push(`--${protocol}-proxy-passwd="${escapeShellQuote(decodeURIComponent(password))}"`);
|
|
1187
|
-
}
|
|
1404
|
+
if (ignoreOpt(binOpts, `--${protocol}-proxy`, `--${protocol}-proxy-user`, `--${protocol}-proxy-passwd`)) {
|
|
1405
|
+
proxy = this.proxyOf(uri) || ARIA2.PROXY[protocol];
|
|
1188
1406
|
}
|
|
1189
1407
|
break;
|
|
1190
1408
|
}
|
|
1191
1409
|
}
|
|
1192
1410
|
}
|
|
1193
|
-
if (
|
|
1194
|
-
|
|
1195
|
-
if (leading.startsWith('-')) {
|
|
1196
|
-
const pattern = new RegExp(`^${leading}(?:=|$)`);
|
|
1197
|
-
for (let i = 0; i < opts.length; ++i) {
|
|
1198
|
-
if (pattern.test(opts[i])) {
|
|
1199
|
-
opts.splice(i--, i);
|
|
1200
|
-
break;
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
args = binOpts.concat(args);
|
|
1411
|
+
if (proxy) {
|
|
1412
|
+
addAria2Proxy(args, protocol, proxy.host);
|
|
1206
1413
|
}
|
|
1207
|
-
if (
|
|
1208
|
-
|
|
1209
|
-
this.formatMessage(32768, 'ARIA2', ARIA2.BIN, args.join(' '), { ...module_1.LOG_STYLE_WARN });
|
|
1210
|
-
}
|
|
1211
|
-
else {
|
|
1212
|
-
this.addLog(types_1.STATUS_TYPE.INFO, path.basename(ARIA2.BIN) + ' ' + args.join(' '), "aria2");
|
|
1213
|
-
}
|
|
1414
|
+
else if (ARIA2.PROXY.all) {
|
|
1415
|
+
addAria2Proxy(opts, 'all', ARIA2.PROXY.all.host);
|
|
1214
1416
|
}
|
|
1417
|
+
args = finalizeBinArgs(this, "aria2", ARIA2.BIN, args, opts, binOpts);
|
|
1215
1418
|
opts.push(`"${escapeShellQuote(uri)}"`);
|
|
1216
1419
|
args = args.concat(init, opts);
|
|
1217
1420
|
const startTime = Date.now();
|
|
1218
1421
|
let out = '', message = '';
|
|
1422
|
+
const commitLog = (type, msg) => {
|
|
1423
|
+
const timeStamp = Date.now();
|
|
1424
|
+
this.addLog(type, msg, { timeStamp, duration: timeStamp - startTime, from: "aria2", source: uri });
|
|
1425
|
+
};
|
|
1219
1426
|
const errorResponse = (pid, err) => {
|
|
1220
1427
|
closeTorrent(pid);
|
|
1221
1428
|
reject(err);
|
|
1222
1429
|
};
|
|
1223
|
-
const { pid, stdout, stderr } = child_process.spawn(
|
|
1430
|
+
const { pid, stdout, stderr } = child_process.spawn((0, types_1.sanitizeCmd)(ARIA2.BIN), args, { cwd: pathname, shell: true, signal: signal || this.signal, uid: ARIA2.EXEC_UID, gid: ARIA2.EXEC_GID })
|
|
1224
1431
|
.on('exit', code => {
|
|
1225
1432
|
closeTorrent(pid);
|
|
1226
1433
|
if (this.aborted) {
|
|
@@ -1231,7 +1438,6 @@ class Request extends module_1 {
|
|
|
1231
1438
|
reject((0, types_1.errorValue)(message || "Unknown", 'Exit status: ' + code));
|
|
1232
1439
|
return;
|
|
1233
1440
|
}
|
|
1234
|
-
const currentTime = Date.now();
|
|
1235
1441
|
const result = [];
|
|
1236
1442
|
let messageUnit;
|
|
1237
1443
|
for (const match of out.matchAll(/\|(OK|ERR|INPR)\s*\|\s*([^|]+)\|\s*(\d+)\|([^\n]+)/g)) {
|
|
@@ -1250,7 +1456,7 @@ class Request extends module_1 {
|
|
|
1250
1456
|
}
|
|
1251
1457
|
case 'ERR':
|
|
1252
1458
|
fs.unlink(file, err => {
|
|
1253
|
-
if (err && !silent && !this
|
|
1459
|
+
if (err && !silent && !this.#singleton) {
|
|
1254
1460
|
this.writeFail(["Unable to delete file", path.basename(file)], err, { type: 32, fatal: false });
|
|
1255
1461
|
}
|
|
1256
1462
|
});
|
|
@@ -1262,18 +1468,18 @@ class Request extends module_1 {
|
|
|
1262
1468
|
if (!silent && LOG_HTTP && LOG_TIMEPROCESS) {
|
|
1263
1469
|
this.writeTimeProcess("aria2", uri, startTime, { type: 1024, queue: true, messageUnit, messageUnitMinWidth: 9, bypassLog: true });
|
|
1264
1470
|
}
|
|
1265
|
-
|
|
1471
|
+
commitLog(types_1.STATUS_TYPE.INFO, out);
|
|
1266
1472
|
}
|
|
1267
1473
|
else {
|
|
1268
|
-
|
|
1474
|
+
commitLog(types_1.STATUS_TYPE.ERROR, "No files were successfully downloaded");
|
|
1269
1475
|
}
|
|
1270
1476
|
resolve(result);
|
|
1271
1477
|
})
|
|
1272
1478
|
.on('error', err => {
|
|
1273
1479
|
errorResponse(pid, err);
|
|
1274
1480
|
});
|
|
1275
|
-
stdout.setEncoding('
|
|
1276
|
-
stderr.setEncoding('
|
|
1481
|
+
stdout.setEncoding('utf8').on('data', (value) => out += value);
|
|
1482
|
+
stderr.setEncoding('utf8').on('data', (value) => message += value);
|
|
1277
1483
|
if (pid !== undefined && module_1.isFile(uri, 'torrent')) {
|
|
1278
1484
|
if (!ARIA2.PID_TIMER) {
|
|
1279
1485
|
ARIA2.PID_TIMER = setInterval(() => {
|
|
@@ -1320,6 +1526,231 @@ class Request extends module_1 {
|
|
|
1320
1526
|
}
|
|
1321
1527
|
});
|
|
1322
1528
|
}
|
|
1529
|
+
async rclone(uri, options = {}) {
|
|
1530
|
+
if (!RCLONE.BIN) {
|
|
1531
|
+
return Promise.reject((0, types_1.errorMessage)("rclone", "Binary not found"));
|
|
1532
|
+
}
|
|
1533
|
+
let pathname, headers, binOpts, silent;
|
|
1534
|
+
if ((0, types_1.isString)(options)) {
|
|
1535
|
+
pathname = options;
|
|
1536
|
+
options = {};
|
|
1537
|
+
}
|
|
1538
|
+
else {
|
|
1539
|
+
silent = options.silent;
|
|
1540
|
+
[pathname, headers, binOpts] = parseBinOpts(this, options, ['--interactive', '--dry-run'], ['--partial-suffix', '--verbose']);
|
|
1541
|
+
}
|
|
1542
|
+
const command = options.command || 'copy';
|
|
1543
|
+
let source;
|
|
1544
|
+
switch (command) {
|
|
1545
|
+
case 'copy':
|
|
1546
|
+
case 'copyto':
|
|
1547
|
+
if (module_1.isURL(source = uri.replace(/^rclone:\?/i, ''))) {
|
|
1548
|
+
return Promise.reject((0, types_1.errorMessage)("rclone", "Unsupported protocol", uri));
|
|
1549
|
+
}
|
|
1550
|
+
break;
|
|
1551
|
+
case 'copyurl':
|
|
1552
|
+
if (!module_1.isURL(source = uri)) {
|
|
1553
|
+
return Promise.reject((0, types_1.errorMessage)("rclone", "Unsupported protocol", uri));
|
|
1554
|
+
}
|
|
1555
|
+
break;
|
|
1556
|
+
default:
|
|
1557
|
+
return Promise.reject((0, types_1.errorMessage)("rclone", "Invalid command", command || uri));
|
|
1558
|
+
}
|
|
1559
|
+
try {
|
|
1560
|
+
pathname = checkBinTarget(this, "rclone", uri, pathname, command, binOpts);
|
|
1561
|
+
}
|
|
1562
|
+
catch (err) {
|
|
1563
|
+
return Promise.reject(err);
|
|
1564
|
+
}
|
|
1565
|
+
silent ??= this.#singleton;
|
|
1566
|
+
return new Promise((resolve, reject) => {
|
|
1567
|
+
const init = [
|
|
1568
|
+
'--links=false',
|
|
1569
|
+
'--delete-excluded=false',
|
|
1570
|
+
'--interactive=false',
|
|
1571
|
+
'--dry-run=false',
|
|
1572
|
+
'--log-level=INFO',
|
|
1573
|
+
'--use-json-log'
|
|
1574
|
+
];
|
|
1575
|
+
const opts = [];
|
|
1576
|
+
let args = [];
|
|
1577
|
+
if (typeof options.update === 'boolean') {
|
|
1578
|
+
init.push('--update=' + options.update.toString());
|
|
1579
|
+
checkBinOpts(init, binOpts);
|
|
1580
|
+
}
|
|
1581
|
+
else {
|
|
1582
|
+
checkBinOpts(init, binOpts);
|
|
1583
|
+
if (RCLONE.UPDATE) {
|
|
1584
|
+
opts.push('--update');
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
if (RCLONE.CHECK_FIRST) {
|
|
1588
|
+
opts.push('--check-first');
|
|
1589
|
+
}
|
|
1590
|
+
if (RCLONE.CHECKSUM) {
|
|
1591
|
+
opts.push('--checksum');
|
|
1592
|
+
}
|
|
1593
|
+
if (RCLONE.CUTOFF_MODE) {
|
|
1594
|
+
opts.push('--cutoff-mode=' + RCLONE.CUTOFF_MODE);
|
|
1595
|
+
}
|
|
1596
|
+
if (RCLONE.IGNORE_CASE_SYNC) {
|
|
1597
|
+
opts.push('--ignore-case-sync');
|
|
1598
|
+
}
|
|
1599
|
+
if (RCLONE.IGNORE_CHECKSUM) {
|
|
1600
|
+
opts.push('--ignore-checksum');
|
|
1601
|
+
}
|
|
1602
|
+
if (RCLONE.IGNORE_EXISTING) {
|
|
1603
|
+
opts.push('--ignore-existing');
|
|
1604
|
+
}
|
|
1605
|
+
if (RCLONE.IGNORE_SIZE) {
|
|
1606
|
+
opts.push('--ignore-size');
|
|
1607
|
+
}
|
|
1608
|
+
if (RCLONE.IGNORE_TIMES) {
|
|
1609
|
+
opts.push('--ignore-times');
|
|
1610
|
+
}
|
|
1611
|
+
if (RCLONE.IMMUTABLE) {
|
|
1612
|
+
opts.push('--immutable');
|
|
1613
|
+
}
|
|
1614
|
+
if (RCLONE.INPLACE) {
|
|
1615
|
+
opts.push('--inplace');
|
|
1616
|
+
}
|
|
1617
|
+
if (RCLONE.MAX_BACKLOG > 0) {
|
|
1618
|
+
opts.push('--max-backlog=' + RCLONE.MAX_BACKLOG);
|
|
1619
|
+
}
|
|
1620
|
+
if (RCLONE.MAX_DURATION) {
|
|
1621
|
+
opts.push('--max-duration=' + RCLONE.MAX_DURATION);
|
|
1622
|
+
}
|
|
1623
|
+
if (RCLONE.MAX_TRANSFER) {
|
|
1624
|
+
opts.push('--max-transfer=' + RCLONE.MAX_TRANSFER);
|
|
1625
|
+
}
|
|
1626
|
+
if (RCLONE.METADATA) {
|
|
1627
|
+
opts.push('--metadata');
|
|
1628
|
+
}
|
|
1629
|
+
if (RCLONE.MODIFY_WINDOW) {
|
|
1630
|
+
opts.push('--modify-window=' + RCLONE.MODIFY_WINDOW);
|
|
1631
|
+
}
|
|
1632
|
+
if (RCLONE.MULTI_THREAD_CHUNK_SIZE) {
|
|
1633
|
+
opts.push('--multi-thread-chunk-size=' + RCLONE.MULTI_THREAD_CHUNK_SIZE);
|
|
1634
|
+
}
|
|
1635
|
+
if (RCLONE.MULTI_THREAD_CUTOFF) {
|
|
1636
|
+
opts.push('--multi-thread-chunk-size=' + RCLONE.MULTI_THREAD_CUTOFF);
|
|
1637
|
+
}
|
|
1638
|
+
if (RCLONE.MULTI_THREAD_STREAMS) {
|
|
1639
|
+
opts.push('--multi-thread-streams=' + RCLONE.MULTI_THREAD_STREAMS);
|
|
1640
|
+
}
|
|
1641
|
+
if (RCLONE.MULTI_THREAD_WRITE_BUFFER_SIZE) {
|
|
1642
|
+
opts.push('--multi-thread-buffer-size=' + RCLONE.MULTI_THREAD_WRITE_BUFFER_SIZE);
|
|
1643
|
+
}
|
|
1644
|
+
if (RCLONE.NO_CHECK_DEST) {
|
|
1645
|
+
opts.push('--no-check-dest');
|
|
1646
|
+
}
|
|
1647
|
+
if (RCLONE.NO_TRAVERSE) {
|
|
1648
|
+
opts.push('--no-traverse');
|
|
1649
|
+
}
|
|
1650
|
+
if (RCLONE.NO_UPDATE_DIR_MODTIME) {
|
|
1651
|
+
opts.push('--no-update-dir-modtime');
|
|
1652
|
+
}
|
|
1653
|
+
if (RCLONE.REFRESH_TIMES) {
|
|
1654
|
+
opts.push('--refresh-times');
|
|
1655
|
+
}
|
|
1656
|
+
if (RCLONE.SIZE_ONLY) {
|
|
1657
|
+
opts.push('--size-only');
|
|
1658
|
+
}
|
|
1659
|
+
if (RCLONE.FAST_LIST) {
|
|
1660
|
+
opts.push('--fast-list');
|
|
1661
|
+
}
|
|
1662
|
+
if (RCLONE.BIND) {
|
|
1663
|
+
opts.push('--bind=' + RCLONE.BIND);
|
|
1664
|
+
}
|
|
1665
|
+
if (RCLONE.CONTIMEOUT) {
|
|
1666
|
+
opts.push('--contimeout=' + RCLONE.CONTIMEOUT);
|
|
1667
|
+
}
|
|
1668
|
+
else if (this._config.connectTimeout > 0) {
|
|
1669
|
+
opts.push(`--contimeout=${this._config.connectTimeout}ms`);
|
|
1670
|
+
}
|
|
1671
|
+
if (RCLONE.DISABLE_HTTP2) {
|
|
1672
|
+
opts.push('--disable-http2');
|
|
1673
|
+
}
|
|
1674
|
+
if (RCLONE.TIMEOUT) {
|
|
1675
|
+
opts.push('--timeout=' + RCLONE.TIMEOUT);
|
|
1676
|
+
}
|
|
1677
|
+
else if (this._config.timeout > 0) {
|
|
1678
|
+
opts.push(`--timeout=${this._config.timeout}ms`);
|
|
1679
|
+
}
|
|
1680
|
+
if (RCLONE.CONFIG) {
|
|
1681
|
+
opts.push(`--config="${escapeShellQuote(RCLONE.CONFIG)}"`);
|
|
1682
|
+
}
|
|
1683
|
+
setBinHeaders(args, headers);
|
|
1684
|
+
const cwd = module_1.isDir(pathname) ? pathname : path.dirname(pathname);
|
|
1685
|
+
const cmd = [source, pathname];
|
|
1686
|
+
args = finalizeBinArgs(this, "rclone", RCLONE.BIN, args, opts, binOpts, cmd).concat(init, opts);
|
|
1687
|
+
args.push(...cmd.map(value => (0, types_1.sanitizeCmd)(value)));
|
|
1688
|
+
args.unshift(command);
|
|
1689
|
+
const startTime = Date.now();
|
|
1690
|
+
const out = [];
|
|
1691
|
+
const commitLog = (type, msg) => {
|
|
1692
|
+
const timeStamp = Date.now();
|
|
1693
|
+
this.addLog(type, msg, { timeStamp, duration: timeStamp - startTime, from: "rclone", source });
|
|
1694
|
+
};
|
|
1695
|
+
const parseOutput = (value) => {
|
|
1696
|
+
try {
|
|
1697
|
+
const data = JSON.parse(value);
|
|
1698
|
+
if ((0, types_1.isPlainObject)(data)) {
|
|
1699
|
+
switch (data.level) {
|
|
1700
|
+
case 'info':
|
|
1701
|
+
if (data.size > 0 && (0, types_1.isString)(data.object)) {
|
|
1702
|
+
out.push(data);
|
|
1703
|
+
}
|
|
1704
|
+
else if ((0, types_1.isPlainObject)(data.stats)) {
|
|
1705
|
+
if (data.stats.fatalError) {
|
|
1706
|
+
commitLog(types_1.STATUS_TYPE.ERROR, data.msg);
|
|
1707
|
+
}
|
|
1708
|
+
else {
|
|
1709
|
+
if (command === 'copyurl' && data.stats.totalTransfers > 0) {
|
|
1710
|
+
data.object = module_1.isPath(pathname, true) ? pathname : '';
|
|
1711
|
+
out.push(data);
|
|
1712
|
+
}
|
|
1713
|
+
commitLog(types_1.STATUS_TYPE.INFO, data.msg);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
break;
|
|
1717
|
+
case 'error':
|
|
1718
|
+
commitLog(types_1.STATUS_TYPE.ERROR, data.msg);
|
|
1719
|
+
break;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
catch (err) {
|
|
1724
|
+
commitLog(types_1.STATUS_TYPE.ERROR, err);
|
|
1725
|
+
}
|
|
1726
|
+
};
|
|
1727
|
+
const { stdout, stderr } = child_process.spawn((0, types_1.sanitizeCmd)(RCLONE.BIN), args, { cwd, shell: true, signal: this.signal, uid: RCLONE.EXEC_UID, gid: RCLONE.EXEC_GID })
|
|
1728
|
+
.on('exit', code => {
|
|
1729
|
+
if (options.signal || this.aborted) {
|
|
1730
|
+
reject((0, types_1.createAbortError)());
|
|
1731
|
+
return;
|
|
1732
|
+
}
|
|
1733
|
+
if (code) {
|
|
1734
|
+
reject((0, types_1.errorValue)("Unknown", 'Exit status: ' + code));
|
|
1735
|
+
return;
|
|
1736
|
+
}
|
|
1737
|
+
if (out.length > 0 && !silent && LOG_HTTP && LOG_TIMEPROCESS) {
|
|
1738
|
+
this.writeTimeProcess("rclone", source, startTime, { type: 1024, queue: true, bypassLog: true });
|
|
1739
|
+
}
|
|
1740
|
+
const result = out.map(item => command === 'copyurl' ? item.object : path.join(cwd, item.object));
|
|
1741
|
+
if (out.length > 0) {
|
|
1742
|
+
commitLog(types_1.STATUS_TYPE.INFO, result);
|
|
1743
|
+
}
|
|
1744
|
+
else {
|
|
1745
|
+
commitLog(types_1.STATUS_TYPE.ERROR, "No files were successfully downloaded");
|
|
1746
|
+
}
|
|
1747
|
+
resolve(result);
|
|
1748
|
+
})
|
|
1749
|
+
.on('error', reject);
|
|
1750
|
+
stdout.setEncoding('utf8').on('data', parseOutput);
|
|
1751
|
+
stderr.setEncoding('utf8').on('data', parseOutput);
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1323
1754
|
async json(uri, options = {}) {
|
|
1324
1755
|
options.format = 'json';
|
|
1325
1756
|
return this.get(uri, options);
|
|
@@ -1329,7 +1760,7 @@ class Request extends module_1 {
|
|
|
1329
1760
|
return this.get(uri, options);
|
|
1330
1761
|
}
|
|
1331
1762
|
opts(url, options) {
|
|
1332
|
-
const base = this
|
|
1763
|
+
const base = this.#baseUrl;
|
|
1333
1764
|
if (base) {
|
|
1334
1765
|
if (typeof url === 'string') {
|
|
1335
1766
|
url = new URL(url, base[0]);
|
|
@@ -1346,7 +1777,7 @@ class Request extends module_1 {
|
|
|
1346
1777
|
host = HTTP.HOST[url.origin] ||= new host_1(url, HTTP.VERSION);
|
|
1347
1778
|
}
|
|
1348
1779
|
else {
|
|
1349
|
-
host = this[
|
|
1780
|
+
host = this.#hostInfo[url.origin] ||= new host_1(url, this.httpVersion || 1);
|
|
1350
1781
|
}
|
|
1351
1782
|
return { ...options, host, url };
|
|
1352
1783
|
}
|
|
@@ -1397,7 +1828,7 @@ class Request extends module_1 {
|
|
|
1397
1828
|
url = uri;
|
|
1398
1829
|
uri = url.toString();
|
|
1399
1830
|
}
|
|
1400
|
-
const base = this
|
|
1831
|
+
const base = this.#baseUrl;
|
|
1401
1832
|
if (!host) {
|
|
1402
1833
|
({ host, url } = this.opts(url || uri, { base: options.base }));
|
|
1403
1834
|
options.host = host;
|
|
@@ -1416,7 +1847,7 @@ class Request extends module_1 {
|
|
|
1416
1847
|
options.url = url;
|
|
1417
1848
|
}
|
|
1418
1849
|
if (options.base) {
|
|
1419
|
-
this
|
|
1850
|
+
this.#baseUrl = [url, httpVersion, headers];
|
|
1420
1851
|
}
|
|
1421
1852
|
else if (base) {
|
|
1422
1853
|
httpVersion ??= base[1];
|
|
@@ -1458,13 +1889,13 @@ class Request extends module_1 {
|
|
|
1458
1889
|
expectContinue = false;
|
|
1459
1890
|
}
|
|
1460
1891
|
if (secure) {
|
|
1461
|
-
const certs = this
|
|
1892
|
+
const certs = this.#certs?.[0][origin] || this.host && TLS.TEXT[origin];
|
|
1462
1893
|
if (certs) {
|
|
1463
1894
|
({ ca, cert, key, ciphers, version: minVersion } = certs);
|
|
1464
1895
|
}
|
|
1465
1896
|
}
|
|
1466
1897
|
if (!proxy && httpVersion !== 1 && ((httpVersion || host.version) === 2 && version !== 1 || secure && version === 2 && host.failed(2, true) === 0)) {
|
|
1467
|
-
request = (this[
|
|
1898
|
+
request = (this.#session[0][origin] ||= http2.connect(origin, { lookup: this.lookupDns(hostname), ca, cert, key, ciphers, minVersion, settings: host.localhost ? { maxFrameSize: 16777215, enablePush: false } : { enablePush: false } })).request({ ...baseHeaders, ...host_1.getBasicAuth(url), ...headers, ':path': pathname, ':method': method });
|
|
1468
1899
|
if (getting) {
|
|
1469
1900
|
const listenerMap = {};
|
|
1470
1901
|
const onEvent = request.on.bind(request);
|
|
@@ -1473,7 +1904,7 @@ class Request extends module_1 {
|
|
|
1473
1904
|
request.on('response', response => {
|
|
1474
1905
|
const statusCode = response[':status'];
|
|
1475
1906
|
if (expectContinue) {
|
|
1476
|
-
abortHeaders
|
|
1907
|
+
this.abortHeaders(url.href, request, options, statusCode, "Did not receive continue acknowledgment");
|
|
1477
1908
|
return;
|
|
1478
1909
|
}
|
|
1479
1910
|
connected = true;
|
|
@@ -1502,7 +1933,7 @@ class Request extends module_1 {
|
|
|
1502
1933
|
}
|
|
1503
1934
|
}
|
|
1504
1935
|
if (LOG_HTTP) {
|
|
1505
|
-
this[
|
|
1936
|
+
this.#connectHttp[1][origin] = (this.#connectHttp[1][origin] || 0) + 1;
|
|
1506
1937
|
}
|
|
1507
1938
|
}
|
|
1508
1939
|
this.matchHeaders(url, response, request, options);
|
|
@@ -1556,7 +1987,7 @@ class Request extends module_1 {
|
|
|
1556
1987
|
try {
|
|
1557
1988
|
keepAlive ??= proxy.keepAlive;
|
|
1558
1989
|
agentTimeout ??= proxy.agentTimeout;
|
|
1559
|
-
const proxyHeaders = this
|
|
1990
|
+
const proxyHeaders = this.#headers && getBaseHeaders(proxy.host.href, this.#headers) || getBaseHeaders(proxy.host.href, HTTP.HEADERS);
|
|
1560
1991
|
agent = require(pkg)(proxy.host, (typeof keepAlive === 'boolean' || agentTimeout > 0) && agentTimeout !== 0 ? { keepAlive: keepAlive ?? true, timeout: agentTimeout, headers: proxyHeaders } : { headers: proxyHeaders });
|
|
1561
1992
|
}
|
|
1562
1993
|
catch (err) {
|
|
@@ -1652,7 +2083,7 @@ class Request extends module_1 {
|
|
|
1652
2083
|
}
|
|
1653
2084
|
}
|
|
1654
2085
|
if (LOG_HTTP) {
|
|
1655
|
-
this[
|
|
2086
|
+
this.#connectHttp[0][origin] = (this.#connectHttp[0][origin] || 0) + 1;
|
|
1656
2087
|
}
|
|
1657
2088
|
}
|
|
1658
2089
|
else {
|
|
@@ -1667,7 +2098,7 @@ class Request extends module_1 {
|
|
|
1667
2098
|
request.emit('end');
|
|
1668
2099
|
});
|
|
1669
2100
|
if (expectContinue) {
|
|
1670
|
-
abortHeaders
|
|
2101
|
+
this.abortHeaders(url.href, request, options, statusCode, "Did not receive continue acknowledgment");
|
|
1671
2102
|
return;
|
|
1672
2103
|
}
|
|
1673
2104
|
}
|
|
@@ -1685,7 +2116,7 @@ class Request extends module_1 {
|
|
|
1685
2116
|
}
|
|
1686
2117
|
if (getting || posting) {
|
|
1687
2118
|
const ac = new AbortController();
|
|
1688
|
-
this
|
|
2119
|
+
this.#downloading.add(options.outAbort = ac);
|
|
1689
2120
|
stream.addAbortSignal(ac.signal, request);
|
|
1690
2121
|
if (options.signal) {
|
|
1691
2122
|
stream.addAbortSignal(options.signal, request);
|
|
@@ -1885,11 +2316,11 @@ class Request extends module_1 {
|
|
|
1885
2316
|
return this.get(uri, options);
|
|
1886
2317
|
}
|
|
1887
2318
|
async get(uri, options) {
|
|
1888
|
-
const opts = (typeof options === 'string' ? { format: options, encoding: '
|
|
2319
|
+
const opts = (typeof options === 'string' ? { format: options, encoding: 'utf8' } : options || {});
|
|
1889
2320
|
if (this.readExpect === 'string') {
|
|
1890
2321
|
opts.encoding = (0, types_1.getEncoding)(opts.encoding);
|
|
1891
2322
|
}
|
|
1892
|
-
const singleton = this
|
|
2323
|
+
const singleton = this.#singleton;
|
|
1893
2324
|
const verbose = !opts.silent && !singleton || opts.silent === false;
|
|
1894
2325
|
const log = verbose && LOG_HTTP && LOG_TIMEPROCESS;
|
|
1895
2326
|
const state = Object.freeze({
|
|
@@ -1898,7 +2329,7 @@ class Request extends module_1 {
|
|
|
1898
2329
|
singleton,
|
|
1899
2330
|
config: this._config
|
|
1900
2331
|
});
|
|
1901
|
-
return new this
|
|
2332
|
+
return new this.#adapter(this, state, uri, opts).start();
|
|
1902
2333
|
}
|
|
1903
2334
|
reset(adapter) {
|
|
1904
2335
|
if (adapter) {
|
|
@@ -1908,26 +2339,26 @@ class Request extends module_1 {
|
|
|
1908
2339
|
}
|
|
1909
2340
|
const ac = adapter.abortController;
|
|
1910
2341
|
if (ac) {
|
|
1911
|
-
this
|
|
2342
|
+
this.#downloading.delete(ac);
|
|
1912
2343
|
adapter.abortController = null;
|
|
1913
2344
|
}
|
|
1914
2345
|
return;
|
|
1915
2346
|
}
|
|
1916
|
-
this
|
|
1917
|
-
this
|
|
2347
|
+
this.#pendingDns = Object.create(null);
|
|
2348
|
+
this.#downloading.clear();
|
|
1918
2349
|
}
|
|
1919
2350
|
close() {
|
|
1920
|
-
const session = this
|
|
2351
|
+
const session = this.#session;
|
|
1921
2352
|
session.forEach((protocol, index) => {
|
|
1922
2353
|
for (const host in protocol) {
|
|
1923
2354
|
protocol[host].close();
|
|
1924
2355
|
}
|
|
1925
2356
|
session[index] = Object.create(null);
|
|
1926
2357
|
});
|
|
1927
|
-
this
|
|
2358
|
+
this.#downloading.clear();
|
|
1928
2359
|
}
|
|
1929
2360
|
matchStatus(code, url, headers, request, options) {
|
|
1930
|
-
const status = this
|
|
2361
|
+
const status = this.#statusOn?.get(code);
|
|
1931
2362
|
if (status) {
|
|
1932
2363
|
const href = url.href;
|
|
1933
2364
|
const called = new Set();
|
|
@@ -1939,7 +2370,7 @@ class Request extends module_1 {
|
|
|
1939
2370
|
for (const callback of called) {
|
|
1940
2371
|
try {
|
|
1941
2372
|
if (callback(code, headers, url) === true) {
|
|
1942
|
-
abortHeaders
|
|
2373
|
+
this.abortHeaders(href, request, options, code);
|
|
1943
2374
|
return false;
|
|
1944
2375
|
}
|
|
1945
2376
|
}
|
|
@@ -1951,7 +2382,7 @@ class Request extends module_1 {
|
|
|
1951
2382
|
return true;
|
|
1952
2383
|
}
|
|
1953
2384
|
matchHeaders(url, headers, request, options) {
|
|
1954
|
-
const on = this
|
|
2385
|
+
const on = this.#headersOn;
|
|
1955
2386
|
if (on?.size) {
|
|
1956
2387
|
const href = url.href;
|
|
1957
2388
|
const called = new Map();
|
|
@@ -1971,7 +2402,7 @@ class Request extends module_1 {
|
|
|
1971
2402
|
for (const [callback, data] of called) {
|
|
1972
2403
|
try {
|
|
1973
2404
|
if (callback(data, url) === true) {
|
|
1974
|
-
abortHeaders
|
|
2405
|
+
this.abortHeaders(href, request, options);
|
|
1975
2406
|
return false;
|
|
1976
2407
|
}
|
|
1977
2408
|
}
|
|
@@ -1982,50 +2413,58 @@ class Request extends module_1 {
|
|
|
1982
2413
|
}
|
|
1983
2414
|
return true;
|
|
1984
2415
|
}
|
|
2416
|
+
abortHeaders(href, request, options, statusCode = '', message = "Aborted by client") {
|
|
2417
|
+
const reason = (0, types_1.errorMessage)(statusCode, message, href);
|
|
2418
|
+
const outAbort = options.outAbort;
|
|
2419
|
+
if (outAbort) {
|
|
2420
|
+
outAbort.abort(reason);
|
|
2421
|
+
this.#downloading.delete(outAbort);
|
|
2422
|
+
}
|
|
2423
|
+
request.destroy(reason);
|
|
2424
|
+
}
|
|
1985
2425
|
set adapter(value) {
|
|
1986
|
-
if (
|
|
1987
|
-
this
|
|
2426
|
+
if (isConstructor(value) && value.prototype instanceof adapter_1) {
|
|
2427
|
+
this.#adapter = value;
|
|
1988
2428
|
}
|
|
1989
2429
|
}
|
|
1990
2430
|
set agentTimeout(value) {
|
|
1991
2431
|
if (value > 0) {
|
|
1992
|
-
this
|
|
2432
|
+
this.#agentTimeout = value;
|
|
1993
2433
|
this.keepAlive ??= true;
|
|
1994
2434
|
}
|
|
1995
2435
|
else {
|
|
1996
|
-
this
|
|
2436
|
+
this.#agentTimeout = 0;
|
|
1997
2437
|
this.keepAlive ??= false;
|
|
1998
2438
|
}
|
|
1999
2439
|
}
|
|
2000
2440
|
get agentTimeout() {
|
|
2001
|
-
return this
|
|
2441
|
+
return this.#agentTimeout;
|
|
2002
2442
|
}
|
|
2003
2443
|
set httpVersion(value) {
|
|
2004
2444
|
switch (value) {
|
|
2005
2445
|
case 1:
|
|
2006
2446
|
case 2:
|
|
2007
|
-
this
|
|
2447
|
+
this.#httpVersion = value;
|
|
2008
2448
|
break;
|
|
2009
2449
|
}
|
|
2010
2450
|
}
|
|
2011
2451
|
get httpVersion() {
|
|
2012
|
-
return this
|
|
2452
|
+
return this.#httpVersion;
|
|
2013
2453
|
}
|
|
2014
2454
|
set ipVersion(value) {
|
|
2015
2455
|
switch (value) {
|
|
2016
2456
|
case 0:
|
|
2017
2457
|
case 4:
|
|
2018
2458
|
case 6:
|
|
2019
|
-
this
|
|
2459
|
+
this.#ipVersion = value;
|
|
2020
2460
|
break;
|
|
2021
2461
|
}
|
|
2022
2462
|
}
|
|
2023
2463
|
get ipVersion() {
|
|
2024
|
-
return this
|
|
2464
|
+
return this.#ipVersion;
|
|
2025
2465
|
}
|
|
2026
2466
|
get settings() {
|
|
2027
2467
|
return this.module.settings ||= {};
|
|
2028
2468
|
}
|
|
2029
2469
|
}
|
|
2030
|
-
_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;
|
|
2031
2470
|
module.exports = Request;
|