@zuplo/cli 6.70.71 → 6.71.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/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +1 -1
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/node_modules/axios/CHANGELOG.md +52 -1
- package/node_modules/axios/README.md +30 -2
- package/node_modules/axios/dist/axios.js +350 -134
- package/node_modules/axios/dist/axios.min.js +3 -3
- package/node_modules/axios/dist/axios.min.js.map +1 -1
- package/node_modules/axios/dist/browser/axios.cjs +355 -90
- package/node_modules/axios/dist/esm/axios.js +355 -90
- package/node_modules/axios/dist/esm/axios.min.js +2 -2
- package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
- package/node_modules/axios/dist/node/axios.cjs +399 -104
- package/node_modules/axios/index.d.cts +2 -0
- package/node_modules/axios/index.d.ts +2 -0
- package/node_modules/axios/lib/adapters/fetch.js +113 -37
- package/node_modules/axios/lib/adapters/http.js +132 -43
- package/node_modules/axios/lib/core/Axios.js +3 -2
- package/node_modules/axios/lib/core/AxiosHeaders.js +10 -7
- package/node_modules/axios/lib/core/buildFullPath.js +29 -1
- package/node_modules/axios/lib/core/mergeConfig.js +34 -0
- package/node_modules/axios/lib/defaults/transitional.js +1 -0
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/helpers/buildURL.js +5 -3
- package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
- package/node_modules/axios/lib/helpers/formDataToJSON.js +25 -3
- package/node_modules/axios/lib/helpers/resolveConfig.js +5 -3
- package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
- package/node_modules/axios/lib/helpers/toFormData.js +40 -10
- package/node_modules/axios/lib/utils.js +75 -11
- package/node_modules/axios/package.json +1 -1
- package/node_modules/form-data/CHANGELOG.md +29 -2
- package/node_modules/form-data/README.md +4 -4
- package/node_modules/form-data/lib/form_data.js +14 -2
- package/node_modules/form-data/package.json +7 -7
- package/package.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Axios v1.
|
|
1
|
+
/*! Axios v1.18.0 Copyright (c) 2026 Matt Zabriskie and contributors */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var FormData$1 = require('form-data');
|
|
@@ -40,6 +40,52 @@ const {
|
|
|
40
40
|
iterator,
|
|
41
41
|
toStringTag
|
|
42
42
|
} = Symbol;
|
|
43
|
+
|
|
44
|
+
/* Creating a function that will check if an object has a property. */
|
|
45
|
+
const hasOwnProperty = (({
|
|
46
|
+
hasOwnProperty
|
|
47
|
+
}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Walk the prototype chain (excluding the shared Object.prototype) looking for
|
|
51
|
+
* an own `prop`. This distinguishes genuine own/inherited members — including
|
|
52
|
+
* class accessors and template prototypes — from members injected via
|
|
53
|
+
* Object.prototype pollution (e.g. `Object.prototype.username = '...'`), which
|
|
54
|
+
* live on Object.prototype itself and are therefore never matched.
|
|
55
|
+
*
|
|
56
|
+
* @param {*} thing The value whose chain to inspect
|
|
57
|
+
* @param {string|symbol} prop The property key to look for
|
|
58
|
+
*
|
|
59
|
+
* @returns {boolean} True when `prop` is owned below Object.prototype
|
|
60
|
+
*/
|
|
61
|
+
const hasOwnInPrototypeChain = (thing, prop) => {
|
|
62
|
+
let obj = thing;
|
|
63
|
+
const seen = [];
|
|
64
|
+
while (obj != null && obj !== Object.prototype) {
|
|
65
|
+
if (seen.indexOf(obj) !== -1) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
seen.push(obj);
|
|
69
|
+
if (hasOwnProperty(obj, prop)) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
obj = getPrototypeOf(obj);
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Read `obj[prop]` only when it is safe from Object.prototype pollution. Own
|
|
79
|
+
* properties and members inherited from a non-Object.prototype source (a class
|
|
80
|
+
* instance or template object) are honored; a value reachable only through a
|
|
81
|
+
* polluted Object.prototype is ignored and `undefined` is returned.
|
|
82
|
+
*
|
|
83
|
+
* @param {*} obj The source object
|
|
84
|
+
* @param {string|symbol} prop The property key to read
|
|
85
|
+
*
|
|
86
|
+
* @returns {*} The resolved value, or undefined when unsafe/absent
|
|
87
|
+
*/
|
|
88
|
+
const getSafeProp = (obj, prop) => obj != null && hasOwnInPrototypeChain(obj, prop) ? obj[prop] : undefined;
|
|
43
89
|
const kindOf = (cache => thing => {
|
|
44
90
|
const str = toString.call(thing);
|
|
45
91
|
return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
|
|
@@ -158,11 +204,15 @@ const isBoolean = thing => thing === true || thing === false;
|
|
|
158
204
|
* @returns {boolean} True if value is a plain Object, otherwise false
|
|
159
205
|
*/
|
|
160
206
|
const isPlainObject = val => {
|
|
161
|
-
if (
|
|
207
|
+
if (!isObject(val)) {
|
|
162
208
|
return false;
|
|
163
209
|
}
|
|
164
210
|
const prototype = getPrototypeOf(val);
|
|
165
|
-
return (prototype === null || prototype === Object.prototype ||
|
|
211
|
+
return (prototype === null || prototype === Object.prototype || getPrototypeOf(prototype) === null) &&
|
|
212
|
+
// Treat any genuine (non-Object.prototype-polluted) Symbol.toStringTag or
|
|
213
|
+
// Symbol.iterator as evidence the value is a tagged/iterable type rather
|
|
214
|
+
// than a plain object, while ignoring keys injected onto Object.prototype.
|
|
215
|
+
!hasOwnInPrototypeChain(val, toStringTag) && !hasOwnInPrototypeChain(val, iterator);
|
|
166
216
|
};
|
|
167
217
|
|
|
168
218
|
/**
|
|
@@ -662,11 +712,6 @@ const toCamelCase = str => {
|
|
|
662
712
|
return p1.toUpperCase() + p2;
|
|
663
713
|
});
|
|
664
714
|
};
|
|
665
|
-
|
|
666
|
-
/* Creating a function that will check if an object has a property. */
|
|
667
|
-
const hasOwnProperty = (({
|
|
668
|
-
hasOwnProperty
|
|
669
|
-
}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);
|
|
670
715
|
const {
|
|
671
716
|
propertyIsEnumerable
|
|
672
717
|
} = Object.prototype;
|
|
@@ -844,6 +889,19 @@ const asap = typeof queueMicrotask !== 'undefined' ? queueMicrotask.bind(_global
|
|
|
844
889
|
// *********************
|
|
845
890
|
|
|
846
891
|
const isIterable = thing => thing != null && isFunction$1(thing[iterator]);
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* Determine if a value is iterable via an iterator that is NOT sourced solely
|
|
895
|
+
* from a polluted Object.prototype. Use this instead of `isIterable` whenever
|
|
896
|
+
* the iterable comes from untrusted input (e.g. user-supplied header sources),
|
|
897
|
+
* so `Object.prototype[Symbol.iterator] = ...` cannot turn an ordinary object
|
|
898
|
+
* into an attacker-controlled entries iterator.
|
|
899
|
+
*
|
|
900
|
+
* @param {*} thing The value to test
|
|
901
|
+
*
|
|
902
|
+
* @returns {boolean} True if value has a non-polluted iterator
|
|
903
|
+
*/
|
|
904
|
+
const isSafeIterable = thing => thing != null && hasOwnInPrototypeChain(thing, iterator) && isIterable(thing);
|
|
847
905
|
var utils$1 = {
|
|
848
906
|
isArray,
|
|
849
907
|
isArrayBuffer,
|
|
@@ -889,6 +947,8 @@ var utils$1 = {
|
|
|
889
947
|
hasOwnProperty,
|
|
890
948
|
hasOwnProp: hasOwnProperty,
|
|
891
949
|
// an alias to avoid ESLint no-prototype-builtins detection
|
|
950
|
+
hasOwnInPrototypeChain,
|
|
951
|
+
getSafeProp,
|
|
892
952
|
reduceDescriptors,
|
|
893
953
|
freezeMethods,
|
|
894
954
|
toObjectSet,
|
|
@@ -904,7 +964,8 @@ var utils$1 = {
|
|
|
904
964
|
isThenable,
|
|
905
965
|
setImmediate: _setImmediate,
|
|
906
966
|
asap,
|
|
907
|
-
isIterable
|
|
967
|
+
isIterable,
|
|
968
|
+
isSafeIterable
|
|
908
969
|
};
|
|
909
970
|
|
|
910
971
|
// RawAxiosHeaders whose duplicates are ignored by node
|
|
@@ -1066,15 +1127,21 @@ class AxiosHeaders {
|
|
|
1066
1127
|
setHeaders(header, valueOrRewrite);
|
|
1067
1128
|
} else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
|
|
1068
1129
|
setHeaders(parseHeaders(header), valueOrRewrite);
|
|
1069
|
-
} else if (utils$1.isObject(header) && utils$1.
|
|
1070
|
-
let obj =
|
|
1130
|
+
} else if (utils$1.isObject(header) && utils$1.isSafeIterable(header)) {
|
|
1131
|
+
let obj = Object.create(null),
|
|
1071
1132
|
dest,
|
|
1072
1133
|
key;
|
|
1073
1134
|
for (const entry of header) {
|
|
1074
1135
|
if (!utils$1.isArray(entry)) {
|
|
1075
1136
|
throw new TypeError('Object iterator must return a key-value pair');
|
|
1076
1137
|
}
|
|
1077
|
-
|
|
1138
|
+
key = entry[0];
|
|
1139
|
+
if (utils$1.hasOwnProp(obj, key)) {
|
|
1140
|
+
dest = obj[key];
|
|
1141
|
+
obj[key] = utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]];
|
|
1142
|
+
} else {
|
|
1143
|
+
obj[key] = entry[1];
|
|
1144
|
+
}
|
|
1078
1145
|
}
|
|
1079
1146
|
setHeaders(obj, valueOrRewrite);
|
|
1080
1147
|
} else {
|
|
@@ -1377,6 +1444,10 @@ AxiosError.ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT';
|
|
|
1377
1444
|
AxiosError.ERR_INVALID_URL = 'ERR_INVALID_URL';
|
|
1378
1445
|
AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED';
|
|
1379
1446
|
|
|
1447
|
+
// Default nesting limit shared with the inverse transform (formDataToJSON) so
|
|
1448
|
+
// the FormData <-> JSON round-trip stays symmetric.
|
|
1449
|
+
const DEFAULT_FORM_DATA_MAX_DEPTH = 100;
|
|
1450
|
+
|
|
1380
1451
|
/**
|
|
1381
1452
|
* Determines if the given thing is a array or js object.
|
|
1382
1453
|
*
|
|
@@ -1477,8 +1548,9 @@ function toFormData(obj, formData, options) {
|
|
|
1477
1548
|
const dots = options.dots;
|
|
1478
1549
|
const indexes = options.indexes;
|
|
1479
1550
|
const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;
|
|
1480
|
-
const maxDepth = options.maxDepth === undefined ?
|
|
1551
|
+
const maxDepth = options.maxDepth === undefined ? DEFAULT_FORM_DATA_MAX_DEPTH : options.maxDepth;
|
|
1481
1552
|
const useBlob = _Blob && utils$1.isSpecCompliantForm(formData);
|
|
1553
|
+
const stack = [];
|
|
1482
1554
|
if (!utils$1.isFunction(visitor)) {
|
|
1483
1555
|
throw new TypeError('visitor must be a function');
|
|
1484
1556
|
}
|
|
@@ -1498,6 +1570,28 @@ function toFormData(obj, formData, options) {
|
|
|
1498
1570
|
}
|
|
1499
1571
|
return value;
|
|
1500
1572
|
}
|
|
1573
|
+
function throwIfMaxDepthExceeded(depth) {
|
|
1574
|
+
if (depth > maxDepth) {
|
|
1575
|
+
throw new AxiosError('Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
function stringifyWithDepthLimit(value, depth) {
|
|
1579
|
+
if (maxDepth === Infinity) {
|
|
1580
|
+
return JSON.stringify(value);
|
|
1581
|
+
}
|
|
1582
|
+
const ancestors = [];
|
|
1583
|
+
return JSON.stringify(value, function limitDepth(_key, currentValue) {
|
|
1584
|
+
if (!utils$1.isObject(currentValue)) {
|
|
1585
|
+
return currentValue;
|
|
1586
|
+
}
|
|
1587
|
+
while (ancestors.length && ancestors[ancestors.length - 1] !== this) {
|
|
1588
|
+
ancestors.pop();
|
|
1589
|
+
}
|
|
1590
|
+
ancestors.push(currentValue);
|
|
1591
|
+
throwIfMaxDepthExceeded(depth + ancestors.length - 1);
|
|
1592
|
+
return currentValue;
|
|
1593
|
+
});
|
|
1594
|
+
}
|
|
1501
1595
|
|
|
1502
1596
|
/**
|
|
1503
1597
|
* Default visitor.
|
|
@@ -1520,7 +1614,7 @@ function toFormData(obj, formData, options) {
|
|
|
1520
1614
|
// eslint-disable-next-line no-param-reassign
|
|
1521
1615
|
key = metaTokens ? key : key.slice(0, -2);
|
|
1522
1616
|
// eslint-disable-next-line no-param-reassign
|
|
1523
|
-
value =
|
|
1617
|
+
value = stringifyWithDepthLimit(value, 1);
|
|
1524
1618
|
} else if (utils$1.isArray(value) && isFlatArray(value) || (utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value))) {
|
|
1525
1619
|
// eslint-disable-next-line no-param-reassign
|
|
1526
1620
|
key = removeBrackets(key);
|
|
@@ -1538,7 +1632,6 @@ function toFormData(obj, formData, options) {
|
|
|
1538
1632
|
formData.append(renderKey(path, key, dots), convertValue(value));
|
|
1539
1633
|
return false;
|
|
1540
1634
|
}
|
|
1541
|
-
const stack = [];
|
|
1542
1635
|
const exposedHelpers = Object.assign(predicates, {
|
|
1543
1636
|
defaultVisitor,
|
|
1544
1637
|
convertValue,
|
|
@@ -1546,9 +1639,7 @@ function toFormData(obj, formData, options) {
|
|
|
1546
1639
|
});
|
|
1547
1640
|
function build(value, path, depth = 0) {
|
|
1548
1641
|
if (utils$1.isUndefined(value)) return;
|
|
1549
|
-
|
|
1550
|
-
throw new AxiosError('Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
|
|
1551
|
-
}
|
|
1642
|
+
throwIfMaxDepthExceeded(depth);
|
|
1552
1643
|
if (stack.indexOf(value) !== -1) {
|
|
1553
1644
|
throw new Error('Circular reference detected in ' + path.join('.'));
|
|
1554
1645
|
}
|
|
@@ -1640,11 +1731,15 @@ function buildURL(url, params, options) {
|
|
|
1640
1731
|
if (!params) {
|
|
1641
1732
|
return url;
|
|
1642
1733
|
}
|
|
1643
|
-
const _encode = options && options.encode || encode;
|
|
1644
1734
|
const _options = utils$1.isFunction(options) ? {
|
|
1645
1735
|
serialize: options
|
|
1646
1736
|
} : options;
|
|
1647
|
-
|
|
1737
|
+
|
|
1738
|
+
// Read serializer options pollution-safely: own properties and methods on a
|
|
1739
|
+
// class/template prototype are honored, but values injected onto a polluted
|
|
1740
|
+
// Object.prototype are ignored.
|
|
1741
|
+
const _encode = utils$1.getSafeProp(_options, 'encode') || encode;
|
|
1742
|
+
const serializeFn = utils$1.getSafeProp(_options, 'serialize');
|
|
1648
1743
|
let serializedParams;
|
|
1649
1744
|
if (serializeFn) {
|
|
1650
1745
|
serializedParams = serializeFn(params, _options);
|
|
@@ -1733,7 +1828,8 @@ var transitionalDefaults = {
|
|
|
1733
1828
|
forcedJSONParsing: true,
|
|
1734
1829
|
clarifyTimeoutError: false,
|
|
1735
1830
|
legacyInterceptorReqResOrdering: true,
|
|
1736
|
-
advertiseZstdAcceptEncoding: false
|
|
1831
|
+
advertiseZstdAcceptEncoding: false,
|
|
1832
|
+
validateStatusUndefinedResolves: true
|
|
1737
1833
|
};
|
|
1738
1834
|
|
|
1739
1835
|
var URLSearchParams = url.URLSearchParams;
|
|
@@ -1834,6 +1930,13 @@ function toURLEncodedForm(data, options) {
|
|
|
1834
1930
|
});
|
|
1835
1931
|
}
|
|
1836
1932
|
|
|
1933
|
+
const MAX_DEPTH = DEFAULT_FORM_DATA_MAX_DEPTH;
|
|
1934
|
+
function throwIfDepthExceeded(index) {
|
|
1935
|
+
if (index > MAX_DEPTH) {
|
|
1936
|
+
throw new AxiosError('FormData field is too deeply nested (' + index + ' levels). Max depth: ' + MAX_DEPTH, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1837
1940
|
/**
|
|
1838
1941
|
* It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']
|
|
1839
1942
|
*
|
|
@@ -1846,9 +1949,14 @@ function parsePropPath(name) {
|
|
|
1846
1949
|
// foo.x.y.z
|
|
1847
1950
|
// foo-x-y-z
|
|
1848
1951
|
// foo x y z
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1952
|
+
const path = [];
|
|
1953
|
+
const pattern = /\w+|\[(\w*)]/g;
|
|
1954
|
+
let match;
|
|
1955
|
+
while ((match = pattern.exec(name)) !== null) {
|
|
1956
|
+
throwIfDepthExceeded(path.length);
|
|
1957
|
+
path.push(match[0] === '[]' ? '' : match[1] || match[0]);
|
|
1958
|
+
}
|
|
1959
|
+
return path;
|
|
1852
1960
|
}
|
|
1853
1961
|
|
|
1854
1962
|
/**
|
|
@@ -1880,6 +1988,7 @@ function arrayToObject(arr) {
|
|
|
1880
1988
|
*/
|
|
1881
1989
|
function formDataToJSON(formData) {
|
|
1882
1990
|
function buildPath(path, value, target, index) {
|
|
1991
|
+
throwIfDepthExceeded(index);
|
|
1883
1992
|
let name = path[index++];
|
|
1884
1993
|
if (name === '__proto__') return true;
|
|
1885
1994
|
const isNumericKey = Number.isFinite(+name);
|
|
@@ -2120,6 +2229,24 @@ function combineURLs(baseURL, relativeURL) {
|
|
|
2120
2229
|
return relativeURL ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;
|
|
2121
2230
|
}
|
|
2122
2231
|
|
|
2232
|
+
const malformedHttpProtocol = /^https?:(?!\/\/)/i;
|
|
2233
|
+
const httpProtocolControlCharacters = /[\t\n\r]/g;
|
|
2234
|
+
function stripLeadingC0ControlOrSpace(url) {
|
|
2235
|
+
let i = 0;
|
|
2236
|
+
while (i < url.length && url.charCodeAt(i) <= 0x20) {
|
|
2237
|
+
i++;
|
|
2238
|
+
}
|
|
2239
|
+
return url.slice(i);
|
|
2240
|
+
}
|
|
2241
|
+
function normalizeURLForProtocolCheck(url) {
|
|
2242
|
+
return stripLeadingC0ControlOrSpace(url).replace(httpProtocolControlCharacters, '');
|
|
2243
|
+
}
|
|
2244
|
+
function assertValidHttpProtocolURL(url, config) {
|
|
2245
|
+
if (typeof url === 'string' && malformedHttpProtocol.test(normalizeURLForProtocolCheck(url))) {
|
|
2246
|
+
throw new AxiosError('Invalid URL: missing "//" after protocol', AxiosError.ERR_INVALID_URL, config);
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2123
2250
|
/**
|
|
2124
2251
|
* Creates a new URL by combining the baseURL with the requestedURL,
|
|
2125
2252
|
* only when the requestedURL is not already an absolute URL.
|
|
@@ -2130,9 +2257,11 @@ function combineURLs(baseURL, relativeURL) {
|
|
|
2130
2257
|
*
|
|
2131
2258
|
* @returns {string} The combined full path
|
|
2132
2259
|
*/
|
|
2133
|
-
function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
|
|
2260
|
+
function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls, config) {
|
|
2261
|
+
assertValidHttpProtocolURL(requestedURL, config);
|
|
2134
2262
|
let isRelativeUrl = !isAbsoluteURL(requestedURL);
|
|
2135
2263
|
if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) {
|
|
2264
|
+
assertValidHttpProtocolURL(baseURL, config);
|
|
2136
2265
|
return combineURLs(baseURL, requestedURL);
|
|
2137
2266
|
}
|
|
2138
2267
|
return requestedURL;
|
|
@@ -2234,7 +2363,7 @@ function getEnv(key) {
|
|
|
2234
2363
|
return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
|
|
2235
2364
|
}
|
|
2236
2365
|
|
|
2237
|
-
const VERSION = "1.
|
|
2366
|
+
const VERSION = "1.18.0";
|
|
2238
2367
|
|
|
2239
2368
|
function parseProtocol(url) {
|
|
2240
2369
|
const match = /^([-+\w]{1,25}):(?:\/\/)?/.exec(url);
|
|
@@ -2617,13 +2746,34 @@ const callbackify = (fn, reducer) => {
|
|
|
2617
2746
|
} : fn;
|
|
2618
2747
|
};
|
|
2619
2748
|
|
|
2620
|
-
const LOOPBACK_HOSTNAMES = new Set(['localhost']);
|
|
2749
|
+
const LOOPBACK_HOSTNAMES = new Set(['localhost', '0.0.0.0']);
|
|
2621
2750
|
const isIPv4Loopback = host => {
|
|
2622
2751
|
const parts = host.split('.');
|
|
2623
2752
|
if (parts.length !== 4) return false;
|
|
2624
2753
|
if (parts[0] !== '127') return false;
|
|
2625
2754
|
return parts.every(p => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
|
|
2626
2755
|
};
|
|
2756
|
+
const isIPv6ZeroGroup = group => /^0{1,4}$/.test(group);
|
|
2757
|
+
|
|
2758
|
+
// The unspecified address (IPv4 0.0.0.0 / IPv6 ::) resolves to the local host
|
|
2759
|
+
// for outbound connections, so treat it as loopback-equivalent for NO_PROXY
|
|
2760
|
+
// matching. 0.0.0.0 is covered by LOOPBACK_HOSTNAMES; this handles compressed
|
|
2761
|
+
// and full IPv6 all-zero forms so both families bypass symmetrically.
|
|
2762
|
+
const isIPv6Unspecified = host => {
|
|
2763
|
+
if (host === '::') return true;
|
|
2764
|
+
const compressionIndex = host.indexOf('::');
|
|
2765
|
+
if (compressionIndex !== -1) {
|
|
2766
|
+
if (compressionIndex !== host.lastIndexOf('::')) return false;
|
|
2767
|
+
const left = host.slice(0, compressionIndex);
|
|
2768
|
+
const right = host.slice(compressionIndex + 2);
|
|
2769
|
+
const leftGroups = left ? left.split(':') : [];
|
|
2770
|
+
const rightGroups = right ? right.split(':') : [];
|
|
2771
|
+
const explicitGroups = leftGroups.length + rightGroups.length;
|
|
2772
|
+
return explicitGroups < 8 && leftGroups.every(isIPv6ZeroGroup) && rightGroups.every(isIPv6ZeroGroup);
|
|
2773
|
+
}
|
|
2774
|
+
const groups = host.split(':');
|
|
2775
|
+
return groups.length === 8 && groups.every(isIPv6ZeroGroup);
|
|
2776
|
+
};
|
|
2627
2777
|
const isIPv6Loopback = host => {
|
|
2628
2778
|
// Collapse all-zero groups: any form of ::1 / 0:0:...:0:1
|
|
2629
2779
|
// First, strip any leading "::" by normalising with Set lookup of common forms,
|
|
@@ -2656,6 +2806,7 @@ const isLoopback = host => {
|
|
|
2656
2806
|
if (!host) return false;
|
|
2657
2807
|
if (LOOPBACK_HOSTNAMES.has(host)) return true;
|
|
2658
2808
|
if (isIPv4Loopback(host)) return true;
|
|
2809
|
+
if (isIPv6Unspecified(host)) return true;
|
|
2659
2810
|
return isIPv6Loopback(host);
|
|
2660
2811
|
};
|
|
2661
2812
|
const DEFAULT_PORTS = {
|
|
@@ -2875,11 +3026,13 @@ const asyncDecorator = fn => (...args) => utils$1.asap(() => fn(...args));
|
|
|
2875
3026
|
* Estimate decoded byte length of a data:// URL *without* allocating large buffers.
|
|
2876
3027
|
* - For base64: compute exact decoded size using length and padding;
|
|
2877
3028
|
* handle %XX at the character-count level (no string allocation).
|
|
2878
|
-
* - For non-base64:
|
|
3029
|
+
* - For non-base64: compute the exact percent-decoded UTF-8 byte length.
|
|
2879
3030
|
*
|
|
2880
3031
|
* @param {string} url
|
|
2881
3032
|
* @returns {number}
|
|
2882
3033
|
*/
|
|
3034
|
+
const isHexDigit = charCode => charCode >= 48 && charCode <= 57 || charCode >= 65 && charCode <= 70 || charCode >= 97 && charCode <= 102;
|
|
3035
|
+
const isPercentEncodedByte = (str, i, len) => i + 2 < len && isHexDigit(str.charCodeAt(i + 1)) && isHexDigit(str.charCodeAt(i + 2));
|
|
2883
3036
|
function estimateDataURLDecodedBytes(url) {
|
|
2884
3037
|
if (!url || typeof url !== 'string') return 0;
|
|
2885
3038
|
if (!url.startsWith('data:')) return 0;
|
|
@@ -2896,7 +3049,7 @@ function estimateDataURLDecodedBytes(url) {
|
|
|
2896
3049
|
if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {
|
|
2897
3050
|
const a = body.charCodeAt(i + 1);
|
|
2898
3051
|
const b = body.charCodeAt(i + 2);
|
|
2899
|
-
const isHex = (a
|
|
3052
|
+
const isHex = isHexDigit(a) && isHexDigit(b);
|
|
2900
3053
|
if (isHex) {
|
|
2901
3054
|
effectiveLen -= 2;
|
|
2902
3055
|
i += 2;
|
|
@@ -2931,18 +3084,18 @@ function estimateDataURLDecodedBytes(url) {
|
|
|
2931
3084
|
const bytes = groups * 3 - (pad || 0);
|
|
2932
3085
|
return bytes > 0 ? bytes : 0;
|
|
2933
3086
|
}
|
|
2934
|
-
if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') {
|
|
2935
|
-
return Buffer.byteLength(body, 'utf8');
|
|
2936
|
-
}
|
|
2937
3087
|
|
|
2938
3088
|
// Compute UTF-8 byte length directly from UTF-16 code units without allocating
|
|
2939
3089
|
// a byte buffer (TextEncoder.encode would defeat the DoS guard on large bodies).
|
|
2940
|
-
//
|
|
2941
|
-
//
|
|
3090
|
+
// Valid %XX triplets count as one decoded byte; this matches the bytes that
|
|
3091
|
+
// decodeURIComponent(body) would produce before Buffer re-encodes the string.
|
|
2942
3092
|
let bytes = 0;
|
|
2943
3093
|
for (let i = 0, len = body.length; i < len; i++) {
|
|
2944
3094
|
const c = body.charCodeAt(i);
|
|
2945
|
-
if (c
|
|
3095
|
+
if (c === 37 /* '%' */ && isPercentEncodedByte(body, i, len)) {
|
|
3096
|
+
bytes += 1;
|
|
3097
|
+
i += 2;
|
|
3098
|
+
} else if (c < 0x80) {
|
|
2946
3099
|
bytes += 1;
|
|
2947
3100
|
} else if (c < 0x800) {
|
|
2948
3101
|
bytes += 2;
|
|
@@ -3066,8 +3219,8 @@ const flushOnFinish = (stream, [throttled, flush]) => {
|
|
|
3066
3219
|
const http2Sessions = new Http2Sessions();
|
|
3067
3220
|
|
|
3068
3221
|
/**
|
|
3069
|
-
* If the proxy, auth, or config beforeRedirects functions are defined,
|
|
3070
|
-
* with the options object.
|
|
3222
|
+
* If the proxy, auth, sensitive header, or config beforeRedirects functions are defined,
|
|
3223
|
+
* call them with the options object.
|
|
3071
3224
|
*
|
|
3072
3225
|
* @param {Object<string, any>} options - The options object that was passed to the request.
|
|
3073
3226
|
*
|
|
@@ -3080,10 +3233,34 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
|
|
|
3080
3233
|
if (options.beforeRedirects.auth) {
|
|
3081
3234
|
options.beforeRedirects.auth(options);
|
|
3082
3235
|
}
|
|
3236
|
+
if (options.beforeRedirects.sensitiveHeaders) {
|
|
3237
|
+
options.beforeRedirects.sensitiveHeaders(options, requestDetails);
|
|
3238
|
+
}
|
|
3083
3239
|
if (options.beforeRedirects.config) {
|
|
3084
3240
|
options.beforeRedirects.config(options, responseDetails, requestDetails);
|
|
3085
3241
|
}
|
|
3086
3242
|
}
|
|
3243
|
+
function stripMatchingHeaders(headers, sensitiveSet) {
|
|
3244
|
+
if (!headers) {
|
|
3245
|
+
return;
|
|
3246
|
+
}
|
|
3247
|
+
Object.keys(headers).forEach(header => {
|
|
3248
|
+
if (sensitiveSet.has(header.toLowerCase())) {
|
|
3249
|
+
delete headers[header];
|
|
3250
|
+
}
|
|
3251
|
+
});
|
|
3252
|
+
}
|
|
3253
|
+
function isSameOriginRedirect(redirectOptions, requestDetails) {
|
|
3254
|
+
if (!requestDetails) {
|
|
3255
|
+
return false;
|
|
3256
|
+
}
|
|
3257
|
+
try {
|
|
3258
|
+
return new URL(requestDetails.url).origin === new URL(redirectOptions.href).origin;
|
|
3259
|
+
} catch (e) {
|
|
3260
|
+
// If origin comparison fails, treat the redirect as unsafe.
|
|
3261
|
+
return false;
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3087
3264
|
|
|
3088
3265
|
/**
|
|
3089
3266
|
* If the proxy or config afterRedirects functions are defined, call them with the options
|
|
@@ -3187,7 +3364,7 @@ function setProxy(options, configProxy, location, isRedirect, configHttpsAgent)
|
|
|
3187
3364
|
}
|
|
3188
3365
|
const tunnelingAgent = getTunnelingAgent(agentOptions, configHttpsAgent);
|
|
3189
3366
|
// Set both: `options.agent` is consumed by the native https.request path
|
|
3190
|
-
// (
|
|
3367
|
+
// (maxRedirects === 0); `options.agents.https` is consumed by
|
|
3191
3368
|
// follow-redirects, which ignores `options.agent` when `options.agents`
|
|
3192
3369
|
// is present.
|
|
3193
3370
|
options.agent = tunnelingAgent;
|
|
@@ -3314,7 +3491,12 @@ const http2Transport = {
|
|
|
3314
3491
|
/*eslint consistent-return:0*/
|
|
3315
3492
|
var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
3316
3493
|
return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
|
|
3317
|
-
|
|
3494
|
+
// Read config pollution-safely: own properties and members inherited from
|
|
3495
|
+
// a non-Object.prototype source (e.g. an Object.create(defaults) template)
|
|
3496
|
+
// are honored, but values injected onto a polluted Object.prototype are
|
|
3497
|
+
// ignored. All behavior-affecting reads in this adapter go through own()
|
|
3498
|
+
// so the protection boundary stays consistent.
|
|
3499
|
+
const own = key => utils$1.getSafeProp(config, key);
|
|
3318
3500
|
const transitional = own('transitional') || transitionalDefaults;
|
|
3319
3501
|
let data = own('data');
|
|
3320
3502
|
let lookup = own('lookup');
|
|
@@ -3324,7 +3506,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3324
3506
|
let http2Options = own('http2Options');
|
|
3325
3507
|
const responseType = own('responseType');
|
|
3326
3508
|
const responseEncoding = own('responseEncoding');
|
|
3327
|
-
const
|
|
3509
|
+
const httpAgent = own('httpAgent');
|
|
3510
|
+
const httpsAgent = own('httpsAgent');
|
|
3511
|
+
const method = own('method').toUpperCase();
|
|
3512
|
+
const maxRedirects = own('maxRedirects');
|
|
3513
|
+
const maxBodyLength = own('maxBodyLength');
|
|
3514
|
+
const maxContentLength = own('maxContentLength');
|
|
3515
|
+
const decompress = own('decompress');
|
|
3328
3516
|
let isDone;
|
|
3329
3517
|
let rejected = false;
|
|
3330
3518
|
let req;
|
|
@@ -3365,9 +3553,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3365
3553
|
}
|
|
3366
3554
|
}
|
|
3367
3555
|
function createTimeoutError() {
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3556
|
+
const configTimeout = own('timeout');
|
|
3557
|
+
let timeoutErrorMessage = configTimeout ? 'timeout of ' + configTimeout + 'ms exceeded' : 'timeout exceeded';
|
|
3558
|
+
const configTimeoutErrorMessage = own('timeoutErrorMessage');
|
|
3559
|
+
if (configTimeoutErrorMessage) {
|
|
3560
|
+
timeoutErrorMessage = configTimeoutErrorMessage;
|
|
3371
3561
|
}
|
|
3372
3562
|
return new AxiosError(timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, req);
|
|
3373
3563
|
}
|
|
@@ -3410,17 +3600,17 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3410
3600
|
});
|
|
3411
3601
|
|
|
3412
3602
|
// Parse url
|
|
3413
|
-
const fullPath = buildFullPath(
|
|
3603
|
+
const fullPath = buildFullPath(own('baseURL'), own('url'), own('allowAbsoluteUrls'), config);
|
|
3414
3604
|
const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
|
|
3415
3605
|
const protocol = parsed.protocol || supportedProtocols[0];
|
|
3416
3606
|
if (protocol === 'data:') {
|
|
3417
3607
|
// Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
|
|
3418
|
-
if (
|
|
3419
|
-
// Use the exact string passed to fromDataURI (
|
|
3420
|
-
const dataUrl = String(
|
|
3608
|
+
if (maxContentLength > -1) {
|
|
3609
|
+
// Use the exact string passed to fromDataURI (the configured url); fall back to fullPath if needed.
|
|
3610
|
+
const dataUrl = String(own('url') || fullPath || '');
|
|
3421
3611
|
const estimated = estimateDataURLDecodedBytes(dataUrl);
|
|
3422
|
-
if (estimated >
|
|
3423
|
-
return reject(new AxiosError('maxContentLength size of ' +
|
|
3612
|
+
if (estimated > maxContentLength) {
|
|
3613
|
+
return reject(new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config));
|
|
3424
3614
|
}
|
|
3425
3615
|
}
|
|
3426
3616
|
let convertedData;
|
|
@@ -3433,7 +3623,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3433
3623
|
});
|
|
3434
3624
|
}
|
|
3435
3625
|
try {
|
|
3436
|
-
convertedData = fromDataURI(
|
|
3626
|
+
convertedData = fromDataURI(own('url'), responseType === 'blob', {
|
|
3437
3627
|
Blob: config.env && config.env.Blob
|
|
3438
3628
|
});
|
|
3439
3629
|
} catch (err) {
|
|
@@ -3507,7 +3697,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3507
3697
|
|
|
3508
3698
|
// Add Content-Length header if data exists
|
|
3509
3699
|
headers.setContentLength(data.length, false);
|
|
3510
|
-
if (
|
|
3700
|
+
if (maxBodyLength > -1 && data.length > maxBodyLength) {
|
|
3511
3701
|
return reject(new AxiosError('Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config));
|
|
3512
3702
|
}
|
|
3513
3703
|
}
|
|
@@ -3534,8 +3724,8 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3534
3724
|
let auth = undefined;
|
|
3535
3725
|
const configAuth = own('auth');
|
|
3536
3726
|
if (configAuth) {
|
|
3537
|
-
const username = configAuth
|
|
3538
|
-
const password = configAuth
|
|
3727
|
+
const username = utils$1.getSafeProp(configAuth, 'username') || '';
|
|
3728
|
+
const password = utils$1.getSafeProp(configAuth, 'password') || '';
|
|
3539
3729
|
auth = username + ':' + password;
|
|
3540
3730
|
}
|
|
3541
3731
|
if (!auth && (parsed.username || parsed.password)) {
|
|
@@ -3546,11 +3736,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3546
3736
|
auth && headers.delete('authorization');
|
|
3547
3737
|
let path$1;
|
|
3548
3738
|
try {
|
|
3549
|
-
path$1 = buildURL(parsed.pathname + parsed.search,
|
|
3739
|
+
path$1 = buildURL(parsed.pathname + parsed.search, own('params'), own('paramsSerializer')).replace(/^\?/, '');
|
|
3550
3740
|
} catch (err) {
|
|
3551
3741
|
const customErr = new Error(err.message);
|
|
3552
3742
|
customErr.config = config;
|
|
3553
|
-
customErr.url =
|
|
3743
|
+
customErr.url = own('url');
|
|
3554
3744
|
customErr.exists = true;
|
|
3555
3745
|
return reject(customErr);
|
|
3556
3746
|
}
|
|
@@ -3563,8 +3753,8 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3563
3753
|
method: method,
|
|
3564
3754
|
headers: toByteStringHeaderObject(headers),
|
|
3565
3755
|
agents: {
|
|
3566
|
-
http:
|
|
3567
|
-
https:
|
|
3756
|
+
http: httpAgent,
|
|
3757
|
+
https: httpsAgent
|
|
3568
3758
|
},
|
|
3569
3759
|
auth,
|
|
3570
3760
|
protocol,
|
|
@@ -3594,15 +3784,20 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3594
3784
|
} else {
|
|
3595
3785
|
options.hostname = parsed.hostname.startsWith('[') ? parsed.hostname.slice(1, -1) : parsed.hostname;
|
|
3596
3786
|
options.port = parsed.port;
|
|
3597
|
-
setProxy(options,
|
|
3787
|
+
setProxy(options, own('proxy'), protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path, false, httpsAgent);
|
|
3598
3788
|
}
|
|
3599
3789
|
let transport;
|
|
3600
3790
|
let isNativeTransport = false;
|
|
3791
|
+
// True only for the follow-redirects transport, which applies
|
|
3792
|
+
// options.maxBodyLength itself. Every other transport (http2, native
|
|
3793
|
+
// http/https, a user-supplied custom transport) needs the explicit
|
|
3794
|
+
// byte-counting pipeline below to enforce maxBodyLength on streamed uploads.
|
|
3795
|
+
let transportEnforcesMaxBodyLength = false;
|
|
3601
3796
|
const isHttpsRequest = isHttps.test(options.protocol);
|
|
3602
3797
|
// Don't clobber a CONNECT-tunneling agent installed by setProxy() for an
|
|
3603
3798
|
// HTTPS target.
|
|
3604
3799
|
if (options.agent == null) {
|
|
3605
|
-
options.agent = isHttpsRequest ?
|
|
3800
|
+
options.agent = isHttpsRequest ? httpsAgent : httpAgent;
|
|
3606
3801
|
}
|
|
3607
3802
|
if (isHttp2) {
|
|
3608
3803
|
transport = http2Transport;
|
|
@@ -3610,12 +3805,14 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3610
3805
|
const configTransport = own('transport');
|
|
3611
3806
|
if (configTransport) {
|
|
3612
3807
|
transport = configTransport;
|
|
3613
|
-
} else if (
|
|
3808
|
+
} else if (maxRedirects === 0) {
|
|
3614
3809
|
transport = isHttpsRequest ? https : http;
|
|
3615
3810
|
isNativeTransport = true;
|
|
3616
3811
|
} else {
|
|
3617
|
-
|
|
3618
|
-
|
|
3812
|
+
transportEnforcesMaxBodyLength = true;
|
|
3813
|
+
options.sensitiveHeaders = [];
|
|
3814
|
+
if (maxRedirects) {
|
|
3815
|
+
options.maxRedirects = maxRedirects;
|
|
3619
3816
|
}
|
|
3620
3817
|
const configBeforeRedirect = own('beforeRedirect');
|
|
3621
3818
|
if (configBeforeRedirect) {
|
|
@@ -3638,11 +3835,32 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3638
3835
|
}
|
|
3639
3836
|
};
|
|
3640
3837
|
}
|
|
3838
|
+
const sensitiveHeaders = own('sensitiveHeaders');
|
|
3839
|
+
if (sensitiveHeaders != null) {
|
|
3840
|
+
if (!utils$1.isArray(sensitiveHeaders)) {
|
|
3841
|
+
return reject(new AxiosError('sensitiveHeaders must be an array of strings', AxiosError.ERR_BAD_OPTION_VALUE, config));
|
|
3842
|
+
}
|
|
3843
|
+
const sensitiveSet = new Set();
|
|
3844
|
+
for (const header of sensitiveHeaders) {
|
|
3845
|
+
if (!utils$1.isString(header)) {
|
|
3846
|
+
return reject(new AxiosError('sensitiveHeaders must be an array of strings', AxiosError.ERR_BAD_OPTION_VALUE, config));
|
|
3847
|
+
}
|
|
3848
|
+
sensitiveSet.add(header.toLowerCase());
|
|
3849
|
+
}
|
|
3850
|
+
if (sensitiveSet.size) {
|
|
3851
|
+
options.sensitiveHeaders = Array.from(sensitiveSet);
|
|
3852
|
+
options.beforeRedirects.sensitiveHeaders = function beforeRedirectSensitiveHeaders(redirectOptions, requestDetails) {
|
|
3853
|
+
if (!isSameOriginRedirect(redirectOptions, requestDetails)) {
|
|
3854
|
+
stripMatchingHeaders(redirectOptions.headers, sensitiveSet);
|
|
3855
|
+
}
|
|
3856
|
+
};
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3641
3859
|
transport = isHttpsRequest ? httpsFollow : httpFollow;
|
|
3642
3860
|
}
|
|
3643
3861
|
}
|
|
3644
|
-
if (
|
|
3645
|
-
options.maxBodyLength =
|
|
3862
|
+
if (maxBodyLength > -1) {
|
|
3863
|
+
options.maxBodyLength = maxBodyLength;
|
|
3646
3864
|
} else {
|
|
3647
3865
|
// follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
|
|
3648
3866
|
options.maxBodyLength = Infinity;
|
|
@@ -3674,7 +3892,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3674
3892
|
const lastRequest = res.req || req;
|
|
3675
3893
|
|
|
3676
3894
|
// if decompress disabled we should not decompress
|
|
3677
|
-
if (
|
|
3895
|
+
if (decompress !== false && res.headers['content-encoding']) {
|
|
3678
3896
|
// if no content, but headers still say that it is encoded,
|
|
3679
3897
|
// remove the header not confuse downstream operations
|
|
3680
3898
|
if (method === 'HEAD' || res.statusCode === 204) {
|
|
@@ -3726,8 +3944,8 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3726
3944
|
if (responseType === 'stream') {
|
|
3727
3945
|
// Enforce maxContentLength on streamed responses; previously this
|
|
3728
3946
|
// was applied only to buffered responses.
|
|
3729
|
-
if (
|
|
3730
|
-
const limit =
|
|
3947
|
+
if (maxContentLength > -1) {
|
|
3948
|
+
const limit = maxContentLength;
|
|
3731
3949
|
const source = responseStream;
|
|
3732
3950
|
async function* enforceMaxContentLength() {
|
|
3733
3951
|
let totalResponseBytes = 0;
|
|
@@ -3753,11 +3971,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3753
3971
|
totalResponseBytes += chunk.length;
|
|
3754
3972
|
|
|
3755
3973
|
// make sure the content length is not over the maxContentLength if specified
|
|
3756
|
-
if (
|
|
3974
|
+
if (maxContentLength > -1 && totalResponseBytes > maxContentLength) {
|
|
3757
3975
|
// stream.destroy() emit aborted event before calling reject() on Node.js v16
|
|
3758
3976
|
rejected = true;
|
|
3759
3977
|
responseStream.destroy();
|
|
3760
|
-
abort(new AxiosError('maxContentLength size of ' +
|
|
3978
|
+
abort(new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
|
|
3761
3979
|
}
|
|
3762
3980
|
});
|
|
3763
3981
|
responseStream.on('aborted', function handlerStreamAborted() {
|
|
@@ -3850,9 +4068,9 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3850
4068
|
});
|
|
3851
4069
|
|
|
3852
4070
|
// Handle request timeout
|
|
3853
|
-
if (
|
|
4071
|
+
if (own('timeout')) {
|
|
3854
4072
|
// This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
|
|
3855
|
-
const timeout = parseInt(
|
|
4073
|
+
const timeout = parseInt(own('timeout'), 10);
|
|
3856
4074
|
if (Number.isNaN(timeout)) {
|
|
3857
4075
|
abort(new AxiosError('error trying to parse `config.timeout` to int', AxiosError.ERR_BAD_OPTION_VALUE, config, req));
|
|
3858
4076
|
return;
|
|
@@ -3896,12 +4114,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3896
4114
|
}
|
|
3897
4115
|
});
|
|
3898
4116
|
|
|
3899
|
-
// Enforce maxBodyLength for streamed uploads on
|
|
3900
|
-
//
|
|
3901
|
-
//
|
|
4117
|
+
// Enforce maxBodyLength for streamed uploads on every transport that
|
|
4118
|
+
// does not apply options.maxBodyLength itself (native http/https, http2,
|
|
4119
|
+
// and user-supplied custom transports). The follow-redirects transport
|
|
4120
|
+
// enforces it on the redirected HTTP/1 path.
|
|
3902
4121
|
let uploadStream = data;
|
|
3903
|
-
if (
|
|
3904
|
-
const limit =
|
|
4122
|
+
if (maxBodyLength > -1 && !transportEnforcesMaxBodyLength) {
|
|
4123
|
+
const limit = maxBodyLength;
|
|
3905
4124
|
let bytesSent = 0;
|
|
3906
4125
|
uploadStream = stream.pipeline([data, new stream.Transform({
|
|
3907
4126
|
transform(chunk, _enc, cb) {
|
|
@@ -4048,6 +4267,23 @@ function mergeConfig(config1, config2) {
|
|
|
4048
4267
|
return getMergedValue(undefined, a);
|
|
4049
4268
|
}
|
|
4050
4269
|
}
|
|
4270
|
+
function getMergedTransitionalOption(prop) {
|
|
4271
|
+
const transitional2 = utils$1.hasOwnProp(config2, 'transitional') ? config2.transitional : undefined;
|
|
4272
|
+
if (!utils$1.isUndefined(transitional2)) {
|
|
4273
|
+
if (utils$1.isPlainObject(transitional2)) {
|
|
4274
|
+
if (utils$1.hasOwnProp(transitional2, prop)) {
|
|
4275
|
+
return transitional2[prop];
|
|
4276
|
+
}
|
|
4277
|
+
} else {
|
|
4278
|
+
return undefined;
|
|
4279
|
+
}
|
|
4280
|
+
}
|
|
4281
|
+
const transitional1 = utils$1.hasOwnProp(config1, 'transitional') ? config1.transitional : undefined;
|
|
4282
|
+
if (utils$1.isPlainObject(transitional1) && utils$1.hasOwnProp(transitional1, prop)) {
|
|
4283
|
+
return transitional1[prop];
|
|
4284
|
+
}
|
|
4285
|
+
return undefined;
|
|
4286
|
+
}
|
|
4051
4287
|
|
|
4052
4288
|
// eslint-disable-next-line consistent-return
|
|
4053
4289
|
function mergeDirectKeys(a, b, prop) {
|
|
@@ -4100,6 +4336,13 @@ function mergeConfig(config1, config2) {
|
|
|
4100
4336
|
const configValue = merge(a, b, prop);
|
|
4101
4337
|
utils$1.isUndefined(configValue) && merge !== mergeDirectKeys || (config[prop] = configValue);
|
|
4102
4338
|
});
|
|
4339
|
+
if (utils$1.hasOwnProp(config2, 'validateStatus') && utils$1.isUndefined(config2.validateStatus) && getMergedTransitionalOption('validateStatusUndefinedResolves') === false) {
|
|
4340
|
+
if (utils$1.hasOwnProp(config1, 'validateStatus')) {
|
|
4341
|
+
config.validateStatus = getMergedValue(undefined, config1.validateStatus);
|
|
4342
|
+
} else {
|
|
4343
|
+
delete config.validateStatus;
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4103
4346
|
return config;
|
|
4104
4347
|
}
|
|
4105
4348
|
|
|
@@ -4141,11 +4384,13 @@ function resolveConfig(config) {
|
|
|
4141
4384
|
const allowAbsoluteUrls = own('allowAbsoluteUrls');
|
|
4142
4385
|
const url = own('url');
|
|
4143
4386
|
newConfig.headers = headers = AxiosHeaders.from(headers);
|
|
4144
|
-
newConfig.url = buildURL(buildFullPath(baseURL, url, allowAbsoluteUrls), own('params'), own('paramsSerializer'));
|
|
4387
|
+
newConfig.url = buildURL(buildFullPath(baseURL, url, allowAbsoluteUrls, newConfig), own('params'), own('paramsSerializer'));
|
|
4145
4388
|
|
|
4146
4389
|
// HTTP basic authentication
|
|
4147
4390
|
if (auth) {
|
|
4148
|
-
|
|
4391
|
+
const username = utils$1.getSafeProp(auth, 'username') || '';
|
|
4392
|
+
const password = utils$1.getSafeProp(auth, 'password') || '';
|
|
4393
|
+
headers.set('Authorization', 'Basic ' + btoa(username + ':' + (password ? encodeUTF8$1(password) : '')));
|
|
4149
4394
|
}
|
|
4150
4395
|
if (utils$1.isFormData(data)) {
|
|
4151
4396
|
if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv || utils$1.isReactNative(data)) {
|
|
@@ -4630,13 +4875,20 @@ const factory = env => {
|
|
|
4630
4875
|
composedSignal.unsubscribe();
|
|
4631
4876
|
});
|
|
4632
4877
|
let requestContentLength;
|
|
4878
|
+
|
|
4879
|
+
// AxiosError we raise while the request body is being streamed. Captured
|
|
4880
|
+
// by identity so the catch block can surface it directly, regardless of
|
|
4881
|
+
// how the runtime wraps the resulting fetch rejection (undici exposes it
|
|
4882
|
+
// as `err.cause`; some browsers drop the original error entirely).
|
|
4883
|
+
let pendingBodyError = null;
|
|
4884
|
+
const maxBodyLengthError = () => new AxiosError('Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config, request);
|
|
4633
4885
|
try {
|
|
4634
4886
|
// HTTP basic authentication
|
|
4635
4887
|
let auth = undefined;
|
|
4636
4888
|
const configAuth = own('auth');
|
|
4637
4889
|
if (configAuth) {
|
|
4638
|
-
const username = configAuth
|
|
4639
|
-
const password = configAuth
|
|
4890
|
+
const username = utils$1.getSafeProp(configAuth, 'username') || '';
|
|
4891
|
+
const password = utils$1.getSafeProp(configAuth, 'password') || '';
|
|
4640
4892
|
auth = {
|
|
4641
4893
|
username,
|
|
4642
4894
|
password
|
|
@@ -4673,30 +4925,54 @@ const factory = env => {
|
|
|
4673
4925
|
}
|
|
4674
4926
|
}
|
|
4675
4927
|
|
|
4676
|
-
// Enforce maxBodyLength against
|
|
4677
|
-
//
|
|
4678
|
-
//
|
|
4679
|
-
//
|
|
4928
|
+
// Enforce maxBodyLength against known-size bodies before dispatch using
|
|
4929
|
+
// the body's *actual* size — never a caller-declared Content-Length,
|
|
4930
|
+
// which could under-report to slip an oversized body past the check.
|
|
4931
|
+
// Unknown-size streams return undefined here and are counted per-chunk
|
|
4932
|
+
// below as fetch consumes them.
|
|
4680
4933
|
if (hasMaxBodyLength && method !== 'get' && method !== 'head') {
|
|
4681
|
-
const outboundLength = await
|
|
4682
|
-
if (typeof outboundLength === 'number' && isFinite(outboundLength)
|
|
4683
|
-
|
|
4934
|
+
const outboundLength = await getBodyLength(data);
|
|
4935
|
+
if (typeof outboundLength === 'number' && isFinite(outboundLength)) {
|
|
4936
|
+
requestContentLength = outboundLength;
|
|
4937
|
+
if (outboundLength > maxBodyLength) {
|
|
4938
|
+
throw maxBodyLengthError();
|
|
4939
|
+
}
|
|
4684
4940
|
}
|
|
4685
4941
|
}
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
|
|
4694
|
-
headers.setContentType(contentTypeHeader);
|
|
4942
|
+
|
|
4943
|
+
// A streamed body under maxBodyLength must be counted as fetch consumes
|
|
4944
|
+
// it; its size is never trusted from a caller-declared Content-Length.
|
|
4945
|
+
const mustEnforceStreamBody = hasMaxBodyLength && (utils$1.isReadableStream(data) || utils$1.isStream(data));
|
|
4946
|
+
const trackRequestStream = (stream, onProgress, flush) => trackStream(stream, DEFAULT_CHUNK_SIZE, loadedBytes => {
|
|
4947
|
+
if (hasMaxBodyLength && loadedBytes > maxBodyLength) {
|
|
4948
|
+
throw pendingBodyError = maxBodyLengthError();
|
|
4695
4949
|
}
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4950
|
+
onProgress && onProgress(loadedBytes);
|
|
4951
|
+
}, flush);
|
|
4952
|
+
if (supportsRequestStream && method !== 'get' && method !== 'head' && (onUploadProgress || mustEnforceStreamBody)) {
|
|
4953
|
+
requestContentLength = requestContentLength == null ? await resolveBodyLength(headers, data) : requestContentLength;
|
|
4954
|
+
|
|
4955
|
+
// A declared length of 0 is only trusted to skip the wrap when we are
|
|
4956
|
+
// not enforcing a stream limit (which must not rely on that header).
|
|
4957
|
+
if (requestContentLength !== 0 || mustEnforceStreamBody) {
|
|
4958
|
+
let _request = new Request(url, {
|
|
4959
|
+
method: 'POST',
|
|
4960
|
+
body: data,
|
|
4961
|
+
duplex: 'half'
|
|
4962
|
+
});
|
|
4963
|
+
let contentTypeHeader;
|
|
4964
|
+
if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
|
|
4965
|
+
headers.setContentType(contentTypeHeader);
|
|
4966
|
+
}
|
|
4967
|
+
if (_request.body) {
|
|
4968
|
+
const [onProgress, flush] = onUploadProgress && progressEventDecorator(requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress))) || [];
|
|
4969
|
+
data = trackRequestStream(_request.body, onProgress, flush);
|
|
4970
|
+
}
|
|
4699
4971
|
}
|
|
4972
|
+
} else if (mustEnforceStreamBody && !isRequestSupported && isReadableStreamSupported && method !== 'get' && method !== 'head') {
|
|
4973
|
+
data = trackRequestStream(data);
|
|
4974
|
+
} else if (mustEnforceStreamBody && isRequestSupported && !supportsRequestStream && method !== 'get' && method !== 'head') {
|
|
4975
|
+
throw new AxiosError('Stream request bodies are not supported by the current fetch implementation', AxiosError.ERR_NOT_SUPPORT, config, request);
|
|
4700
4976
|
}
|
|
4701
4977
|
if (!utils$1.isString(withCredentials)) {
|
|
4702
4978
|
withCredentials = withCredentials ? 'include' : 'omit';
|
|
@@ -4728,11 +5004,12 @@ const factory = env => {
|
|
|
4728
5004
|
};
|
|
4729
5005
|
request = isRequestSupported && new Request(url, resolvedOptions);
|
|
4730
5006
|
let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));
|
|
5007
|
+
const responseHeaders = AxiosHeaders.from(response.headers);
|
|
4731
5008
|
|
|
4732
5009
|
// Cheap pre-check: if the server honestly declares a content-length that
|
|
4733
5010
|
// already exceeds the cap, reject before we start streaming.
|
|
4734
5011
|
if (hasMaxContentLength) {
|
|
4735
|
-
const declaredLength = utils$1.toFiniteNumber(
|
|
5012
|
+
const declaredLength = utils$1.toFiniteNumber(responseHeaders.getContentLength());
|
|
4736
5013
|
if (declaredLength != null && declaredLength > maxContentLength) {
|
|
4737
5014
|
throw new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, request);
|
|
4738
5015
|
}
|
|
@@ -4743,7 +5020,7 @@ const factory = env => {
|
|
|
4743
5020
|
['status', 'statusText', 'headers'].forEach(prop => {
|
|
4744
5021
|
options[prop] = response[prop];
|
|
4745
5022
|
});
|
|
4746
|
-
const responseContentLength = utils$1.toFiniteNumber(
|
|
5023
|
+
const responseContentLength = utils$1.toFiniteNumber(responseHeaders.getContentLength());
|
|
4747
5024
|
const [onProgress, flush] = onDownloadProgress && progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true)) || [];
|
|
4748
5025
|
let bytesRead = 0;
|
|
4749
5026
|
const onChunkProgress = loadedBytes => {
|
|
@@ -4805,6 +5082,23 @@ const factory = env => {
|
|
|
4805
5082
|
err !== canceledError && (canceledError.cause = err);
|
|
4806
5083
|
throw canceledError;
|
|
4807
5084
|
}
|
|
5085
|
+
|
|
5086
|
+
// Surface a maxBodyLength violation we raised while the request body was
|
|
5087
|
+
// being streamed. Matching by identity (rather than reading
|
|
5088
|
+
// `err.cause.isAxiosError`) keeps the error deterministic across runtimes
|
|
5089
|
+
// and avoids both prototype-pollution reads and mis-attributing a foreign
|
|
5090
|
+
// AxiosError that merely happened to land in `err.cause`.
|
|
5091
|
+
if (pendingBodyError) {
|
|
5092
|
+
request && !pendingBodyError.request && (pendingBodyError.request = request);
|
|
5093
|
+
throw pendingBodyError;
|
|
5094
|
+
}
|
|
5095
|
+
|
|
5096
|
+
// Re-throw AxiosErrors we raised synchronously (data: URL / content-length
|
|
5097
|
+
// pre-checks, response size enforcement) without re-wrapping them.
|
|
5098
|
+
if (err instanceof AxiosError) {
|
|
5099
|
+
request && !err.request && (err.request = request);
|
|
5100
|
+
throw err;
|
|
5101
|
+
}
|
|
4808
5102
|
if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
|
|
4809
5103
|
throw Object.assign(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request, err && err.response), {
|
|
4810
5104
|
cause: err.cause || err
|
|
@@ -5180,7 +5474,8 @@ class Axios {
|
|
|
5180
5474
|
forcedJSONParsing: validators.transitional(validators.boolean),
|
|
5181
5475
|
clarifyTimeoutError: validators.transitional(validators.boolean),
|
|
5182
5476
|
legacyInterceptorReqResOrdering: validators.transitional(validators.boolean),
|
|
5183
|
-
advertiseZstdAcceptEncoding: validators.transitional(validators.boolean)
|
|
5477
|
+
advertiseZstdAcceptEncoding: validators.transitional(validators.boolean),
|
|
5478
|
+
validateStatusUndefinedResolves: validators.transitional(validators.boolean)
|
|
5184
5479
|
}, false);
|
|
5185
5480
|
}
|
|
5186
5481
|
if (paramsSerializer != null) {
|
|
@@ -5277,7 +5572,7 @@ class Axios {
|
|
|
5277
5572
|
}
|
|
5278
5573
|
getUri(config) {
|
|
5279
5574
|
config = mergeConfig(this.defaults, config);
|
|
5280
|
-
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
|
|
5575
|
+
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls, config);
|
|
5281
5576
|
return buildURL(fullPath, config.params, config.paramsSerializer);
|
|
5282
5577
|
}
|
|
5283
5578
|
}
|
|
@@ -5289,7 +5584,7 @@ utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoDa
|
|
|
5289
5584
|
return this.request(mergeConfig(config || {}, {
|
|
5290
5585
|
method,
|
|
5291
5586
|
url,
|
|
5292
|
-
data: (config
|
|
5587
|
+
data: config && utils$1.hasOwnProp(config, 'data') ? config.data : undefined
|
|
5293
5588
|
}));
|
|
5294
5589
|
};
|
|
5295
5590
|
});
|