rekwest 2.3.3 → 2.4.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 +2 -1
- package/dist/formdata.js +3 -3
- package/dist/helpers.js +31 -27
- package/dist/index.js +39 -22
- package/package.json +6 -5
- package/src/helpers.mjs +331 -324
- package/src/index.mjs +14 -7
package/README.md
CHANGED
|
@@ -130,7 +130,7 @@ console.log(res.body);
|
|
|
130
130
|
* `h2` **{boolean}** `Default: false` Forces use of the HTTP2 protocol
|
|
131
131
|
* `headers` **{Object}** Headers to add to the request
|
|
132
132
|
* `parse` **{boolean}** `Default: true` Parse response body, or simply return a buffer
|
|
133
|
-
* `redirect` **{
|
|
133
|
+
* `redirect` **{error | follow | manual}** `Default: 'follow'` Controls redirect flow
|
|
134
134
|
* `thenable` **{boolean}** `Default: false` Controls promise resolutions
|
|
135
135
|
* **Returns:** Promise that resolves to
|
|
136
136
|
extended [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
|
|
@@ -168,6 +168,7 @@ Method with limited functionality to use with streams and pipes
|
|
|
168
168
|
* No automata
|
|
169
169
|
* No redirects
|
|
170
170
|
* Pass `h2: true` in options to use the HTTP2 protocol
|
|
171
|
+
* Or use `ackn({ url: URL })` method in advance to probe the available protocols
|
|
171
172
|
|
|
172
173
|
---
|
|
173
174
|
|
package/dist/formdata.js
CHANGED
|
@@ -9,11 +9,11 @@ var _http = _interopRequireDefault(require("http2"));
|
|
|
9
9
|
|
|
10
10
|
var _util = require("util");
|
|
11
11
|
|
|
12
|
-
var _file = require("./file.
|
|
12
|
+
var _file = require("./file.js");
|
|
13
13
|
|
|
14
|
-
var _helpers = require("./helpers.
|
|
14
|
+
var _helpers = require("./helpers.js");
|
|
15
15
|
|
|
16
|
-
var _mediatypes = require("./mediatypes.
|
|
16
|
+
var _mediatypes = require("./mediatypes.js");
|
|
17
17
|
|
|
18
18
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
19
|
|
package/dist/helpers.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
|
-
exports.premix = exports.preflight = exports.merge = exports.dispatch = exports.decompress = exports.compress = void 0;
|
|
4
|
+
exports.redirects = exports.premix = exports.preflight = exports.merge = exports.dispatch = exports.decompress = exports.compress = void 0;
|
|
5
5
|
exports.tap = tap;
|
|
6
6
|
exports.transform = void 0;
|
|
7
7
|
|
|
8
8
|
var _buffer = require("buffer");
|
|
9
9
|
|
|
10
|
-
var _http = require("
|
|
11
|
-
|
|
12
|
-
var _http2 = _interopRequireDefault(require("http2"));
|
|
10
|
+
var _http = _interopRequireDefault(require("http2"));
|
|
13
11
|
|
|
14
12
|
var _stream = require("stream");
|
|
15
13
|
|
|
@@ -17,13 +15,13 @@ var _util = require("util");
|
|
|
17
15
|
|
|
18
16
|
var _zlib = _interopRequireDefault(require("zlib"));
|
|
19
17
|
|
|
20
|
-
var _cookies = require("./cookies.
|
|
18
|
+
var _cookies = require("./cookies.js");
|
|
21
19
|
|
|
22
|
-
var _file = require("./file.
|
|
20
|
+
var _file = require("./file.js");
|
|
23
21
|
|
|
24
|
-
var _formdata = require("./formdata.
|
|
22
|
+
var _formdata = require("./formdata.js");
|
|
25
23
|
|
|
26
|
-
var _mediatypes = require("./mediatypes.
|
|
24
|
+
var _mediatypes = require("./mediatypes.js");
|
|
27
25
|
|
|
28
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
29
27
|
|
|
@@ -40,7 +38,7 @@ const {
|
|
|
40
38
|
HTTP2_HEADER_SCHEME,
|
|
41
39
|
HTTP2_METHOD_GET,
|
|
42
40
|
HTTP2_METHOD_HEAD
|
|
43
|
-
} =
|
|
41
|
+
} = _http.default.constants;
|
|
44
42
|
const brotliCompress = (0, _util.promisify)(_zlib.default.brotliCompress);
|
|
45
43
|
const brotliDecompress = (0, _util.promisify)(_zlib.default.brotliDecompress);
|
|
46
44
|
const gzip = (0, _util.promisify)(_zlib.default.gzip);
|
|
@@ -139,9 +137,7 @@ const preflight = options => {
|
|
|
139
137
|
redirected
|
|
140
138
|
} = options;
|
|
141
139
|
|
|
142
|
-
if (
|
|
143
|
-
options.agent ??= url.protocol === 'http:' ? _http.globalAgent : void 0;
|
|
144
|
-
} else {
|
|
140
|
+
if (h2) {
|
|
145
141
|
options.endStream = [HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(method);
|
|
146
142
|
}
|
|
147
143
|
|
|
@@ -183,7 +179,13 @@ const preflight = options => {
|
|
|
183
179
|
};
|
|
184
180
|
options.method ??= method;
|
|
185
181
|
options.parse ??= true;
|
|
186
|
-
options.redirect ??=
|
|
182
|
+
options.redirect ??= redirects.follow;
|
|
183
|
+
|
|
184
|
+
if (!Object.values(redirects).includes(options.redirect)) {
|
|
185
|
+
options.createConnection?.().destroy();
|
|
186
|
+
throw new TypeError(`Failed to read the 'redirect' property from 'options': The provided value '${options.redirect}' is not a valid enum value.`);
|
|
187
|
+
}
|
|
188
|
+
|
|
187
189
|
options.redirected ??= false;
|
|
188
190
|
options.thenable ??= false;
|
|
189
191
|
return options;
|
|
@@ -199,35 +201,31 @@ const premix = (res, {
|
|
|
199
201
|
Object.defineProperties(res, {
|
|
200
202
|
arrayBuffer: {
|
|
201
203
|
enumerable: true,
|
|
202
|
-
value:
|
|
204
|
+
value: function () {
|
|
203
205
|
parse &&= false;
|
|
204
|
-
|
|
206
|
+
return this.body().then(({
|
|
205
207
|
buffer,
|
|
206
208
|
byteLength,
|
|
207
209
|
byteOffset
|
|
208
|
-
}
|
|
209
|
-
return buffer.slice(byteOffset, byteOffset + byteLength);
|
|
210
|
+
}) => buffer.slice(byteOffset, byteOffset + byteLength));
|
|
210
211
|
}
|
|
211
212
|
},
|
|
212
213
|
blob: {
|
|
213
214
|
enumerable: true,
|
|
214
|
-
value:
|
|
215
|
-
|
|
216
|
-
return new _buffer.Blob([val]);
|
|
215
|
+
value: function () {
|
|
216
|
+
return this.arrayBuffer().then(res => new _buffer.Blob([res]));
|
|
217
217
|
}
|
|
218
218
|
},
|
|
219
219
|
json: {
|
|
220
220
|
enumerable: true,
|
|
221
|
-
value:
|
|
222
|
-
|
|
223
|
-
return JSON.parse(val);
|
|
221
|
+
value: function () {
|
|
222
|
+
return this.text().then(res => JSON.parse(res));
|
|
224
223
|
}
|
|
225
224
|
},
|
|
226
225
|
text: {
|
|
227
226
|
enumerable: true,
|
|
228
|
-
value:
|
|
229
|
-
|
|
230
|
-
return val.toString();
|
|
227
|
+
value: function () {
|
|
228
|
+
return this.blob().then(blob => blob.text());
|
|
231
229
|
}
|
|
232
230
|
}
|
|
233
231
|
});
|
|
@@ -238,7 +236,7 @@ const premix = (res, {
|
|
|
238
236
|
enumerable: true,
|
|
239
237
|
value: async function () {
|
|
240
238
|
if (this.bodyUsed) {
|
|
241
|
-
throw new TypeError('Response stream already read');
|
|
239
|
+
throw new TypeError('Response stream already read.');
|
|
242
240
|
}
|
|
243
241
|
|
|
244
242
|
let spool = [];
|
|
@@ -284,6 +282,12 @@ const premix = (res, {
|
|
|
284
282
|
};
|
|
285
283
|
|
|
286
284
|
exports.premix = premix;
|
|
285
|
+
const redirects = {
|
|
286
|
+
error: 'error',
|
|
287
|
+
follow: 'follow',
|
|
288
|
+
manual: 'manual'
|
|
289
|
+
};
|
|
290
|
+
exports.redirects = redirects;
|
|
287
291
|
|
|
288
292
|
async function* tap(value) {
|
|
289
293
|
if (Reflect.has(value, Symbol.asyncIterator)) {
|
package/dist/index.js
CHANGED
|
@@ -7,13 +7,15 @@ var _exportNames = {
|
|
|
7
7
|
exports.constants = void 0;
|
|
8
8
|
exports.default = rekwest;
|
|
9
9
|
|
|
10
|
-
var _http = _interopRequireDefault(require("
|
|
10
|
+
var _http = _interopRequireDefault(require("http"));
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
var _http2 = _interopRequireDefault(require("http2"));
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
exports.constants = _http2.constants;
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var _https = _interopRequireDefault(require("https"));
|
|
17
|
+
|
|
18
|
+
var _ackn = require("./ackn.js");
|
|
17
19
|
|
|
18
20
|
Object.keys(_ackn).forEach(function (key) {
|
|
19
21
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -22,7 +24,7 @@ Object.keys(_ackn).forEach(function (key) {
|
|
|
22
24
|
exports[key] = _ackn[key];
|
|
23
25
|
});
|
|
24
26
|
|
|
25
|
-
var _cookies = require("./cookies.
|
|
27
|
+
var _cookies = require("./cookies.js");
|
|
26
28
|
|
|
27
29
|
Object.keys(_cookies).forEach(function (key) {
|
|
28
30
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -31,7 +33,7 @@ Object.keys(_cookies).forEach(function (key) {
|
|
|
31
33
|
exports[key] = _cookies[key];
|
|
32
34
|
});
|
|
33
35
|
|
|
34
|
-
var _errors = require("./errors.
|
|
36
|
+
var _errors = require("./errors.js");
|
|
35
37
|
|
|
36
38
|
Object.keys(_errors).forEach(function (key) {
|
|
37
39
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -40,7 +42,7 @@ Object.keys(_errors).forEach(function (key) {
|
|
|
40
42
|
exports[key] = _errors[key];
|
|
41
43
|
});
|
|
42
44
|
|
|
43
|
-
var _helpers = require("./helpers.
|
|
45
|
+
var _helpers = require("./helpers.js");
|
|
44
46
|
|
|
45
47
|
Object.keys(_helpers).forEach(function (key) {
|
|
46
48
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -49,9 +51,9 @@ Object.keys(_helpers).forEach(function (key) {
|
|
|
49
51
|
exports[key] = _helpers[key];
|
|
50
52
|
});
|
|
51
53
|
|
|
52
|
-
var _mediatypes = require("./mediatypes.
|
|
54
|
+
var _mediatypes = require("./mediatypes.js");
|
|
53
55
|
|
|
54
|
-
var _file = require("./file.
|
|
56
|
+
var _file = require("./file.js");
|
|
55
57
|
|
|
56
58
|
Object.keys(_file).forEach(function (key) {
|
|
57
59
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -60,7 +62,7 @@ Object.keys(_file).forEach(function (key) {
|
|
|
60
62
|
exports[key] = _file[key];
|
|
61
63
|
});
|
|
62
64
|
|
|
63
|
-
var _formdata = require("./formdata.
|
|
65
|
+
var _formdata = require("./formdata.js");
|
|
64
66
|
|
|
65
67
|
Object.keys(_formdata).forEach(function (key) {
|
|
66
68
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -81,7 +83,7 @@ const {
|
|
|
81
83
|
HTTP2_METHOD_HEAD,
|
|
82
84
|
HTTP_STATUS_BAD_REQUEST,
|
|
83
85
|
HTTP_STATUS_SEE_OTHER
|
|
84
|
-
} =
|
|
86
|
+
} = _http2.default.constants;
|
|
85
87
|
|
|
86
88
|
async function rekwest(url, options = {}) {
|
|
87
89
|
url = options.url = new URL(url);
|
|
@@ -94,7 +96,7 @@ async function rekwest(url, options = {}) {
|
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
if (options.body && [HTTP2_METHOD_GET, HTTP2_METHOD_HEAD].includes(options.method)) {
|
|
97
|
-
throw new TypeError(`Request with ${HTTP2_METHOD_GET}/${HTTP2_METHOD_HEAD} method cannot have body
|
|
99
|
+
throw new TypeError(`Request with ${HTTP2_METHOD_GET}/${HTTP2_METHOD_HEAD} method cannot have body.`);
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
if (!options.follow) {
|
|
@@ -115,8 +117,14 @@ async function rekwest(url, options = {}) {
|
|
|
115
117
|
h2,
|
|
116
118
|
redirect,
|
|
117
119
|
redirected,
|
|
118
|
-
thenable
|
|
120
|
+
thenable,
|
|
121
|
+
url: {
|
|
122
|
+
protocol
|
|
123
|
+
}
|
|
119
124
|
} = options;
|
|
125
|
+
const {
|
|
126
|
+
request
|
|
127
|
+
} = protocol === 'http:' ? _http.default : _https.default;
|
|
120
128
|
let {
|
|
121
129
|
body
|
|
122
130
|
} = options;
|
|
@@ -125,10 +133,10 @@ async function rekwest(url, options = {}) {
|
|
|
125
133
|
body &&= (0, _helpers.transform)(body, options);
|
|
126
134
|
|
|
127
135
|
if (h2) {
|
|
128
|
-
client =
|
|
136
|
+
client = _http2.default.connect(url.origin, options);
|
|
129
137
|
req = client.request(options.headers, options);
|
|
130
138
|
} else {
|
|
131
|
-
req =
|
|
139
|
+
req = request(url, options);
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
req.on('response', res => {
|
|
@@ -167,15 +175,15 @@ async function rekwest(url, options = {}) {
|
|
|
167
175
|
});
|
|
168
176
|
|
|
169
177
|
if (follow && /^3\d{2}$/.test(res.statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
|
|
170
|
-
if (redirect ===
|
|
171
|
-
res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'
|
|
178
|
+
if (redirect === _helpers.redirects.error) {
|
|
179
|
+
res.emit('error', new _errors.RequestError(`Unexpected redirect, redirect mode is set to '${redirect}'.`));
|
|
172
180
|
}
|
|
173
181
|
|
|
174
|
-
if (redirect ===
|
|
182
|
+
if (redirect === _helpers.redirects.follow) {
|
|
175
183
|
options.url = new URL(res.headers[HTTP2_HEADER_LOCATION], url).href;
|
|
176
184
|
|
|
177
185
|
if (res.statusCode !== HTTP_STATUS_SEE_OTHER && body === Object(body) && body.pipe?.constructor === Function) {
|
|
178
|
-
res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with body as readable stream
|
|
186
|
+
res.emit('error', new _errors.RequestError(`Unable to ${redirect} redirect with body as readable stream.`));
|
|
179
187
|
}
|
|
180
188
|
|
|
181
189
|
options.follow--;
|
|
@@ -254,11 +262,12 @@ Reflect.defineProperty(rekwest, 'stream', {
|
|
|
254
262
|
headers: {
|
|
255
263
|
[HTTP2_HEADER_CONTENT_TYPE]: _mediatypes.APPLICATION_OCTET_STREAM
|
|
256
264
|
}
|
|
257
|
-
}, options)
|
|
265
|
+
}, options),
|
|
266
|
+
redirect: _helpers.redirects.manual
|
|
258
267
|
});
|
|
259
268
|
|
|
260
269
|
if (options.h2) {
|
|
261
|
-
const client =
|
|
270
|
+
const client = _http2.default.connect(url.origin, options);
|
|
262
271
|
|
|
263
272
|
const req = client.request(options.headers, options);
|
|
264
273
|
req.on('end', () => {
|
|
@@ -267,7 +276,15 @@ Reflect.defineProperty(rekwest, 'stream', {
|
|
|
267
276
|
return req;
|
|
268
277
|
}
|
|
269
278
|
|
|
270
|
-
|
|
279
|
+
const {
|
|
280
|
+
url: {
|
|
281
|
+
protocol
|
|
282
|
+
}
|
|
283
|
+
} = options;
|
|
284
|
+
const {
|
|
285
|
+
request
|
|
286
|
+
} = protocol === 'http:' ? _http.default : _https.default;
|
|
287
|
+
return request(options.url, options);
|
|
271
288
|
}
|
|
272
289
|
});
|
|
273
290
|
Reflect.defineProperty(rekwest, 'defaults', {
|
package/package.json
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"@babel/eslint-parser": "^7.16.5",
|
|
14
14
|
"@babel/preset-env": "^7.16.11",
|
|
15
15
|
"c8": "^7.11.0",
|
|
16
|
-
"eslint": "^8.
|
|
17
|
-
"eslint-config-ultra-refined": "^2.
|
|
16
|
+
"eslint": "^8.8.0",
|
|
17
|
+
"eslint-config-ultra-refined": "^2.4.0",
|
|
18
18
|
"mocha": "^9.2.0"
|
|
19
19
|
},
|
|
20
20
|
"description": "The robust request library that humanity deserves 🌐",
|
|
@@ -54,10 +54,11 @@
|
|
|
54
54
|
"cert:gen": "openssl req -days 365 -keyout localhost.key -newkey ec -nodes -pkeyopt ec_paramgen_curve:prime256v1 -subj //SKIP=1/CN=localhost -out localhost.cert -x509",
|
|
55
55
|
"cert:ken": "openssl x509 -in localhost.cert -noout -text",
|
|
56
56
|
"lint": "eslint . --ext .cjs,.js,.mjs",
|
|
57
|
-
"prepack": "npm run build",
|
|
57
|
+
"prepack": "npm run build && sh pony.sh",
|
|
58
58
|
"pretest": "rm -rf coverage && npm run cert:gen",
|
|
59
|
-
"test": "mocha
|
|
59
|
+
"test": "mocha",
|
|
60
|
+
"test:bail": "mocha --bail",
|
|
60
61
|
"test:cover": "c8 --include=src --reporter=lcov --reporter=text npm test"
|
|
61
62
|
},
|
|
62
|
-
"version": "2.
|
|
63
|
+
"version": "2.4.0"
|
|
63
64
|
}
|
package/src/helpers.mjs
CHANGED
|
@@ -1,324 +1,331 @@
|
|
|
1
|
-
import { Blob } from 'buffer';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
options.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
[
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
options.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
.replace('
|
|
246
|
-
.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
headers = {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
1
|
+
import { Blob } from 'buffer';
|
|
2
|
+
import http2 from 'http2';
|
|
3
|
+
import {
|
|
4
|
+
PassThrough,
|
|
5
|
+
Readable,
|
|
6
|
+
} from 'stream';
|
|
7
|
+
import {
|
|
8
|
+
promisify,
|
|
9
|
+
types,
|
|
10
|
+
} from 'util';
|
|
11
|
+
import zlib from 'zlib';
|
|
12
|
+
import { Cookies } from './cookies.mjs';
|
|
13
|
+
import { File } from './file.mjs';
|
|
14
|
+
import { FormData } from './formdata.mjs';
|
|
15
|
+
import {
|
|
16
|
+
APPLICATION_FORM_URLENCODED,
|
|
17
|
+
APPLICATION_JSON,
|
|
18
|
+
APPLICATION_OCTET_STREAM,
|
|
19
|
+
TEXT_PLAIN,
|
|
20
|
+
WILDCARD,
|
|
21
|
+
} from './mediatypes.mjs';
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
HTTP2_HEADER_ACCEPT,
|
|
25
|
+
HTTP2_HEADER_ACCEPT_ENCODING,
|
|
26
|
+
HTTP2_HEADER_AUTHORITY,
|
|
27
|
+
HTTP2_HEADER_CONTENT_ENCODING,
|
|
28
|
+
HTTP2_HEADER_CONTENT_LENGTH,
|
|
29
|
+
HTTP2_HEADER_CONTENT_TYPE,
|
|
30
|
+
HTTP2_HEADER_COOKIE,
|
|
31
|
+
HTTP2_HEADER_METHOD,
|
|
32
|
+
HTTP2_HEADER_PATH,
|
|
33
|
+
HTTP2_HEADER_SCHEME,
|
|
34
|
+
HTTP2_METHOD_GET,
|
|
35
|
+
HTTP2_METHOD_HEAD,
|
|
36
|
+
} = http2.constants;
|
|
37
|
+
|
|
38
|
+
const brotliCompress = promisify(zlib.brotliCompress);
|
|
39
|
+
const brotliDecompress = promisify(zlib.brotliDecompress);
|
|
40
|
+
const gzip = promisify(zlib.gzip);
|
|
41
|
+
const gunzip = promisify(zlib.gunzip);
|
|
42
|
+
const deflate = promisify(zlib.deflate);
|
|
43
|
+
const inflate = promisify(zlib.inflate);
|
|
44
|
+
|
|
45
|
+
export const compress = (buf, encoding, { async = false } = {}) => {
|
|
46
|
+
encoding &&= encoding.match(/(?<encoding>\bbr\b|\bdeflate\b|\bgzip\b)/i)?.groups.encoding.toLowerCase();
|
|
47
|
+
const compressor = {
|
|
48
|
+
br: async ? brotliCompress : zlib.brotliCompressSync,
|
|
49
|
+
deflate: async ? deflate : zlib.deflateSync,
|
|
50
|
+
gzip: async ? gzip : zlib.gzipSync,
|
|
51
|
+
}[encoding];
|
|
52
|
+
|
|
53
|
+
return compressor?.(buf) ?? (async ? Promise.resolve(buf) : buf);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const decompress = (buf, encoding, { async = false } = {}) => {
|
|
57
|
+
encoding &&= encoding.match(/(?<encoding>\bbr\b|\bdeflate\b|\bgzip\b)/i)?.groups.encoding.toLowerCase();
|
|
58
|
+
const decompressor = {
|
|
59
|
+
br: async ? brotliDecompress : zlib.brotliDecompressSync,
|
|
60
|
+
deflate: async ? inflate : zlib.inflateSync,
|
|
61
|
+
gzip: async ? gunzip : zlib.gunzipSync,
|
|
62
|
+
}[encoding];
|
|
63
|
+
|
|
64
|
+
return decompressor?.(buf) ?? (async ? Promise.resolve(buf) : buf);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const dispatch = (req, { body, headers }) => {
|
|
68
|
+
if (types.isUint8Array(body)) {
|
|
69
|
+
return req.end(body);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (body === Object(body) && !Buffer.isBuffer(body)) {
|
|
73
|
+
if (body.pipe?.constructor !== Function
|
|
74
|
+
&& (Reflect.has(body, Symbol.asyncIterator) || Reflect.has(body, Symbol.iterator))) {
|
|
75
|
+
body = Readable.from(body);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const compressor = {
|
|
79
|
+
br: zlib.createBrotliCompress,
|
|
80
|
+
deflate: zlib.createDeflate,
|
|
81
|
+
gzip: zlib.createGzip,
|
|
82
|
+
}[headers[HTTP2_HEADER_CONTENT_ENCODING]] ?? PassThrough;
|
|
83
|
+
|
|
84
|
+
body.pipe(compressor()).pipe(req);
|
|
85
|
+
} else {
|
|
86
|
+
req.end(body);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const merge = (target = {}, ...rest) => {
|
|
91
|
+
target = JSON.parse(JSON.stringify(target));
|
|
92
|
+
if (!rest.length) {
|
|
93
|
+
return target;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
rest.filter((it) => it === Object(it)).forEach((it) => {
|
|
97
|
+
Object.entries(it).reduce((acc, [key, val]) => {
|
|
98
|
+
if ([
|
|
99
|
+
acc[key]?.constructor,
|
|
100
|
+
val?.constructor,
|
|
101
|
+
].every((it) => [
|
|
102
|
+
Array,
|
|
103
|
+
Object,
|
|
104
|
+
].includes(it))) {
|
|
105
|
+
if (acc[key]?.constructor === val.constructor) {
|
|
106
|
+
acc[key] = merge(acc[key], val);
|
|
107
|
+
} else {
|
|
108
|
+
acc[key] = val;
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
acc[key] = val;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return acc;
|
|
115
|
+
}, target);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return target;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const preflight = (options) => {
|
|
122
|
+
const url = options.url = new URL(options.url);
|
|
123
|
+
const { cookies, h2 = false, method = HTTP2_METHOD_GET, headers, redirected } = options;
|
|
124
|
+
|
|
125
|
+
if (h2) {
|
|
126
|
+
options.endStream = [
|
|
127
|
+
HTTP2_METHOD_GET,
|
|
128
|
+
HTTP2_METHOD_HEAD,
|
|
129
|
+
].includes(method);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (cookies !== false) {
|
|
133
|
+
let cookie = Cookies.jar.get(url.origin);
|
|
134
|
+
|
|
135
|
+
if (cookies === Object(cookies) && !redirected) {
|
|
136
|
+
if (cookie) {
|
|
137
|
+
new Cookies(cookies).forEach(function (val, key) {
|
|
138
|
+
this.set(key, val);
|
|
139
|
+
}, cookie);
|
|
140
|
+
} else {
|
|
141
|
+
cookie = new Cookies(cookies);
|
|
142
|
+
Cookies.jar.set(url.origin, cookie);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
options.headers = {
|
|
147
|
+
...cookie && { [HTTP2_HEADER_COOKIE]: cookie },
|
|
148
|
+
...headers,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
options.digest ??= true;
|
|
153
|
+
options.follow ??= 20;
|
|
154
|
+
options.h2 ??= h2;
|
|
155
|
+
options.headers = {
|
|
156
|
+
[HTTP2_HEADER_ACCEPT]: `${ APPLICATION_JSON }, ${ TEXT_PLAIN }, ${ WILDCARD }`,
|
|
157
|
+
[HTTP2_HEADER_ACCEPT_ENCODING]: 'br, deflate, gzip, identity',
|
|
158
|
+
...Object.entries(options.headers ?? {})
|
|
159
|
+
.reduce((acc, [key, val]) => (acc[key.toLowerCase()] = val, acc), {}),
|
|
160
|
+
...h2 && {
|
|
161
|
+
[HTTP2_HEADER_AUTHORITY]: url.host,
|
|
162
|
+
[HTTP2_HEADER_METHOD]: method,
|
|
163
|
+
[HTTP2_HEADER_PATH]: `${ url.pathname }${ url.search }`,
|
|
164
|
+
[HTTP2_HEADER_SCHEME]: url.protocol.replace(/\p{Punctuation}/gu, ''),
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
options.method ??= method;
|
|
169
|
+
options.parse ??= true;
|
|
170
|
+
options.redirect ??= redirects.follow;
|
|
171
|
+
|
|
172
|
+
if (!Object.values(redirects).includes(options.redirect)) {
|
|
173
|
+
options.createConnection?.().destroy();
|
|
174
|
+
throw new TypeError(`Failed to read the 'redirect' property from 'options': The provided value '${
|
|
175
|
+
options.redirect
|
|
176
|
+
}' is not a valid enum value.`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
options.redirected ??= false;
|
|
180
|
+
options.thenable ??= false;
|
|
181
|
+
|
|
182
|
+
return options;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export const premix = (res, { digest = false, parse = false } = {}) => {
|
|
186
|
+
if (!digest) {
|
|
187
|
+
Object.defineProperties(res, {
|
|
188
|
+
arrayBuffer: {
|
|
189
|
+
enumerable: true,
|
|
190
|
+
value: function () {
|
|
191
|
+
parse &&= false;
|
|
192
|
+
|
|
193
|
+
return this.body().then(({ buffer, byteLength, byteOffset }) => buffer.slice(
|
|
194
|
+
byteOffset,
|
|
195
|
+
byteOffset + byteLength,
|
|
196
|
+
));
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
blob: {
|
|
200
|
+
enumerable: true,
|
|
201
|
+
value: function () {
|
|
202
|
+
return this.arrayBuffer().then((res) => new Blob([res]));
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
json: {
|
|
206
|
+
enumerable: true,
|
|
207
|
+
value: function () {
|
|
208
|
+
return this.text().then((res) => JSON.parse(res));
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
text: {
|
|
212
|
+
enumerable: true,
|
|
213
|
+
value: function () {
|
|
214
|
+
return this.blob().then((blob) => blob.text());
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return Object.defineProperties(res, {
|
|
221
|
+
body: {
|
|
222
|
+
enumerable: true,
|
|
223
|
+
value: async function () {
|
|
224
|
+
if (this.bodyUsed) {
|
|
225
|
+
throw new TypeError('Response stream already read.');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
let spool = [];
|
|
229
|
+
|
|
230
|
+
for await (const chunk of this) {
|
|
231
|
+
spool.push(chunk);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
spool = Buffer.concat(spool);
|
|
235
|
+
|
|
236
|
+
if (spool.length) {
|
|
237
|
+
spool = await decompress(spool, this.headers[HTTP2_HEADER_CONTENT_ENCODING], { async: true });
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (spool.length && parse) {
|
|
241
|
+
const contentType = this.headers[HTTP2_HEADER_CONTENT_TYPE] ?? '';
|
|
242
|
+
const charset = contentType.split(';')
|
|
243
|
+
.find((it) => /charset=/i.test(it))
|
|
244
|
+
?.toLowerCase()
|
|
245
|
+
.replace('charset=', '')
|
|
246
|
+
.replace('iso-8859-1', 'latin1')
|
|
247
|
+
.trim() || 'utf-8';
|
|
248
|
+
|
|
249
|
+
if (/\bjson\b/i.test(contentType)) {
|
|
250
|
+
spool = JSON.parse(spool.toString(charset));
|
|
251
|
+
} else if (/\b(text|xml)\b/i.test(contentType)) {
|
|
252
|
+
if (/\b(latin1|ucs-2|utf-(8|16le))\b/.test(charset)) {
|
|
253
|
+
spool = spool.toString(charset);
|
|
254
|
+
} else {
|
|
255
|
+
spool = new TextDecoder(charset).decode(spool);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return spool;
|
|
261
|
+
},
|
|
262
|
+
writable: true,
|
|
263
|
+
},
|
|
264
|
+
bodyUsed: {
|
|
265
|
+
enumerable: true,
|
|
266
|
+
get: function () {
|
|
267
|
+
return this.readableEnded;
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
export const redirects = {
|
|
274
|
+
error: 'error',
|
|
275
|
+
follow: 'follow',
|
|
276
|
+
manual: 'manual',
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export async function* tap(value) {
|
|
280
|
+
if (Reflect.has(value, Symbol.asyncIterator)) {
|
|
281
|
+
yield* value;
|
|
282
|
+
} else if (value.stream) {
|
|
283
|
+
yield* value.stream();
|
|
284
|
+
} else {
|
|
285
|
+
yield await value.arrayBuffer();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export const transform = (body, options) => {
|
|
290
|
+
let headers = {};
|
|
291
|
+
|
|
292
|
+
if (File.alike(body)) {
|
|
293
|
+
headers = {
|
|
294
|
+
[HTTP2_HEADER_CONTENT_LENGTH]: body.size,
|
|
295
|
+
[HTTP2_HEADER_CONTENT_TYPE]: body.type || APPLICATION_OCTET_STREAM,
|
|
296
|
+
};
|
|
297
|
+
body = body.stream?.() ?? Readable.from(tap(body));
|
|
298
|
+
} else if (FormData.alike(body)) {
|
|
299
|
+
body = FormData.actuate(body);
|
|
300
|
+
headers = { [HTTP2_HEADER_CONTENT_TYPE]: body.contentType };
|
|
301
|
+
} else if (body === Object(body) && !Reflect.has(body, Symbol.asyncIterator)) {
|
|
302
|
+
if (body.constructor === URLSearchParams) {
|
|
303
|
+
headers = { [HTTP2_HEADER_CONTENT_TYPE]: APPLICATION_FORM_URLENCODED };
|
|
304
|
+
body = body.toString();
|
|
305
|
+
} else if (!Buffer.isBuffer(body)
|
|
306
|
+
&& !(!Array.isArray(body) && Reflect.has(body, Symbol.iterator))) {
|
|
307
|
+
headers = { [HTTP2_HEADER_CONTENT_TYPE]: APPLICATION_JSON };
|
|
308
|
+
body = JSON.stringify(body);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (types.isUint8Array(body) || Buffer.isBuffer(body) || body !== Object(body)) {
|
|
312
|
+
if (options.headers[HTTP2_HEADER_CONTENT_ENCODING]) {
|
|
313
|
+
body = compress(body, options.headers[HTTP2_HEADER_CONTENT_ENCODING]);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
headers = {
|
|
317
|
+
...headers,
|
|
318
|
+
[HTTP2_HEADER_CONTENT_LENGTH]: Buffer.byteLength(body),
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
Object.assign(options.headers, {
|
|
324
|
+
...headers,
|
|
325
|
+
...options.headers[HTTP2_HEADER_CONTENT_TYPE] && {
|
|
326
|
+
[HTTP2_HEADER_CONTENT_TYPE]: options.headers[HTTP2_HEADER_CONTENT_TYPE],
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
return body;
|
|
331
|
+
};
|
package/src/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import http from 'http';
|
|
1
2
|
import http2 from 'http2';
|
|
2
|
-
import
|
|
3
|
+
import https from 'https';
|
|
3
4
|
import { ackn } from './ackn.mjs';
|
|
4
5
|
import { Cookies } from './cookies.mjs';
|
|
5
6
|
import { RequestError } from './errors.mjs';
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
merge,
|
|
9
10
|
preflight,
|
|
10
11
|
premix,
|
|
12
|
+
redirects,
|
|
11
13
|
transform,
|
|
12
14
|
} from './helpers.mjs';
|
|
13
15
|
import { APPLICATION_OCTET_STREAM } from './mediatypes.mjs';
|
|
@@ -43,7 +45,7 @@ export default async function rekwest(url, options = {}) {
|
|
|
43
45
|
HTTP2_METHOD_GET,
|
|
44
46
|
HTTP2_METHOD_HEAD,
|
|
45
47
|
].includes(options.method)) {
|
|
46
|
-
throw new TypeError(`Request with ${ HTTP2_METHOD_GET }/${ HTTP2_METHOD_HEAD } method cannot have body
|
|
48
|
+
throw new TypeError(`Request with ${ HTTP2_METHOD_GET }/${ HTTP2_METHOD_HEAD } method cannot have body.`);
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
if (!options.follow) {
|
|
@@ -63,7 +65,8 @@ export default async function rekwest(url, options = {}) {
|
|
|
63
65
|
|
|
64
66
|
options = preflight(options);
|
|
65
67
|
|
|
66
|
-
const { cookies, digest, follow, h2, redirect, redirected, thenable } = options;
|
|
68
|
+
const { cookies, digest, follow, h2, redirect, redirected, thenable, url: { protocol } } = options;
|
|
69
|
+
const { request } = (protocol === 'http:' ? http : https);
|
|
67
70
|
let { body } = options;
|
|
68
71
|
|
|
69
72
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -120,16 +123,16 @@ export default async function rekwest(url, options = {}) {
|
|
|
120
123
|
});
|
|
121
124
|
|
|
122
125
|
if (follow && /^3\d{2}$/.test(res.statusCode) && res.headers[HTTP2_HEADER_LOCATION]) {
|
|
123
|
-
if (redirect ===
|
|
124
|
-
res.emit('error', new RequestError(`Unexpected redirect, redirect mode is set to '${ redirect }'
|
|
126
|
+
if (redirect === redirects.error) {
|
|
127
|
+
res.emit('error', new RequestError(`Unexpected redirect, redirect mode is set to '${ redirect }'.`));
|
|
125
128
|
}
|
|
126
129
|
|
|
127
|
-
if (redirect ===
|
|
130
|
+
if (redirect === redirects.follow) {
|
|
128
131
|
options.url = new URL(res.headers[HTTP2_HEADER_LOCATION], url).href;
|
|
129
132
|
|
|
130
133
|
if (res.statusCode !== HTTP_STATUS_SEE_OTHER
|
|
131
134
|
&& body === Object(body) && body.pipe?.constructor === Function) {
|
|
132
|
-
res.emit('error', new RequestError(`Unable to ${ redirect } redirect with body as readable stream
|
|
135
|
+
res.emit('error', new RequestError(`Unable to ${ redirect } redirect with body as readable stream.`));
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
options.follow--;
|
|
@@ -209,6 +212,7 @@ Reflect.defineProperty(rekwest, 'stream', {
|
|
|
209
212
|
...merge(rekwest.defaults, {
|
|
210
213
|
headers: { [HTTP2_HEADER_CONTENT_TYPE]: APPLICATION_OCTET_STREAM },
|
|
211
214
|
}, options),
|
|
215
|
+
redirect: redirects.manual,
|
|
212
216
|
});
|
|
213
217
|
|
|
214
218
|
if (options.h2) {
|
|
@@ -222,6 +226,9 @@ Reflect.defineProperty(rekwest, 'stream', {
|
|
|
222
226
|
return req;
|
|
223
227
|
}
|
|
224
228
|
|
|
229
|
+
const { url: { protocol } } = options;
|
|
230
|
+
const { request } = (protocol === 'http:' ? http : https);
|
|
231
|
+
|
|
225
232
|
return request(options.url, options);
|
|
226
233
|
},
|
|
227
234
|
});
|