rekwest 4.1.0 → 4.2.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/README.md +188 -187
- package/dist/ackn.js +1 -1
- package/dist/constants.js +11 -5
- package/dist/defaults.js +41 -0
- package/dist/index.js +30 -211
- package/dist/postflight.js +111 -0
- package/dist/preflight.js +65 -0
- package/dist/utils.js +122 -73
- package/package.json +1 -1
- package/src/ackn.mjs +1 -1
- package/src/constants.mjs +8 -2
- package/src/defaults.mjs +44 -0
- package/src/index.mjs +15 -243
- package/src/postflight.mjs +136 -0
- package/src/preflight.mjs +69 -0
- package/src/utils.mjs +146 -79
package/dist/index.js
CHANGED
|
@@ -12,14 +12,6 @@ var _nodeHttp = _interopRequireDefault(require("node:http"));
|
|
|
12
12
|
var _nodeHttp2 = _interopRequireWildcard(require("node:http2"));
|
|
13
13
|
exports.constants = _nodeHttp2.constants;
|
|
14
14
|
var _nodeHttps = _interopRequireDefault(require("node:https"));
|
|
15
|
-
var _promises = require("node:timers/promises");
|
|
16
|
-
var _ackn = require("./ackn");
|
|
17
|
-
Object.keys(_ackn).forEach(function (key) {
|
|
18
|
-
if (key === "default" || key === "__esModule") return;
|
|
19
|
-
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
20
|
-
if (key in exports && exports[key] === _ackn[key]) return;
|
|
21
|
-
exports[key] = _ackn[key];
|
|
22
|
-
});
|
|
23
15
|
var _constants = require("./constants");
|
|
24
16
|
Object.keys(_constants).forEach(function (key) {
|
|
25
17
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -27,6 +19,24 @@ Object.keys(_constants).forEach(function (key) {
|
|
|
27
19
|
if (key in exports && exports[key] === _constants[key]) return;
|
|
28
20
|
exports[key] = _constants[key];
|
|
29
21
|
});
|
|
22
|
+
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
23
|
+
var _mediatypes = _interopRequireWildcard(require("./mediatypes"));
|
|
24
|
+
exports.mediatypes = _mediatypes;
|
|
25
|
+
var _preflight = require("./preflight");
|
|
26
|
+
var _utils = require("./utils");
|
|
27
|
+
Object.keys(_utils).forEach(function (key) {
|
|
28
|
+
if (key === "default" || key === "__esModule") return;
|
|
29
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
30
|
+
if (key in exports && exports[key] === _utils[key]) return;
|
|
31
|
+
exports[key] = _utils[key];
|
|
32
|
+
});
|
|
33
|
+
var _ackn = require("./ackn");
|
|
34
|
+
Object.keys(_ackn).forEach(function (key) {
|
|
35
|
+
if (key === "default" || key === "__esModule") return;
|
|
36
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
37
|
+
if (key in exports && exports[key] === _ackn[key]) return;
|
|
38
|
+
exports[key] = _ackn[key];
|
|
39
|
+
});
|
|
30
40
|
var _cookies = require("./cookies");
|
|
31
41
|
Object.keys(_cookies).forEach(function (key) {
|
|
32
42
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -41,15 +51,6 @@ Object.keys(_errors).forEach(function (key) {
|
|
|
41
51
|
if (key in exports && exports[key] === _errors[key]) return;
|
|
42
52
|
exports[key] = _errors[key];
|
|
43
53
|
});
|
|
44
|
-
var _mediatypes = _interopRequireWildcard(require("./mediatypes"));
|
|
45
|
-
exports.mediatypes = _mediatypes;
|
|
46
|
-
var _utils = require("./utils");
|
|
47
|
-
Object.keys(_utils).forEach(function (key) {
|
|
48
|
-
if (key === "default" || key === "__esModule") return;
|
|
49
|
-
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
50
|
-
if (key in exports && exports[key] === _utils[key]) return;
|
|
51
|
-
exports[key] = _utils[key];
|
|
52
|
-
});
|
|
53
54
|
var _file = require("./file");
|
|
54
55
|
Object.keys(_file).forEach(function (key) {
|
|
55
56
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -68,220 +69,38 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
|
|
|
68
69
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
69
70
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
70
71
|
const {
|
|
71
|
-
|
|
72
|
-
HTTP2_HEADER_CONTENT_TYPE,
|
|
73
|
-
HTTP2_HEADER_LOCATION,
|
|
74
|
-
HTTP2_HEADER_RETRY_AFTER,
|
|
75
|
-
HTTP2_HEADER_SET_COOKIE,
|
|
76
|
-
HTTP2_METHOD_GET,
|
|
77
|
-
HTTP2_METHOD_HEAD,
|
|
78
|
-
HTTP2_METHOD_POST,
|
|
79
|
-
HTTP_STATUS_BAD_REQUEST,
|
|
80
|
-
HTTP_STATUS_FOUND,
|
|
81
|
-
HTTP_STATUS_MOVED_PERMANENTLY,
|
|
82
|
-
HTTP_STATUS_SEE_OTHER,
|
|
83
|
-
HTTP_STATUS_SERVICE_UNAVAILABLE,
|
|
84
|
-
HTTP_STATUS_TOO_MANY_REQUESTS
|
|
72
|
+
HTTP2_HEADER_CONTENT_TYPE
|
|
85
73
|
} = _nodeHttp2.default.constants;
|
|
86
|
-
|
|
87
|
-
const maxRetryAfterError = (interval, options) => new _errors.RequestError(`Maximum '${HTTP2_HEADER_RETRY_AFTER}' limit exceeded: ${interval} ms.`, options);
|
|
88
|
-
let defaults = {
|
|
89
|
-
follow: 20,
|
|
90
|
-
get maxRetryAfter() {
|
|
91
|
-
return this[maxRetryAfter] ?? this.timeout;
|
|
92
|
-
},
|
|
93
|
-
set maxRetryAfter(value) {
|
|
94
|
-
this[maxRetryAfter] = value;
|
|
95
|
-
},
|
|
96
|
-
method: HTTP2_METHOD_GET,
|
|
97
|
-
retry: {
|
|
98
|
-
attempts: 0,
|
|
99
|
-
backoffStrategy: 'interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)',
|
|
100
|
-
interval: 1e3,
|
|
101
|
-
retryAfter: true,
|
|
102
|
-
statusCodes: [HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_SERVICE_UNAVAILABLE]
|
|
103
|
-
},
|
|
104
|
-
timeout: 3e5
|
|
105
|
-
};
|
|
106
|
-
async function rekwest(...args) {
|
|
74
|
+
function rekwest(...args) {
|
|
107
75
|
let options = (0, _utils.sanitize)(...args);
|
|
108
|
-
const {
|
|
109
|
-
url
|
|
110
|
-
} = options;
|
|
111
76
|
if (!options.redirected) {
|
|
112
77
|
options = (0, _utils.merge)(rekwest.defaults, options);
|
|
113
78
|
}
|
|
114
|
-
|
|
115
|
-
throw new TypeError(`Request with ${HTTP2_METHOD_GET}/${HTTP2_METHOD_HEAD} method cannot have body.`);
|
|
116
|
-
}
|
|
117
|
-
if (options.follow === 0) {
|
|
118
|
-
throw new _errors.RequestError(`Maximum redirect reached at: ${url.href}`);
|
|
119
|
-
}
|
|
120
|
-
if (url.protocol === 'https:') {
|
|
121
|
-
options = await (0, _ackn.ackn)(options);
|
|
122
|
-
} else if (Reflect.has(options, 'alpnProtocol')) {
|
|
123
|
-
['alpnProtocol', 'createConnection', 'h2', 'protocol'].forEach(it => Reflect.deleteProperty(options, it));
|
|
124
|
-
}
|
|
125
|
-
options = await (0, _utils.transform)((0, _utils.preflight)(options));
|
|
126
|
-
const {
|
|
127
|
-
cookies,
|
|
128
|
-
digest,
|
|
129
|
-
follow,
|
|
130
|
-
h2,
|
|
131
|
-
redirect,
|
|
132
|
-
redirected,
|
|
133
|
-
thenable
|
|
134
|
-
} = options;
|
|
135
|
-
const {
|
|
136
|
-
request
|
|
137
|
-
} = url.protocol === 'http:' ? _nodeHttp.default : _nodeHttps.default;
|
|
138
|
-
const promise = new Promise((resolve, reject) => {
|
|
139
|
-
let client, req;
|
|
140
|
-
if (h2) {
|
|
141
|
-
client = _nodeHttp2.default.connect(url.origin, options);
|
|
142
|
-
req = client.request(options.headers, options);
|
|
143
|
-
} else {
|
|
144
|
-
req = request(url, options);
|
|
145
|
-
}
|
|
146
|
-
(0, _utils.affix)(client, req, options);
|
|
147
|
-
req.once('error', reject);
|
|
148
|
-
req.once('frameError', reject);
|
|
149
|
-
req.once('goaway', reject);
|
|
150
|
-
req.once('response', res => {
|
|
151
|
-
let headers;
|
|
152
|
-
if (h2) {
|
|
153
|
-
headers = res;
|
|
154
|
-
res = req;
|
|
155
|
-
} else {
|
|
156
|
-
res.once('error', reject);
|
|
157
|
-
}
|
|
158
|
-
(0, _utils.admix)(res, headers, options);
|
|
159
|
-
if (cookies !== false && res.headers[HTTP2_HEADER_SET_COOKIE]) {
|
|
160
|
-
if (_cookies.Cookies.jar.has(url.origin)) {
|
|
161
|
-
new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]).forEach(function (val, key) {
|
|
162
|
-
this.set(key, val);
|
|
163
|
-
}, _cookies.Cookies.jar.get(url.origin));
|
|
164
|
-
} else {
|
|
165
|
-
_cookies.Cookies.jar.set(url.origin, new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]));
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
Reflect.defineProperty(res, 'cookies', {
|
|
169
|
-
enumerable: true,
|
|
170
|
-
value: cookies !== false && _cookies.Cookies.jar.has(url.origin) ? _cookies.Cookies.jar.get(url.origin) : void 0
|
|
171
|
-
});
|
|
172
|
-
const {
|
|
173
|
-
statusCode
|
|
174
|
-
} = res;
|
|
175
|
-
if (follow && /3\d{2}/.test(statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
|
|
176
|
-
if (!_constants.redirectStatusCodes.includes(statusCode)) {
|
|
177
|
-
return res.emit('error', new RangeError(`Invalid status code: ${statusCode}`));
|
|
178
|
-
}
|
|
179
|
-
if (redirect === _constants.redirectModes.error) {
|
|
180
|
-
return res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
|
|
181
|
-
}
|
|
182
|
-
if (redirect === _constants.redirectModes.follow) {
|
|
183
|
-
const location = new URL(res.headers[HTTP2_HEADER_LOCATION], url);
|
|
184
|
-
if (!/^https?:/.test(location.protocol)) {
|
|
185
|
-
return res.emit('error', new _errors.RequestError('URL scheme must be "http" or "https".'));
|
|
186
|
-
}
|
|
187
|
-
if (!(0, _utils.sameOrigin)(location, url)) {
|
|
188
|
-
Reflect.deleteProperty(options.headers, HTTP2_HEADER_AUTHORIZATION);
|
|
189
|
-
location.password = location.username = '';
|
|
190
|
-
}
|
|
191
|
-
options.url = location;
|
|
192
|
-
if (statusCode !== HTTP_STATUS_SEE_OTHER && options?.body?.pipe?.constructor === Function) {
|
|
193
|
-
return res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with streamable body.`));
|
|
194
|
-
}
|
|
195
|
-
options.follow--;
|
|
196
|
-
if ([HTTP_STATUS_MOVED_PERMANENTLY, HTTP_STATUS_FOUND].includes(statusCode) && request.method === HTTP2_METHOD_POST || statusCode === HTTP_STATUS_SEE_OTHER && ![HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(options.method)) {
|
|
197
|
-
Object.keys(options.headers).filter(it => /^content-/i.test(it)).forEach(it => Reflect.deleteProperty(options.headers, it));
|
|
198
|
-
options.body = null;
|
|
199
|
-
options.method = HTTP2_METHOD_GET;
|
|
200
|
-
}
|
|
201
|
-
Reflect.set(options, 'redirected', true);
|
|
202
|
-
if (statusCode === HTTP_STATUS_MOVED_PERMANENTLY && res.headers[HTTP2_HEADER_RETRY_AFTER]) {
|
|
203
|
-
let interval = res.headers[HTTP2_HEADER_RETRY_AFTER];
|
|
204
|
-
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
205
|
-
if (interval > options.maxRetryAfter) {
|
|
206
|
-
return res.emit('error', maxRetryAfterError(interval, {
|
|
207
|
-
cause: (0, _utils.mixin)(res, options)
|
|
208
|
-
}));
|
|
209
|
-
}
|
|
210
|
-
return (0, _promises.setTimeout)(interval).then(() => rekwest(options.url, options).then(resolve, reject));
|
|
211
|
-
}
|
|
212
|
-
return rekwest(options.url, options).then(resolve, reject);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
if (statusCode >= HTTP_STATUS_BAD_REQUEST) {
|
|
216
|
-
return reject((0, _utils.mixin)(res, options));
|
|
217
|
-
}
|
|
218
|
-
resolve((0, _utils.mixin)(res, options));
|
|
219
|
-
});
|
|
220
|
-
(0, _utils.dispatch)(options, req);
|
|
221
|
-
});
|
|
222
|
-
try {
|
|
223
|
-
const res = await promise;
|
|
224
|
-
if (digest && !redirected) {
|
|
225
|
-
res.body = await res.body();
|
|
226
|
-
}
|
|
227
|
-
return res;
|
|
228
|
-
} catch (ex) {
|
|
229
|
-
const {
|
|
230
|
-
maxRetryAfter,
|
|
231
|
-
retry
|
|
232
|
-
} = options;
|
|
233
|
-
if (retry?.attempts && retry?.statusCodes.includes(ex.statusCode)) {
|
|
234
|
-
let {
|
|
235
|
-
interval
|
|
236
|
-
} = retry;
|
|
237
|
-
if (retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
|
|
238
|
-
interval = ex.headers[HTTP2_HEADER_RETRY_AFTER];
|
|
239
|
-
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
240
|
-
if (interval > maxRetryAfter) {
|
|
241
|
-
throw maxRetryAfterError(interval, {
|
|
242
|
-
cause: ex
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
} else {
|
|
246
|
-
interval = new Function('interval', `return Math.ceil(${retry.backoffStrategy});`)(interval);
|
|
247
|
-
}
|
|
248
|
-
retry.attempts--;
|
|
249
|
-
retry.interval = interval;
|
|
250
|
-
return (0, _promises.setTimeout)(interval).then(() => rekwest(url, options));
|
|
251
|
-
}
|
|
252
|
-
if (digest && !redirected && ex.body) {
|
|
253
|
-
ex.body = await ex.body();
|
|
254
|
-
}
|
|
255
|
-
if (!thenable) {
|
|
256
|
-
throw ex;
|
|
257
|
-
} else {
|
|
258
|
-
return ex;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
79
|
+
return (0, _utils.transfer)((0, _utils.validation)(options));
|
|
261
80
|
}
|
|
262
81
|
Reflect.defineProperty(rekwest, 'stream', {
|
|
263
82
|
enumerable: true,
|
|
264
83
|
value(...args) {
|
|
265
|
-
const options = (0,
|
|
266
|
-
...(0, _utils.merge)(rekwest.defaults, {
|
|
84
|
+
const options = (0, _preflight.preflight)({
|
|
85
|
+
...(0, _utils.validation)((0, _utils.merge)(rekwest.defaults, {
|
|
267
86
|
headers: {
|
|
268
87
|
[HTTP2_HEADER_CONTENT_TYPE]: _mediatypes.APPLICATION_OCTET_STREAM
|
|
269
88
|
}
|
|
270
|
-
}, (0, _utils.sanitize)(...args)),
|
|
271
|
-
redirect: _constants.
|
|
89
|
+
}, (0, _utils.sanitize)(...args))),
|
|
90
|
+
redirect: _constants.requestRedirect.manual
|
|
272
91
|
});
|
|
273
92
|
const {
|
|
274
93
|
h2,
|
|
275
94
|
url
|
|
276
95
|
} = options;
|
|
277
|
-
const {
|
|
278
|
-
request
|
|
279
|
-
} = url.protocol === 'http:' ? _nodeHttp.default : _nodeHttps.default;
|
|
280
96
|
let client, req;
|
|
281
97
|
if (h2) {
|
|
282
98
|
client = _nodeHttp2.default.connect(url.origin, options);
|
|
283
99
|
req = client.request(options.headers, options);
|
|
284
100
|
} else {
|
|
101
|
+
const {
|
|
102
|
+
request
|
|
103
|
+
} = url.protocol === 'http:' ? _nodeHttp.default : _nodeHttps.default;
|
|
285
104
|
req = request(url, options);
|
|
286
105
|
}
|
|
287
106
|
(0, _utils.affix)(client, req, options);
|
|
@@ -299,9 +118,9 @@ Reflect.defineProperty(rekwest, 'stream', {
|
|
|
299
118
|
Reflect.defineProperty(rekwest, 'defaults', {
|
|
300
119
|
enumerable: true,
|
|
301
120
|
get() {
|
|
302
|
-
return
|
|
121
|
+
return _defaults.default.stash;
|
|
303
122
|
},
|
|
304
123
|
set(value) {
|
|
305
|
-
|
|
124
|
+
_defaults.default.stash = (0, _utils.merge)(_defaults.default.stash, value);
|
|
306
125
|
}
|
|
307
126
|
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.postflight = void 0;
|
|
5
|
+
var _nodeHttp = _interopRequireDefault(require("node:http2"));
|
|
6
|
+
var _promises = require("node:timers/promises");
|
|
7
|
+
var _constants = require("./constants");
|
|
8
|
+
var _cookies = require("./cookies");
|
|
9
|
+
var _errors = require("./errors");
|
|
10
|
+
var _index = _interopRequireDefault(require("./index"));
|
|
11
|
+
var _utils = require("./utils");
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
const {
|
|
14
|
+
HTTP2_HEADER_AUTHORIZATION,
|
|
15
|
+
HTTP2_HEADER_LOCATION,
|
|
16
|
+
HTTP2_HEADER_RETRY_AFTER,
|
|
17
|
+
HTTP2_HEADER_SET_COOKIE,
|
|
18
|
+
HTTP2_METHOD_GET,
|
|
19
|
+
HTTP2_METHOD_HEAD,
|
|
20
|
+
HTTP2_METHOD_POST,
|
|
21
|
+
HTTP_STATUS_BAD_REQUEST,
|
|
22
|
+
HTTP_STATUS_FOUND,
|
|
23
|
+
HTTP_STATUS_MOVED_PERMANENTLY,
|
|
24
|
+
HTTP_STATUS_SEE_OTHER
|
|
25
|
+
} = _nodeHttp.default.constants;
|
|
26
|
+
const postflight = (req, res, options, {
|
|
27
|
+
reject,
|
|
28
|
+
resolve
|
|
29
|
+
}) => {
|
|
30
|
+
const {
|
|
31
|
+
cookies,
|
|
32
|
+
credentials,
|
|
33
|
+
follow,
|
|
34
|
+
h2,
|
|
35
|
+
redirect,
|
|
36
|
+
url
|
|
37
|
+
} = options;
|
|
38
|
+
let headers;
|
|
39
|
+
if (h2) {
|
|
40
|
+
headers = res;
|
|
41
|
+
res = req;
|
|
42
|
+
} else {
|
|
43
|
+
res.once('error', reject);
|
|
44
|
+
}
|
|
45
|
+
(0, _utils.admix)(res, headers, options);
|
|
46
|
+
if (cookies !== false && res.headers[HTTP2_HEADER_SET_COOKIE]) {
|
|
47
|
+
if (_cookies.Cookies.jar.has(url.origin)) {
|
|
48
|
+
new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]).forEach(function (val, key) {
|
|
49
|
+
this.set(key, val);
|
|
50
|
+
}, _cookies.Cookies.jar.get(url.origin));
|
|
51
|
+
} else {
|
|
52
|
+
_cookies.Cookies.jar.set(url.origin, new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
Reflect.defineProperty(res, 'cookies', {
|
|
56
|
+
enumerable: true,
|
|
57
|
+
value: cookies !== false && _cookies.Cookies.jar.has(url.origin) ? _cookies.Cookies.jar.get(url.origin) : void 0
|
|
58
|
+
});
|
|
59
|
+
const {
|
|
60
|
+
statusCode
|
|
61
|
+
} = res;
|
|
62
|
+
if (follow && /3\d{2}/.test(statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
|
|
63
|
+
if (!_constants.requestRedirectCodes.includes(statusCode)) {
|
|
64
|
+
return res.emit('error', new RangeError(`Invalid status code: ${statusCode}`));
|
|
65
|
+
}
|
|
66
|
+
if (redirect === _constants.requestRedirect.error) {
|
|
67
|
+
return res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
|
|
68
|
+
}
|
|
69
|
+
if (redirect === _constants.requestRedirect.follow) {
|
|
70
|
+
const location = new URL(res.headers[HTTP2_HEADER_LOCATION], url);
|
|
71
|
+
if (!/^https?:/i.test(location.protocol)) {
|
|
72
|
+
return res.emit('error', new _errors.RequestError('URL scheme must be "http" or "https".'));
|
|
73
|
+
}
|
|
74
|
+
if (!(0, _utils.sameOrigin)(location, url) && [_constants.requestCredentials.omit, _constants.requestCredentials.sameOrigin].includes(credentials)) {
|
|
75
|
+
Reflect.deleteProperty(options.headers, HTTP2_HEADER_AUTHORIZATION);
|
|
76
|
+
location.password = location.username = '';
|
|
77
|
+
if (credentials === _constants.requestCredentials.omit) {
|
|
78
|
+
options.cookies = false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
options.url = location;
|
|
82
|
+
if (statusCode !== HTTP_STATUS_SEE_OTHER && options.body?.pipe?.constructor === Function) {
|
|
83
|
+
return res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with streamable body.`));
|
|
84
|
+
}
|
|
85
|
+
options.follow--;
|
|
86
|
+
if ([HTTP_STATUS_MOVED_PERMANENTLY, HTTP_STATUS_FOUND].includes(statusCode) && options.method === HTTP2_METHOD_POST || statusCode === HTTP_STATUS_SEE_OTHER && ![HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(options.method)) {
|
|
87
|
+
Object.keys(options.headers).filter(it => /^content-/i.test(it)).forEach(it => Reflect.deleteProperty(options.headers, it));
|
|
88
|
+
options.body = null;
|
|
89
|
+
options.method = HTTP2_METHOD_GET;
|
|
90
|
+
}
|
|
91
|
+
Reflect.set(options, 'h2', false);
|
|
92
|
+
Reflect.set(options, 'redirected', true);
|
|
93
|
+
if (statusCode === HTTP_STATUS_MOVED_PERMANENTLY && res.headers[HTTP2_HEADER_RETRY_AFTER]) {
|
|
94
|
+
let interval = res.headers[HTTP2_HEADER_RETRY_AFTER];
|
|
95
|
+
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
96
|
+
if (interval > options.maxRetryAfter) {
|
|
97
|
+
return res.emit('error', (0, _utils.maxRetryAfterError)(interval, {
|
|
98
|
+
cause: (0, _utils.mixin)(res, options)
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
return (0, _promises.setTimeout)(interval).then(() => (0, _index.default)(options.url, options).then(resolve, reject));
|
|
102
|
+
}
|
|
103
|
+
return (0, _index.default)(options.url, options).then(resolve, reject);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (statusCode >= HTTP_STATUS_BAD_REQUEST) {
|
|
107
|
+
return reject((0, _utils.mixin)(res, options));
|
|
108
|
+
}
|
|
109
|
+
resolve((0, _utils.mixin)(res, options));
|
|
110
|
+
};
|
|
111
|
+
exports.postflight = postflight;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.preflight = void 0;
|
|
5
|
+
var _nodeHttp = _interopRequireDefault(require("node:http2"));
|
|
6
|
+
var _constants = require("./constants");
|
|
7
|
+
var _cookies = require("./cookies");
|
|
8
|
+
var _mediatypes = require("./mediatypes");
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const {
|
|
11
|
+
HTTP2_HEADER_ACCEPT,
|
|
12
|
+
HTTP2_HEADER_ACCEPT_ENCODING,
|
|
13
|
+
HTTP2_HEADER_AUTHORITY,
|
|
14
|
+
HTTP2_HEADER_COOKIE,
|
|
15
|
+
HTTP2_HEADER_METHOD,
|
|
16
|
+
HTTP2_HEADER_PATH,
|
|
17
|
+
HTTP2_HEADER_SCHEME,
|
|
18
|
+
HTTP2_METHOD_GET,
|
|
19
|
+
HTTP2_METHOD_HEAD
|
|
20
|
+
} = _nodeHttp.default.constants;
|
|
21
|
+
const preflight = options => {
|
|
22
|
+
const {
|
|
23
|
+
cookies,
|
|
24
|
+
credentials,
|
|
25
|
+
h2,
|
|
26
|
+
headers,
|
|
27
|
+
method,
|
|
28
|
+
url
|
|
29
|
+
} = options;
|
|
30
|
+
if (h2) {
|
|
31
|
+
options.endStream = [HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(method);
|
|
32
|
+
}
|
|
33
|
+
if (cookies !== false) {
|
|
34
|
+
let cookie = _cookies.Cookies.jar.get(url.origin);
|
|
35
|
+
if (cookies === Object(cookies) && [_constants.requestCredentials.include, _constants.requestCredentials.sameOrigin].includes(credentials)) {
|
|
36
|
+
if (cookie) {
|
|
37
|
+
new _cookies.Cookies(cookies).forEach(function (val, key) {
|
|
38
|
+
this.set(key, val);
|
|
39
|
+
}, cookie);
|
|
40
|
+
} else {
|
|
41
|
+
cookie = new _cookies.Cookies(cookies);
|
|
42
|
+
_cookies.Cookies.jar.set(url.origin, cookie);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
options.headers = {
|
|
46
|
+
...(cookie && {
|
|
47
|
+
[HTTP2_HEADER_COOKIE]: cookie
|
|
48
|
+
}),
|
|
49
|
+
...headers
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
options.headers = {
|
|
53
|
+
[HTTP2_HEADER_ACCEPT]: `${_mediatypes.APPLICATION_JSON}, ${_mediatypes.TEXT_PLAIN}, ${_mediatypes.WILDCARD}`,
|
|
54
|
+
[HTTP2_HEADER_ACCEPT_ENCODING]: 'br, deflate, deflate-raw, gzip, identity',
|
|
55
|
+
...Object.entries(options.headers ?? {}).reduce((acc, [key, val]) => (acc[key.toLowerCase()] = val, acc), {}),
|
|
56
|
+
...(h2 && {
|
|
57
|
+
[HTTP2_HEADER_AUTHORITY]: url.host,
|
|
58
|
+
[HTTP2_HEADER_METHOD]: method,
|
|
59
|
+
[HTTP2_HEADER_PATH]: `${url.pathname}${url.search}`,
|
|
60
|
+
[HTTP2_HEADER_SCHEME]: url.protocol.replace(/\p{Punctuation}/gu, '')
|
|
61
|
+
})
|
|
62
|
+
};
|
|
63
|
+
return options;
|
|
64
|
+
};
|
|
65
|
+
exports.preflight = preflight;
|