@common.js/node-fetch 3.3.2
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/@types/index.d.ts +219 -0
- package/LICENSE.md +22 -0
- package/README.md +5 -0
- package/package.json +117 -0
- package/src/body.js +902 -0
- package/src/errors/abort-error.js +93 -0
- package/src/errors/base.js +181 -0
- package/src/errors/fetch-error.js +100 -0
- package/src/headers.js +737 -0
- package/src/index.js +602 -0
- package/src/request.js +434 -0
- package/src/response.js +382 -0
- package/src/utils/get-search.js +18 -0
- package/src/utils/is-redirect.js +20 -0
- package/src/utils/is.js +51 -0
- package/src/utils/multipart-parser.js +661 -0
- package/src/utils/referrer.js +272 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index.js
|
|
3
|
+
*
|
|
4
|
+
* a request API compatible with window.fetch
|
|
5
|
+
*
|
|
6
|
+
* All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.
|
|
7
|
+
*/ "use strict";
|
|
8
|
+
Object.defineProperty(exports, "__esModule", {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
function _export(target, all) {
|
|
12
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: all[name]
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
_export(exports, {
|
|
18
|
+
FormData: function() {
|
|
19
|
+
return _esmMinJs.FormData;
|
|
20
|
+
},
|
|
21
|
+
Headers: function() {
|
|
22
|
+
return _headersJs.default;
|
|
23
|
+
},
|
|
24
|
+
Request: function() {
|
|
25
|
+
return _requestJs.default;
|
|
26
|
+
},
|
|
27
|
+
Response: function() {
|
|
28
|
+
return _responseJs.default;
|
|
29
|
+
},
|
|
30
|
+
FetchError: function() {
|
|
31
|
+
return _fetchErrorJs.FetchError;
|
|
32
|
+
},
|
|
33
|
+
AbortError: function() {
|
|
34
|
+
return _abortErrorJs.AbortError;
|
|
35
|
+
},
|
|
36
|
+
isRedirect: function() {
|
|
37
|
+
return _isRedirectJs.isRedirect;
|
|
38
|
+
},
|
|
39
|
+
Blob: function() {
|
|
40
|
+
return _fromJs.Blob;
|
|
41
|
+
},
|
|
42
|
+
File: function() {
|
|
43
|
+
return _fromJs.File;
|
|
44
|
+
},
|
|
45
|
+
fileFromSync: function() {
|
|
46
|
+
return _fromJs.fileFromSync;
|
|
47
|
+
},
|
|
48
|
+
fileFrom: function() {
|
|
49
|
+
return _fromJs.fileFrom;
|
|
50
|
+
},
|
|
51
|
+
blobFromSync: function() {
|
|
52
|
+
return _fromJs.blobFromSync;
|
|
53
|
+
},
|
|
54
|
+
blobFrom: function() {
|
|
55
|
+
return _fromJs.blobFrom;
|
|
56
|
+
},
|
|
57
|
+
/**
|
|
58
|
+
* Fetch function
|
|
59
|
+
*
|
|
60
|
+
* @param {string | URL | import('./request').default} url - Absolute url or Request instance
|
|
61
|
+
* @param {*} [options_] - Fetch options
|
|
62
|
+
* @return {Promise<import('./response').default>}
|
|
63
|
+
*/ default: function() {
|
|
64
|
+
return fetch;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
var _nodeHttp = /*#__PURE__*/ _interopRequireDefault(require("node:http"));
|
|
68
|
+
var _nodeHttps = /*#__PURE__*/ _interopRequireDefault(require("node:https"));
|
|
69
|
+
var _nodeZlib = /*#__PURE__*/ _interopRequireDefault(require("node:zlib"));
|
|
70
|
+
var _nodeStream = /*#__PURE__*/ _interopRequireWildcard(require("node:stream"));
|
|
71
|
+
var _nodeBuffer = require("node:buffer");
|
|
72
|
+
var _dataUriToBuffer = /*#__PURE__*/ _interopRequireDefault(require("data-uri-to-buffer"));
|
|
73
|
+
var _bodyJs = require("./body.js");
|
|
74
|
+
var _responseJs = /*#__PURE__*/ _interopRequireDefault(require("./response.js"));
|
|
75
|
+
var _headersJs = /*#__PURE__*/ _interopRequireWildcard(require("./headers.js"));
|
|
76
|
+
var _requestJs = /*#__PURE__*/ _interopRequireWildcard(require("./request.js"));
|
|
77
|
+
var _fetchErrorJs = require("./errors/fetch-error.js");
|
|
78
|
+
var _abortErrorJs = require("./errors/abort-error.js");
|
|
79
|
+
var _isRedirectJs = require("./utils/is-redirect.js");
|
|
80
|
+
var _esmMinJs = require("formdata-polyfill/esm.min.js");
|
|
81
|
+
var _isJs = require("./utils/is.js");
|
|
82
|
+
var _referrerJs = require("./utils/referrer.js");
|
|
83
|
+
var _fromJs = require("fetch-blob/from.js");
|
|
84
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
85
|
+
try {
|
|
86
|
+
var info = gen[key](arg);
|
|
87
|
+
var value = info.value;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
reject(error);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (info.done) {
|
|
93
|
+
resolve(value);
|
|
94
|
+
} else {
|
|
95
|
+
Promise.resolve(value).then(_next, _throw);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function _asyncToGenerator(fn) {
|
|
99
|
+
return function() {
|
|
100
|
+
var self = this, args = arguments;
|
|
101
|
+
return new Promise(function(resolve, reject) {
|
|
102
|
+
var gen = fn.apply(self, args);
|
|
103
|
+
function _next(value) {
|
|
104
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
105
|
+
}
|
|
106
|
+
function _throw(err) {
|
|
107
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
108
|
+
}
|
|
109
|
+
_next(undefined);
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function _instanceof(left, right) {
|
|
114
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
115
|
+
return !!right[Symbol.hasInstance](left);
|
|
116
|
+
} else {
|
|
117
|
+
return left instanceof right;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function _interopRequireDefault(obj) {
|
|
121
|
+
return obj && obj.__esModule ? obj : {
|
|
122
|
+
default: obj
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
126
|
+
if (typeof WeakMap !== "function") return null;
|
|
127
|
+
var cacheBabelInterop = new WeakMap();
|
|
128
|
+
var cacheNodeInterop = new WeakMap();
|
|
129
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
130
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
131
|
+
})(nodeInterop);
|
|
132
|
+
}
|
|
133
|
+
function _interopRequireWildcard(obj, nodeInterop) {
|
|
134
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
135
|
+
return obj;
|
|
136
|
+
}
|
|
137
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
138
|
+
return {
|
|
139
|
+
default: obj
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
143
|
+
if (cache && cache.has(obj)) {
|
|
144
|
+
return cache.get(obj);
|
|
145
|
+
}
|
|
146
|
+
var newObj = {};
|
|
147
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
148
|
+
for(var key in obj){
|
|
149
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
150
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
151
|
+
if (desc && (desc.get || desc.set)) {
|
|
152
|
+
Object.defineProperty(newObj, key, desc);
|
|
153
|
+
} else {
|
|
154
|
+
newObj[key] = obj[key];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
newObj.default = obj;
|
|
159
|
+
if (cache) {
|
|
160
|
+
cache.set(obj, newObj);
|
|
161
|
+
}
|
|
162
|
+
return newObj;
|
|
163
|
+
}
|
|
164
|
+
var __generator = (void 0) && (void 0).__generator || function(thisArg, body) {
|
|
165
|
+
var f, y, t, g, _ = {
|
|
166
|
+
label: 0,
|
|
167
|
+
sent: function() {
|
|
168
|
+
if (t[0] & 1) throw t[1];
|
|
169
|
+
return t[1];
|
|
170
|
+
},
|
|
171
|
+
trys: [],
|
|
172
|
+
ops: []
|
|
173
|
+
};
|
|
174
|
+
return g = {
|
|
175
|
+
next: verb(0),
|
|
176
|
+
"throw": verb(1),
|
|
177
|
+
"return": verb(2)
|
|
178
|
+
}, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
179
|
+
return this;
|
|
180
|
+
}), g;
|
|
181
|
+
function verb(n) {
|
|
182
|
+
return function(v) {
|
|
183
|
+
return step([
|
|
184
|
+
n,
|
|
185
|
+
v
|
|
186
|
+
]);
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function step(op) {
|
|
190
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
191
|
+
while(_)try {
|
|
192
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
193
|
+
if (y = 0, t) op = [
|
|
194
|
+
op[0] & 2,
|
|
195
|
+
t.value
|
|
196
|
+
];
|
|
197
|
+
switch(op[0]){
|
|
198
|
+
case 0:
|
|
199
|
+
case 1:
|
|
200
|
+
t = op;
|
|
201
|
+
break;
|
|
202
|
+
case 4:
|
|
203
|
+
_.label++;
|
|
204
|
+
return {
|
|
205
|
+
value: op[1],
|
|
206
|
+
done: false
|
|
207
|
+
};
|
|
208
|
+
case 5:
|
|
209
|
+
_.label++;
|
|
210
|
+
y = op[1];
|
|
211
|
+
op = [
|
|
212
|
+
0
|
|
213
|
+
];
|
|
214
|
+
continue;
|
|
215
|
+
case 7:
|
|
216
|
+
op = _.ops.pop();
|
|
217
|
+
_.trys.pop();
|
|
218
|
+
continue;
|
|
219
|
+
default:
|
|
220
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
221
|
+
_ = 0;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
225
|
+
_.label = op[1];
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
229
|
+
_.label = t[1];
|
|
230
|
+
t = op;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
if (t && _.label < t[2]) {
|
|
234
|
+
_.label = t[2];
|
|
235
|
+
_.ops.push(op);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
if (t[2]) _.ops.pop();
|
|
239
|
+
_.trys.pop();
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
op = body.call(thisArg, _);
|
|
243
|
+
} catch (e) {
|
|
244
|
+
op = [
|
|
245
|
+
6,
|
|
246
|
+
e
|
|
247
|
+
];
|
|
248
|
+
y = 0;
|
|
249
|
+
} finally{
|
|
250
|
+
f = t = 0;
|
|
251
|
+
}
|
|
252
|
+
if (op[0] & 5) throw op[1];
|
|
253
|
+
return {
|
|
254
|
+
value: op[0] ? op[1] : void 0,
|
|
255
|
+
done: true
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
var supportedSchemas = new Set([
|
|
260
|
+
"data:",
|
|
261
|
+
"http:",
|
|
262
|
+
"https:"
|
|
263
|
+
]);
|
|
264
|
+
function fetch(url, options_) {
|
|
265
|
+
return _fetch.apply(this, arguments);
|
|
266
|
+
}
|
|
267
|
+
function _fetch() {
|
|
268
|
+
_fetch = _asyncToGenerator(function(url, options_) {
|
|
269
|
+
return __generator(this, function(_state) {
|
|
270
|
+
return [
|
|
271
|
+
2,
|
|
272
|
+
new Promise(function(resolve, reject) {
|
|
273
|
+
// Build request object
|
|
274
|
+
var request = new _requestJs.default(url, options_);
|
|
275
|
+
var ref = (0, _requestJs.getNodeRequestOptions)(request), parsedURL = ref.parsedURL, options = ref.options;
|
|
276
|
+
if (!supportedSchemas.has(parsedURL.protocol)) {
|
|
277
|
+
throw new TypeError("node-fetch cannot load ".concat(url, '. URL scheme "').concat(parsedURL.protocol.replace(/:$/, ""), '" is not supported.'));
|
|
278
|
+
}
|
|
279
|
+
if (parsedURL.protocol === "data:") {
|
|
280
|
+
var data = (0, _dataUriToBuffer.default)(request.url);
|
|
281
|
+
var response = new _responseJs.default(data, {
|
|
282
|
+
headers: {
|
|
283
|
+
"Content-Type": data.typeFull
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
resolve(response);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
// Wrap http.request into fetch
|
|
290
|
+
var send = (parsedURL.protocol === "https:" ? _nodeHttps.default : _nodeHttp.default).request;
|
|
291
|
+
var signal = request.signal;
|
|
292
|
+
var response1 = null;
|
|
293
|
+
var abort = function() {
|
|
294
|
+
var error = new _abortErrorJs.AbortError("The operation was aborted.");
|
|
295
|
+
reject(error);
|
|
296
|
+
if (request.body && _instanceof(request.body, _nodeStream.default.Readable)) {
|
|
297
|
+
request.body.destroy(error);
|
|
298
|
+
}
|
|
299
|
+
if (!response1 || !response1.body) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
response1.body.emit("error", error);
|
|
303
|
+
};
|
|
304
|
+
if (signal && signal.aborted) {
|
|
305
|
+
abort();
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
var abortAndFinalize = function() {
|
|
309
|
+
abort();
|
|
310
|
+
finalize();
|
|
311
|
+
};
|
|
312
|
+
// Send request
|
|
313
|
+
var request_ = send(parsedURL.toString(), options);
|
|
314
|
+
if (signal) {
|
|
315
|
+
signal.addEventListener("abort", abortAndFinalize);
|
|
316
|
+
}
|
|
317
|
+
var finalize = function() {
|
|
318
|
+
request_.abort();
|
|
319
|
+
if (signal) {
|
|
320
|
+
signal.removeEventListener("abort", abortAndFinalize);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
request_.on("error", function(error) {
|
|
324
|
+
reject(new _fetchErrorJs.FetchError("request to ".concat(request.url, " failed, reason: ").concat(error.message), "system", error));
|
|
325
|
+
finalize();
|
|
326
|
+
});
|
|
327
|
+
fixResponseChunkedTransferBadEnding(request_, function(error) {
|
|
328
|
+
if (response1 && response1.body) {
|
|
329
|
+
response1.body.destroy(error);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
/* c8 ignore next 18 */ if (process.version < "v14") {
|
|
333
|
+
// Before Node.js 14, pipeline() does not fully support async iterators and does not always
|
|
334
|
+
// properly handle when the socket close/end events are out of order.
|
|
335
|
+
request_.on("socket", function(s) {
|
|
336
|
+
var endedWithEventsCount;
|
|
337
|
+
s.prependListener("end", function() {
|
|
338
|
+
endedWithEventsCount = s._eventsCount;
|
|
339
|
+
});
|
|
340
|
+
s.prependListener("close", function(hadError) {
|
|
341
|
+
// if end happened before close but the socket didn't emit an error, do it now
|
|
342
|
+
if (response1 && endedWithEventsCount < s._eventsCount && !hadError) {
|
|
343
|
+
var error = new Error("Premature close");
|
|
344
|
+
error.code = "ERR_STREAM_PREMATURE_CLOSE";
|
|
345
|
+
response1.body.emit("error", error);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
request_.on("response", function(response_) {
|
|
351
|
+
request_.setTimeout(0);
|
|
352
|
+
var headers = (0, _headersJs.fromRawHeaders)(response_.rawHeaders);
|
|
353
|
+
// HTTP fetch step 5
|
|
354
|
+
if ((0, _isRedirectJs.isRedirect)(response_.statusCode)) {
|
|
355
|
+
// HTTP fetch step 5.2
|
|
356
|
+
var location = headers.get("Location");
|
|
357
|
+
// HTTP fetch step 5.3
|
|
358
|
+
var locationURL = null;
|
|
359
|
+
try {
|
|
360
|
+
locationURL = location === null ? null : new URL(location, request.url);
|
|
361
|
+
} catch (e) {
|
|
362
|
+
// error here can only be invalid URL in Location: header
|
|
363
|
+
// do not throw when options.redirect == manual
|
|
364
|
+
// let the user extract the errorneous redirect URL
|
|
365
|
+
if (request.redirect !== "manual") {
|
|
366
|
+
reject(new _fetchErrorJs.FetchError("uri requested responds with an invalid redirect URL: ".concat(location), "invalid-redirect"));
|
|
367
|
+
finalize();
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
// HTTP fetch step 5.5
|
|
372
|
+
switch(request.redirect){
|
|
373
|
+
case "error":
|
|
374
|
+
reject(new _fetchErrorJs.FetchError("uri requested responds with a redirect, redirect mode is set to error: ".concat(request.url), "no-redirect"));
|
|
375
|
+
finalize();
|
|
376
|
+
return;
|
|
377
|
+
case "manual":
|
|
378
|
+
break;
|
|
379
|
+
case "follow":
|
|
380
|
+
{
|
|
381
|
+
// HTTP-redirect fetch step 2
|
|
382
|
+
if (locationURL === null) {
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
// HTTP-redirect fetch step 5
|
|
386
|
+
if (request.counter >= request.follow) {
|
|
387
|
+
reject(new _fetchErrorJs.FetchError("maximum redirect reached at: ".concat(request.url), "max-redirect"));
|
|
388
|
+
finalize();
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
// HTTP-redirect fetch step 6 (counter increment)
|
|
392
|
+
// Create a new Request object.
|
|
393
|
+
var requestOptions = {
|
|
394
|
+
headers: new _headersJs.default(request.headers),
|
|
395
|
+
follow: request.follow,
|
|
396
|
+
counter: request.counter + 1,
|
|
397
|
+
agent: request.agent,
|
|
398
|
+
compress: request.compress,
|
|
399
|
+
method: request.method,
|
|
400
|
+
body: (0, _bodyJs.clone)(request),
|
|
401
|
+
signal: request.signal,
|
|
402
|
+
size: request.size,
|
|
403
|
+
referrer: request.referrer,
|
|
404
|
+
referrerPolicy: request.referrerPolicy
|
|
405
|
+
};
|
|
406
|
+
// when forwarding sensitive headers like "Authorization",
|
|
407
|
+
// "WWW-Authenticate", and "Cookie" to untrusted targets,
|
|
408
|
+
// headers will be ignored when following a redirect to a domain
|
|
409
|
+
// that is not a subdomain match or exact match of the initial domain.
|
|
410
|
+
// For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com"
|
|
411
|
+
// will forward the sensitive headers, but a redirect to "bar.com" will not.
|
|
412
|
+
// headers will also be ignored when following a redirect to a domain using
|
|
413
|
+
// a different protocol. For example, a redirect from "https://foo.com" to "http://foo.com"
|
|
414
|
+
// will not forward the sensitive headers
|
|
415
|
+
if (!(0, _isJs.isDomainOrSubdomain)(request.url, locationURL) || !(0, _isJs.isSameProtocol)(request.url, locationURL)) {
|
|
416
|
+
for(var _i = 0, _iter = [
|
|
417
|
+
"authorization",
|
|
418
|
+
"www-authenticate",
|
|
419
|
+
"cookie",
|
|
420
|
+
"cookie2"
|
|
421
|
+
]; _i < _iter.length; _i++){
|
|
422
|
+
var name = _iter[_i];
|
|
423
|
+
requestOptions.headers.delete(name);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
// HTTP-redirect fetch step 9
|
|
427
|
+
if (response_.statusCode !== 303 && request.body && _instanceof(options_.body, _nodeStream.default.Readable)) {
|
|
428
|
+
reject(new _fetchErrorJs.FetchError("Cannot follow redirect with body being a readable stream", "unsupported-redirect"));
|
|
429
|
+
finalize();
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
// HTTP-redirect fetch step 11
|
|
433
|
+
if (response_.statusCode === 303 || (response_.statusCode === 301 || response_.statusCode === 302) && request.method === "POST") {
|
|
434
|
+
requestOptions.method = "GET";
|
|
435
|
+
requestOptions.body = undefined;
|
|
436
|
+
requestOptions.headers.delete("content-length");
|
|
437
|
+
}
|
|
438
|
+
// HTTP-redirect fetch step 14
|
|
439
|
+
var responseReferrerPolicy = (0, _referrerJs.parseReferrerPolicyFromHeader)(headers);
|
|
440
|
+
if (responseReferrerPolicy) {
|
|
441
|
+
requestOptions.referrerPolicy = responseReferrerPolicy;
|
|
442
|
+
}
|
|
443
|
+
// HTTP-redirect fetch step 15
|
|
444
|
+
resolve(fetch(new _requestJs.default(locationURL, requestOptions)));
|
|
445
|
+
finalize();
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
default:
|
|
449
|
+
return reject(new TypeError("Redirect option '".concat(request.redirect, "' is not a valid value of RequestRedirect")));
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
// Prepare response
|
|
453
|
+
if (signal) {
|
|
454
|
+
response_.once("end", function() {
|
|
455
|
+
signal.removeEventListener("abort", abortAndFinalize);
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
var body = (0, _nodeStream.pipeline)(response_, new _nodeStream.PassThrough(), function(error) {
|
|
459
|
+
if (error) {
|
|
460
|
+
reject(error);
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
// see https://github.com/nodejs/node/pull/29376
|
|
464
|
+
/* c8 ignore next 3 */ if (process.version < "v12.10") {
|
|
465
|
+
response_.on("aborted", abortAndFinalize);
|
|
466
|
+
}
|
|
467
|
+
var responseOptions = {
|
|
468
|
+
url: request.url,
|
|
469
|
+
status: response_.statusCode,
|
|
470
|
+
statusText: response_.statusMessage,
|
|
471
|
+
headers: headers,
|
|
472
|
+
size: request.size,
|
|
473
|
+
counter: request.counter,
|
|
474
|
+
highWaterMark: request.highWaterMark
|
|
475
|
+
};
|
|
476
|
+
// HTTP-network fetch step 12.1.1.3
|
|
477
|
+
var codings = headers.get("Content-Encoding");
|
|
478
|
+
// HTTP-network fetch step 12.1.1.4: handle content codings
|
|
479
|
+
// in following scenarios we ignore compression support
|
|
480
|
+
// 1. compression support is disabled
|
|
481
|
+
// 2. HEAD request
|
|
482
|
+
// 3. no Content-Encoding header
|
|
483
|
+
// 4. no content response (204)
|
|
484
|
+
// 5. content not modified response (304)
|
|
485
|
+
if (!request.compress || request.method === "HEAD" || codings === null || response_.statusCode === 204 || response_.statusCode === 304) {
|
|
486
|
+
response1 = new _responseJs.default(body, responseOptions);
|
|
487
|
+
resolve(response1);
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
// For Node v6+
|
|
491
|
+
// Be less strict when decoding compressed responses, since sometimes
|
|
492
|
+
// servers send slightly invalid responses that are still accepted
|
|
493
|
+
// by common browsers.
|
|
494
|
+
// Always using Z_SYNC_FLUSH is what cURL does.
|
|
495
|
+
var zlibOptions = {
|
|
496
|
+
flush: _nodeZlib.default.Z_SYNC_FLUSH,
|
|
497
|
+
finishFlush: _nodeZlib.default.Z_SYNC_FLUSH
|
|
498
|
+
};
|
|
499
|
+
// For gzip
|
|
500
|
+
if (codings === "gzip" || codings === "x-gzip") {
|
|
501
|
+
body = (0, _nodeStream.pipeline)(body, _nodeZlib.default.createGunzip(zlibOptions), function(error) {
|
|
502
|
+
if (error) {
|
|
503
|
+
reject(error);
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
response1 = new _responseJs.default(body, responseOptions);
|
|
507
|
+
resolve(response1);
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
// For deflate
|
|
511
|
+
if (codings === "deflate" || codings === "x-deflate") {
|
|
512
|
+
// Handle the infamous raw deflate response from old servers
|
|
513
|
+
// a hack for old IIS and Apache servers
|
|
514
|
+
var raw = (0, _nodeStream.pipeline)(response_, new _nodeStream.PassThrough(), function(error) {
|
|
515
|
+
if (error) {
|
|
516
|
+
reject(error);
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
raw.once("data", function(chunk) {
|
|
520
|
+
// See http://stackoverflow.com/questions/37519828
|
|
521
|
+
if ((chunk[0] & 0x0F) === 0x08) {
|
|
522
|
+
body = (0, _nodeStream.pipeline)(body, _nodeZlib.default.createInflate(), function(error) {
|
|
523
|
+
if (error) {
|
|
524
|
+
reject(error);
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
} else {
|
|
528
|
+
body = (0, _nodeStream.pipeline)(body, _nodeZlib.default.createInflateRaw(), function(error) {
|
|
529
|
+
if (error) {
|
|
530
|
+
reject(error);
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
response1 = new _responseJs.default(body, responseOptions);
|
|
535
|
+
resolve(response1);
|
|
536
|
+
});
|
|
537
|
+
raw.once("end", function() {
|
|
538
|
+
// Some old IIS servers return zero-length OK deflate responses, so
|
|
539
|
+
// 'data' is never emitted. See https://github.com/node-fetch/node-fetch/pull/903
|
|
540
|
+
if (!response1) {
|
|
541
|
+
response1 = new _responseJs.default(body, responseOptions);
|
|
542
|
+
resolve(response1);
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
// For br
|
|
548
|
+
if (codings === "br") {
|
|
549
|
+
body = (0, _nodeStream.pipeline)(body, _nodeZlib.default.createBrotliDecompress(), function(error) {
|
|
550
|
+
if (error) {
|
|
551
|
+
reject(error);
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
response1 = new _responseJs.default(body, responseOptions);
|
|
555
|
+
resolve(response1);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
// Otherwise, use response as-is
|
|
559
|
+
response1 = new _responseJs.default(body, responseOptions);
|
|
560
|
+
resolve(response1);
|
|
561
|
+
});
|
|
562
|
+
// eslint-disable-next-line promise/prefer-await-to-then
|
|
563
|
+
(0, _bodyJs.writeToStream)(request_, request).catch(reject);
|
|
564
|
+
})
|
|
565
|
+
];
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
return _fetch.apply(this, arguments);
|
|
569
|
+
}
|
|
570
|
+
function fixResponseChunkedTransferBadEnding(request, errorCallback) {
|
|
571
|
+
var LAST_CHUNK = _nodeBuffer.Buffer.from("0\r\n\r\n");
|
|
572
|
+
var isChunkedTransfer = false;
|
|
573
|
+
var properLastChunkReceived = false;
|
|
574
|
+
var previousChunk;
|
|
575
|
+
request.on("response", function(response) {
|
|
576
|
+
var headers = response.headers;
|
|
577
|
+
isChunkedTransfer = headers["transfer-encoding"] === "chunked" && !headers["content-length"];
|
|
578
|
+
});
|
|
579
|
+
request.on("socket", function(socket) {
|
|
580
|
+
var onSocketClose = function() {
|
|
581
|
+
if (isChunkedTransfer && !properLastChunkReceived) {
|
|
582
|
+
var error = new Error("Premature close");
|
|
583
|
+
error.code = "ERR_STREAM_PREMATURE_CLOSE";
|
|
584
|
+
errorCallback(error);
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
var onData = function(buf) {
|
|
588
|
+
properLastChunkReceived = _nodeBuffer.Buffer.compare(buf.slice(-5), LAST_CHUNK) === 0;
|
|
589
|
+
// Sometimes final 0-length chunk and end of message code are in separate packets
|
|
590
|
+
if (!properLastChunkReceived && previousChunk) {
|
|
591
|
+
properLastChunkReceived = _nodeBuffer.Buffer.compare(previousChunk.slice(-3), LAST_CHUNK.slice(0, 3)) === 0 && _nodeBuffer.Buffer.compare(buf.slice(-2), LAST_CHUNK.slice(3)) === 0;
|
|
592
|
+
}
|
|
593
|
+
previousChunk = buf;
|
|
594
|
+
};
|
|
595
|
+
socket.prependListener("close", onSocketClose);
|
|
596
|
+
socket.on("data", onData);
|
|
597
|
+
request.on("close", function() {
|
|
598
|
+
socket.removeListener("close", onSocketClose);
|
|
599
|
+
socket.removeListener("data", onData);
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
}
|