@e-mc/request 0.8.10 → 0.9.1
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 +7 -3
- package/README.md +131 -10
- package/http/host/index.js +8 -17
- package/index.js +139 -136
- package/package.json +5 -5
- package/util.d.ts +9 -0
- package/util.js +79 -7
package/LICENSE
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
Copyright 2024 An Pham
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
+
|
|
9
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
+
|
|
11
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @e-mc/request
|
|
2
2
|
|
|
3
|
-
* NodeJS
|
|
4
|
-
*
|
|
3
|
+
* NodeJS 16
|
|
4
|
+
* ES2020
|
|
5
5
|
|
|
6
6
|
## General Usage
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## Interface
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
* [View Source](https://www.unpkg.com/@e-mc/types@0.9.1/lib/index.d.ts)
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { IModule, ModuleConstructor } from "./index";
|
|
@@ -32,13 +32,13 @@ interface IRequest extends IModule {
|
|
|
32
32
|
init(config?: RequestInit): this;
|
|
33
33
|
apply(options: ApplyOptions): this;
|
|
34
34
|
addDns(hostname: string, address: string, timeout: number): void;
|
|
35
|
-
addDns(hostname: string, address: string, family?:
|
|
35
|
+
addDns(hostname: string, address: string, family?: string, timeout?: number): void;
|
|
36
36
|
lookupDns(hostname: string): LookupFunction;
|
|
37
37
|
proxyOf(uri: string, localhost?: boolean): ProxySettings | undefined;
|
|
38
38
|
statusOn(name: number | number[], callback: StatusOnCallback): void;
|
|
39
|
-
statusOn(name: number | number[],
|
|
39
|
+
statusOn(name: number | number[], globUrl: string, callback: StatusOnCallback): void;
|
|
40
40
|
headersOn(name: string | string[], callback: HeadersOnCallback): void;
|
|
41
|
-
headersOn(name: string | string[],
|
|
41
|
+
headersOn(name: string | string[], globUrl: string, callback: HeadersOnCallback): void;
|
|
42
42
|
headersOf(uri: string): OutgoingHttpHeaders | undefined;
|
|
43
43
|
aria2c(uri: string | URL, pathname: string): Promise<string[]>;
|
|
44
44
|
aria2c(uri: string | URL, options?: Aria2Options): Promise<string[]>;
|
|
@@ -80,12 +80,133 @@ interface RequestConstructor extends ModuleConstructor {
|
|
|
80
80
|
}
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
## Settings
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import type { PermittedDirectories } from "./core";
|
|
87
|
+
import type { SecureConfig } from "./http";
|
|
88
|
+
import type { PurgeComponent } from "./settings";
|
|
89
|
+
|
|
90
|
+
import type { LookupAddress } from "dns";
|
|
91
|
+
import type { OutgoingHttpHeaders } from "http";
|
|
92
|
+
|
|
93
|
+
interface RequestModule {
|
|
94
|
+
handler: "@e-mc/request";
|
|
95
|
+
timeout?: number | string;
|
|
96
|
+
read_timeout?: number | string;
|
|
97
|
+
agent?: {
|
|
98
|
+
keep_alive?: boolean;
|
|
99
|
+
timeout?: number | string;
|
|
100
|
+
};
|
|
101
|
+
connect?: {
|
|
102
|
+
timeout?: number | string;
|
|
103
|
+
retry_wait?: number | string;
|
|
104
|
+
retry_after?: number | string;
|
|
105
|
+
retry_limit?: number;
|
|
106
|
+
redirect_limit?: number;
|
|
107
|
+
};
|
|
108
|
+
dns?: {
|
|
109
|
+
family?: number;
|
|
110
|
+
expires?: number | string;
|
|
111
|
+
resolve?: Record<string, Partial<LookupAddress>>;
|
|
112
|
+
};
|
|
113
|
+
use?: {
|
|
114
|
+
http_version?: 1 | 2;
|
|
115
|
+
accept_encoding?: boolean;
|
|
116
|
+
};
|
|
117
|
+
proxy?: {
|
|
118
|
+
address?: string;
|
|
119
|
+
port?: number;
|
|
120
|
+
username?: string;
|
|
121
|
+
password?: string;
|
|
122
|
+
include?: string[];
|
|
123
|
+
exclude?: string[];
|
|
124
|
+
keep_alive?: boolean;
|
|
125
|
+
};
|
|
126
|
+
headers: Record<string, OutgoingHttpHeaders>;
|
|
127
|
+
certs?: Record<string, SecureConfig<string | string[]>>;
|
|
128
|
+
localhost?: string[];
|
|
129
|
+
protocol?: {
|
|
130
|
+
"http/1.1"?: string[];
|
|
131
|
+
h2c?: string[];
|
|
132
|
+
h2?: string[];
|
|
133
|
+
};
|
|
134
|
+
post_limit?: number | string;
|
|
135
|
+
settings?: {
|
|
136
|
+
broadcast_id?: string | string[];
|
|
137
|
+
time_format?: "readable" | "relative" | "none";
|
|
138
|
+
purge?: PurgeComponent;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
interface DownloadModule {
|
|
143
|
+
expires?: number | string;
|
|
144
|
+
aria2?: {
|
|
145
|
+
bin?: string | false;
|
|
146
|
+
exec?: {
|
|
147
|
+
uid?: number;
|
|
148
|
+
gid?: number;
|
|
149
|
+
};
|
|
150
|
+
update_status?: number | { interval?: number; broadcast_only?: boolean };
|
|
151
|
+
max_concurrent_downloads?: number;
|
|
152
|
+
max_connection_per_server?: number;
|
|
153
|
+
bt_stop_timeout?: number;
|
|
154
|
+
bt_tracker_connect_timeout?: number;
|
|
155
|
+
bt_tracker_timeout?: number;
|
|
156
|
+
min_split_size?: string;
|
|
157
|
+
disk_cache?: number | string;
|
|
158
|
+
lowest_speed_limit?: number | string;
|
|
159
|
+
always_resume?: boolean;
|
|
160
|
+
file_allocation?: "none" | "prealloc" | "trunc" | "falloc";
|
|
161
|
+
conf_path?: string;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Example usage
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
const Request = require("@e-mc/request");
|
|
170
|
+
|
|
171
|
+
const instance = new Request({
|
|
172
|
+
read_timeout: 30,
|
|
173
|
+
connect: {
|
|
174
|
+
timeout: 20, // Seconds
|
|
175
|
+
retry_wait: 1,
|
|
176
|
+
retry_after: 30,
|
|
177
|
+
retry_limit: 3, // Max attempts
|
|
178
|
+
redirect_limit: 10
|
|
179
|
+
},
|
|
180
|
+
use: {
|
|
181
|
+
http_version: 2,
|
|
182
|
+
accept_encoding: true
|
|
183
|
+
},
|
|
184
|
+
dns: {
|
|
185
|
+
family: 4 // ipVersion
|
|
186
|
+
},
|
|
187
|
+
agent: { keep_alive: true }
|
|
188
|
+
});
|
|
189
|
+
request.init({ ipVersion: 6 });
|
|
190
|
+
|
|
191
|
+
const options = {
|
|
192
|
+
format: "yaml",
|
|
193
|
+
httpVersion: 1,
|
|
194
|
+
silent: true,
|
|
195
|
+
headers: { "x-goog-user-project": "project-1" }
|
|
196
|
+
};
|
|
197
|
+
instance.get("http://hostname/path/config.yml", options).then(data => {
|
|
198
|
+
console.log(data.property);
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
83
202
|
## References
|
|
84
203
|
|
|
85
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
86
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
87
|
-
- https://www.unpkg.com/@e-mc/types@0.
|
|
204
|
+
- https://www.unpkg.com/@e-mc/types@0.9.1/lib/http.d.ts
|
|
205
|
+
- https://www.unpkg.com/@e-mc/types@0.9.1/lib/request.d.ts
|
|
206
|
+
- https://www.unpkg.com/@e-mc/types@0.9.1/lib/settings.d.ts
|
|
207
|
+
|
|
208
|
+
* https://www.npmjs.com/package/@types/node
|
|
88
209
|
|
|
89
210
|
## LICENSE
|
|
90
211
|
|
|
91
|
-
|
|
212
|
+
BSD 3-Clause
|
package/http/host/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a, _b, _c, _d;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
const tls = require("tls");
|
|
5
|
-
const types_1 = require("@e-mc/types");
|
|
6
4
|
const kProtocol = Symbol('protocol');
|
|
7
5
|
const kSecure = Symbol('secure');
|
|
8
6
|
const kHostname = Symbol('hostname');
|
|
@@ -27,7 +25,7 @@ const HOST_ALPN_H2 = [];
|
|
|
27
25
|
})();
|
|
28
26
|
class HttpHost {
|
|
29
27
|
static normalizeOrigin(value) {
|
|
30
|
-
return value.replace(/\/+$/, '') + (!/:\d+$/.test(value) ? ':' + (value.startsWith('https') ? '443' : '80') : '');
|
|
28
|
+
return (value = value.trim()).replace(/\/+$/, '') + (!/:\d+$/.test(value) ? ':' + (value.startsWith('https') ? '443' : '80') : '');
|
|
31
29
|
}
|
|
32
30
|
static formatBasicAuth(url) {
|
|
33
31
|
return url.username ? decodeURIComponent(url.username) + (url.password ? ':' + decodeURIComponent(url.password) : '') : '';
|
|
@@ -40,19 +38,19 @@ class HttpHost {
|
|
|
40
38
|
}
|
|
41
39
|
static defineLocalHost(value) {
|
|
42
40
|
HOST_LOCAL.clear();
|
|
43
|
-
value.forEach(address =>
|
|
41
|
+
value.forEach(address => HOST_LOCAL.add(address));
|
|
44
42
|
}
|
|
45
43
|
static defineProtocolNegotiation(value) {
|
|
46
44
|
const { h2c, h2 } = value;
|
|
47
45
|
const http11 = value['http/1.1'];
|
|
48
46
|
if (Array.isArray(http11)) {
|
|
49
|
-
HOST_HTTP_1_1.push(...http11.map(address => this.normalizeOrigin(address
|
|
47
|
+
HOST_HTTP_1_1.push(...http11.map(address => this.normalizeOrigin(address)));
|
|
50
48
|
}
|
|
51
49
|
if (Array.isArray(h2c)) {
|
|
52
|
-
HOST_ALPN_H2C.push(...h2c.map(address => this.normalizeOrigin(address
|
|
50
|
+
HOST_ALPN_H2C.push(...h2c.map(address => this.normalizeOrigin(address)));
|
|
53
51
|
}
|
|
54
52
|
if (Array.isArray(h2)) {
|
|
55
|
-
HOST_ALPN_H2.push(...h2.map(address => this.normalizeOrigin(address
|
|
53
|
+
HOST_ALPN_H2.push(...h2.map(address => this.normalizeOrigin(address)));
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
56
|
constructor(url, httpVersion = 1) {
|
|
@@ -154,7 +152,6 @@ class HttpHost {
|
|
|
154
152
|
return ++data[2];
|
|
155
153
|
}
|
|
156
154
|
upgrade(version, altSvc) {
|
|
157
|
-
var _e;
|
|
158
155
|
if (altSvc && this.secure) {
|
|
159
156
|
if (altSvc === 'clear') {
|
|
160
157
|
this.clearAltSvc();
|
|
@@ -174,13 +171,11 @@ class HttpHost {
|
|
|
174
171
|
}
|
|
175
172
|
return false;
|
|
176
173
|
};
|
|
177
|
-
const pattern = new RegExp(`h${i + 1}(?:-\\d+)?="([^:]*):(\\d+)"([^,]*)`, 'g');
|
|
178
174
|
const addresses = [];
|
|
179
175
|
const time = Date.now();
|
|
180
176
|
const hostname = this[kHostname];
|
|
181
177
|
const excluded = this[kAltSvcError];
|
|
182
|
-
|
|
183
|
-
while (match = pattern.exec(altSvc)) {
|
|
178
|
+
for (const match of altSvc.matchAll(new RegExp(`h${i + 1}(?:-\\d+)?="([^:]*):(\\d+)"([^,]*)`, 'g'))) {
|
|
184
179
|
const port = match[2];
|
|
185
180
|
if (!match[1] && port === this.port) {
|
|
186
181
|
increment(2);
|
|
@@ -188,7 +183,7 @@ class HttpHost {
|
|
|
188
183
|
break;
|
|
189
184
|
}
|
|
190
185
|
const address = match[1] || hostname;
|
|
191
|
-
const ma = +(
|
|
186
|
+
const ma = +(/ma=(\d+)/.exec(match[3])?.[1] || 86400);
|
|
192
187
|
if (!excluded.includes(`h${i + 1}:${address}:${port}`)) {
|
|
193
188
|
addresses.push([
|
|
194
189
|
address,
|
|
@@ -328,9 +323,5 @@ class HttpHost {
|
|
|
328
323
|
}
|
|
329
324
|
}
|
|
330
325
|
_a = kVersionData, _b = kAltSvc, _c = kAltSvcQueue, _d = kAltSvcError;
|
|
331
|
-
exports.default = HttpHost;
|
|
332
326
|
|
|
333
|
-
|
|
334
|
-
module.exports = exports.default;
|
|
335
|
-
module.exports.default = exports.default;
|
|
336
|
-
}
|
|
327
|
+
module.exports = HttpHost;
|
package/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
const path = require("path");
|
|
5
4
|
const fs = require("fs");
|
|
6
5
|
const child_process = require("child_process");
|
|
@@ -16,7 +15,6 @@ const combined = require("combined-stream");
|
|
|
16
15
|
const pm = require("picomatch");
|
|
17
16
|
const yaml = require("js-yaml");
|
|
18
17
|
const which = require("which");
|
|
19
|
-
const lib_v4_1 = require("@e-mc/module/lib-v4");
|
|
20
18
|
const types_1 = require("@e-mc/types");
|
|
21
19
|
const module_1 = require("@e-mc/module");
|
|
22
20
|
const host_1 = require("@e-mc/request/http/host");
|
|
@@ -36,8 +34,7 @@ const kConnectHttp = Symbol('connectHttp');
|
|
|
36
34
|
const kStatusOn = Symbol('statusOn');
|
|
37
35
|
const kHeadersOn = Symbol('headersOn');
|
|
38
36
|
const PLATFORM_WIN32 = process.platform === 'win32';
|
|
39
|
-
const SUPPORT_NODEJS20 = module_1.
|
|
40
|
-
const SUPPORT_ABORTSIGNAL = module_1.default.supported(15, 4);
|
|
37
|
+
const SUPPORT_NODEJS20 = module_1.supported(20);
|
|
41
38
|
const HTTP = {
|
|
42
39
|
HOST: {},
|
|
43
40
|
HEADERS: {},
|
|
@@ -106,7 +103,7 @@ function getBaseHeaders(uri, headers) {
|
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
function setDnsCache(hostname, value, expires) {
|
|
109
|
-
expires
|
|
106
|
+
expires ?? (expires = DNS.EXPIRES);
|
|
110
107
|
if (expires > 0 && !DNS.CACHE[hostname]) {
|
|
111
108
|
DNS.CACHE[hostname] = value;
|
|
112
109
|
if (expires !== Infinity) {
|
|
@@ -137,12 +134,12 @@ function setOutgoingHeaders(output, headers) {
|
|
|
137
134
|
}
|
|
138
135
|
function getProxySettings(request, agentTimeout) {
|
|
139
136
|
const proxy = request.proxy;
|
|
140
|
-
if (
|
|
137
|
+
if (proxy?.address && proxy.port) {
|
|
141
138
|
const port = (0, util_1.asInt)(proxy.port);
|
|
142
|
-
const address = (!module_1.
|
|
139
|
+
const address = (!module_1.isURL(proxy.address) ? port === 80 ? 'http://' : 'https://' : '') + proxy.address;
|
|
143
140
|
try {
|
|
144
141
|
let host = new URL(address + ':' + port), include, exclude;
|
|
145
|
-
if (
|
|
142
|
+
if (proxy.username) {
|
|
146
143
|
host = new URL(host.protocol + '//' + (0, util_1.getBasicAuth)(proxy.username, proxy.password) + host.host);
|
|
147
144
|
}
|
|
148
145
|
if ((0, types_1.isArray)(proxy.include)) {
|
|
@@ -199,7 +196,7 @@ function validateCerts(certs) {
|
|
|
199
196
|
const file = {};
|
|
200
197
|
const checkFile = (values) => {
|
|
201
198
|
for (let pathname of values) {
|
|
202
|
-
if (module_1.
|
|
199
|
+
if (module_1.isPath(pathname = path.resolve(pathname))) {
|
|
203
200
|
return pathname;
|
|
204
201
|
}
|
|
205
202
|
}
|
|
@@ -270,7 +267,7 @@ function abortHeaders(href, request, options) {
|
|
|
270
267
|
}
|
|
271
268
|
request.destroy(reason);
|
|
272
269
|
}
|
|
273
|
-
class Request extends module_1
|
|
270
|
+
class Request extends module_1 {
|
|
274
271
|
static async purgeMemory(percent = 1, limit = 0, parent) {
|
|
275
272
|
if (percent >= 1) {
|
|
276
273
|
resetHttpHost();
|
|
@@ -285,7 +282,6 @@ class Request extends module_1.default {
|
|
|
285
282
|
return parent ? super.purgeMemory(percent, limit) : 0;
|
|
286
283
|
}
|
|
287
284
|
static loadSettings(settings, password) {
|
|
288
|
-
var _o;
|
|
289
285
|
if (this.enabled("process.password") && !super.loadSettings({ process: settings.process }, password)) {
|
|
290
286
|
return false;
|
|
291
287
|
}
|
|
@@ -404,7 +400,7 @@ class Request extends module_1.default {
|
|
|
404
400
|
[TLS.TEXT, TLS.FILE] = validateCerts(certs);
|
|
405
401
|
}
|
|
406
402
|
HTTP.PROXY = getProxySettings(request, agent_timeout);
|
|
407
|
-
const time_format =
|
|
403
|
+
const time_format = request.settings?.time_format;
|
|
408
404
|
switch (time_format) {
|
|
409
405
|
case 'readable':
|
|
410
406
|
case 'relative':
|
|
@@ -415,7 +411,7 @@ class Request extends module_1.default {
|
|
|
415
411
|
}
|
|
416
412
|
LOG_HTTP = this.hasLogType(1024);
|
|
417
413
|
LOG_TIMEPROCESS = this.hasLogType(256);
|
|
418
|
-
LOG_STDOUT = module_1.
|
|
414
|
+
LOG_STDOUT = module_1.hasLogType(32768);
|
|
419
415
|
return true;
|
|
420
416
|
}
|
|
421
417
|
static readCACert(value, cache) {
|
|
@@ -434,7 +430,7 @@ class Request extends module_1.default {
|
|
|
434
430
|
if (this.isURL(value)) {
|
|
435
431
|
return value;
|
|
436
432
|
}
|
|
437
|
-
const auth = host_1.
|
|
433
|
+
const auth = host_1.formatBasicAuth(url);
|
|
438
434
|
return url.protocol + '//' + (auth && (auth + '@')) + url.hostname + (url.port ? ':' + url.port : '') + (value.startsWith('/') ? '' : '/') + value;
|
|
439
435
|
}
|
|
440
436
|
static fromStatusCode(value) {
|
|
@@ -629,7 +625,6 @@ class Request extends module_1.default {
|
|
|
629
625
|
return ARIA2.BIN;
|
|
630
626
|
}
|
|
631
627
|
constructor(data) {
|
|
632
|
-
var _o;
|
|
633
628
|
super();
|
|
634
629
|
this.startTime = Date.now();
|
|
635
630
|
this.readExpect = 'none';
|
|
@@ -661,13 +656,13 @@ class Request extends module_1.default {
|
|
|
661
656
|
const timeout = (0, util_1.fromSeconds)(data.timeout);
|
|
662
657
|
let value;
|
|
663
658
|
this.readTimeout = (value = (0, util_1.fromSeconds)(read_timeout)) >= 0 ? value : READ_TIMEOUT;
|
|
664
|
-
this.keepAlive = typeof (value = agent
|
|
665
|
-
this.acceptEncoding = typeof (value = use
|
|
666
|
-
if ((value = (0, util_1.asInt)(use
|
|
659
|
+
this.keepAlive = typeof (value = agent?.keep_alive) === 'boolean' ? value : KEEP_ALIVE;
|
|
660
|
+
this.acceptEncoding = typeof (value = use?.accept_encoding) === 'boolean' ? value : ACCEPT_ENCODING;
|
|
661
|
+
if ((value = (0, util_1.asInt)(use?.http_version)) === 1 || value === 2) {
|
|
667
662
|
this[kHttpVersion] = value;
|
|
668
663
|
}
|
|
669
|
-
this[kIpVersion] = (value = (0, util_1.asInt)(
|
|
670
|
-
if ((value = (0, util_1.fromSeconds)(agent
|
|
664
|
+
this[kIpVersion] = (value = (0, util_1.asInt)(data.dns?.family)) && (value === 4 || value === 6) ? value : 0;
|
|
665
|
+
if ((value = (0, util_1.fromSeconds)(agent?.timeout)) >= 0) {
|
|
671
666
|
this[kAgentTimeout] = value;
|
|
672
667
|
}
|
|
673
668
|
else {
|
|
@@ -709,13 +704,12 @@ class Request extends module_1.default {
|
|
|
709
704
|
this.module = data;
|
|
710
705
|
}
|
|
711
706
|
flushLog() {
|
|
712
|
-
var _o;
|
|
713
707
|
const log = this._logQueued;
|
|
714
708
|
if (this[kSingleton]) {
|
|
715
709
|
log.length = 0;
|
|
716
710
|
}
|
|
717
711
|
else {
|
|
718
|
-
if (log.length && !
|
|
712
|
+
if (log.length && !this.host?.aborted) {
|
|
719
713
|
const output = [];
|
|
720
714
|
let count = 0;
|
|
721
715
|
this[kConnectHttp].forEach((protocol, index) => {
|
|
@@ -748,19 +742,19 @@ class Request extends module_1.default {
|
|
|
748
742
|
const width = count.toString().length;
|
|
749
743
|
output.forEach(item => {
|
|
750
744
|
const [title, origin, downloads, messages] = item;
|
|
751
|
-
const options = { ...title === 'HTTP1' ? module_1.
|
|
745
|
+
const options = { ...title === 'HTTP1' ? module_1.LOG_STYLE_NOTICE : module_1.LOG_STYLE_INFO };
|
|
752
746
|
if (messages.length === 1) {
|
|
753
747
|
const message = messages[0];
|
|
754
748
|
message[1] = title;
|
|
755
749
|
message[2] = [origin + message[2][0], message[2][1]];
|
|
756
750
|
message[4] = Object.assign(message[4], options);
|
|
757
|
-
module_1.
|
|
751
|
+
module_1.formatMessage(...message);
|
|
758
752
|
}
|
|
759
753
|
else {
|
|
760
754
|
this.formatMessage(1024, title, [origin, 'downloads: ' + downloads.toString().padStart(width)], '', options);
|
|
761
755
|
messages.forEach(args => {
|
|
762
756
|
args[4].titleIndent = true;
|
|
763
|
-
module_1.
|
|
757
|
+
module_1.formatMessage(...args);
|
|
764
758
|
});
|
|
765
759
|
}
|
|
766
760
|
});
|
|
@@ -787,7 +781,7 @@ class Request extends module_1.default {
|
|
|
787
781
|
}
|
|
788
782
|
init(config) {
|
|
789
783
|
if (config) {
|
|
790
|
-
const { headers, httpVersion, ipVersion,
|
|
784
|
+
const { headers, httpVersion, ipVersion, readTimeout } = config;
|
|
791
785
|
if ((0, types_1.isObject)(headers)) {
|
|
792
786
|
setOutgoingHeaders(this[kHeaders] || (this[kHeaders] = {}), headers);
|
|
793
787
|
}
|
|
@@ -822,7 +816,7 @@ class Request extends module_1.default {
|
|
|
822
816
|
this._config.retryWait = Math.min(retryWait, 600 * 1000);
|
|
823
817
|
}
|
|
824
818
|
if (retryAfter >= 0) {
|
|
825
|
-
this._config.retryAfter = Math.min(retryAfter, module_1.
|
|
819
|
+
this._config.retryAfter = Math.min(retryAfter, module_1.MAX_TIMEOUT);
|
|
826
820
|
}
|
|
827
821
|
if (retryLimit >= 0) {
|
|
828
822
|
this._config.retryLimit = retryLimit;
|
|
@@ -998,7 +992,7 @@ class Request extends module_1.default {
|
|
|
998
992
|
if (!ARIA2.BIN) {
|
|
999
993
|
return Promise.reject((0, types_1.errorMessage)("aria2", "Binary not found"));
|
|
1000
994
|
}
|
|
1001
|
-
if (typeof uri === 'string' && module_1.
|
|
995
|
+
if (typeof uri === 'string' && module_1.isURL(uri)) {
|
|
1002
996
|
try {
|
|
1003
997
|
uri = new URL(uri);
|
|
1004
998
|
}
|
|
@@ -1017,7 +1011,7 @@ class Request extends module_1.default {
|
|
|
1017
1011
|
let next = false;
|
|
1018
1012
|
binOpts = binOpts.filter(opt => !((0, types_1.isString)(opt) && /^-[a-z][\S\s]*$/i.test(opt.trim()))).map((opt) => {
|
|
1019
1013
|
if (next) {
|
|
1020
|
-
if (!module_1.
|
|
1014
|
+
if (!module_1.asString(opt).startsWith('--')) {
|
|
1021
1015
|
return [];
|
|
1022
1016
|
}
|
|
1023
1017
|
next = false;
|
|
@@ -1039,12 +1033,12 @@ class Request extends module_1.default {
|
|
|
1039
1033
|
}
|
|
1040
1034
|
break;
|
|
1041
1035
|
default:
|
|
1042
|
-
return match[3] ? [match[1], module_1.
|
|
1036
|
+
return match[3] ? [match[1], module_1.sanitizeArgs(match[3])] : [match[1]];
|
|
1043
1037
|
}
|
|
1044
1038
|
}
|
|
1045
1039
|
}
|
|
1046
1040
|
else if (value) {
|
|
1047
|
-
return [module_1.
|
|
1041
|
+
return [module_1.sanitizeArgs(value)];
|
|
1048
1042
|
}
|
|
1049
1043
|
break;
|
|
1050
1044
|
}
|
|
@@ -1053,7 +1047,7 @@ class Request extends module_1.default {
|
|
|
1053
1047
|
return [opt.toString()];
|
|
1054
1048
|
default:
|
|
1055
1049
|
if ((0, types_1.isArray)(opt)) {
|
|
1056
|
-
return opt.filter(item => (0, types_1.isString)(item)).map((item) => module_1.
|
|
1050
|
+
return opt.filter(item => (0, types_1.isString)(item)).map((item) => module_1.sanitizeArgs(item));
|
|
1057
1051
|
}
|
|
1058
1052
|
break;
|
|
1059
1053
|
}
|
|
@@ -1062,7 +1056,7 @@ class Request extends module_1.default {
|
|
|
1062
1056
|
}
|
|
1063
1057
|
}
|
|
1064
1058
|
}
|
|
1065
|
-
if (!
|
|
1059
|
+
if (!pathname) {
|
|
1066
1060
|
if (this.host) {
|
|
1067
1061
|
return Promise.reject((0, types_1.errorMessage)("aria2", "Invalid parameters", 'pathname'));
|
|
1068
1062
|
}
|
|
@@ -1071,12 +1065,11 @@ class Request extends module_1.default {
|
|
|
1071
1065
|
if ((this.host || this.hasOwnPermission()) && !this.canWrite(pathname = path.resolve(pathname.trim()))) {
|
|
1072
1066
|
return Promise.reject((0, types_1.errorMessage)("aria2", "Unsupported access", pathname));
|
|
1073
1067
|
}
|
|
1074
|
-
if (!module_1.
|
|
1068
|
+
if (!module_1.createDir(pathname)) {
|
|
1075
1069
|
return Promise.reject((0, types_1.errorMessage)("aria2", "Path is not a directory", pathname));
|
|
1076
1070
|
}
|
|
1077
|
-
silent
|
|
1071
|
+
silent ?? (silent = this[kSingleton]);
|
|
1078
1072
|
return new Promise((resolve, reject) => {
|
|
1079
|
-
var _o;
|
|
1080
1073
|
let protocol, origin, username, password;
|
|
1081
1074
|
if (uri instanceof URL) {
|
|
1082
1075
|
({ protocol, origin, username, password, href: uri } = uri);
|
|
@@ -1134,7 +1127,7 @@ class Request extends module_1.default {
|
|
|
1134
1127
|
'--file-allocation=' + ARIA2.FILE_ALLOCATION,
|
|
1135
1128
|
'--max-tries=' + (retryLimit + 1)
|
|
1136
1129
|
];
|
|
1137
|
-
const ignoreOpt = (...values) => !
|
|
1130
|
+
const ignoreOpt = (...values) => !binOpts?.some(item => values.includes(item));
|
|
1138
1131
|
if (ARIA2.MAX_CONCURRENT_DOWNLOADS) {
|
|
1139
1132
|
opts.push('--max-concurrent-downloads=' + ARIA2.MAX_CONCURRENT_DOWNLOADS);
|
|
1140
1133
|
}
|
|
@@ -1183,7 +1176,7 @@ class Request extends module_1.default {
|
|
|
1183
1176
|
}
|
|
1184
1177
|
}
|
|
1185
1178
|
if (origin) {
|
|
1186
|
-
const secure =
|
|
1179
|
+
const secure = this[kCerts]?.[1][origin] || this.host && TLS.FILE[origin];
|
|
1187
1180
|
if (secure) {
|
|
1188
1181
|
if (secure.ca && ignoreOpt('--ca-certificate')) {
|
|
1189
1182
|
args.push(`--ca-certificate="${escapeQuote(secure.ca)}"`);
|
|
@@ -1238,8 +1231,8 @@ class Request extends module_1.default {
|
|
|
1238
1231
|
args = binOpts.concat(args);
|
|
1239
1232
|
}
|
|
1240
1233
|
if (args.length) {
|
|
1241
|
-
if (module_1.
|
|
1242
|
-
this.formatMessage(32768, 'ARIA2', ARIA2.BIN, args.join(' '), { ...module_1.
|
|
1234
|
+
if (module_1.hasLogType(32768)) {
|
|
1235
|
+
this.formatMessage(32768, 'ARIA2', ARIA2.BIN, args.join(' '), { ...module_1.LOG_STYLE_WARN });
|
|
1243
1236
|
}
|
|
1244
1237
|
else {
|
|
1245
1238
|
this.addLog(types_1.STATUS_TYPE.INFO, path.basename(ARIA2.BIN) + ' ' + args.join(' '), "aria2");
|
|
@@ -1254,7 +1247,7 @@ class Request extends module_1.default {
|
|
|
1254
1247
|
closeTorrent(pid);
|
|
1255
1248
|
reject(err);
|
|
1256
1249
|
};
|
|
1257
|
-
const { pid, stdout, stderr } = child_process.spawn(module_1.
|
|
1250
|
+
const { pid, stdout, stderr } = child_process.spawn(module_1.sanitizeCmd(ARIA2.BIN), args, { cwd: pathname, shell: true, signal: this.signal, uid: ARIA2.EXEC_UID, gid: ARIA2.EXEC_GID })
|
|
1258
1251
|
.on('exit', code => {
|
|
1259
1252
|
closeTorrent(pid);
|
|
1260
1253
|
if (aborted) {
|
|
@@ -1264,15 +1257,15 @@ class Request extends module_1.default {
|
|
|
1264
1257
|
errorResponse(pid, (0, types_1.createAbortError)());
|
|
1265
1258
|
return;
|
|
1266
1259
|
}
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1260
|
+
if (code) {
|
|
1261
|
+
reject((0, types_1.errorValue)(message || "Unknown", 'Exit status: ' + code));
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
const currentTime = Date.now();
|
|
1265
|
+
const result = [];
|
|
1266
|
+
let messageUnit;
|
|
1267
|
+
for (const match of out.matchAll(/\|(OK|ERR|INPR)\s*\|\s*([^|]+)\|\s*(\d+)\|([^\n]+)/g)) {
|
|
1268
|
+
if (!match[4].startsWith('[MEMORY]')) {
|
|
1276
1269
|
const file = path.normalize(match[4].trim());
|
|
1277
1270
|
switch (match[1]) {
|
|
1278
1271
|
case 'OK':
|
|
@@ -1290,20 +1283,17 @@ class Request extends module_1.default {
|
|
|
1290
1283
|
break;
|
|
1291
1284
|
}
|
|
1292
1285
|
}
|
|
1293
|
-
if (result.length && !silent && LOG_HTTP && LOG_TIMEPROCESS) {
|
|
1294
|
-
this.writeTimeProcess("aria2", uri, startTime, { type: 1024, queue: true, messageUnit, messageUnitMinWidth: 9, bypassLog: true });
|
|
1295
|
-
}
|
|
1296
|
-
this.addLog(result.length ? types_1.STATUS_TYPE.INFO : types_1.STATUS_TYPE.ERROR, out, currentTime, currentTime - startTime, "aria2", uri);
|
|
1297
|
-
resolve(result);
|
|
1298
1286
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1287
|
+
if (result.length && !silent && LOG_HTTP && LOG_TIMEPROCESS) {
|
|
1288
|
+
this.writeTimeProcess("aria2", uri, startTime, { type: 1024, queue: true, messageUnit, messageUnitMinWidth: 9, bypassLog: true });
|
|
1301
1289
|
}
|
|
1290
|
+
this.addLog(result.length ? types_1.STATUS_TYPE.INFO : types_1.STATUS_TYPE.ERROR, out, currentTime, currentTime - startTime, "aria2", uri);
|
|
1291
|
+
resolve(result);
|
|
1302
1292
|
})
|
|
1303
1293
|
.on('error', err => errorResponse(pid, err));
|
|
1304
1294
|
stdout.setEncoding('utf-8').on('data', (value) => out += value);
|
|
1305
1295
|
stderr.setEncoding('utf-8').on('data', (value) => message += value);
|
|
1306
|
-
if (pid !== undefined && module_1.
|
|
1296
|
+
if (pid !== undefined && module_1.isFile(uri, 'torrent')) {
|
|
1307
1297
|
if (!ARIA2.PID_TIMER) {
|
|
1308
1298
|
const clearTimer = () => {
|
|
1309
1299
|
clearInterval(ARIA2.PID_TIMER);
|
|
@@ -1324,24 +1314,22 @@ class Request extends module_1.default {
|
|
|
1324
1314
|
}
|
|
1325
1315
|
if (ARIA2.UPDATE_STATUS && !silent) {
|
|
1326
1316
|
const item = ARIA2.PID_QUEUE.shift();
|
|
1327
|
-
if (item) {
|
|
1328
|
-
const broadcastId = item[2];
|
|
1329
|
-
if (!ARIA2.UPDATE_BROADCAST_ONLY || broadcastId) {
|
|
1330
|
-
let progressBar;
|
|
1331
|
-
if (item[2]) {
|
|
1332
|
-
progressBar = true;
|
|
1333
|
-
}
|
|
1334
|
-
else {
|
|
1335
|
-
const current = (0, types_1.getLogCurrent)();
|
|
1336
|
-
progressBar = (current === null || current === void 0 ? void 0 : current.type) === 128 && current.title === "aria2";
|
|
1337
|
-
}
|
|
1338
|
-
this.formatMessage(128, "aria2", ['Downloading...', (0, types_1.formatTime)(startTime, true)], (PLATFORM_WIN32 ? 'taskkill /f /pid' : 'kill') + ` ${item[0]} -> ` + item[1], { ...module_1.default.LOG_STYLE_INFO, progressBar, broadcastId });
|
|
1339
|
-
}
|
|
1340
|
-
ARIA2.PID_QUEUE.push(item);
|
|
1341
|
-
}
|
|
1342
|
-
else {
|
|
1317
|
+
if (!item) {
|
|
1343
1318
|
clearTimer();
|
|
1319
|
+
return;
|
|
1344
1320
|
}
|
|
1321
|
+
if ((!ARIA2.UPDATE_BROADCAST_ONLY || item[2]) && this.host?.logState !== 0) {
|
|
1322
|
+
let progressBar;
|
|
1323
|
+
if (item[2]) {
|
|
1324
|
+
progressBar = true;
|
|
1325
|
+
}
|
|
1326
|
+
else {
|
|
1327
|
+
const current = (0, types_1.getLogCurrent)();
|
|
1328
|
+
progressBar = current?.type === 128 && current.title === "aria2";
|
|
1329
|
+
}
|
|
1330
|
+
this.formatMessage(128, "aria2", ['Downloading...', (0, types_1.formatTime)(startTime, true)], (PLATFORM_WIN32 ? 'taskkill /f /pid' : 'kill') + ` ${item[0]} -> ` + item[1], { ...module_1.LOG_STYLE_INFO, progressBar, broadcastId: item[2] });
|
|
1331
|
+
}
|
|
1332
|
+
ARIA2.PID_QUEUE.push(item);
|
|
1345
1333
|
}
|
|
1346
1334
|
}, (ARIA2.UPDATE_STATUS || 30) * 1000);
|
|
1347
1335
|
}
|
|
@@ -1364,17 +1352,16 @@ class Request extends module_1.default {
|
|
|
1364
1352
|
}
|
|
1365
1353
|
let host;
|
|
1366
1354
|
if (this.host) {
|
|
1367
|
-
host = (_o = HTTP.HOST)[_p = url.origin] || (_o[_p] = new host_1
|
|
1355
|
+
host = (_o = HTTP.HOST)[_p = url.origin] || (_o[_p] = new host_1(url, HTTP.VERSION));
|
|
1368
1356
|
}
|
|
1369
1357
|
else {
|
|
1370
|
-
host = (_q = this[kHostInfo])[_r = url.origin] || (_q[_r] = new host_1
|
|
1358
|
+
host = (_q = this[kHostInfo])[_r = url.origin] || (_q[_r] = new host_1(url, this.httpVersion || 1));
|
|
1371
1359
|
}
|
|
1372
1360
|
return { ...options, host, url };
|
|
1373
1361
|
}
|
|
1374
1362
|
open(uri, options) {
|
|
1375
|
-
var _o;
|
|
1376
|
-
|
|
1377
|
-
let { host, url, httpVersion, method = 'GET', encoding, format, headers, postData, keepAlive, agentTimeout, socketPath, timeout = this._config.connectTimeout, outStream } = options;
|
|
1363
|
+
var _o, _p;
|
|
1364
|
+
let { host, url, httpVersion, method = 'GET', search, encoding, format, headers, postData, keepAlive, agentTimeout, socketPath, timeout = this._config.connectTimeout, outStream } = options;
|
|
1378
1365
|
const getting = method === 'GET';
|
|
1379
1366
|
const posting = method === 'POST';
|
|
1380
1367
|
if (format) {
|
|
@@ -1421,6 +1408,12 @@ class Request extends module_1.default {
|
|
|
1421
1408
|
url = new URL(uri);
|
|
1422
1409
|
options.url = url;
|
|
1423
1410
|
}
|
|
1411
|
+
if (search) {
|
|
1412
|
+
for (const param in search) {
|
|
1413
|
+
url.searchParams.append(param, search[param]);
|
|
1414
|
+
}
|
|
1415
|
+
uri = url.href;
|
|
1416
|
+
}
|
|
1424
1417
|
const checkEncoding = (response, statusCode, contentEncoding = '') => {
|
|
1425
1418
|
switch (statusCode) {
|
|
1426
1419
|
case 206:
|
|
@@ -1428,7 +1421,7 @@ class Request extends module_1.default {
|
|
|
1428
1421
|
case 204:
|
|
1429
1422
|
return;
|
|
1430
1423
|
}
|
|
1431
|
-
const chunkSize = outStream
|
|
1424
|
+
const chunkSize = outStream?.writableHighWaterMark;
|
|
1432
1425
|
let pipeTo;
|
|
1433
1426
|
switch (contentEncoding.trim().toLowerCase()) {
|
|
1434
1427
|
case 'gzip':
|
|
@@ -1464,17 +1457,17 @@ class Request extends module_1.default {
|
|
|
1464
1457
|
const proxy = this.proxyOf(uri, localhost);
|
|
1465
1458
|
const version = this.httpVersion;
|
|
1466
1459
|
let request, ca, cert, key, minVersion, baseHeaders = this.headersOf(uri);
|
|
1467
|
-
if (getting && this.acceptEncoding && !localhost && !
|
|
1468
|
-
(
|
|
1460
|
+
if (getting && this.acceptEncoding && !localhost && !baseHeaders?.['accept-encoding']) {
|
|
1461
|
+
(_o = (headers || (headers = {})))['accept-encoding'] || (_o['accept-encoding'] = 'gzip, deflate, br' + (LIB_ZSTD ? ', zstd' : ''));
|
|
1469
1462
|
}
|
|
1470
1463
|
if (secure) {
|
|
1471
|
-
const certs =
|
|
1464
|
+
const certs = this[kCerts]?.[0][origin] || this.host && TLS.TEXT[origin];
|
|
1472
1465
|
if (certs) {
|
|
1473
1466
|
({ ca, cert, key, version: minVersion } = certs);
|
|
1474
1467
|
}
|
|
1475
1468
|
}
|
|
1476
1469
|
if (!proxy && httpVersion !== 1 && ((httpVersion || host.version) === 2 && version !== 1 || secure && version === 2 && host.failed(2, true) === 0)) {
|
|
1477
|
-
request = ((
|
|
1470
|
+
request = ((_p = this[kSession][0])[origin] || (_p[origin] = http2.connect(origin, { lookup: this.lookupDns(hostname), ca, cert, key, minVersion, settings: localhost ? { maxFrameSize: 16777215, enablePush: false } : { enablePush: false } }))).request({ ...baseHeaders, ...host_1.getBasicAuth(url), ...headers, ':path': pathname, ':method': method });
|
|
1478
1471
|
if (getting) {
|
|
1479
1472
|
const listenerMap = {};
|
|
1480
1473
|
const onEvent = request.on.bind(request);
|
|
@@ -1558,8 +1551,8 @@ class Request extends module_1.default {
|
|
|
1558
1551
|
const pkg = secure ? 'https-proxy-agent' : 'http-proxy-agent';
|
|
1559
1552
|
try {
|
|
1560
1553
|
const { protocol, hostname: proxyname, port, username, password, href } = proxy.host;
|
|
1561
|
-
keepAlive
|
|
1562
|
-
agentTimeout
|
|
1554
|
+
keepAlive ?? (keepAlive = proxy.keepAlive || false);
|
|
1555
|
+
agentTimeout ?? (agentTimeout = proxy.agentTimeout);
|
|
1563
1556
|
agent = require(pkg)(keepAlive || agentTimeout > 0 ? { protocol, hostname: proxyname, port, username, password, keepAlive, timeout: agentTimeout } : href);
|
|
1564
1557
|
const proxyHeaders = this[kHeaders] && getBaseHeaders(href, this[kHeaders]) || getBaseHeaders(href, HTTP.HEADERS);
|
|
1565
1558
|
if (proxyHeaders) {
|
|
@@ -1578,13 +1571,13 @@ class Request extends module_1.default {
|
|
|
1578
1571
|
}
|
|
1579
1572
|
else if (agentTimeout !== 0) {
|
|
1580
1573
|
keepAlive = this.keepAlive || false;
|
|
1581
|
-
agentTimeout
|
|
1574
|
+
agentTimeout ?? (agentTimeout = this.agentTimeout);
|
|
1582
1575
|
if (keepAlive || agentTimeout > 0) {
|
|
1583
1576
|
agent = new (secure ? https.Agent : http.Agent)({ keepAlive, timeout: agentTimeout });
|
|
1584
1577
|
}
|
|
1585
1578
|
}
|
|
1586
1579
|
}
|
|
1587
|
-
const basicAuth = host_1.
|
|
1580
|
+
const basicAuth = host_1.getBasicAuth(url);
|
|
1588
1581
|
if (baseHeaders || basicAuth) {
|
|
1589
1582
|
headers = { ...baseHeaders, ...basicAuth, ...headers };
|
|
1590
1583
|
}
|
|
@@ -1602,7 +1595,6 @@ class Request extends module_1.default {
|
|
|
1602
1595
|
lookup: this.lookupDns(hostname),
|
|
1603
1596
|
agent
|
|
1604
1597
|
}, response => {
|
|
1605
|
-
var _o;
|
|
1606
1598
|
const statusCode = response.statusCode;
|
|
1607
1599
|
const incoming = response.headers;
|
|
1608
1600
|
if (this.matchStatus(statusCode, url, incoming, request, options) && (getting || posting) && statusCode >= 200 && statusCode < 300) {
|
|
@@ -1638,7 +1630,7 @@ class Request extends module_1.default {
|
|
|
1638
1630
|
source.on('error', err => request.emit('error', err));
|
|
1639
1631
|
}
|
|
1640
1632
|
if (!posting) {
|
|
1641
|
-
if (version === 2 &&
|
|
1633
|
+
if (version === 2 && incoming.upgrade?.includes('h2')) {
|
|
1642
1634
|
host.version = 2;
|
|
1643
1635
|
}
|
|
1644
1636
|
else if (!host.didAltSvc(1)) {
|
|
@@ -1665,7 +1657,7 @@ class Request extends module_1.default {
|
|
|
1665
1657
|
if (timeout > 0) {
|
|
1666
1658
|
request.setTimeout(timeout);
|
|
1667
1659
|
}
|
|
1668
|
-
if (
|
|
1660
|
+
if (getting || posting) {
|
|
1669
1661
|
const ac = new AbortController();
|
|
1670
1662
|
this[kDownloading].add(options.outAbort = ac);
|
|
1671
1663
|
stream.addAbortSignal(ac.signal, request);
|
|
@@ -1741,7 +1733,7 @@ class Request extends module_1.default {
|
|
|
1741
1733
|
};
|
|
1742
1734
|
const addValue = (name, value) => {
|
|
1743
1735
|
if (value !== undefined) {
|
|
1744
|
-
const disposition = createPart(name) + module_1.
|
|
1736
|
+
const disposition = createPart(name) + module_1.asString(value) + "\r\n";
|
|
1745
1737
|
write.append(disposition);
|
|
1746
1738
|
contentLength += Buffer.byteLength(disposition);
|
|
1747
1739
|
}
|
|
@@ -1760,7 +1752,7 @@ class Request extends module_1.default {
|
|
|
1760
1752
|
try {
|
|
1761
1753
|
if (typeof target === 'string') {
|
|
1762
1754
|
filename || (filename = path.basename(target));
|
|
1763
|
-
type || (type = module_1.
|
|
1755
|
+
type || (type = module_1.lookupMime(filename));
|
|
1764
1756
|
target = fs.readFileSync(target);
|
|
1765
1757
|
}
|
|
1766
1758
|
else if (target instanceof stream.Readable) {
|
|
@@ -1774,14 +1766,14 @@ class Request extends module_1.default {
|
|
|
1774
1766
|
throw (0, types_1.errorMessage)('File', "Unknown", "multipart/form-data");
|
|
1775
1767
|
}
|
|
1776
1768
|
if (!type || !filename) {
|
|
1777
|
-
const result = await module_1.
|
|
1769
|
+
const result = await module_1.resolveMime(target);
|
|
1778
1770
|
let ext;
|
|
1779
1771
|
if (result) {
|
|
1780
1772
|
type || (type = result.mime);
|
|
1781
1773
|
ext = result.ext;
|
|
1782
1774
|
}
|
|
1783
1775
|
else if (type) {
|
|
1784
|
-
ext = module_1.
|
|
1776
|
+
ext = module_1.lookupMime(type, true);
|
|
1785
1777
|
}
|
|
1786
1778
|
if (ext && !filename) {
|
|
1787
1779
|
filename = (0, types_1.generateUUID)() + '.' + ext;
|
|
@@ -1809,7 +1801,7 @@ class Request extends module_1.default {
|
|
|
1809
1801
|
}
|
|
1810
1802
|
}
|
|
1811
1803
|
if (!valid) {
|
|
1812
|
-
return Promise.reject((0, types_1.errorValue)(
|
|
1804
|
+
return Promise.reject((0, types_1.errorValue)("No files were attached", "multipart/form-data"));
|
|
1813
1805
|
}
|
|
1814
1806
|
}
|
|
1815
1807
|
else {
|
|
@@ -1817,7 +1809,7 @@ class Request extends module_1.default {
|
|
|
1817
1809
|
contentType = 'application/' + contentType.trim();
|
|
1818
1810
|
}
|
|
1819
1811
|
if (!(0, types_1.isPlainObject)(data)) {
|
|
1820
|
-
data = module_1.
|
|
1812
|
+
data = module_1.asString(data);
|
|
1821
1813
|
}
|
|
1822
1814
|
else if (contentType === "application/x-www-form-urlencoded") {
|
|
1823
1815
|
data = qs.stringify(data);
|
|
@@ -1848,7 +1840,7 @@ class Request extends module_1.default {
|
|
|
1848
1840
|
if (!closed) {
|
|
1849
1841
|
closed = true;
|
|
1850
1842
|
if (outStream && (0, types_1.isString)(pipeTo)) {
|
|
1851
|
-
(0,
|
|
1843
|
+
(0, util_1.cleanupStream)(outStream, pipeTo);
|
|
1852
1844
|
}
|
|
1853
1845
|
reject(typeof err === 'string' ? new Error(err) : err);
|
|
1854
1846
|
}
|
|
@@ -1865,10 +1857,10 @@ class Request extends module_1.default {
|
|
|
1865
1857
|
try {
|
|
1866
1858
|
const request = this.opts(href, opts);
|
|
1867
1859
|
if (outStream && (0, types_1.isString)(pipeTo)) {
|
|
1868
|
-
(0,
|
|
1860
|
+
(0, util_1.cleanupStream)(outStream, pipeTo);
|
|
1869
1861
|
}
|
|
1870
1862
|
if (pipeTo) {
|
|
1871
|
-
if (
|
|
1863
|
+
if (typeof pipeTo === 'string') {
|
|
1872
1864
|
outStream = fs.createWriteStream(pipeTo, { emitClose: false, highWaterMark: request.host.localhost ? 65536 : 4096 });
|
|
1873
1865
|
request.outStream = outStream;
|
|
1874
1866
|
}
|
|
@@ -1880,7 +1872,7 @@ class Request extends module_1.default {
|
|
|
1880
1872
|
request.httpVersion = httpVersion;
|
|
1881
1873
|
}
|
|
1882
1874
|
const client = this.open(href, request);
|
|
1883
|
-
const { host, url, encoding, outFormat } = request;
|
|
1875
|
+
const { host, url, encoding, progressId, outFormat } = request;
|
|
1884
1876
|
let buffer, aborted;
|
|
1885
1877
|
({ httpVersion, outAbort } = request);
|
|
1886
1878
|
const isAborted = () => client.destroyed || httpVersion === 2 && client.aborted;
|
|
@@ -1912,21 +1904,21 @@ class Request extends module_1.default {
|
|
|
1912
1904
|
downloadUri.call(this, href);
|
|
1913
1905
|
};
|
|
1914
1906
|
const acceptResponse = (headers) => {
|
|
1915
|
-
var _o;
|
|
1916
1907
|
if ('outHeaders' in opts) {
|
|
1917
1908
|
opts.outHeaders = headers;
|
|
1918
1909
|
}
|
|
1919
1910
|
if ('outFilename' in opts) {
|
|
1920
1911
|
opts.outFilename = (0, util_1.parseHeader)(headers, 'content-disposition');
|
|
1921
1912
|
}
|
|
1922
|
-
const buffering =
|
|
1913
|
+
const buffering = request.connected?.call(client, headers);
|
|
1923
1914
|
const pipeline = pipeTo ? !(0, types_1.isString)(pipeTo) : false;
|
|
1924
1915
|
const enabled = buffering !== false && !pipeline;
|
|
1925
|
-
const
|
|
1926
|
-
|
|
1927
|
-
|
|
1916
|
+
const maxBufferSize = request.maxBufferSize ? (0, types_1.alignSize)(request.maxBufferSize) : 0;
|
|
1917
|
+
const { host: parent, readTimeout } = this;
|
|
1918
|
+
const contentLength = parent && progressId !== undefined ? parseInt(headers['content-length'] || '0') : 0;
|
|
1919
|
+
let dataLength = 0, mibsTime, delayTime;
|
|
1920
|
+
if (log || readTimeout > 0 || contentLength > 0) {
|
|
1928
1921
|
client.once('readable', () => {
|
|
1929
|
-
var _o;
|
|
1930
1922
|
if (readTimeout > 0) {
|
|
1931
1923
|
timeout = setTimeout(() => {
|
|
1932
1924
|
abortResponse();
|
|
@@ -1934,7 +1926,7 @@ class Request extends module_1.default {
|
|
|
1934
1926
|
}, readTimeout);
|
|
1935
1927
|
}
|
|
1936
1928
|
if (log) {
|
|
1937
|
-
switch (
|
|
1929
|
+
switch (this.settings?.time_format || LOG_TIMEFORMAT) {
|
|
1938
1930
|
case 'readable':
|
|
1939
1931
|
delayTime = process.hrtime(startTime);
|
|
1940
1932
|
break;
|
|
@@ -1942,7 +1934,10 @@ class Request extends module_1.default {
|
|
|
1942
1934
|
delayTime = Date.now() - this.startTime;
|
|
1943
1935
|
break;
|
|
1944
1936
|
}
|
|
1945
|
-
|
|
1937
|
+
}
|
|
1938
|
+
mibsTime = process.hrtime();
|
|
1939
|
+
if (contentLength > 0) {
|
|
1940
|
+
parent.updateProgress("request", progressId, 0, 0, mibsTime);
|
|
1946
1941
|
}
|
|
1947
1942
|
});
|
|
1948
1943
|
}
|
|
@@ -1962,6 +1957,19 @@ class Request extends module_1.default {
|
|
|
1962
1957
|
else {
|
|
1963
1958
|
buffer = typeof chunk === 'string' ? chunk : [chunk];
|
|
1964
1959
|
}
|
|
1960
|
+
if (contentLength > 0) {
|
|
1961
|
+
dataLength += Buffer.byteLength(chunk, encoding);
|
|
1962
|
+
parent.updateProgress("request", progressId, dataLength, contentLength);
|
|
1963
|
+
}
|
|
1964
|
+
if (maxBufferSize > 0) {
|
|
1965
|
+
if (contentLength === 0) {
|
|
1966
|
+
dataLength += Buffer.byteLength(chunk, encoding);
|
|
1967
|
+
}
|
|
1968
|
+
if (dataLength > maxBufferSize) {
|
|
1969
|
+
abortResponse();
|
|
1970
|
+
throwError((0, types_1.errorValue)("Size limit was exceeded", href.toString()));
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1965
1973
|
});
|
|
1966
1974
|
}
|
|
1967
1975
|
client.once('end', () => {
|
|
@@ -1984,20 +1992,15 @@ class Request extends module_1.default {
|
|
|
1984
1992
|
buffer = buffer.toString(encoding);
|
|
1985
1993
|
}
|
|
1986
1994
|
}
|
|
1995
|
+
dataLength = Buffer.byteLength(buffer, encoding);
|
|
1987
1996
|
if (mibsTime) {
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
else if (unit < 1000) {
|
|
1993
|
-
messageUnit = unit.toPrecision(3) + 'MiB/s';
|
|
1994
|
-
}
|
|
1995
|
-
else {
|
|
1996
|
-
messageUnit = (unit / 1000).toPrecision(3) + 'GiB/s';
|
|
1997
|
-
}
|
|
1997
|
+
messageUnit = (0, util_1.getTransferRate)(dataLength, (0, types_1.convertTime)(process.hrtime(mibsTime), false) * 1000);
|
|
1998
|
+
}
|
|
1999
|
+
if (contentLength > 0) {
|
|
2000
|
+
parent.updateProgress("request", progressId, dataLength, dataLength);
|
|
1998
2001
|
}
|
|
1999
2002
|
if (typeof buffer === 'string') {
|
|
2000
|
-
if (buffer.startsWith('\uFEFF') && encoding !== 'utf16le') {
|
|
2003
|
+
if (buffer.startsWith('\uFEFF') && encoding !== 'utf16le' && encoding !== 'utf-16le') {
|
|
2001
2004
|
buffer = buffer.substring(1);
|
|
2002
2005
|
}
|
|
2003
2006
|
if (outFormat) {
|
|
@@ -2037,11 +2040,14 @@ class Request extends module_1.default {
|
|
|
2037
2040
|
result = buffer;
|
|
2038
2041
|
}
|
|
2039
2042
|
}
|
|
2040
|
-
else if (enabled && this.readExpect === 'always') {
|
|
2041
|
-
throwError('No data received');
|
|
2042
|
-
return;
|
|
2043
|
-
}
|
|
2044
2043
|
else {
|
|
2044
|
+
if (contentLength > 0) {
|
|
2045
|
+
parent.updateProgress("request", progressId, 0, contentLength);
|
|
2046
|
+
}
|
|
2047
|
+
if (enabled && this.readExpect === 'always') {
|
|
2048
|
+
throwError('No data received');
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2045
2051
|
result = encoding && !pipeline ? '' : null;
|
|
2046
2052
|
titleBgColor = 'bgBlue';
|
|
2047
2053
|
}
|
|
@@ -2055,7 +2061,10 @@ class Request extends module_1.default {
|
|
|
2055
2061
|
const redirectResponse = (statusCode, location) => {
|
|
2056
2062
|
abortResponse();
|
|
2057
2063
|
if (location) {
|
|
2058
|
-
if (
|
|
2064
|
+
if (request.follow_redirect === false) {
|
|
2065
|
+
throwError(formatStatus(statusCode, 'Follow redirect was disabled'));
|
|
2066
|
+
}
|
|
2067
|
+
else if (++redirects <= this._config.redirectLimit) {
|
|
2059
2068
|
downloadUri.call(this, Request.fromURL(url, location));
|
|
2060
2069
|
}
|
|
2061
2070
|
else {
|
|
@@ -2264,8 +2273,7 @@ class Request extends module_1.default {
|
|
|
2264
2273
|
this[kDownloading].clear();
|
|
2265
2274
|
}
|
|
2266
2275
|
matchStatus(code, url, headers, request, options) {
|
|
2267
|
-
|
|
2268
|
-
const status = (_o = this[kStatusOn]) === null || _o === void 0 ? void 0 : _o.get(code);
|
|
2276
|
+
const status = this[kStatusOn]?.get(code);
|
|
2269
2277
|
if (status) {
|
|
2270
2278
|
const href = url.href;
|
|
2271
2279
|
const called = new Set();
|
|
@@ -2290,7 +2298,7 @@ class Request extends module_1.default {
|
|
|
2290
2298
|
}
|
|
2291
2299
|
matchHeaders(url, headers, request, options) {
|
|
2292
2300
|
const on = this[kHeadersOn];
|
|
2293
|
-
if (on
|
|
2301
|
+
if (on?.size) {
|
|
2294
2302
|
const href = url.href;
|
|
2295
2303
|
const called = new Map();
|
|
2296
2304
|
for (const [name, item] of on) {
|
|
@@ -2321,14 +2329,13 @@ class Request extends module_1.default {
|
|
|
2321
2329
|
return true;
|
|
2322
2330
|
}
|
|
2323
2331
|
set agentTimeout(value) {
|
|
2324
|
-
var _o, _p;
|
|
2325
2332
|
if (value > 0) {
|
|
2326
2333
|
this[kAgentTimeout] = value;
|
|
2327
|
-
|
|
2334
|
+
this.keepAlive ?? (this.keepAlive = true);
|
|
2328
2335
|
}
|
|
2329
2336
|
else {
|
|
2330
2337
|
this[kAgentTimeout] = 0;
|
|
2331
|
-
|
|
2338
|
+
this.keepAlive ?? (this.keepAlive = false);
|
|
2332
2339
|
}
|
|
2333
2340
|
}
|
|
2334
2341
|
get agentTimeout() {
|
|
@@ -2363,9 +2370,5 @@ class Request extends module_1.default {
|
|
|
2363
2370
|
}
|
|
2364
2371
|
}
|
|
2365
2372
|
_a = kSingleton, _b = kHttpVersion, _c = kHeaders, _d = kCerts, _e = kConnectDns, _f = kPendingDns, _g = kConnectHttp, _h = kStatusOn, _j = kHeadersOn, _k = kDownloading, _l = kHostInfo, _m = kSession;
|
|
2366
|
-
exports.default = Request;
|
|
2367
2373
|
|
|
2368
|
-
|
|
2369
|
-
module.exports = exports.default;
|
|
2370
|
-
module.exports.default = exports.default;
|
|
2371
|
-
}
|
|
2374
|
+
module.exports = Request;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/request",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Request constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
"squared-functions"
|
|
18
18
|
],
|
|
19
19
|
"author": "An Pham <anpham6@gmail.com>",
|
|
20
|
-
"license": "
|
|
20
|
+
"license": "BSD 3-Clause",
|
|
21
21
|
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/module": "0.
|
|
24
|
-
"@e-mc/types": "0.
|
|
23
|
+
"@e-mc/module": "0.9.1",
|
|
24
|
+
"@e-mc/types": "0.9.1",
|
|
25
25
|
"combined-stream": "^1.0.8",
|
|
26
26
|
"js-yaml": "^4.1.0",
|
|
27
|
-
"picomatch": "^
|
|
27
|
+
"picomatch": "^4.0.2",
|
|
28
28
|
"which": "^2.0.2"
|
|
29
29
|
}
|
|
30
30
|
}
|
package/util.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import type { AuthValue } from '../types/lib/http';
|
|
2
|
+
|
|
1
3
|
import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'http';
|
|
4
|
+
import type { Readable, Writable } from 'stream';
|
|
2
5
|
|
|
3
6
|
declare namespace util {
|
|
4
7
|
function parseHeader<T = unknown>(headers: IncomingHttpHeaders, name: string): T | undefined;
|
|
@@ -12,6 +15,12 @@ declare namespace util {
|
|
|
12
15
|
function asInt(value: unknown): number;
|
|
13
16
|
function asFloat(value: unknown): number;
|
|
14
17
|
function fromSeconds(value: unknown): number;
|
|
18
|
+
function getTransferRate(length: number, timeMs: number, unitSeparator?: string): string;
|
|
19
|
+
function hasSameStat(src: string, dest: string, keepEmpty?: boolean): boolean;
|
|
20
|
+
function hasSize(value: string, keepEmpty?: boolean): boolean;
|
|
21
|
+
function getSize(value: string, diskUsed?: boolean): number;
|
|
22
|
+
function byteLength(value: Bufferable, encoding?: BufferEncoding): number;
|
|
23
|
+
function cleanupStream(target: Readable | Writable, pathname?: string): void;
|
|
15
24
|
}
|
|
16
25
|
|
|
17
26
|
export = util;
|
package/util.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
exports.cleanupStream = exports.byteLength = exports.hasSameStat = exports.getSize = exports.hasSize = exports.getTransferRate = exports.fromSeconds = exports.asFloat = exports.asInt = exports.trimPath = exports.isRetryable = exports.checkRetryable = exports.hasBasicAuth = exports.getBasicAuth = exports.normalizeHeaders = exports.parseHeader = void 0;
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
4
5
|
const module_1 = require("@e-mc/module");
|
|
5
6
|
const types_1 = require("@e-mc/types");
|
|
6
7
|
const safeInt = (value) => value >= 0 ? Math.min(value, Number.MAX_SAFE_INTEGER) : NaN;
|
|
@@ -9,9 +10,8 @@ function parseHeader(headers, name) {
|
|
|
9
10
|
if (value) {
|
|
10
11
|
switch (name.toLowerCase()) {
|
|
11
12
|
case 'content-disposition': {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
while (match = pattern.exec(value)) {
|
|
13
|
+
let result;
|
|
14
|
+
for (const match of value.matchAll(/\bfilename(?:\*\s*=\s*UTF-8''([^\s;]+)|\s*=\s*(?:"([^"]+)"|([^\s;]+)))/gi)) {
|
|
15
15
|
if (match[1]) {
|
|
16
16
|
return decodeURIComponent(match[1]).trim();
|
|
17
17
|
}
|
|
@@ -36,7 +36,7 @@ function normalizeHeaders(headers) {
|
|
|
36
36
|
break;
|
|
37
37
|
default:
|
|
38
38
|
if (Array.isArray(value)) {
|
|
39
|
-
value = value.map(out => module_1.
|
|
39
|
+
value = value.map(out => module_1.asString(out).trim());
|
|
40
40
|
break;
|
|
41
41
|
}
|
|
42
42
|
continue;
|
|
@@ -57,7 +57,7 @@ function getBasicAuth(username, password) {
|
|
|
57
57
|
exports.getBasicAuth = getBasicAuth;
|
|
58
58
|
function hasBasicAuth(value) {
|
|
59
59
|
try {
|
|
60
|
-
return
|
|
60
|
+
return new URL(value).username.length > 0;
|
|
61
61
|
}
|
|
62
62
|
catch {
|
|
63
63
|
}
|
|
@@ -146,3 +146,75 @@ function fromSeconds(value) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
exports.fromSeconds = fromSeconds;
|
|
149
|
+
function getTransferRate(length, timeMs, unitSeparator = '') {
|
|
150
|
+
const unit = (length * 8) / timeMs;
|
|
151
|
+
if (unit < 1) {
|
|
152
|
+
return Math.ceil(unit * 1000) + unitSeparator + 'KiB/s';
|
|
153
|
+
}
|
|
154
|
+
if (unit < 1000) {
|
|
155
|
+
return unit.toPrecision(3) + unitSeparator + 'MiB/s';
|
|
156
|
+
}
|
|
157
|
+
return (unit / 1000).toPrecision(3) + unitSeparator + 'GiB/s';
|
|
158
|
+
}
|
|
159
|
+
exports.getTransferRate = getTransferRate;
|
|
160
|
+
function hasSize(value, keepEmpty) {
|
|
161
|
+
try {
|
|
162
|
+
const statSrc = fs.statSync(value);
|
|
163
|
+
if (statSrc.size > 0) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
if (!keepEmpty) {
|
|
167
|
+
fs.unlinkSync(value);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
}
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
exports.hasSize = hasSize;
|
|
175
|
+
function getSize(value, diskUsed) {
|
|
176
|
+
try {
|
|
177
|
+
return (diskUsed ? fs.lstatSync(value) : fs.statSync(value)).size;
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.getSize = getSize;
|
|
184
|
+
function hasSameStat(src, dest, keepEmpty) {
|
|
185
|
+
try {
|
|
186
|
+
if (fs.existsSync(dest)) {
|
|
187
|
+
const { size, mtimeMs } = fs.statSync(src);
|
|
188
|
+
if (size > 0) {
|
|
189
|
+
const statDest = fs.statSync(dest);
|
|
190
|
+
return size === statDest.size && mtimeMs === statDest.mtimeMs;
|
|
191
|
+
}
|
|
192
|
+
if (!keepEmpty) {
|
|
193
|
+
fs.unlinkSync(src);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
}
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
exports.hasSameStat = hasSameStat;
|
|
202
|
+
function byteLength(value, encoding) {
|
|
203
|
+
return typeof value === 'string' && (path.isAbsolute(value) || module_1.isPath(value)) ? getSize(value) : Buffer.byteLength(value, encoding && (0, types_1.getEncoding)(encoding));
|
|
204
|
+
}
|
|
205
|
+
exports.byteLength = byteLength;
|
|
206
|
+
function cleanupStream(stream, uri) {
|
|
207
|
+
try {
|
|
208
|
+
stream.removeAllListeners();
|
|
209
|
+
stream.destroy();
|
|
210
|
+
if (uri && fs.existsSync(uri)) {
|
|
211
|
+
fs.unlinkSync(uri);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
if (!module_1.isErrorCode(err, 'ENOENT')) {
|
|
216
|
+
module_1.writeFail(["Unable to delete file", path.basename(uri)], err, 32);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
exports.cleanupStream = cleanupStream;
|