rekwest 4.0.0 → 4.2.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 +4 -3
- package/dist/ackn.js +1 -1
- package/dist/constants.js +27 -0
- package/dist/cookies.js +1 -1
- package/dist/defaults.js +41 -0
- package/dist/formdata.js +12 -12
- package/dist/index.js +27 -185
- package/dist/postflight.js +110 -0
- package/dist/preflight.js +66 -0
- package/dist/utils.js +138 -95
- package/package.json +3 -3
- package/src/ackn.mjs +1 -1
- package/src/constants.mjs +29 -0
- package/src/cookies.mjs +2 -2
- package/src/defaults.mjs +44 -0
- package/src/formdata.mjs +16 -13
- package/src/index.mjs +84 -282
- package/src/postflight.mjs +135 -0
- package/src/preflight.mjs +70 -0
- package/src/utils.mjs +159 -99
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ const file = new File(['bits'], 'file.dab');
|
|
|
85
85
|
const readable = Readable.from('bits');
|
|
86
86
|
|
|
87
87
|
const fd = new FormData({
|
|
88
|
-
aux: Date.now(), // either [[key, value]]
|
|
88
|
+
aux: Date.now(), // either [[key, value]] or kv sequenceable
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
fd.append('celestial', 'payload');
|
|
@@ -122,10 +122,11 @@ console.log(res.body);
|
|
|
122
122
|
and [tls.ConnectionOptions](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback)
|
|
123
123
|
for HTTP/2 attunes
|
|
124
124
|
* `body` **{string | Array | ArrayBuffer | ArrayBufferView | AsyncIterator | Blob | Buffer | DataView | File |
|
|
125
|
-
FormData | Iterator | Object | Readable |
|
|
126
|
-
with the request
|
|
125
|
+
FormData | Iterator | Object | Readable | SharedArrayBuffer | URLSearchParams}** The body to send with the request
|
|
127
126
|
* `cookies` **{boolean | Array<[k, v]> | Cookies | Object | URLSearchParams}** `Default: true` The cookies to add to
|
|
128
127
|
the request
|
|
128
|
+
* `credentials` **{include | omit | same-origin}** `Default: same-origin` Controls credentials in case of cross-origin
|
|
129
|
+
redirects
|
|
129
130
|
* `digest` **{boolean}** `Default: true` Controls whether to read the response stream or simply add a mixin
|
|
130
131
|
* `follow` **{number}** `Default: 20` The number of redirects to follow
|
|
131
132
|
* `h2` **{boolean}** `Default: false` Forces the use of HTTP/2 protocol
|
package/dist/ackn.js
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.requestRedirectCodes = exports.requestRedirect = exports.requestCredentials = void 0;
|
|
5
|
+
var _nodeHttp = _interopRequireDefault(require("node:http2"));
|
|
6
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
7
|
+
const {
|
|
8
|
+
HTTP_STATUS_FOUND,
|
|
9
|
+
HTTP_STATUS_MOVED_PERMANENTLY,
|
|
10
|
+
HTTP_STATUS_PERMANENT_REDIRECT,
|
|
11
|
+
HTTP_STATUS_SEE_OTHER,
|
|
12
|
+
HTTP_STATUS_TEMPORARY_REDIRECT
|
|
13
|
+
} = _nodeHttp.default.constants;
|
|
14
|
+
const requestCredentials = {
|
|
15
|
+
include: 'include',
|
|
16
|
+
omit: 'omit',
|
|
17
|
+
sameOrigin: 'same-origin'
|
|
18
|
+
};
|
|
19
|
+
exports.requestCredentials = requestCredentials;
|
|
20
|
+
const requestRedirect = {
|
|
21
|
+
error: 'error',
|
|
22
|
+
follow: 'follow',
|
|
23
|
+
manual: 'manual'
|
|
24
|
+
};
|
|
25
|
+
exports.requestRedirect = requestRedirect;
|
|
26
|
+
const requestRedirectCodes = [HTTP_STATUS_MOVED_PERMANENTLY, HTTP_STATUS_FOUND, HTTP_STATUS_SEE_OTHER, HTTP_STATUS_TEMPORARY_REDIRECT, HTTP_STATUS_PERMANENT_REDIRECT];
|
|
27
|
+
exports.requestRedirectCodes = requestRedirectCodes;
|
package/dist/cookies.js
CHANGED
package/dist/defaults.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _nodeHttp = _interopRequireDefault(require("node:http2"));
|
|
6
|
+
var _constants = require("./constants");
|
|
7
|
+
var _utils = require("./utils");
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
const {
|
|
10
|
+
HTTP2_METHOD_GET,
|
|
11
|
+
HTTP_STATUS_SERVICE_UNAVAILABLE,
|
|
12
|
+
HTTP_STATUS_TOO_MANY_REQUESTS
|
|
13
|
+
} = _nodeHttp.default.constants;
|
|
14
|
+
const stash = {
|
|
15
|
+
credentials: _constants.requestCredentials.sameOrigin,
|
|
16
|
+
digest: true,
|
|
17
|
+
follow: 20,
|
|
18
|
+
get maxRetryAfter() {
|
|
19
|
+
return this[_utils.maxRetryAfter] ?? this.timeout;
|
|
20
|
+
},
|
|
21
|
+
set maxRetryAfter(value) {
|
|
22
|
+
this[_utils.maxRetryAfter] = value;
|
|
23
|
+
},
|
|
24
|
+
method: HTTP2_METHOD_GET,
|
|
25
|
+
parse: true,
|
|
26
|
+
redirect: _constants.requestRedirect.follow,
|
|
27
|
+
redirected: false,
|
|
28
|
+
retry: {
|
|
29
|
+
attempts: 0,
|
|
30
|
+
backoffStrategy: 'interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)',
|
|
31
|
+
interval: 1e3,
|
|
32
|
+
retryAfter: true,
|
|
33
|
+
statusCodes: [HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_SERVICE_UNAVAILABLE]
|
|
34
|
+
},
|
|
35
|
+
thenable: false,
|
|
36
|
+
timeout: 3e5
|
|
37
|
+
};
|
|
38
|
+
var _default = {
|
|
39
|
+
stash
|
|
40
|
+
};
|
|
41
|
+
exports.default = _default;
|
package/dist/formdata.js
CHANGED
|
@@ -31,7 +31,7 @@ class FormData {
|
|
|
31
31
|
} else {
|
|
32
32
|
yield encoder.encode(`${prefix}; name="${escape(normalize(name))}"${value.name ? `; filename="${escape(value.name)}"` : ''}${CRLF}${HTTP2_HEADER_CONTENT_TYPE}: ${value.type || _mediatypes.APPLICATION_OCTET_STREAM}${CRLF.repeat(2)}`);
|
|
33
33
|
yield* (0, _utils.tap)(value);
|
|
34
|
-
yield
|
|
34
|
+
yield new Uint8Array([13, 10]);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
yield encoder.encode(`--${boundary}--`);
|
|
@@ -98,18 +98,18 @@ class FormData {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
append(...args) {
|
|
101
|
-
(0, _utils.
|
|
101
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
102
102
|
this.#ensureArgs(args, 2, 'append');
|
|
103
103
|
this.#entries.push(this.constructor.#enfoldEntry(...args));
|
|
104
104
|
}
|
|
105
105
|
delete(...args) {
|
|
106
|
-
(0, _utils.
|
|
106
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
107
107
|
this.#ensureArgs(args, 1, 'delete');
|
|
108
108
|
const name = (0, _nodeUtil.toUSVString)(args[0]);
|
|
109
109
|
this.#entries = this.#entries.filter(it => it.name !== name);
|
|
110
110
|
}
|
|
111
111
|
forEach(...args) {
|
|
112
|
-
(0, _utils.
|
|
112
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
113
113
|
this.#ensureArgs(args, 1, 'forEach');
|
|
114
114
|
const [callback, thisArg] = args;
|
|
115
115
|
for (const entry of this) {
|
|
@@ -117,25 +117,25 @@ class FormData {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
get(...args) {
|
|
120
|
-
(0, _utils.
|
|
120
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
121
121
|
this.#ensureArgs(args, 1, 'get');
|
|
122
122
|
const name = (0, _nodeUtil.toUSVString)(args[0]);
|
|
123
123
|
return (this.#entries.find(it => it.name === name) ?? {}).value ?? null;
|
|
124
124
|
}
|
|
125
125
|
getAll(...args) {
|
|
126
|
-
(0, _utils.
|
|
126
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
127
127
|
this.#ensureArgs(args, 1, 'getAll');
|
|
128
128
|
const name = (0, _nodeUtil.toUSVString)(args[0]);
|
|
129
129
|
return this.#entries.filter(it => it.name === name).map(it => it.value);
|
|
130
130
|
}
|
|
131
131
|
has(...args) {
|
|
132
|
-
(0, _utils.
|
|
132
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
133
133
|
this.#ensureArgs(args, 1, 'has');
|
|
134
134
|
const name = (0, _nodeUtil.toUSVString)(args[0]);
|
|
135
135
|
return !!this.#entries.find(it => it.name === name);
|
|
136
136
|
}
|
|
137
137
|
set(...args) {
|
|
138
|
-
(0, _utils.
|
|
138
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
139
139
|
this.#ensureArgs(args, 2, 'set');
|
|
140
140
|
const entry = this.constructor.#enfoldEntry(...args);
|
|
141
141
|
const idx = this.#entries.findIndex(it => it.name === entry.name);
|
|
@@ -146,7 +146,7 @@ class FormData {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
*entries() {
|
|
149
|
-
(0, _utils.
|
|
149
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
150
150
|
for (const {
|
|
151
151
|
name,
|
|
152
152
|
value
|
|
@@ -155,19 +155,19 @@ class FormData {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
*keys() {
|
|
158
|
-
(0, _utils.
|
|
158
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
159
159
|
for (const [name] of this) {
|
|
160
160
|
yield name;
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
*values() {
|
|
164
|
-
(0, _utils.
|
|
164
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
165
165
|
for (const [, value] of this) {
|
|
166
166
|
yield value;
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
[Symbol.iterator]() {
|
|
170
|
-
(0, _utils.
|
|
170
|
+
(0, _utils.brandCheck)(this, FormData);
|
|
171
171
|
return this.entries();
|
|
172
172
|
}
|
|
173
173
|
}
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,24 @@ 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
|
|
15
|
+
var _constants = require("./constants");
|
|
16
|
+
Object.keys(_constants).forEach(function (key) {
|
|
17
|
+
if (key === "default" || key === "__esModule") return;
|
|
18
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
19
|
+
if (key in exports && exports[key] === _constants[key]) return;
|
|
20
|
+
exports[key] = _constants[key];
|
|
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
|
+
});
|
|
16
33
|
var _ackn = require("./ackn");
|
|
17
34
|
Object.keys(_ackn).forEach(function (key) {
|
|
18
35
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -34,15 +51,6 @@ Object.keys(_errors).forEach(function (key) {
|
|
|
34
51
|
if (key in exports && exports[key] === _errors[key]) return;
|
|
35
52
|
exports[key] = _errors[key];
|
|
36
53
|
});
|
|
37
|
-
var _mediatypes = _interopRequireWildcard(require("./mediatypes"));
|
|
38
|
-
exports.mediatypes = _mediatypes;
|
|
39
|
-
var _utils = require("./utils");
|
|
40
|
-
Object.keys(_utils).forEach(function (key) {
|
|
41
|
-
if (key === "default" || key === "__esModule") return;
|
|
42
|
-
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
43
|
-
if (key in exports && exports[key] === _utils[key]) return;
|
|
44
|
-
exports[key] = _utils[key];
|
|
45
|
-
});
|
|
46
54
|
var _file = require("./file");
|
|
47
55
|
Object.keys(_file).forEach(function (key) {
|
|
48
56
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -61,191 +69,25 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
|
|
|
61
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; }
|
|
62
70
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
63
71
|
const {
|
|
64
|
-
|
|
65
|
-
HTTP2_HEADER_CONTENT_TYPE,
|
|
66
|
-
HTTP2_HEADER_LOCATION,
|
|
67
|
-
HTTP2_HEADER_RETRY_AFTER,
|
|
68
|
-
HTTP2_HEADER_SET_COOKIE,
|
|
69
|
-
HTTP2_METHOD_GET,
|
|
70
|
-
HTTP2_METHOD_HEAD,
|
|
71
|
-
HTTP_STATUS_BAD_REQUEST,
|
|
72
|
-
HTTP_STATUS_MOVED_PERMANENTLY,
|
|
73
|
-
HTTP_STATUS_SEE_OTHER,
|
|
74
|
-
HTTP_STATUS_SERVICE_UNAVAILABLE,
|
|
75
|
-
HTTP_STATUS_TOO_MANY_REQUESTS
|
|
72
|
+
HTTP2_HEADER_CONTENT_TYPE
|
|
76
73
|
} = _nodeHttp2.default.constants;
|
|
77
|
-
|
|
78
|
-
const maxRetryAfterError = (interval, options) => new _errors.RequestError(`Maximum '${HTTP2_HEADER_RETRY_AFTER}' limit exceeded: ${interval} ms.`, options);
|
|
79
|
-
let defaults = {
|
|
80
|
-
follow: 20,
|
|
81
|
-
get maxRetryAfter() {
|
|
82
|
-
return this[maxRetryAfter] ?? this.timeout;
|
|
83
|
-
},
|
|
84
|
-
set maxRetryAfter(value) {
|
|
85
|
-
this[maxRetryAfter] = value;
|
|
86
|
-
},
|
|
87
|
-
method: HTTP2_METHOD_GET,
|
|
88
|
-
retry: {
|
|
89
|
-
attempts: 0,
|
|
90
|
-
backoffStrategy: 'interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)',
|
|
91
|
-
interval: 1e3,
|
|
92
|
-
retryAfter: true,
|
|
93
|
-
statusCodes: [HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_SERVICE_UNAVAILABLE]
|
|
94
|
-
},
|
|
95
|
-
timeout: 3e5
|
|
96
|
-
};
|
|
97
|
-
async function rekwest(...args) {
|
|
74
|
+
function rekwest(...args) {
|
|
98
75
|
let options = (0, _utils.sanitize)(...args);
|
|
99
|
-
const {
|
|
100
|
-
url
|
|
101
|
-
} = options;
|
|
102
76
|
if (!options.redirected) {
|
|
103
77
|
options = (0, _utils.merge)(rekwest.defaults, options);
|
|
104
78
|
}
|
|
105
|
-
|
|
106
|
-
throw new TypeError(`Request with ${HTTP2_METHOD_GET}/${HTTP2_METHOD_HEAD} method cannot have body.`);
|
|
107
|
-
}
|
|
108
|
-
if (options.follow === 0) {
|
|
109
|
-
throw new _errors.RequestError(`Maximum redirect reached at: ${url.href}`);
|
|
110
|
-
}
|
|
111
|
-
if (url.protocol === 'https:') {
|
|
112
|
-
options = await (0, _ackn.ackn)(options);
|
|
113
|
-
} else if (Reflect.has(options, 'alpnProtocol')) {
|
|
114
|
-
['alpnProtocol', 'createConnection', 'h2', 'protocol'].forEach(it => Reflect.deleteProperty(options, it));
|
|
115
|
-
}
|
|
116
|
-
options = await (0, _utils.transform)((0, _utils.preflight)(options));
|
|
117
|
-
const {
|
|
118
|
-
cookies,
|
|
119
|
-
digest,
|
|
120
|
-
follow,
|
|
121
|
-
h2,
|
|
122
|
-
redirect,
|
|
123
|
-
redirected,
|
|
124
|
-
thenable
|
|
125
|
-
} = options;
|
|
126
|
-
const {
|
|
127
|
-
request
|
|
128
|
-
} = url.protocol === 'http:' ? _nodeHttp.default : _nodeHttps.default;
|
|
129
|
-
const promise = new Promise((resolve, reject) => {
|
|
130
|
-
let client, req;
|
|
131
|
-
if (h2) {
|
|
132
|
-
client = _nodeHttp2.default.connect(url.origin, options);
|
|
133
|
-
req = client.request(options.headers, options);
|
|
134
|
-
} else {
|
|
135
|
-
req = request(url, options);
|
|
136
|
-
}
|
|
137
|
-
(0, _utils.affix)(client, req, options);
|
|
138
|
-
req.once('error', reject);
|
|
139
|
-
req.once('frameError', reject);
|
|
140
|
-
req.once('goaway', reject);
|
|
141
|
-
req.once('response', res => {
|
|
142
|
-
let headers;
|
|
143
|
-
if (h2) {
|
|
144
|
-
headers = res;
|
|
145
|
-
res = req;
|
|
146
|
-
} else {
|
|
147
|
-
res.once('error', reject);
|
|
148
|
-
}
|
|
149
|
-
(0, _utils.admix)(res, headers, options);
|
|
150
|
-
if (cookies !== false && res.headers[HTTP2_HEADER_SET_COOKIE]) {
|
|
151
|
-
if (_cookies.Cookies.jar.has(url.origin)) {
|
|
152
|
-
new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]).forEach(function (val, key) {
|
|
153
|
-
this.set(key, val);
|
|
154
|
-
}, _cookies.Cookies.jar.get(url.origin));
|
|
155
|
-
} else {
|
|
156
|
-
_cookies.Cookies.jar.set(url.origin, new _cookies.Cookies(res.headers[HTTP2_HEADER_SET_COOKIE]));
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
Reflect.defineProperty(res, 'cookies', {
|
|
160
|
-
enumerable: true,
|
|
161
|
-
value: cookies !== false && _cookies.Cookies.jar.has(url.origin) ? _cookies.Cookies.jar.get(url.origin) : void 0
|
|
162
|
-
});
|
|
163
|
-
if (follow && /^3\d{2}$/.test(res.statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
|
|
164
|
-
if (redirect === _utils.redirects.error) {
|
|
165
|
-
return res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
|
|
166
|
-
}
|
|
167
|
-
if (redirect === _utils.redirects.follow) {
|
|
168
|
-
options.url = new URL(res.headers[HTTP2_HEADER_LOCATION], url).href;
|
|
169
|
-
if (res.statusCode !== HTTP_STATUS_SEE_OTHER && options?.body?.pipe?.constructor === Function) {
|
|
170
|
-
return res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with streamable body.`));
|
|
171
|
-
}
|
|
172
|
-
options.follow--;
|
|
173
|
-
if (res.statusCode === HTTP_STATUS_SEE_OTHER) {
|
|
174
|
-
Reflect.deleteProperty(options.headers, HTTP2_HEADER_CONTENT_LENGTH);
|
|
175
|
-
options.method = HTTP2_METHOD_GET;
|
|
176
|
-
options.body = null;
|
|
177
|
-
}
|
|
178
|
-
Reflect.set(options, 'redirected', true);
|
|
179
|
-
if (res.statusCode === HTTP_STATUS_MOVED_PERMANENTLY && res.headers[HTTP2_HEADER_RETRY_AFTER]) {
|
|
180
|
-
let interval = res.headers[HTTP2_HEADER_RETRY_AFTER];
|
|
181
|
-
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
182
|
-
if (interval > options.maxRetryAfter) {
|
|
183
|
-
return res.emit('error', maxRetryAfterError(interval, {
|
|
184
|
-
cause: (0, _utils.mixin)(res, options)
|
|
185
|
-
}));
|
|
186
|
-
}
|
|
187
|
-
return (0, _promises.setTimeout)(interval).then(() => rekwest(options.url, options).then(resolve, reject));
|
|
188
|
-
}
|
|
189
|
-
return rekwest(options.url, options).then(resolve, reject);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (res.statusCode >= HTTP_STATUS_BAD_REQUEST) {
|
|
193
|
-
return reject((0, _utils.mixin)(res, options));
|
|
194
|
-
}
|
|
195
|
-
resolve((0, _utils.mixin)(res, options));
|
|
196
|
-
});
|
|
197
|
-
(0, _utils.dispatch)(options, req);
|
|
198
|
-
});
|
|
199
|
-
try {
|
|
200
|
-
const res = await promise;
|
|
201
|
-
if (digest && !redirected) {
|
|
202
|
-
res.body = await res.body();
|
|
203
|
-
}
|
|
204
|
-
return res;
|
|
205
|
-
} catch (ex) {
|
|
206
|
-
const {
|
|
207
|
-
maxRetryAfter,
|
|
208
|
-
retry
|
|
209
|
-
} = options;
|
|
210
|
-
if (retry?.attempts && retry?.statusCodes.includes(ex.statusCode)) {
|
|
211
|
-
let {
|
|
212
|
-
interval
|
|
213
|
-
} = retry;
|
|
214
|
-
if (retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
|
|
215
|
-
interval = ex.headers[HTTP2_HEADER_RETRY_AFTER];
|
|
216
|
-
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
217
|
-
if (interval > maxRetryAfter) {
|
|
218
|
-
throw maxRetryAfterError(interval, {
|
|
219
|
-
cause: ex
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
} else {
|
|
223
|
-
interval = new Function('interval', `return Math.ceil(${retry.backoffStrategy});`)(interval);
|
|
224
|
-
}
|
|
225
|
-
retry.attempts--;
|
|
226
|
-
retry.interval = interval;
|
|
227
|
-
return (0, _promises.setTimeout)(interval).then(() => rekwest(url, options));
|
|
228
|
-
}
|
|
229
|
-
if (digest && !redirected && ex.body) {
|
|
230
|
-
ex.body = await ex.body();
|
|
231
|
-
}
|
|
232
|
-
if (!thenable) {
|
|
233
|
-
throw ex;
|
|
234
|
-
} else {
|
|
235
|
-
return ex;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
79
|
+
return (0, _utils.transfer)((0, _utils.validation)(options));
|
|
238
80
|
}
|
|
239
81
|
Reflect.defineProperty(rekwest, 'stream', {
|
|
240
82
|
enumerable: true,
|
|
241
83
|
value(...args) {
|
|
242
|
-
const options = (0,
|
|
243
|
-
...(0, _utils.merge)(rekwest.defaults, {
|
|
84
|
+
const options = (0, _preflight.preflight)({
|
|
85
|
+
...(0, _utils.validation)((0, _utils.merge)(rekwest.defaults, {
|
|
244
86
|
headers: {
|
|
245
87
|
[HTTP2_HEADER_CONTENT_TYPE]: _mediatypes.APPLICATION_OCTET_STREAM
|
|
246
88
|
}
|
|
247
|
-
}, (0, _utils.sanitize)(...args)),
|
|
248
|
-
redirect:
|
|
89
|
+
}, (0, _utils.sanitize)(...args))),
|
|
90
|
+
redirect: _constants.requestRedirect.manual
|
|
249
91
|
});
|
|
250
92
|
const {
|
|
251
93
|
h2,
|
|
@@ -276,9 +118,9 @@ Reflect.defineProperty(rekwest, 'stream', {
|
|
|
276
118
|
Reflect.defineProperty(rekwest, 'defaults', {
|
|
277
119
|
enumerable: true,
|
|
278
120
|
get() {
|
|
279
|
-
return
|
|
121
|
+
return _defaults.default.stash;
|
|
280
122
|
},
|
|
281
123
|
set(value) {
|
|
282
|
-
|
|
124
|
+
_defaults.default.stash = (0, _utils.merge)(_defaults.default.stash, value);
|
|
283
125
|
}
|
|
284
126
|
});
|
|
@@ -0,0 +1,110 @@
|
|
|
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, 'redirected', true);
|
|
92
|
+
if (statusCode === HTTP_STATUS_MOVED_PERMANENTLY && res.headers[HTTP2_HEADER_RETRY_AFTER]) {
|
|
93
|
+
let interval = res.headers[HTTP2_HEADER_RETRY_AFTER];
|
|
94
|
+
interval = Number(interval) * 1000 || new Date(interval) - Date.now();
|
|
95
|
+
if (interval > options.maxRetryAfter) {
|
|
96
|
+
return res.emit('error', (0, _utils.maxRetryAfterError)(interval, {
|
|
97
|
+
cause: (0, _utils.mixin)(res, options)
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
return (0, _promises.setTimeout)(interval).then(() => (0, _index.default)(options.url, options).then(resolve, reject));
|
|
101
|
+
}
|
|
102
|
+
return (0, _index.default)(options.url, options).then(resolve, reject);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (statusCode >= HTTP_STATUS_BAD_REQUEST) {
|
|
106
|
+
return reject((0, _utils.mixin)(res, options));
|
|
107
|
+
}
|
|
108
|
+
resolve((0, _utils.mixin)(res, options));
|
|
109
|
+
};
|
|
110
|
+
exports.postflight = postflight;
|
|
@@ -0,0 +1,66 @@
|
|
|
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 = false,
|
|
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.h2 ??= h2;
|
|
53
|
+
options.headers = {
|
|
54
|
+
[HTTP2_HEADER_ACCEPT]: `${_mediatypes.APPLICATION_JSON}, ${_mediatypes.TEXT_PLAIN}, ${_mediatypes.WILDCARD}`,
|
|
55
|
+
[HTTP2_HEADER_ACCEPT_ENCODING]: 'br, deflate, deflate-raw, gzip, identity',
|
|
56
|
+
...Object.entries(options.headers ?? {}).reduce((acc, [key, val]) => (acc[key.toLowerCase()] = val, acc), {}),
|
|
57
|
+
...(h2 && {
|
|
58
|
+
[HTTP2_HEADER_AUTHORITY]: url.host,
|
|
59
|
+
[HTTP2_HEADER_METHOD]: method,
|
|
60
|
+
[HTTP2_HEADER_PATH]: `${url.pathname}${url.search}`,
|
|
61
|
+
[HTTP2_HEADER_SCHEME]: url.protocol.replace(/\p{Punctuation}/gu, '')
|
|
62
|
+
})
|
|
63
|
+
};
|
|
64
|
+
return options;
|
|
65
|
+
};
|
|
66
|
+
exports.preflight = preflight;
|