@openclaw/slack 2026.7.2-beta.2 → 2026.7.2-beta.4
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/dist/{account-configured-DzC407uv.js → account-configured-BwfXBo_F.js} +1 -1
- package/dist/account-inspect-api.js +1 -1
- package/dist/{account-inspect-Di7ditqZ.js → account-inspect-jn1xLaVi.js} +9 -2
- package/dist/account-reply-mode-DrUXogvO.js +14 -0
- package/dist/{accounts-BOJJiHSr.js → accounts-BSr252c_.js} +13 -25
- package/dist/accounts.runtime-CjULMLTa.js +2 -0
- package/dist/{action-runtime-Cee2ih0s.js → action-runtime-CFU52n4W.js} +11 -17
- package/dist/action-runtime.runtime-9-17zvKH.js +2 -0
- package/dist/{actions-BZiuSTIq.js → actions-D51foiwR.js} +5 -5
- package/dist/{actions.runtime-DoD0-gxw.js → actions.runtime-BMJwtf5C.js} +1 -1
- package/dist/api.js +15 -15
- package/dist/{approval-handler.runtime-CUPtIM4k.js → approval-handler.runtime-3b4-wxMl.js} +2 -2
- package/dist/{channel-DaIiGUOp.js → channel-Ds8NKvfr.js} +75 -41
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-type-Cfm6_6n1.js → channel-type-DXkUajFP.js} +3 -3
- package/dist/{channel.setup-C-mLz50O.js → channel.setup-DOSTEDfA.js} +8 -5
- package/dist/{config-schema-xPSnK2VK.js → config-schema-B4j4tCOI.js} +236 -30
- package/dist/{directory-config-DRkFujwG.js → directory-config-B08pm5ZT.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-D_yZhjgp.js → directory-live-DpPKzPrn.js} +2 -2
- package/dist/doctor-contract-U6oVntbM.js +173 -0
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{group-policy-85UWiriS.js → group-policy-CdnQzQBI.js} +98 -125
- package/dist/{interactive-replies-BilWUdcI.js → interactive-replies-C3ffk6oN.js} +1 -1
- package/dist/interactive-replies-api.js +1 -1
- package/dist/{message-tool-api-CA9jZrCY.js → message-tool-api-ByVyIVOh.js} +3 -3
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-CalGciTs.js → monitor-CnB_WKvF.js} +3 -3
- package/dist/{outbound-adapter-BiLKcnyH.js → outbound-adapter-DuPz2HHt.js} +49 -5
- package/dist/{pipeline.runtime-DofAvTtb.js → pipeline.runtime-5rRYZuX5.js} +490 -345
- package/dist/{policy-BVs4LiSa.js → policy-C31RYSuT.js} +1 -1
- package/dist/probe-CVRuArHA.js +340 -0
- package/dist/{provider-CmeoUiIM.js → provider-htuIJGFD.js} +791 -359
- package/dist/{relay-source-DMmgtvg4.js → relay-source-Df9EaiTF.js} +6 -11
- package/dist/{replies-CJJCp6qz.js → replies-Cgr2Gli4.js} +3 -3
- package/dist/{resolve-channels-Rfts6POK.js → resolve-channels-DodP2TFx.js} +1 -1
- package/dist/{resolve-users-y6wAxR8E.js → resolve-users-M9eF8891.js} +1 -1
- package/dist/{runtime-api-BGDyOt1D.js → runtime-api-D5XYMMsf.js} +3 -2
- package/dist/runtime-api.js +11 -11
- package/dist/{scopes-CuxNQZ6v.js → scopes-CJRpHkDC.js} +1 -2
- package/dist/{secret-contract-CMohXFWS.js → secret-contract-DxmvbxBF.js} +1 -0
- package/dist/secret-contract-api.js +1 -1
- package/dist/{security-audit-CikQhBUY.js → security-audit-Cz6erklv.js} +0 -10
- package/dist/security-contract-api.js +1 -1
- package/dist/{send-DYp8ca-l.js → send-BZ1tPv7-.js} +28 -11
- package/dist/send.runtime-a2pilFor.js +2 -0
- package/dist/setup-core-tPxMuFez.js +600 -0
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-oSd3NX9J.js → setup-surface-wV-S1dE_.js} +58 -32
- package/dist/{shared-D9yz5Otg.js → shared-BfMskaMx.js} +57 -10
- package/dist/{slash-dispatch.runtime-CSja9VuD.js → slash-dispatch.runtime-lfeIsXTX.js} +1 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/fs/promises.d.ts +16 -6
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/agent-base/README.md +145 -0
- package/node_modules/agent-base/dist/src/index.d.ts +78 -0
- package/node_modules/agent-base/dist/src/index.js +203 -0
- package/node_modules/agent-base/dist/src/index.js.map +1 -0
- package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
- package/node_modules/agent-base/dist/src/promisify.js +18 -0
- package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
- package/node_modules/agent-base/package.json +64 -0
- package/node_modules/agent-base/src/index.ts +345 -0
- package/node_modules/agent-base/src/promisify.ts +33 -0
- package/node_modules/axios/CHANGELOG.md +197 -1
- package/node_modules/axios/README.md +424 -256
- package/node_modules/axios/dist/axios.js +589 -204
- 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 +630 -185
- package/node_modules/axios/dist/esm/axios.js +630 -185
- 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 +949 -301
- package/node_modules/axios/index.d.cts +28 -5
- package/node_modules/axios/index.d.ts +24 -3
- package/node_modules/axios/lib/adapters/adapters.js +1 -1
- package/node_modules/axios/lib/adapters/fetch.js +223 -49
- package/node_modules/axios/lib/adapters/http.js +408 -193
- package/node_modules/axios/lib/adapters/xhr.js +3 -1
- package/node_modules/axios/lib/core/Axios.js +4 -2
- package/node_modules/axios/lib/core/AxiosError.js +13 -1
- package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
- package/node_modules/axios/lib/core/buildFullPath.js +29 -1
- package/node_modules/axios/lib/core/mergeConfig.js +35 -0
- package/node_modules/axios/lib/defaults/transitional.js +2 -0
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -3
- package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
- package/node_modules/axios/lib/helpers/buildURL.js +7 -4
- package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
- package/node_modules/axios/lib/helpers/cookies.js +5 -1
- package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
- package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
- package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
- package/node_modules/axios/lib/helpers/fromDataURI.js +20 -5
- package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
- package/node_modules/axios/lib/helpers/resolveConfig.js +26 -13
- package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
- package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
- package/node_modules/axios/lib/helpers/toFormData.js +48 -12
- package/node_modules/axios/lib/helpers/validator.js +1 -1
- package/node_modules/axios/lib/utils.js +105 -19
- package/node_modules/axios/package.json +31 -13
- package/node_modules/https-proxy-agent/README.md +137 -0
- package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
- package/node_modules/https-proxy-agent/dist/agent.js +177 -0
- package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
- package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
- package/node_modules/https-proxy-agent/dist/index.js +14 -0
- package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
- package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
- package/node_modules/https-proxy-agent/package.json +56 -0
- package/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
- package/node_modules/iconv-lite/encodings/utf32.js +10 -3
- package/node_modules/iconv-lite/package.json +2 -2
- package/node_modules/iconv-lite/types/encodings.d.ts +2 -0
- package/node_modules/path-to-regexp/Readme.md +3 -3
- package/node_modules/path-to-regexp/dist/index.js +135 -158
- package/node_modules/path-to-regexp/dist/index.js.map +1 -1
- package/node_modules/path-to-regexp/package.json +2 -2
- package/node_modules/qs/CHANGELOG.md +11 -0
- package/node_modules/qs/dist/qs.js +17 -17
- package/node_modules/qs/lib/parse.js +19 -8
- package/node_modules/qs/lib/utils.js +47 -8
- package/node_modules/qs/package.json +6 -5
- package/node_modules/qs/test/parse.js +230 -0
- package/node_modules/qs/test/utils.js +194 -0
- package/node_modules/typebox/build/compile/validator.d.mts +1 -4
- package/node_modules/typebox/build/guard/guard.d.mts +1 -1
- package/node_modules/typebox/build/guard/guard.mjs +5 -2
- package/node_modules/typebox/build/guard/string.mjs +16 -4
- package/node_modules/typebox/build/schema/engine/_functions.mjs +34 -15
- package/node_modules/typebox/build/type/action/readonly_object.d.mts +5 -0
- package/node_modules/typebox/build/type/action/readonly_object.mjs +8 -0
- package/node_modules/typebox/build/typebox.d.mts +1 -1
- package/node_modules/typebox/build/typebox.mjs +1 -1
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +29 -32
- package/node_modules/ws/lib/receiver.js +15 -32
- package/node_modules/ws/lib/websocket-server.js +4 -4
- package/node_modules/ws/lib/websocket.js +4 -4
- package/node_modules/ws/package.json +5 -1
- package/npm-shrinkwrap.json +54 -27
- package/openclaw.plugin.json +1331 -1424
- package/package.json +92 -14
- package/dist/accounts.runtime-KvftRRek.js +0 -2
- package/dist/action-runtime.runtime-DZfd7IFr.js +0 -2
- package/dist/client-WIPAS3Yr.js +0 -160
- package/dist/config-api-Df9a1B8C.js +0 -3
- package/dist/doctor-contract-DddfkMlF.js +0 -134
- package/dist/probe-CN0ssfLN.js +0 -48
- package/dist/send.runtime-CJLxAt26.js +0 -2
- package/dist/setup-core-CkwVLzFO.js +0 -337
- package/node_modules/axios/dist/axios.js.map +0 -1
- package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
- package/node_modules/axios/dist/esm/axios.js.map +0 -1
- package/node_modules/axios/dist/node/axios.cjs.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
/*! Axios v1.
|
|
1
|
+
/*! Axios v1.18.1 Copyright (c) 2026 Matt Zabriskie and contributors */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var FormData$1 = require('form-data');
|
|
5
5
|
var crypto = require('crypto');
|
|
6
6
|
var url = require('url');
|
|
7
|
+
var HttpsProxyAgent = require('https-proxy-agent');
|
|
7
8
|
var http = require('http');
|
|
8
9
|
var https = require('https');
|
|
9
10
|
var http2 = require('http2');
|
|
@@ -39,6 +40,52 @@ const {
|
|
|
39
40
|
iterator,
|
|
40
41
|
toStringTag
|
|
41
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;
|
|
42
89
|
const kindOf = (cache => thing => {
|
|
43
90
|
const str = toString.call(thing);
|
|
44
91
|
return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
|
|
@@ -157,11 +204,15 @@ const isBoolean = thing => thing === true || thing === false;
|
|
|
157
204
|
* @returns {boolean} True if value is a plain Object, otherwise false
|
|
158
205
|
*/
|
|
159
206
|
const isPlainObject = val => {
|
|
160
|
-
if (
|
|
207
|
+
if (!isObject(val)) {
|
|
161
208
|
return false;
|
|
162
209
|
}
|
|
163
210
|
const prototype = getPrototypeOf(val);
|
|
164
|
-
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);
|
|
165
216
|
};
|
|
166
217
|
|
|
167
218
|
/**
|
|
@@ -416,7 +467,10 @@ function merge(...objs) {
|
|
|
416
467
|
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
417
468
|
return;
|
|
418
469
|
}
|
|
419
|
-
|
|
470
|
+
|
|
471
|
+
// findKey lowercases the key, so caseless lookup only applies to strings —
|
|
472
|
+
// symbol keys are identity-matched.
|
|
473
|
+
const targetKey = caseless && typeof key === 'string' && findKey(result, key) || key;
|
|
420
474
|
// Read via own-prop only — a bare `result[targetKey]` walks the prototype
|
|
421
475
|
// chain, so a polluted Object.prototype value could surface here and get
|
|
422
476
|
// copied into the merged result.
|
|
@@ -432,7 +486,21 @@ function merge(...objs) {
|
|
|
432
486
|
}
|
|
433
487
|
};
|
|
434
488
|
for (let i = 0, l = objs.length; i < l; i++) {
|
|
435
|
-
|
|
489
|
+
const source = objs[i];
|
|
490
|
+
if (!source || isBuffer(source)) {
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
forEach(source, assignValue);
|
|
494
|
+
if (typeof source !== 'object' || isArray(source)) {
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
const symbols = Object.getOwnPropertySymbols(source);
|
|
498
|
+
for (let j = 0; j < symbols.length; j++) {
|
|
499
|
+
const symbol = symbols[j];
|
|
500
|
+
if (propertyIsEnumerable.call(source, symbol)) {
|
|
501
|
+
assignValue(source[symbol], symbol);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
436
504
|
}
|
|
437
505
|
return result;
|
|
438
506
|
}
|
|
@@ -644,11 +712,9 @@ const toCamelCase = str => {
|
|
|
644
712
|
return p1.toUpperCase() + p2;
|
|
645
713
|
});
|
|
646
714
|
};
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
hasOwnProperty
|
|
651
|
-
}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);
|
|
715
|
+
const {
|
|
716
|
+
propertyIsEnumerable
|
|
717
|
+
} = Object.prototype;
|
|
652
718
|
|
|
653
719
|
/**
|
|
654
720
|
* Determine if a value is a RegExp object
|
|
@@ -737,10 +803,10 @@ function isSpecCompliantForm(thing) {
|
|
|
737
803
|
* @returns {Object} The JSON-compatible object.
|
|
738
804
|
*/
|
|
739
805
|
const toJSONObject = obj => {
|
|
740
|
-
const
|
|
741
|
-
const visit =
|
|
806
|
+
const visited = new WeakSet();
|
|
807
|
+
const visit = source => {
|
|
742
808
|
if (isObject(source)) {
|
|
743
|
-
if (
|
|
809
|
+
if (visited.has(source)) {
|
|
744
810
|
return;
|
|
745
811
|
}
|
|
746
812
|
|
|
@@ -749,19 +815,20 @@ const toJSONObject = obj => {
|
|
|
749
815
|
return source;
|
|
750
816
|
}
|
|
751
817
|
if (!('toJSON' in source)) {
|
|
752
|
-
|
|
818
|
+
// add-on descent / delete-on-ascent: preserves path semantics, so DAG nodes serialise at every occurrence (see #7230).
|
|
819
|
+
visited.add(source);
|
|
753
820
|
const target = isArray(source) ? [] : {};
|
|
754
821
|
forEach(source, (value, key) => {
|
|
755
|
-
const reducedValue = visit(value
|
|
822
|
+
const reducedValue = visit(value);
|
|
756
823
|
!isUndefined(reducedValue) && (target[key] = reducedValue);
|
|
757
824
|
});
|
|
758
|
-
|
|
825
|
+
visited.delete(source);
|
|
759
826
|
return target;
|
|
760
827
|
}
|
|
761
828
|
}
|
|
762
829
|
return source;
|
|
763
830
|
};
|
|
764
|
-
return visit(obj
|
|
831
|
+
return visit(obj);
|
|
765
832
|
};
|
|
766
833
|
|
|
767
834
|
/**
|
|
@@ -822,6 +889,19 @@ const asap = typeof queueMicrotask !== 'undefined' ? queueMicrotask.bind(_global
|
|
|
822
889
|
// *********************
|
|
823
890
|
|
|
824
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);
|
|
825
905
|
var utils$1 = {
|
|
826
906
|
isArray,
|
|
827
907
|
isArrayBuffer,
|
|
@@ -867,6 +947,8 @@ var utils$1 = {
|
|
|
867
947
|
hasOwnProperty,
|
|
868
948
|
hasOwnProp: hasOwnProperty,
|
|
869
949
|
// an alias to avoid ESLint no-prototype-builtins detection
|
|
950
|
+
hasOwnInPrototypeChain,
|
|
951
|
+
getSafeProp,
|
|
870
952
|
reduceDescriptors,
|
|
871
953
|
freezeMethods,
|
|
872
954
|
toObjectSet,
|
|
@@ -882,7 +964,8 @@ var utils$1 = {
|
|
|
882
964
|
isThenable,
|
|
883
965
|
setImmediate: _setImmediate,
|
|
884
966
|
asap,
|
|
885
|
-
isIterable
|
|
967
|
+
isIterable,
|
|
968
|
+
isSafeIterable
|
|
886
969
|
};
|
|
887
970
|
|
|
888
971
|
// RawAxiosHeaders whose duplicates are ignored by node
|
|
@@ -928,8 +1011,6 @@ var parseHeaders = rawHeaders => {
|
|
|
928
1011
|
return parsed;
|
|
929
1012
|
};
|
|
930
1013
|
|
|
931
|
-
const $internals = Symbol('internals');
|
|
932
|
-
const INVALID_HEADER_VALUE_CHARS_RE = /[^\x09\x20-\x7E\x80-\xFF]/g;
|
|
933
1014
|
function trimSPorHTAB(str) {
|
|
934
1015
|
let start = 0;
|
|
935
1016
|
let end = str.length;
|
|
@@ -949,12 +1030,32 @@ function trimSPorHTAB(str) {
|
|
|
949
1030
|
}
|
|
950
1031
|
return start === 0 && end === str.length ? str : str.slice(start, end);
|
|
951
1032
|
}
|
|
1033
|
+
|
|
1034
|
+
// The control-code ranges are intentional: header sanitization strips C0/DEL bytes.
|
|
1035
|
+
// eslint-disable-next-line no-control-regex
|
|
1036
|
+
const INVALID_UNICODE_HEADER_VALUE_CHARS = new RegExp('[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+', 'g');
|
|
1037
|
+
// eslint-disable-next-line no-control-regex
|
|
1038
|
+
const INVALID_BYTE_STRING_HEADER_VALUE_CHARS = new RegExp('[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+', 'g');
|
|
1039
|
+
function sanitizeValue(value, invalidChars) {
|
|
1040
|
+
if (utils$1.isArray(value)) {
|
|
1041
|
+
return value.map(item => sanitizeValue(item, invalidChars));
|
|
1042
|
+
}
|
|
1043
|
+
return trimSPorHTAB(String(value).replace(invalidChars, ''));
|
|
1044
|
+
}
|
|
1045
|
+
const sanitizeHeaderValue = value => sanitizeValue(value, INVALID_UNICODE_HEADER_VALUE_CHARS);
|
|
1046
|
+
const sanitizeByteStringHeaderValue = value => sanitizeValue(value, INVALID_BYTE_STRING_HEADER_VALUE_CHARS);
|
|
1047
|
+
function toByteStringHeaderObject(headers) {
|
|
1048
|
+
const byteStringHeaders = Object.create(null);
|
|
1049
|
+
utils$1.forEach(headers.toJSON(), (value, header) => {
|
|
1050
|
+
byteStringHeaders[header] = sanitizeByteStringHeaderValue(value);
|
|
1051
|
+
});
|
|
1052
|
+
return byteStringHeaders;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
const $internals = Symbol('internals');
|
|
952
1056
|
function normalizeHeader(header) {
|
|
953
1057
|
return header && String(header).trim().toLowerCase();
|
|
954
1058
|
}
|
|
955
|
-
function sanitizeHeaderValue(str) {
|
|
956
|
-
return trimSPorHTAB(str.replace(INVALID_HEADER_VALUE_CHARS_RE, ''));
|
|
957
|
-
}
|
|
958
1059
|
function normalizeValue(value) {
|
|
959
1060
|
if (value === false || value == null) {
|
|
960
1061
|
return value;
|
|
@@ -1014,7 +1115,7 @@ class AxiosHeaders {
|
|
|
1014
1115
|
function setHeader(_value, _header, _rewrite) {
|
|
1015
1116
|
const lHeader = normalizeHeader(_header);
|
|
1016
1117
|
if (!lHeader) {
|
|
1017
|
-
|
|
1118
|
+
return;
|
|
1018
1119
|
}
|
|
1019
1120
|
const key = utils$1.findKey(self, lHeader);
|
|
1020
1121
|
if (!key || self[key] === undefined || _rewrite === true || _rewrite === undefined && self[key] !== false) {
|
|
@@ -1026,15 +1127,21 @@ class AxiosHeaders {
|
|
|
1026
1127
|
setHeaders(header, valueOrRewrite);
|
|
1027
1128
|
} else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
|
|
1028
1129
|
setHeaders(parseHeaders(header), valueOrRewrite);
|
|
1029
|
-
} else if (utils$1.isObject(header) && utils$1.
|
|
1030
|
-
let obj =
|
|
1130
|
+
} else if (utils$1.isObject(header) && utils$1.isSafeIterable(header)) {
|
|
1131
|
+
let obj = Object.create(null),
|
|
1031
1132
|
dest,
|
|
1032
1133
|
key;
|
|
1033
1134
|
for (const entry of header) {
|
|
1034
1135
|
if (!utils$1.isArray(entry)) {
|
|
1035
|
-
throw TypeError('Object iterator must return a key-value pair');
|
|
1136
|
+
throw new TypeError('Object iterator must return a key-value pair');
|
|
1137
|
+
}
|
|
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];
|
|
1036
1144
|
}
|
|
1037
|
-
obj[key = entry[0]] = (dest = obj[key]) ? utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]] : entry[1];
|
|
1038
1145
|
}
|
|
1039
1146
|
setHeaders(obj, valueOrRewrite);
|
|
1040
1147
|
} else {
|
|
@@ -1246,7 +1353,19 @@ function redactConfig(config, redactKeys) {
|
|
|
1246
1353
|
class AxiosError extends Error {
|
|
1247
1354
|
static from(error, code, config, request, response, customProps) {
|
|
1248
1355
|
const axiosError = new AxiosError(error.message, code || error.code, config, request, response);
|
|
1249
|
-
|
|
1356
|
+
// Match native `Error` `cause` semantics: non-enumerable. The wrapped
|
|
1357
|
+
// error often carries circular internals (sockets, requests, agents), so
|
|
1358
|
+
// an enumerable `cause` makes structured loggers (pino/winston) and any
|
|
1359
|
+
// own-property walk throw "Converting circular structure to JSON".
|
|
1360
|
+
// Regression from #6982; see #7205. `__proto__: null` mirrors the
|
|
1361
|
+
// `message` descriptor below (prototype-pollution-safe descriptor).
|
|
1362
|
+
Object.defineProperty(axiosError, 'cause', {
|
|
1363
|
+
__proto__: null,
|
|
1364
|
+
value: error,
|
|
1365
|
+
writable: true,
|
|
1366
|
+
enumerable: false,
|
|
1367
|
+
configurable: true
|
|
1368
|
+
});
|
|
1250
1369
|
axiosError.name = error.name;
|
|
1251
1370
|
|
|
1252
1371
|
// Preserve status from the original error if not already set from response
|
|
@@ -1337,6 +1456,10 @@ AxiosError.ERR_NOT_SUPPORT = 'ERR_NOT_SUPPORT';
|
|
|
1337
1456
|
AxiosError.ERR_INVALID_URL = 'ERR_INVALID_URL';
|
|
1338
1457
|
AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED = 'ERR_FORM_DATA_DEPTH_EXCEEDED';
|
|
1339
1458
|
|
|
1459
|
+
// Default nesting limit shared with the inverse transform (formDataToJSON) so
|
|
1460
|
+
// the FormData <-> JSON round-trip stays symmetric.
|
|
1461
|
+
const DEFAULT_FORM_DATA_MAX_DEPTH = 100;
|
|
1462
|
+
|
|
1340
1463
|
/**
|
|
1341
1464
|
* Determines if the given thing is a array or js object.
|
|
1342
1465
|
*
|
|
@@ -1437,8 +1560,9 @@ function toFormData(obj, formData, options) {
|
|
|
1437
1560
|
const dots = options.dots;
|
|
1438
1561
|
const indexes = options.indexes;
|
|
1439
1562
|
const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;
|
|
1440
|
-
const maxDepth = options.maxDepth === undefined ?
|
|
1563
|
+
const maxDepth = options.maxDepth === undefined ? DEFAULT_FORM_DATA_MAX_DEPTH : options.maxDepth;
|
|
1441
1564
|
const useBlob = _Blob && utils$1.isSpecCompliantForm(formData);
|
|
1565
|
+
const stack = [];
|
|
1442
1566
|
if (!utils$1.isFunction(visitor)) {
|
|
1443
1567
|
throw new TypeError('visitor must be a function');
|
|
1444
1568
|
}
|
|
@@ -1454,10 +1578,38 @@ function toFormData(obj, formData, options) {
|
|
|
1454
1578
|
throw new AxiosError('Blob is not supported. Use a Buffer instead.');
|
|
1455
1579
|
}
|
|
1456
1580
|
if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) {
|
|
1457
|
-
|
|
1581
|
+
if (useBlob && typeof _Blob === 'function') {
|
|
1582
|
+
return new _Blob([value]);
|
|
1583
|
+
}
|
|
1584
|
+
if (typeof Buffer !== 'undefined') {
|
|
1585
|
+
return Buffer.from(value);
|
|
1586
|
+
}
|
|
1587
|
+
throw new AxiosError('Blob is not supported. Use a Buffer instead.', AxiosError.ERR_NOT_SUPPORT);
|
|
1458
1588
|
}
|
|
1459
1589
|
return value;
|
|
1460
1590
|
}
|
|
1591
|
+
function throwIfMaxDepthExceeded(depth) {
|
|
1592
|
+
if (depth > maxDepth) {
|
|
1593
|
+
throw new AxiosError('Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
function stringifyWithDepthLimit(value, depth) {
|
|
1597
|
+
if (maxDepth === Infinity) {
|
|
1598
|
+
return JSON.stringify(value);
|
|
1599
|
+
}
|
|
1600
|
+
const ancestors = [];
|
|
1601
|
+
return JSON.stringify(value, function limitDepth(_key, currentValue) {
|
|
1602
|
+
if (!utils$1.isObject(currentValue)) {
|
|
1603
|
+
return currentValue;
|
|
1604
|
+
}
|
|
1605
|
+
while (ancestors.length && ancestors[ancestors.length - 1] !== this) {
|
|
1606
|
+
ancestors.pop();
|
|
1607
|
+
}
|
|
1608
|
+
ancestors.push(currentValue);
|
|
1609
|
+
throwIfMaxDepthExceeded(depth + ancestors.length - 1);
|
|
1610
|
+
return currentValue;
|
|
1611
|
+
});
|
|
1612
|
+
}
|
|
1461
1613
|
|
|
1462
1614
|
/**
|
|
1463
1615
|
* Default visitor.
|
|
@@ -1480,7 +1632,7 @@ function toFormData(obj, formData, options) {
|
|
|
1480
1632
|
// eslint-disable-next-line no-param-reassign
|
|
1481
1633
|
key = metaTokens ? key : key.slice(0, -2);
|
|
1482
1634
|
// eslint-disable-next-line no-param-reassign
|
|
1483
|
-
value =
|
|
1635
|
+
value = stringifyWithDepthLimit(value, 1);
|
|
1484
1636
|
} else if (utils$1.isArray(value) && isFlatArray(value) || (utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value))) {
|
|
1485
1637
|
// eslint-disable-next-line no-param-reassign
|
|
1486
1638
|
key = removeBrackets(key);
|
|
@@ -1498,7 +1650,6 @@ function toFormData(obj, formData, options) {
|
|
|
1498
1650
|
formData.append(renderKey(path, key, dots), convertValue(value));
|
|
1499
1651
|
return false;
|
|
1500
1652
|
}
|
|
1501
|
-
const stack = [];
|
|
1502
1653
|
const exposedHelpers = Object.assign(predicates, {
|
|
1503
1654
|
defaultVisitor,
|
|
1504
1655
|
convertValue,
|
|
@@ -1506,11 +1657,9 @@ function toFormData(obj, formData, options) {
|
|
|
1506
1657
|
});
|
|
1507
1658
|
function build(value, path, depth = 0) {
|
|
1508
1659
|
if (utils$1.isUndefined(value)) return;
|
|
1509
|
-
|
|
1510
|
-
throw new AxiosError('Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
|
|
1511
|
-
}
|
|
1660
|
+
throwIfMaxDepthExceeded(depth);
|
|
1512
1661
|
if (stack.indexOf(value) !== -1) {
|
|
1513
|
-
throw Error('Circular reference detected in ' + path.join('.'));
|
|
1662
|
+
throw new Error('Circular reference detected in ' + path.join('.'));
|
|
1514
1663
|
}
|
|
1515
1664
|
stack.push(value);
|
|
1516
1665
|
utils$1.forEach(value, function each(el, key) {
|
|
@@ -1567,9 +1716,7 @@ prototype.append = function append(name, value) {
|
|
|
1567
1716
|
this._pairs.push([name, value]);
|
|
1568
1717
|
};
|
|
1569
1718
|
prototype.toString = function toString(encoder) {
|
|
1570
|
-
const _encode = encoder ?
|
|
1571
|
-
return encoder.call(this, value, encode$1);
|
|
1572
|
-
} : encode$1;
|
|
1719
|
+
const _encode = encoder ? value => encoder.call(this, value, encode$1) : encode$1;
|
|
1573
1720
|
return this._pairs.map(function each(pair) {
|
|
1574
1721
|
return _encode(pair[0]) + '=' + _encode(pair[1]);
|
|
1575
1722
|
}, '').join('&');
|
|
@@ -1600,11 +1747,16 @@ function buildURL(url, params, options) {
|
|
|
1600
1747
|
if (!params) {
|
|
1601
1748
|
return url;
|
|
1602
1749
|
}
|
|
1603
|
-
|
|
1750
|
+
url = url || '';
|
|
1604
1751
|
const _options = utils$1.isFunction(options) ? {
|
|
1605
1752
|
serialize: options
|
|
1606
1753
|
} : options;
|
|
1607
|
-
|
|
1754
|
+
|
|
1755
|
+
// Read serializer options pollution-safely: own properties and methods on a
|
|
1756
|
+
// class/template prototype are honored, but values injected onto a polluted
|
|
1757
|
+
// Object.prototype are ignored.
|
|
1758
|
+
const _encode = utils$1.getSafeProp(_options, 'encode') || encode;
|
|
1759
|
+
const serializeFn = utils$1.getSafeProp(_options, 'serialize');
|
|
1608
1760
|
let serializedParams;
|
|
1609
1761
|
if (serializeFn) {
|
|
1610
1762
|
serializedParams = serializeFn(params, _options);
|
|
@@ -1692,7 +1844,9 @@ var transitionalDefaults = {
|
|
|
1692
1844
|
silentJSONParsing: true,
|
|
1693
1845
|
forcedJSONParsing: true,
|
|
1694
1846
|
clarifyTimeoutError: false,
|
|
1695
|
-
legacyInterceptorReqResOrdering: true
|
|
1847
|
+
legacyInterceptorReqResOrdering: true,
|
|
1848
|
+
advertiseZstdAcceptEncoding: false,
|
|
1849
|
+
validateStatusUndefinedResolves: true
|
|
1696
1850
|
};
|
|
1697
1851
|
|
|
1698
1852
|
var URLSearchParams = url.URLSearchParams;
|
|
@@ -1793,6 +1947,13 @@ function toURLEncodedForm(data, options) {
|
|
|
1793
1947
|
});
|
|
1794
1948
|
}
|
|
1795
1949
|
|
|
1950
|
+
const MAX_DEPTH = DEFAULT_FORM_DATA_MAX_DEPTH;
|
|
1951
|
+
function throwIfDepthExceeded(index) {
|
|
1952
|
+
if (index > MAX_DEPTH) {
|
|
1953
|
+
throw new AxiosError('FormData field is too deeply nested (' + index + ' levels). Max depth: ' + MAX_DEPTH, AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED);
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1796
1957
|
/**
|
|
1797
1958
|
* It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']
|
|
1798
1959
|
*
|
|
@@ -1805,9 +1966,14 @@ function parsePropPath(name) {
|
|
|
1805
1966
|
// foo.x.y.z
|
|
1806
1967
|
// foo-x-y-z
|
|
1807
1968
|
// foo x y z
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1969
|
+
const path = [];
|
|
1970
|
+
const pattern = /\w+|\[(\w*)]/g;
|
|
1971
|
+
let match;
|
|
1972
|
+
while ((match = pattern.exec(name)) !== null) {
|
|
1973
|
+
throwIfDepthExceeded(path.length);
|
|
1974
|
+
path.push(match[0] === '[]' ? '' : match[1] || match[0]);
|
|
1975
|
+
}
|
|
1976
|
+
return path;
|
|
1811
1977
|
}
|
|
1812
1978
|
|
|
1813
1979
|
/**
|
|
@@ -1839,6 +2005,7 @@ function arrayToObject(arr) {
|
|
|
1839
2005
|
*/
|
|
1840
2006
|
function formDataToJSON(formData) {
|
|
1841
2007
|
function buildPath(path, value, target, index) {
|
|
2008
|
+
throwIfDepthExceeded(index);
|
|
1842
2009
|
let name = path[index++];
|
|
1843
2010
|
if (name === '__proto__') return true;
|
|
1844
2011
|
const isNumericKey = Number.isFinite(+name);
|
|
@@ -1852,7 +2019,7 @@ function formDataToJSON(formData) {
|
|
|
1852
2019
|
}
|
|
1853
2020
|
return !isNumericKey;
|
|
1854
2021
|
}
|
|
1855
|
-
if (!target
|
|
2022
|
+
if (!utils$1.hasOwnProp(target, name) || !utils$1.isObject(target[name])) {
|
|
1856
2023
|
target[name] = [];
|
|
1857
2024
|
}
|
|
1858
2025
|
const result = buildPath(path, value, target[name], index);
|
|
@@ -2079,6 +2246,24 @@ function combineURLs(baseURL, relativeURL) {
|
|
|
2079
2246
|
return relativeURL ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;
|
|
2080
2247
|
}
|
|
2081
2248
|
|
|
2249
|
+
const malformedHttpProtocol = /^https?:(?!\/\/)/i;
|
|
2250
|
+
const httpProtocolControlCharacters = /[\t\n\r]/g;
|
|
2251
|
+
function stripLeadingC0ControlOrSpace(url) {
|
|
2252
|
+
let i = 0;
|
|
2253
|
+
while (i < url.length && url.charCodeAt(i) <= 0x20) {
|
|
2254
|
+
i++;
|
|
2255
|
+
}
|
|
2256
|
+
return url.slice(i);
|
|
2257
|
+
}
|
|
2258
|
+
function normalizeURLForProtocolCheck(url) {
|
|
2259
|
+
return stripLeadingC0ControlOrSpace(url).replace(httpProtocolControlCharacters, '');
|
|
2260
|
+
}
|
|
2261
|
+
function assertValidHttpProtocolURL(url, config) {
|
|
2262
|
+
if (typeof url === 'string' && malformedHttpProtocol.test(normalizeURLForProtocolCheck(url))) {
|
|
2263
|
+
throw new AxiosError('Invalid URL: missing "//" after protocol', AxiosError.ERR_INVALID_URL, config);
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2082
2267
|
/**
|
|
2083
2268
|
* Creates a new URL by combining the baseURL with the requestedURL,
|
|
2084
2269
|
* only when the requestedURL is not already an absolute URL.
|
|
@@ -2089,9 +2274,11 @@ function combineURLs(baseURL, relativeURL) {
|
|
|
2089
2274
|
*
|
|
2090
2275
|
* @returns {string} The combined full path
|
|
2091
2276
|
*/
|
|
2092
|
-
function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
|
|
2277
|
+
function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls, config) {
|
|
2278
|
+
assertValidHttpProtocolURL(requestedURL, config);
|
|
2093
2279
|
let isRelativeUrl = !isAbsoluteURL(requestedURL);
|
|
2094
2280
|
if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) {
|
|
2281
|
+
assertValidHttpProtocolURL(baseURL, config);
|
|
2095
2282
|
return combineURLs(baseURL, requestedURL);
|
|
2096
2283
|
}
|
|
2097
2284
|
return requestedURL;
|
|
@@ -2193,14 +2380,16 @@ function getEnv(key) {
|
|
|
2193
2380
|
return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
|
|
2194
2381
|
}
|
|
2195
2382
|
|
|
2196
|
-
const VERSION = "1.
|
|
2383
|
+
const VERSION = "1.18.1";
|
|
2197
2384
|
|
|
2198
2385
|
function parseProtocol(url) {
|
|
2199
2386
|
const match = /^([-+\w]{1,25}):(?:\/\/)?/.exec(url);
|
|
2200
2387
|
return match && match[1] || '';
|
|
2201
2388
|
}
|
|
2202
2389
|
|
|
2203
|
-
|
|
2390
|
+
// RFC 2397: data:[<mediatype>][;base64],<data>
|
|
2391
|
+
// mediatype = type/subtype followed by optional ;name=value parameters
|
|
2392
|
+
const DATA_URL_PATTERN = /^([^,;]+\/[^,;]+)?((?:;[^,;=]+=[^,;]+)*)(;base64)?,([\s\S]*)$/;
|
|
2204
2393
|
|
|
2205
2394
|
/**
|
|
2206
2395
|
* Parse data uri to a Buffer or Blob
|
|
@@ -2224,10 +2413,20 @@ function fromDataURI(uri, asBlob, options) {
|
|
|
2224
2413
|
if (!match) {
|
|
2225
2414
|
throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL);
|
|
2226
2415
|
}
|
|
2227
|
-
const
|
|
2228
|
-
const
|
|
2229
|
-
const
|
|
2230
|
-
const
|
|
2416
|
+
const type = match[1];
|
|
2417
|
+
const params = match[2];
|
|
2418
|
+
const encoding = match[3] ? 'base64' : 'utf8';
|
|
2419
|
+
const body = match[4];
|
|
2420
|
+
|
|
2421
|
+
// RFC 2397 section 3: default mediatype is text/plain;charset=US-ASCII
|
|
2422
|
+
// Bare `data:,` leaves mime undefined; Blob normalises that to "" per spec.
|
|
2423
|
+
let mime = '';
|
|
2424
|
+
if (type) {
|
|
2425
|
+
mime = params ? type + params : type;
|
|
2426
|
+
} else if (params) {
|
|
2427
|
+
mime = 'text/plain' + params;
|
|
2428
|
+
}
|
|
2429
|
+
const buffer = encoding === 'base64' ? Buffer.from(body, 'base64') : Buffer.from(decodeURIComponent(body), encoding);
|
|
2231
2430
|
if (asBlob) {
|
|
2232
2431
|
if (!_Blob) {
|
|
2233
2432
|
throw new AxiosError('Blob is not supported', AxiosError.ERR_NOT_SUPPORT);
|
|
@@ -2420,10 +2619,10 @@ const formDataToStream = (form, headersHandler, options) => {
|
|
|
2420
2619
|
boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET)
|
|
2421
2620
|
} = options || {};
|
|
2422
2621
|
if (!utils$1.isFormData(form)) {
|
|
2423
|
-
throw TypeError('FormData instance required');
|
|
2622
|
+
throw new TypeError('FormData instance required');
|
|
2424
2623
|
}
|
|
2425
2624
|
if (boundary.length < 1 || boundary.length > 70) {
|
|
2426
|
-
throw Error('boundary must be 1-70 characters long');
|
|
2625
|
+
throw new Error('boundary must be 1-70 characters long');
|
|
2427
2626
|
}
|
|
2428
2627
|
const boundaryBytes = textEncoder.encode('--' + boundary + CRLF);
|
|
2429
2628
|
const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF);
|
|
@@ -2473,6 +2672,84 @@ class ZlibHeaderTransformStream extends stream.Transform {
|
|
|
2473
2672
|
}
|
|
2474
2673
|
}
|
|
2475
2674
|
|
|
2675
|
+
class Http2Sessions {
|
|
2676
|
+
constructor() {
|
|
2677
|
+
this.sessions = Object.create(null);
|
|
2678
|
+
}
|
|
2679
|
+
getSession(authority, options) {
|
|
2680
|
+
options = Object.assign({
|
|
2681
|
+
sessionTimeout: 1000
|
|
2682
|
+
}, options);
|
|
2683
|
+
let authoritySessions = this.sessions[authority];
|
|
2684
|
+
if (authoritySessions) {
|
|
2685
|
+
let len = authoritySessions.length;
|
|
2686
|
+
for (let i = 0; i < len; i++) {
|
|
2687
|
+
const [sessionHandle, sessionOptions] = authoritySessions[i];
|
|
2688
|
+
if (!sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options)) {
|
|
2689
|
+
return sessionHandle;
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
const session = http2.connect(authority, options);
|
|
2694
|
+
let removed;
|
|
2695
|
+
let timer;
|
|
2696
|
+
const removeSession = () => {
|
|
2697
|
+
if (removed) {
|
|
2698
|
+
return;
|
|
2699
|
+
}
|
|
2700
|
+
removed = true;
|
|
2701
|
+
if (timer) {
|
|
2702
|
+
clearTimeout(timer);
|
|
2703
|
+
timer = null;
|
|
2704
|
+
}
|
|
2705
|
+
let entries = authoritySessions,
|
|
2706
|
+
len = entries.length,
|
|
2707
|
+
i = len;
|
|
2708
|
+
while (i--) {
|
|
2709
|
+
if (entries[i][0] === session) {
|
|
2710
|
+
if (len === 1) {
|
|
2711
|
+
delete this.sessions[authority];
|
|
2712
|
+
} else {
|
|
2713
|
+
entries.splice(i, 1);
|
|
2714
|
+
}
|
|
2715
|
+
if (!session.closed) {
|
|
2716
|
+
session.close();
|
|
2717
|
+
}
|
|
2718
|
+
return;
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
};
|
|
2722
|
+
const originalRequestFn = session.request;
|
|
2723
|
+
const {
|
|
2724
|
+
sessionTimeout
|
|
2725
|
+
} = options;
|
|
2726
|
+
if (sessionTimeout != null) {
|
|
2727
|
+
let streamsCount = 0;
|
|
2728
|
+
session.request = function () {
|
|
2729
|
+
const stream = originalRequestFn.apply(this, arguments);
|
|
2730
|
+
streamsCount++;
|
|
2731
|
+
if (timer) {
|
|
2732
|
+
clearTimeout(timer);
|
|
2733
|
+
timer = null;
|
|
2734
|
+
}
|
|
2735
|
+
stream.once('close', () => {
|
|
2736
|
+
if (! --streamsCount) {
|
|
2737
|
+
timer = setTimeout(() => {
|
|
2738
|
+
timer = null;
|
|
2739
|
+
removeSession();
|
|
2740
|
+
}, sessionTimeout);
|
|
2741
|
+
}
|
|
2742
|
+
});
|
|
2743
|
+
return stream;
|
|
2744
|
+
};
|
|
2745
|
+
}
|
|
2746
|
+
session.once('close', removeSession);
|
|
2747
|
+
let entry = [session, options];
|
|
2748
|
+
authoritySessions ? authoritySessions.push(entry) : authoritySessions = this.sessions[authority] = [entry];
|
|
2749
|
+
return session;
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2476
2753
|
const callbackify = (fn, reducer) => {
|
|
2477
2754
|
return utils$1.isAsyncFn(fn) ? function (...args) {
|
|
2478
2755
|
const cb = args.pop();
|
|
@@ -2486,13 +2763,34 @@ const callbackify = (fn, reducer) => {
|
|
|
2486
2763
|
} : fn;
|
|
2487
2764
|
};
|
|
2488
2765
|
|
|
2489
|
-
const LOOPBACK_HOSTNAMES = new Set(['localhost']);
|
|
2766
|
+
const LOOPBACK_HOSTNAMES = new Set(['localhost', '0.0.0.0']);
|
|
2490
2767
|
const isIPv4Loopback = host => {
|
|
2491
2768
|
const parts = host.split('.');
|
|
2492
2769
|
if (parts.length !== 4) return false;
|
|
2493
2770
|
if (parts[0] !== '127') return false;
|
|
2494
2771
|
return parts.every(p => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
|
|
2495
2772
|
};
|
|
2773
|
+
const isIPv6ZeroGroup = group => /^0{1,4}$/.test(group);
|
|
2774
|
+
|
|
2775
|
+
// The unspecified address (IPv4 0.0.0.0 / IPv6 ::) resolves to the local host
|
|
2776
|
+
// for outbound connections, so treat it as loopback-equivalent for NO_PROXY
|
|
2777
|
+
// matching. 0.0.0.0 is covered by LOOPBACK_HOSTNAMES; this handles compressed
|
|
2778
|
+
// and full IPv6 all-zero forms so both families bypass symmetrically.
|
|
2779
|
+
const isIPv6Unspecified = host => {
|
|
2780
|
+
if (host === '::') return true;
|
|
2781
|
+
const compressionIndex = host.indexOf('::');
|
|
2782
|
+
if (compressionIndex !== -1) {
|
|
2783
|
+
if (compressionIndex !== host.lastIndexOf('::')) return false;
|
|
2784
|
+
const left = host.slice(0, compressionIndex);
|
|
2785
|
+
const right = host.slice(compressionIndex + 2);
|
|
2786
|
+
const leftGroups = left ? left.split(':') : [];
|
|
2787
|
+
const rightGroups = right ? right.split(':') : [];
|
|
2788
|
+
const explicitGroups = leftGroups.length + rightGroups.length;
|
|
2789
|
+
return explicitGroups < 8 && leftGroups.every(isIPv6ZeroGroup) && rightGroups.every(isIPv6ZeroGroup);
|
|
2790
|
+
}
|
|
2791
|
+
const groups = host.split(':');
|
|
2792
|
+
return groups.length === 8 && groups.every(isIPv6ZeroGroup);
|
|
2793
|
+
};
|
|
2496
2794
|
const isIPv6Loopback = host => {
|
|
2497
2795
|
// Collapse all-zero groups: any form of ::1 / 0:0:...:0:1
|
|
2498
2796
|
// First, strip any leading "::" by normalising with Set lookup of common forms,
|
|
@@ -2525,6 +2823,7 @@ const isLoopback = host => {
|
|
|
2525
2823
|
if (!host) return false;
|
|
2526
2824
|
if (LOOPBACK_HOSTNAMES.has(host)) return true;
|
|
2527
2825
|
if (isIPv4Loopback(host)) return true;
|
|
2826
|
+
if (isIPv6Unspecified(host)) return true;
|
|
2528
2827
|
return isIPv6Loopback(host);
|
|
2529
2828
|
};
|
|
2530
2829
|
const DEFAULT_PORTS = {
|
|
@@ -2707,6 +3006,9 @@ const progressEventReducer = (listener, isDownloadStream, freq = 3) => {
|
|
|
2707
3006
|
let bytesNotified = 0;
|
|
2708
3007
|
const _speedometer = speedometer(50, 250);
|
|
2709
3008
|
return throttle(e => {
|
|
3009
|
+
if (!e || typeof e.loaded !== 'number') {
|
|
3010
|
+
return;
|
|
3011
|
+
}
|
|
2710
3012
|
const rawLoaded = e.loaded;
|
|
2711
3013
|
const total = e.lengthComputable ? e.total : undefined;
|
|
2712
3014
|
const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;
|
|
@@ -2741,11 +3043,13 @@ const asyncDecorator = fn => (...args) => utils$1.asap(() => fn(...args));
|
|
|
2741
3043
|
* Estimate decoded byte length of a data:// URL *without* allocating large buffers.
|
|
2742
3044
|
* - For base64: compute exact decoded size using length and padding;
|
|
2743
3045
|
* handle %XX at the character-count level (no string allocation).
|
|
2744
|
-
* - For non-base64:
|
|
3046
|
+
* - For non-base64: compute the exact percent-decoded UTF-8 byte length.
|
|
2745
3047
|
*
|
|
2746
3048
|
* @param {string} url
|
|
2747
3049
|
* @returns {number}
|
|
2748
3050
|
*/
|
|
3051
|
+
const isHexDigit = charCode => charCode >= 48 && charCode <= 57 || charCode >= 65 && charCode <= 70 || charCode >= 97 && charCode <= 102;
|
|
3052
|
+
const isPercentEncodedByte = (str, i, len) => i + 2 < len && isHexDigit(str.charCodeAt(i + 1)) && isHexDigit(str.charCodeAt(i + 2));
|
|
2749
3053
|
function estimateDataURLDecodedBytes(url) {
|
|
2750
3054
|
if (!url || typeof url !== 'string') return 0;
|
|
2751
3055
|
if (!url.startsWith('data:')) return 0;
|
|
@@ -2762,7 +3066,7 @@ function estimateDataURLDecodedBytes(url) {
|
|
|
2762
3066
|
if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {
|
|
2763
3067
|
const a = body.charCodeAt(i + 1);
|
|
2764
3068
|
const b = body.charCodeAt(i + 2);
|
|
2765
|
-
const isHex = (a
|
|
3069
|
+
const isHex = isHexDigit(a) && isHexDigit(b);
|
|
2766
3070
|
if (isHex) {
|
|
2767
3071
|
effectiveLen -= 2;
|
|
2768
3072
|
i += 2;
|
|
@@ -2797,18 +3101,18 @@ function estimateDataURLDecodedBytes(url) {
|
|
|
2797
3101
|
const bytes = groups * 3 - (pad || 0);
|
|
2798
3102
|
return bytes > 0 ? bytes : 0;
|
|
2799
3103
|
}
|
|
2800
|
-
if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') {
|
|
2801
|
-
return Buffer.byteLength(body, 'utf8');
|
|
2802
|
-
}
|
|
2803
3104
|
|
|
2804
3105
|
// Compute UTF-8 byte length directly from UTF-16 code units without allocating
|
|
2805
3106
|
// a byte buffer (TextEncoder.encode would defeat the DoS guard on large bodies).
|
|
2806
|
-
//
|
|
2807
|
-
//
|
|
3107
|
+
// Valid %XX triplets count as one decoded byte; this matches the bytes that
|
|
3108
|
+
// decodeURIComponent(body) would produce before Buffer re-encodes the string.
|
|
2808
3109
|
let bytes = 0;
|
|
2809
3110
|
for (let i = 0, len = body.length; i < len; i++) {
|
|
2810
3111
|
const c = body.charCodeAt(i);
|
|
2811
|
-
if (c
|
|
3112
|
+
if (c === 37 /* '%' */ && isPercentEncodedByte(body, i, len)) {
|
|
3113
|
+
bytes += 1;
|
|
3114
|
+
i += 2;
|
|
3115
|
+
} else if (c < 0x80) {
|
|
2812
3116
|
bytes += 1;
|
|
2813
3117
|
} else if (c < 0x800) {
|
|
2814
3118
|
bytes += 2;
|
|
@@ -2835,7 +3139,14 @@ const brotliOptions = {
|
|
|
2835
3139
|
flush: zlib.constants.BROTLI_OPERATION_FLUSH,
|
|
2836
3140
|
finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
|
|
2837
3141
|
};
|
|
3142
|
+
const zstdOptions = {
|
|
3143
|
+
flush: zlib.constants.ZSTD_e_flush,
|
|
3144
|
+
finishFlush: zlib.constants.ZSTD_e_flush
|
|
3145
|
+
};
|
|
2838
3146
|
const isBrotliSupported = utils$1.isFunction(zlib.createBrotliDecompress);
|
|
3147
|
+
const isZstdSupported = utils$1.isFunction(zlib.createZstdDecompress);
|
|
3148
|
+
const ACCEPT_ENCODING = 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : '');
|
|
3149
|
+
const ACCEPT_ENCODING_WITH_ZSTD = ACCEPT_ENCODING + (isZstdSupported ? ', zstd' : '');
|
|
2839
3150
|
const {
|
|
2840
3151
|
http: httpFollow,
|
|
2841
3152
|
https: httpsFollow
|
|
@@ -2858,6 +3169,78 @@ function setFormDataHeaders$1(headers, formHeaders, policy) {
|
|
|
2858
3169
|
// the request currently owning that socket across keep-alive reuse (issue #10780).
|
|
2859
3170
|
const kAxiosSocketListener = Symbol('axios.http.socketListener');
|
|
2860
3171
|
const kAxiosCurrentReq = Symbol('axios.http.currentReq');
|
|
3172
|
+
|
|
3173
|
+
// Tags HttpsProxyAgent instances installed by setProxy() so the redirect path
|
|
3174
|
+
// can strip them without clobbering a user-supplied agent that happens to be
|
|
3175
|
+
// an HttpsProxyAgent.
|
|
3176
|
+
const kAxiosInstalledTunnel = Symbol('axios.http.installedTunnel');
|
|
3177
|
+
|
|
3178
|
+
// Cache of CONNECT-tunneling agents keyed by proxy config so repeat requests
|
|
3179
|
+
// through the same proxy reuse a single agent (and its socket pool). The
|
|
3180
|
+
// keyspace is bounded by the set of distinct proxy configs the process uses,
|
|
3181
|
+
// so unbounded growth is not a concern in practice.
|
|
3182
|
+
const tunnelingAgentCache = new Map();
|
|
3183
|
+
const tunnelingAgentCacheUser = new WeakMap();
|
|
3184
|
+
// Minimum minor versions where Node's HTTP Agent supports native proxyEnv
|
|
3185
|
+
// handling. Checking the selected agent below also covers startup modes such
|
|
3186
|
+
// as NODE_OPTIONS=--use-env-proxy and --no-use-env-proxy precedence.
|
|
3187
|
+
const NODE_NATIVE_ENV_PROXY_SUPPORT = {
|
|
3188
|
+
22: 21,
|
|
3189
|
+
24: 5
|
|
3190
|
+
};
|
|
3191
|
+
function isNodeNativeEnvProxySupported(nodeVersion = process.versions && process.versions.node) {
|
|
3192
|
+
if (!nodeVersion) {
|
|
3193
|
+
return false;
|
|
3194
|
+
}
|
|
3195
|
+
const [major, minor] = nodeVersion.split('.').map(part => Number(part));
|
|
3196
|
+
if (!Number.isInteger(major) || !Number.isInteger(minor)) {
|
|
3197
|
+
return false;
|
|
3198
|
+
}
|
|
3199
|
+
if (major > 24) {
|
|
3200
|
+
return true;
|
|
3201
|
+
}
|
|
3202
|
+
return NODE_NATIVE_ENV_PROXY_SUPPORT[major] != null && minor >= NODE_NATIVE_ENV_PROXY_SUPPORT[major];
|
|
3203
|
+
}
|
|
3204
|
+
function isNodeEnvProxyEnabled(agent, nodeVersion = process.versions && process.versions.node) {
|
|
3205
|
+
if (!isNodeNativeEnvProxySupported(nodeVersion)) {
|
|
3206
|
+
return false;
|
|
3207
|
+
}
|
|
3208
|
+
const agentOptions = agent && agent.options;
|
|
3209
|
+
return Boolean(agentOptions && utils$1.hasOwnProp(agentOptions, 'proxyEnv') && agentOptions.proxyEnv != null);
|
|
3210
|
+
}
|
|
3211
|
+
function getProxyEnvAgent(options, configHttpAgent, configHttpsAgent) {
|
|
3212
|
+
return isHttps.test(options.protocol) ? configHttpsAgent || https.globalAgent : configHttpAgent || http.globalAgent;
|
|
3213
|
+
}
|
|
3214
|
+
function getTunnelingAgent(agentOptions, userHttpsAgent) {
|
|
3215
|
+
const key = agentOptions.protocol + '//' + agentOptions.hostname + ':' + (agentOptions.port || '') + '#' + (agentOptions.auth || '');
|
|
3216
|
+
const cache = userHttpsAgent ? tunnelingAgentCacheUser.get(userHttpsAgent) || tunnelingAgentCacheUser.set(userHttpsAgent, new Map()).get(userHttpsAgent) : tunnelingAgentCache;
|
|
3217
|
+
let agent = cache.get(key);
|
|
3218
|
+
if (agent) return agent;
|
|
3219
|
+
// Forward the user's TLS options (custom CA, rejectUnauthorized, client cert,
|
|
3220
|
+
// etc.) into the tunneling agent so they apply to the origin TLS upgrade
|
|
3221
|
+
// performed after CONNECT. Our proxy fields take precedence on conflict.
|
|
3222
|
+
const merged = userHttpsAgent && userHttpsAgent.options ? {
|
|
3223
|
+
...userHttpsAgent.options,
|
|
3224
|
+
...agentOptions
|
|
3225
|
+
} : agentOptions;
|
|
3226
|
+
agent = new HttpsProxyAgent(merged);
|
|
3227
|
+
if (userHttpsAgent && userHttpsAgent.options) {
|
|
3228
|
+
const originTLSOptions = {
|
|
3229
|
+
...userHttpsAgent.options
|
|
3230
|
+
};
|
|
3231
|
+
const callback = agent.callback;
|
|
3232
|
+
agent.callback = function axiosTunnelingAgentCallback(req, opts) {
|
|
3233
|
+
// HttpsProxyAgent v5 reads callback opts for the post-CONNECT origin TLS upgrade.
|
|
3234
|
+
return callback.call(this, req, {
|
|
3235
|
+
...originTLSOptions,
|
|
3236
|
+
...opts
|
|
3237
|
+
});
|
|
3238
|
+
};
|
|
3239
|
+
}
|
|
3240
|
+
agent[kAxiosInstalledTunnel] = true;
|
|
3241
|
+
cache.set(key, agent);
|
|
3242
|
+
return agent;
|
|
3243
|
+
}
|
|
2861
3244
|
const supportedProtocols = platform.protocols.map(protocol => {
|
|
2862
3245
|
return protocol + ':';
|
|
2863
3246
|
});
|
|
@@ -2866,7 +3249,7 @@ const supportedProtocols = platform.protocols.map(protocol => {
|
|
|
2866
3249
|
// Decode before composing the `auth` option so credentials such as
|
|
2867
3250
|
// `my%40email.com:pass` are sent as `my@email.com:pass`. Falls back to the
|
|
2868
3251
|
// original value for malformed input so a bad encoding never throws.
|
|
2869
|
-
const decodeURIComponentSafe = value => {
|
|
3252
|
+
const decodeURIComponentSafe$1 = value => {
|
|
2870
3253
|
if (!utils$1.isString(value)) {
|
|
2871
3254
|
return value;
|
|
2872
3255
|
}
|
|
@@ -2880,84 +3263,11 @@ const flushOnFinish = (stream, [throttled, flush]) => {
|
|
|
2880
3263
|
stream.on('end', flush).on('error', flush);
|
|
2881
3264
|
return throttled;
|
|
2882
3265
|
};
|
|
2883
|
-
class Http2Sessions {
|
|
2884
|
-
constructor() {
|
|
2885
|
-
this.sessions = Object.create(null);
|
|
2886
|
-
}
|
|
2887
|
-
getSession(authority, options) {
|
|
2888
|
-
options = Object.assign({
|
|
2889
|
-
sessionTimeout: 1000
|
|
2890
|
-
}, options);
|
|
2891
|
-
let authoritySessions = this.sessions[authority];
|
|
2892
|
-
if (authoritySessions) {
|
|
2893
|
-
let len = authoritySessions.length;
|
|
2894
|
-
for (let i = 0; i < len; i++) {
|
|
2895
|
-
const [sessionHandle, sessionOptions] = authoritySessions[i];
|
|
2896
|
-
if (!sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options)) {
|
|
2897
|
-
return sessionHandle;
|
|
2898
|
-
}
|
|
2899
|
-
}
|
|
2900
|
-
}
|
|
2901
|
-
const session = http2.connect(authority, options);
|
|
2902
|
-
let removed;
|
|
2903
|
-
const removeSession = () => {
|
|
2904
|
-
if (removed) {
|
|
2905
|
-
return;
|
|
2906
|
-
}
|
|
2907
|
-
removed = true;
|
|
2908
|
-
let entries = authoritySessions,
|
|
2909
|
-
len = entries.length,
|
|
2910
|
-
i = len;
|
|
2911
|
-
while (i--) {
|
|
2912
|
-
if (entries[i][0] === session) {
|
|
2913
|
-
if (len === 1) {
|
|
2914
|
-
delete this.sessions[authority];
|
|
2915
|
-
} else {
|
|
2916
|
-
entries.splice(i, 1);
|
|
2917
|
-
}
|
|
2918
|
-
if (!session.closed) {
|
|
2919
|
-
session.close();
|
|
2920
|
-
}
|
|
2921
|
-
return;
|
|
2922
|
-
}
|
|
2923
|
-
}
|
|
2924
|
-
};
|
|
2925
|
-
const originalRequestFn = session.request;
|
|
2926
|
-
const {
|
|
2927
|
-
sessionTimeout
|
|
2928
|
-
} = options;
|
|
2929
|
-
if (sessionTimeout != null) {
|
|
2930
|
-
let timer;
|
|
2931
|
-
let streamsCount = 0;
|
|
2932
|
-
session.request = function () {
|
|
2933
|
-
const stream = originalRequestFn.apply(this, arguments);
|
|
2934
|
-
streamsCount++;
|
|
2935
|
-
if (timer) {
|
|
2936
|
-
clearTimeout(timer);
|
|
2937
|
-
timer = null;
|
|
2938
|
-
}
|
|
2939
|
-
stream.once('close', () => {
|
|
2940
|
-
if (! --streamsCount) {
|
|
2941
|
-
timer = setTimeout(() => {
|
|
2942
|
-
timer = null;
|
|
2943
|
-
removeSession();
|
|
2944
|
-
}, sessionTimeout);
|
|
2945
|
-
}
|
|
2946
|
-
});
|
|
2947
|
-
return stream;
|
|
2948
|
-
};
|
|
2949
|
-
}
|
|
2950
|
-
session.once('close', removeSession);
|
|
2951
|
-
let entry = [session, options];
|
|
2952
|
-
authoritySessions ? authoritySessions.push(entry) : authoritySessions = this.sessions[authority] = [entry];
|
|
2953
|
-
return session;
|
|
2954
|
-
}
|
|
2955
|
-
}
|
|
2956
3266
|
const http2Sessions = new Http2Sessions();
|
|
2957
3267
|
|
|
2958
3268
|
/**
|
|
2959
|
-
* If the proxy or config beforeRedirects functions are defined,
|
|
2960
|
-
* object.
|
|
3269
|
+
* If the proxy, auth, sensitive header, or config beforeRedirects functions are defined,
|
|
3270
|
+
* call them with the options object.
|
|
2961
3271
|
*
|
|
2962
3272
|
* @param {Object<string, any>} options - The options object that was passed to the request.
|
|
2963
3273
|
*
|
|
@@ -2967,10 +3277,37 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
|
|
|
2967
3277
|
if (options.beforeRedirects.proxy) {
|
|
2968
3278
|
options.beforeRedirects.proxy(options);
|
|
2969
3279
|
}
|
|
3280
|
+
if (options.beforeRedirects.auth) {
|
|
3281
|
+
options.beforeRedirects.auth(options);
|
|
3282
|
+
}
|
|
3283
|
+
if (options.beforeRedirects.sensitiveHeaders) {
|
|
3284
|
+
options.beforeRedirects.sensitiveHeaders(options, requestDetails);
|
|
3285
|
+
}
|
|
2970
3286
|
if (options.beforeRedirects.config) {
|
|
2971
3287
|
options.beforeRedirects.config(options, responseDetails, requestDetails);
|
|
2972
3288
|
}
|
|
2973
3289
|
}
|
|
3290
|
+
function stripMatchingHeaders(headers, sensitiveSet) {
|
|
3291
|
+
if (!headers) {
|
|
3292
|
+
return;
|
|
3293
|
+
}
|
|
3294
|
+
Object.keys(headers).forEach(header => {
|
|
3295
|
+
if (sensitiveSet.has(header.toLowerCase())) {
|
|
3296
|
+
delete headers[header];
|
|
3297
|
+
}
|
|
3298
|
+
});
|
|
3299
|
+
}
|
|
3300
|
+
function isSameOriginRedirect(redirectOptions, requestDetails) {
|
|
3301
|
+
if (!requestDetails) {
|
|
3302
|
+
return false;
|
|
3303
|
+
}
|
|
3304
|
+
try {
|
|
3305
|
+
return new URL(requestDetails.url).origin === new URL(redirectOptions.href).origin;
|
|
3306
|
+
} catch (e) {
|
|
3307
|
+
// If origin comparison fails, treat the redirect as unsafe.
|
|
3308
|
+
return false;
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
2974
3311
|
|
|
2975
3312
|
/**
|
|
2976
3313
|
* If the proxy or config afterRedirects functions are defined, call them with the options
|
|
@@ -2981,9 +3318,10 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
|
|
|
2981
3318
|
*
|
|
2982
3319
|
* @returns {http.ClientRequestArgs}
|
|
2983
3320
|
*/
|
|
2984
|
-
function setProxy(options, configProxy, location, isRedirect) {
|
|
3321
|
+
function setProxy(options, configProxy, location, isRedirect, configHttpsAgent, configHttpAgent) {
|
|
2985
3322
|
let proxy = configProxy;
|
|
2986
|
-
|
|
3323
|
+
const proxyEnvAgent = getProxyEnvAgent(options, configHttpAgent, configHttpsAgent);
|
|
3324
|
+
if (!proxy && proxy !== false && !isNodeEnvProxyEnabled(proxyEnvAgent)) {
|
|
2987
3325
|
const proxyUrl = getProxyForUrl(location);
|
|
2988
3326
|
if (proxyUrl) {
|
|
2989
3327
|
if (!shouldBypassProxy(location)) {
|
|
@@ -3002,6 +3340,13 @@ function setProxy(options, configProxy, location, isRedirect) {
|
|
|
3002
3340
|
}
|
|
3003
3341
|
}
|
|
3004
3342
|
}
|
|
3343
|
+
// Strip any tunneling agent we installed for the previous hop so a redirect
|
|
3344
|
+
// that drops the proxy or crosses an HTTPS↔HTTP boundary doesn't reuse a
|
|
3345
|
+
// stale one. Match on our Symbol marker so a user-supplied HttpsProxyAgent
|
|
3346
|
+
// (which won't carry the marker) is left alone.
|
|
3347
|
+
if (isRedirect && options.agent && options.agent[kAxiosInstalledTunnel]) {
|
|
3348
|
+
options.agent = undefined;
|
|
3349
|
+
}
|
|
3005
3350
|
if (proxy) {
|
|
3006
3351
|
// Read proxy fields without traversing the prototype chain. URL instances expose
|
|
3007
3352
|
// username/password/hostname/host/port/protocol via getters on URL.prototype (so
|
|
@@ -3034,37 +3379,84 @@ function setProxy(options, configProxy, location, isRedirect) {
|
|
|
3034
3379
|
proxy
|
|
3035
3380
|
});
|
|
3036
3381
|
}
|
|
3037
|
-
const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64');
|
|
3038
|
-
options.headers['Proxy-Authorization'] = 'Basic ' + base64;
|
|
3039
3382
|
}
|
|
3383
|
+
const targetIsHttps = isHttps.test(options.protocol);
|
|
3384
|
+
if (targetIsHttps) {
|
|
3385
|
+
// CONNECT-tunneling path for HTTPS targets. Preserves end-to-end TLS to
|
|
3386
|
+
// the origin so the proxy cannot inspect the URL, headers, or body — the
|
|
3387
|
+
// behavior already promised by THREATMODEL.md (T-R9). HttpsProxyAgent
|
|
3388
|
+
// sends Proxy-Authorization on the CONNECT request only, never on the
|
|
3389
|
+
// wrapped TLS request, which is why we don't stamp it onto
|
|
3390
|
+
// options.headers here. If the user already supplied an HttpsProxyAgent,
|
|
3391
|
+
// they own tunneling end-to-end and we leave them alone; otherwise we
|
|
3392
|
+
// install our own tunneling agent and forward their TLS options (if any)
|
|
3393
|
+
// so a custom httpsAgent for cert pinning / rejectUnauthorized still
|
|
3394
|
+
// applies to the origin TLS upgrade.
|
|
3395
|
+
if (!(configHttpsAgent instanceof HttpsProxyAgent)) {
|
|
3396
|
+
const proxyHost = readProxyField('hostname') || readProxyField('host');
|
|
3397
|
+
const proxyPort = readProxyField('port');
|
|
3398
|
+
const rawProxyProtocol = readProxyField('protocol');
|
|
3399
|
+
const normalizedProtocol = rawProxyProtocol ? rawProxyProtocol.includes(':') ? rawProxyProtocol : `${rawProxyProtocol}:` : 'http:';
|
|
3400
|
+
// Bracket IPv6 literals for URL parsing; URL.hostname strips the
|
|
3401
|
+
// brackets again on read so the agent receives the raw form.
|
|
3402
|
+
const proxyHostForURL = proxyHost && proxyHost.includes(':') && !proxyHost.startsWith('[') ? `[${proxyHost}]` : proxyHost;
|
|
3403
|
+
const proxyURL = new URL(`${normalizedProtocol}//${proxyHostForURL}${proxyPort ? ':' + proxyPort : ''}`);
|
|
3404
|
+
const agentOptions = {
|
|
3405
|
+
protocol: proxyURL.protocol,
|
|
3406
|
+
hostname: proxyURL.hostname.replace(/^\[|\]$/g, ''),
|
|
3407
|
+
port: proxyURL.port,
|
|
3408
|
+
auth: proxyAuth && typeof proxyAuth === 'string' ? proxyAuth : undefined
|
|
3409
|
+
};
|
|
3410
|
+
if (proxyURL.protocol === 'https:') {
|
|
3411
|
+
agentOptions.ALPNProtocols = ['http/1.1'];
|
|
3412
|
+
}
|
|
3413
|
+
const tunnelingAgent = getTunnelingAgent(agentOptions, configHttpsAgent);
|
|
3414
|
+
// Set both: `options.agent` is consumed by the native https.request path
|
|
3415
|
+
// (maxRedirects === 0); `options.agents.https` is consumed by
|
|
3416
|
+
// follow-redirects, which ignores `options.agent` when `options.agents`
|
|
3417
|
+
// is present.
|
|
3418
|
+
options.agent = tunnelingAgent;
|
|
3419
|
+
if (options.agents) {
|
|
3420
|
+
options.agents.https = tunnelingAgent;
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
} else {
|
|
3424
|
+
// Forward-proxy mode for plaintext HTTP targets. The request line carries
|
|
3425
|
+
// the absolute URL and the proxy sees everything — acceptable for plain
|
|
3426
|
+
// HTTP since the wire was already plaintext.
|
|
3427
|
+
if (proxyAuth) {
|
|
3428
|
+
const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64');
|
|
3429
|
+
options.headers['Proxy-Authorization'] = 'Basic ' + base64;
|
|
3430
|
+
}
|
|
3040
3431
|
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3432
|
+
// Preserve a user-supplied Host header (case-insensitive) so callers can override
|
|
3433
|
+
// the value forwarded to the proxy; otherwise default to the request URL's host.
|
|
3434
|
+
let hasUserHostHeader = false;
|
|
3435
|
+
for (const name of Object.keys(options.headers)) {
|
|
3436
|
+
if (name.toLowerCase() === 'host') {
|
|
3437
|
+
hasUserHostHeader = true;
|
|
3438
|
+
break;
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
if (!hasUserHostHeader) {
|
|
3442
|
+
options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
|
|
3443
|
+
}
|
|
3444
|
+
const proxyHost = readProxyField('hostname') || readProxyField('host');
|
|
3445
|
+
options.hostname = proxyHost;
|
|
3446
|
+
// Replace 'host' since options is not a URL object
|
|
3447
|
+
options.host = proxyHost;
|
|
3448
|
+
options.port = readProxyField('port');
|
|
3449
|
+
options.path = location;
|
|
3450
|
+
const proxyProtocol = readProxyField('protocol');
|
|
3451
|
+
if (proxyProtocol) {
|
|
3452
|
+
options.protocol = proxyProtocol.includes(':') ? proxyProtocol : `${proxyProtocol}:`;
|
|
3048
3453
|
}
|
|
3049
|
-
}
|
|
3050
|
-
if (!hasUserHostHeader) {
|
|
3051
|
-
options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
|
|
3052
|
-
}
|
|
3053
|
-
const proxyHost = readProxyField('hostname') || readProxyField('host');
|
|
3054
|
-
options.hostname = proxyHost;
|
|
3055
|
-
// Replace 'host' since options is not a URL object
|
|
3056
|
-
options.host = proxyHost;
|
|
3057
|
-
options.port = readProxyField('port');
|
|
3058
|
-
options.path = location;
|
|
3059
|
-
const proxyProtocol = readProxyField('protocol');
|
|
3060
|
-
if (proxyProtocol) {
|
|
3061
|
-
options.protocol = proxyProtocol.includes(':') ? proxyProtocol : `${proxyProtocol}:`;
|
|
3062
3454
|
}
|
|
3063
3455
|
}
|
|
3064
3456
|
options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {
|
|
3065
3457
|
// Configure proxy for redirected request, passing the original config proxy to apply
|
|
3066
3458
|
// the exact same logic as if the redirected request was performed by axios directly.
|
|
3067
|
-
setProxy(redirectOptions, configProxy, redirectOptions.href, true);
|
|
3459
|
+
setProxy(redirectOptions, configProxy, redirectOptions.href, true, configHttpsAgent, configHttpAgent);
|
|
3068
3460
|
};
|
|
3069
3461
|
}
|
|
3070
3462
|
const isHttpAdapterSupported = typeof process !== 'undefined' && utils$1.kindOf(process) === 'process';
|
|
@@ -3147,16 +3539,30 @@ const http2Transport = {
|
|
|
3147
3539
|
/*eslint consistent-return:0*/
|
|
3148
3540
|
var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
3149
3541
|
return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
|
|
3150
|
-
|
|
3542
|
+
// Read config pollution-safely: own properties and members inherited from
|
|
3543
|
+
// a non-Object.prototype source (e.g. an Object.create(defaults) template)
|
|
3544
|
+
// are honored, but values injected onto a polluted Object.prototype are
|
|
3545
|
+
// ignored. All behavior-affecting reads in this adapter go through own()
|
|
3546
|
+
// so the protection boundary stays consistent.
|
|
3547
|
+
const own = key => utils$1.getSafeProp(config, key);
|
|
3548
|
+
const transitional = own('transitional') || transitionalDefaults;
|
|
3151
3549
|
let data = own('data');
|
|
3152
3550
|
let lookup = own('lookup');
|
|
3153
3551
|
let family = own('family');
|
|
3154
3552
|
let httpVersion = own('httpVersion');
|
|
3155
3553
|
if (httpVersion === undefined) httpVersion = 1;
|
|
3156
3554
|
let http2Options = own('http2Options');
|
|
3555
|
+
const httpAgent = own('httpAgent');
|
|
3556
|
+
const httpsAgent = own('httpsAgent');
|
|
3557
|
+
const configProxy = own('proxy');
|
|
3157
3558
|
const responseType = own('responseType');
|
|
3158
3559
|
const responseEncoding = own('responseEncoding');
|
|
3159
|
-
const
|
|
3560
|
+
const socketPath = own('socketPath');
|
|
3561
|
+
const method = own('method').toUpperCase();
|
|
3562
|
+
const maxRedirects = own('maxRedirects');
|
|
3563
|
+
const maxBodyLength = own('maxBodyLength');
|
|
3564
|
+
const maxContentLength = own('maxContentLength');
|
|
3565
|
+
const decompress = own('decompress');
|
|
3160
3566
|
let isDone;
|
|
3161
3567
|
let rejected = false;
|
|
3162
3568
|
let req;
|
|
@@ -3187,7 +3593,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3187
3593
|
try {
|
|
3188
3594
|
abortEmitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
|
|
3189
3595
|
} catch (err) {
|
|
3190
|
-
|
|
3596
|
+
// ignore emit errors
|
|
3191
3597
|
}
|
|
3192
3598
|
}
|
|
3193
3599
|
function clearConnectPhaseTimer() {
|
|
@@ -3197,10 +3603,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3197
3603
|
}
|
|
3198
3604
|
}
|
|
3199
3605
|
function createTimeoutError() {
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3606
|
+
const configTimeout = own('timeout');
|
|
3607
|
+
let timeoutErrorMessage = configTimeout ? 'timeout of ' + configTimeout + 'ms exceeded' : 'timeout exceeded';
|
|
3608
|
+
const configTimeoutErrorMessage = own('timeoutErrorMessage');
|
|
3609
|
+
if (configTimeoutErrorMessage) {
|
|
3610
|
+
timeoutErrorMessage = configTimeoutErrorMessage;
|
|
3204
3611
|
}
|
|
3205
3612
|
return new AxiosError(timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, req);
|
|
3206
3613
|
}
|
|
@@ -3243,17 +3650,22 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3243
3650
|
});
|
|
3244
3651
|
|
|
3245
3652
|
// Parse url
|
|
3246
|
-
const fullPath = buildFullPath(
|
|
3247
|
-
|
|
3653
|
+
const fullPath = buildFullPath(own('baseURL'), own('url'), own('allowAbsoluteUrls'), config);
|
|
3654
|
+
// Unix-socket requests (own socketPath) commonly pass a path-only url
|
|
3655
|
+
// like '/foo'; supply a synthetic base so new URL() can still parse it.
|
|
3656
|
+
// Use the own-property value (not config.socketPath) so a polluted
|
|
3657
|
+
// prototype cannot influence URL base selection.
|
|
3658
|
+
const urlBase = socketPath ? 'http://localhost' : platform.hasBrowserEnv ? platform.origin : undefined;
|
|
3659
|
+
const parsed = new URL(fullPath, urlBase);
|
|
3248
3660
|
const protocol = parsed.protocol || supportedProtocols[0];
|
|
3249
3661
|
if (protocol === 'data:') {
|
|
3250
3662
|
// Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
|
|
3251
|
-
if (
|
|
3252
|
-
// Use the exact string passed to fromDataURI (
|
|
3253
|
-
const dataUrl = String(
|
|
3663
|
+
if (maxContentLength > -1) {
|
|
3664
|
+
// Use the exact string passed to fromDataURI (the configured url); fall back to fullPath if needed.
|
|
3665
|
+
const dataUrl = String(own('url') || fullPath || '');
|
|
3254
3666
|
const estimated = estimateDataURLDecodedBytes(dataUrl);
|
|
3255
|
-
if (estimated >
|
|
3256
|
-
return reject(new AxiosError('maxContentLength size of ' +
|
|
3667
|
+
if (estimated > maxContentLength) {
|
|
3668
|
+
return reject(new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config));
|
|
3257
3669
|
}
|
|
3258
3670
|
}
|
|
3259
3671
|
let convertedData;
|
|
@@ -3266,7 +3678,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3266
3678
|
});
|
|
3267
3679
|
}
|
|
3268
3680
|
try {
|
|
3269
|
-
convertedData = fromDataURI(
|
|
3681
|
+
convertedData = fromDataURI(own('url'), responseType === 'blob', {
|
|
3270
3682
|
Blob: config.env && config.env.Blob
|
|
3271
3683
|
});
|
|
3272
3684
|
} catch (err) {
|
|
@@ -3340,7 +3752,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3340
3752
|
|
|
3341
3753
|
// Add Content-Length header if data exists
|
|
3342
3754
|
headers.setContentLength(data.length, false);
|
|
3343
|
-
if (
|
|
3755
|
+
if (maxBodyLength > -1 && data.length > maxBodyLength) {
|
|
3344
3756
|
return reject(new AxiosError('Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config));
|
|
3345
3757
|
}
|
|
3346
3758
|
}
|
|
@@ -3367,37 +3779,36 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3367
3779
|
let auth = undefined;
|
|
3368
3780
|
const configAuth = own('auth');
|
|
3369
3781
|
if (configAuth) {
|
|
3370
|
-
const username = configAuth
|
|
3371
|
-
const password = configAuth
|
|
3782
|
+
const username = utils$1.getSafeProp(configAuth, 'username') || '';
|
|
3783
|
+
const password = utils$1.getSafeProp(configAuth, 'password') || '';
|
|
3372
3784
|
auth = username + ':' + password;
|
|
3373
3785
|
}
|
|
3374
|
-
if (!auth && parsed.username) {
|
|
3375
|
-
const urlUsername = decodeURIComponentSafe(parsed.username);
|
|
3376
|
-
const urlPassword = decodeURIComponentSafe(parsed.password);
|
|
3786
|
+
if (!auth && (parsed.username || parsed.password)) {
|
|
3787
|
+
const urlUsername = decodeURIComponentSafe$1(parsed.username);
|
|
3788
|
+
const urlPassword = decodeURIComponentSafe$1(parsed.password);
|
|
3377
3789
|
auth = urlUsername + ':' + urlPassword;
|
|
3378
3790
|
}
|
|
3379
3791
|
auth && headers.delete('authorization');
|
|
3380
3792
|
let path$1;
|
|
3381
3793
|
try {
|
|
3382
|
-
path$1 = buildURL(parsed.pathname + parsed.search,
|
|
3794
|
+
path$1 = buildURL(parsed.pathname + parsed.search, own('params'), own('paramsSerializer')).replace(/^\?/, '');
|
|
3383
3795
|
} catch (err) {
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
return reject(customErr);
|
|
3796
|
+
return reject(AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config, null, null, {
|
|
3797
|
+
url: own('url'),
|
|
3798
|
+
exists: true
|
|
3799
|
+
}));
|
|
3389
3800
|
}
|
|
3390
|
-
headers.set('Accept-Encoding',
|
|
3801
|
+
headers.set('Accept-Encoding', utils$1.hasOwnProp(transitional, 'advertiseZstdAcceptEncoding') && transitional.advertiseZstdAcceptEncoding === true ? ACCEPT_ENCODING_WITH_ZSTD : ACCEPT_ENCODING, false);
|
|
3391
3802
|
|
|
3392
3803
|
// Null-prototype to block prototype pollution gadgets on properties read
|
|
3393
3804
|
// directly by Node's http.request (e.g. insecureHTTPParser, lookup).
|
|
3394
3805
|
const options = Object.assign(Object.create(null), {
|
|
3395
3806
|
path: path$1,
|
|
3396
3807
|
method: method,
|
|
3397
|
-
headers: headers
|
|
3808
|
+
headers: toByteStringHeaderObject(headers),
|
|
3398
3809
|
agents: {
|
|
3399
|
-
http:
|
|
3400
|
-
https:
|
|
3810
|
+
http: httpAgent,
|
|
3811
|
+
https: httpsAgent
|
|
3401
3812
|
},
|
|
3402
3813
|
auth,
|
|
3403
3814
|
protocol,
|
|
@@ -3409,52 +3820,105 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3409
3820
|
|
|
3410
3821
|
// cacheable-lookup integration hotfix
|
|
3411
3822
|
!utils$1.isUndefined(lookup) && (options.lookup = lookup);
|
|
3412
|
-
if (
|
|
3413
|
-
if (typeof
|
|
3823
|
+
if (socketPath) {
|
|
3824
|
+
if (typeof socketPath !== 'string') {
|
|
3414
3825
|
return reject(new AxiosError('socketPath must be a string', AxiosError.ERR_BAD_OPTION_VALUE, config));
|
|
3415
3826
|
}
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
const
|
|
3827
|
+
const allowedSocketPaths = own('allowedSocketPaths');
|
|
3828
|
+
if (allowedSocketPaths != null) {
|
|
3829
|
+
const allowed = Array.isArray(allowedSocketPaths) ? allowedSocketPaths : [allowedSocketPaths];
|
|
3830
|
+
const resolvedSocket = path.resolve(socketPath);
|
|
3419
3831
|
const isAllowed = allowed.some(entry => typeof entry === 'string' && path.resolve(entry) === resolvedSocket);
|
|
3420
3832
|
if (!isAllowed) {
|
|
3421
|
-
return reject(new AxiosError(`socketPath "${
|
|
3833
|
+
return reject(new AxiosError(`socketPath "${socketPath}" is not permitted by allowedSocketPaths`, AxiosError.ERR_BAD_OPTION_VALUE, config));
|
|
3422
3834
|
}
|
|
3423
3835
|
}
|
|
3424
|
-
options.socketPath =
|
|
3836
|
+
options.socketPath = socketPath;
|
|
3425
3837
|
} else {
|
|
3426
3838
|
options.hostname = parsed.hostname.startsWith('[') ? parsed.hostname.slice(1, -1) : parsed.hostname;
|
|
3427
3839
|
options.port = parsed.port;
|
|
3428
|
-
setProxy(options,
|
|
3840
|
+
setProxy(options, configProxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path, false, httpsAgent, httpAgent);
|
|
3429
3841
|
}
|
|
3430
3842
|
let transport;
|
|
3431
3843
|
let isNativeTransport = false;
|
|
3844
|
+
// True only for the follow-redirects transport, which applies
|
|
3845
|
+
// options.maxBodyLength itself. Every other transport (http2, native
|
|
3846
|
+
// http/https, a user-supplied custom transport) needs the explicit
|
|
3847
|
+
// byte-counting pipeline below to enforce maxBodyLength on streamed uploads.
|
|
3848
|
+
let transportEnforcesMaxBodyLength = false;
|
|
3432
3849
|
const isHttpsRequest = isHttps.test(options.protocol);
|
|
3433
|
-
|
|
3850
|
+
// Don't clobber a CONNECT-tunneling agent installed by setProxy() for an
|
|
3851
|
+
// HTTPS target.
|
|
3852
|
+
if (options.agent == null) {
|
|
3853
|
+
options.agent = isHttpsRequest ? httpsAgent : httpAgent;
|
|
3854
|
+
}
|
|
3434
3855
|
if (isHttp2) {
|
|
3435
3856
|
transport = http2Transport;
|
|
3436
3857
|
} else {
|
|
3437
3858
|
const configTransport = own('transport');
|
|
3438
3859
|
if (configTransport) {
|
|
3439
3860
|
transport = configTransport;
|
|
3440
|
-
} else if (
|
|
3861
|
+
} else if (maxRedirects === 0) {
|
|
3441
3862
|
transport = isHttpsRequest ? https : http;
|
|
3442
3863
|
isNativeTransport = true;
|
|
3443
3864
|
} else {
|
|
3444
|
-
|
|
3445
|
-
|
|
3865
|
+
transportEnforcesMaxBodyLength = true;
|
|
3866
|
+
options.sensitiveHeaders = [];
|
|
3867
|
+
if (maxRedirects) {
|
|
3868
|
+
options.maxRedirects = maxRedirects;
|
|
3446
3869
|
}
|
|
3447
3870
|
const configBeforeRedirect = own('beforeRedirect');
|
|
3448
3871
|
if (configBeforeRedirect) {
|
|
3449
3872
|
options.beforeRedirects.config = configBeforeRedirect;
|
|
3450
3873
|
}
|
|
3874
|
+
if (auth) {
|
|
3875
|
+
// Restore HTTP Basic credentials on same-origin redirects only.
|
|
3876
|
+
// follow-redirects >= 1.15.8 strips Authorization on every redirect (see #6929);
|
|
3877
|
+
// cross-origin stripping is the documented mitigation for T-R2 in THREATMODEL.md
|
|
3878
|
+
// and is preserved by deliberately not restoring on origin change.
|
|
3879
|
+
const requestOrigin = parsed.origin;
|
|
3880
|
+
const authToRestore = auth;
|
|
3881
|
+
options.beforeRedirects.auth = function beforeRedirectAuth(redirectOptions) {
|
|
3882
|
+
try {
|
|
3883
|
+
if (new URL(redirectOptions.href).origin === requestOrigin) {
|
|
3884
|
+
redirectOptions.auth = authToRestore;
|
|
3885
|
+
}
|
|
3886
|
+
} catch (e) {
|
|
3887
|
+
// ignore malformed URL: leaving auth stripped is fail-safe
|
|
3888
|
+
}
|
|
3889
|
+
};
|
|
3890
|
+
}
|
|
3891
|
+
const sensitiveHeaders = own('sensitiveHeaders');
|
|
3892
|
+
if (sensitiveHeaders != null) {
|
|
3893
|
+
if (!utils$1.isArray(sensitiveHeaders)) {
|
|
3894
|
+
return reject(new AxiosError('sensitiveHeaders must be an array of strings', AxiosError.ERR_BAD_OPTION_VALUE, config));
|
|
3895
|
+
}
|
|
3896
|
+
const sensitiveSet = new Set();
|
|
3897
|
+
for (const header of sensitiveHeaders) {
|
|
3898
|
+
if (!utils$1.isString(header)) {
|
|
3899
|
+
return reject(new AxiosError('sensitiveHeaders must be an array of strings', AxiosError.ERR_BAD_OPTION_VALUE, config));
|
|
3900
|
+
}
|
|
3901
|
+
sensitiveSet.add(header.toLowerCase());
|
|
3902
|
+
}
|
|
3903
|
+
if (sensitiveSet.size) {
|
|
3904
|
+
options.sensitiveHeaders = Array.from(sensitiveSet);
|
|
3905
|
+
options.beforeRedirects.sensitiveHeaders = function beforeRedirectSensitiveHeaders(redirectOptions, requestDetails) {
|
|
3906
|
+
if (!isSameOriginRedirect(redirectOptions, requestDetails)) {
|
|
3907
|
+
stripMatchingHeaders(redirectOptions.headers, sensitiveSet);
|
|
3908
|
+
}
|
|
3909
|
+
};
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3451
3912
|
transport = isHttpsRequest ? httpsFollow : httpFollow;
|
|
3452
3913
|
}
|
|
3453
3914
|
}
|
|
3454
|
-
|
|
3455
|
-
|
|
3915
|
+
|
|
3916
|
+
// Set an explicit maxBodyLength option for transports that inspect it.
|
|
3917
|
+
// When maxBodyLength is -1 (default/unlimited), use Infinity so
|
|
3918
|
+
// follow-redirects does not fall back to its own 10MB default.
|
|
3919
|
+
if (maxBodyLength > -1) {
|
|
3920
|
+
options.maxBodyLength = maxBodyLength;
|
|
3456
3921
|
} else {
|
|
3457
|
-
// follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
|
|
3458
3922
|
options.maxBodyLength = Infinity;
|
|
3459
3923
|
}
|
|
3460
3924
|
|
|
@@ -3484,7 +3948,7 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3484
3948
|
const lastRequest = res.req || req;
|
|
3485
3949
|
|
|
3486
3950
|
// if decompress disabled we should not decompress
|
|
3487
|
-
if (
|
|
3951
|
+
if (decompress !== false && res.headers['content-encoding']) {
|
|
3488
3952
|
// if no content, but headers still say that it is encoded,
|
|
3489
3953
|
// remove the header not confuse downstream operations
|
|
3490
3954
|
if (method === 'HEAD' || res.statusCode === 204) {
|
|
@@ -3516,6 +3980,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3516
3980
|
streams.push(zlib.createBrotliDecompress(brotliOptions));
|
|
3517
3981
|
delete res.headers['content-encoding'];
|
|
3518
3982
|
}
|
|
3983
|
+
break;
|
|
3984
|
+
case 'zstd':
|
|
3985
|
+
if (isZstdSupported) {
|
|
3986
|
+
streams.push(zlib.createZstdDecompress(zstdOptions));
|
|
3987
|
+
delete res.headers['content-encoding'];
|
|
3988
|
+
}
|
|
3989
|
+
break;
|
|
3519
3990
|
}
|
|
3520
3991
|
}
|
|
3521
3992
|
responseStream = streams.length > 1 ? stream.pipeline(streams, utils$1.noop) : streams[0];
|
|
@@ -3529,8 +4000,8 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3529
4000
|
if (responseType === 'stream') {
|
|
3530
4001
|
// Enforce maxContentLength on streamed responses; previously this
|
|
3531
4002
|
// was applied only to buffered responses.
|
|
3532
|
-
if (
|
|
3533
|
-
const limit =
|
|
4003
|
+
if (maxContentLength > -1) {
|
|
4004
|
+
const limit = maxContentLength;
|
|
3534
4005
|
const source = responseStream;
|
|
3535
4006
|
async function* enforceMaxContentLength() {
|
|
3536
4007
|
let totalResponseBytes = 0;
|
|
@@ -3556,11 +4027,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3556
4027
|
totalResponseBytes += chunk.length;
|
|
3557
4028
|
|
|
3558
4029
|
// make sure the content length is not over the maxContentLength if specified
|
|
3559
|
-
if (
|
|
4030
|
+
if (maxContentLength > -1 && totalResponseBytes > maxContentLength) {
|
|
3560
4031
|
// stream.destroy() emit aborted event before calling reject() on Node.js v16
|
|
3561
4032
|
rejected = true;
|
|
3562
4033
|
responseStream.destroy();
|
|
3563
|
-
abort(new AxiosError('maxContentLength size of ' +
|
|
4034
|
+
abort(new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
|
|
3564
4035
|
}
|
|
3565
4036
|
});
|
|
3566
4037
|
responseStream.on('aborted', function handlerStreamAborted() {
|
|
@@ -3623,7 +4094,11 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3623
4094
|
const boundSockets = new Set();
|
|
3624
4095
|
req.on('socket', function handleRequestSocket(socket) {
|
|
3625
4096
|
// default interval of sending ack packet is 1 minute
|
|
3626
|
-
|
|
4097
|
+
// proxy agents (e.g. agent-base) may return a generic Duplex stream
|
|
4098
|
+
// that doesn't have setKeepAlive, so guard before calling
|
|
4099
|
+
if (typeof socket.setKeepAlive === 'function') {
|
|
4100
|
+
socket.setKeepAlive(true, 1000 * 60);
|
|
4101
|
+
}
|
|
3627
4102
|
|
|
3628
4103
|
// Install a single 'error' listener per socket (not per request) to avoid
|
|
3629
4104
|
// accumulating listeners on pooled keep-alive sockets that get reassigned
|
|
@@ -3653,9 +4128,9 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3653
4128
|
});
|
|
3654
4129
|
|
|
3655
4130
|
// Handle request timeout
|
|
3656
|
-
if (
|
|
4131
|
+
if (own('timeout')) {
|
|
3657
4132
|
// This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
|
|
3658
|
-
const timeout = parseInt(
|
|
4133
|
+
const timeout = parseInt(own('timeout'), 10);
|
|
3659
4134
|
if (Number.isNaN(timeout)) {
|
|
3660
4135
|
abort(new AxiosError('error trying to parse `config.timeout` to int', AxiosError.ERR_BAD_OPTION_VALUE, config, req));
|
|
3661
4136
|
return;
|
|
@@ -3699,12 +4174,13 @@ var httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
3699
4174
|
}
|
|
3700
4175
|
});
|
|
3701
4176
|
|
|
3702
|
-
// Enforce maxBodyLength for streamed uploads on
|
|
3703
|
-
//
|
|
3704
|
-
//
|
|
4177
|
+
// Enforce maxBodyLength for streamed uploads on every transport that
|
|
4178
|
+
// does not apply options.maxBodyLength itself (native http/https, http2,
|
|
4179
|
+
// and user-supplied custom transports). The follow-redirects transport
|
|
4180
|
+
// enforces it on the redirected HTTP/1 path.
|
|
3705
4181
|
let uploadStream = data;
|
|
3706
|
-
if (
|
|
3707
|
-
const limit =
|
|
4182
|
+
if (maxBodyLength > -1 && !transportEnforcesMaxBodyLength) {
|
|
4183
|
+
const limit = maxBodyLength;
|
|
3708
4184
|
let bytesSent = 0;
|
|
3709
4185
|
uploadStream = stream.pipeline([data, new stream.Transform({
|
|
3710
4186
|
transform(chunk, _enc, cb) {
|
|
@@ -3767,7 +4243,11 @@ var cookies = platform.hasStandardBrowserEnv ?
|
|
|
3767
4243
|
const cookie = cookies[i].replace(/^\s+/, '');
|
|
3768
4244
|
const eq = cookie.indexOf('=');
|
|
3769
4245
|
if (eq !== -1 && cookie.slice(0, eq) === name) {
|
|
3770
|
-
|
|
4246
|
+
try {
|
|
4247
|
+
return decodeURIComponent(cookie.slice(eq + 1));
|
|
4248
|
+
} catch (e) {
|
|
4249
|
+
return cookie.slice(eq + 1);
|
|
4250
|
+
}
|
|
3771
4251
|
}
|
|
3772
4252
|
}
|
|
3773
4253
|
return null;
|
|
@@ -3800,6 +4280,7 @@ const headersToObject = thing => thing instanceof AxiosHeaders ? {
|
|
|
3800
4280
|
*/
|
|
3801
4281
|
function mergeConfig(config1, config2) {
|
|
3802
4282
|
// eslint-disable-next-line no-param-reassign
|
|
4283
|
+
config1 = config1 || {};
|
|
3803
4284
|
config2 = config2 || {};
|
|
3804
4285
|
|
|
3805
4286
|
// Use a null-prototype object so that downstream reads such as `config.auth`
|
|
@@ -3851,6 +4332,23 @@ function mergeConfig(config1, config2) {
|
|
|
3851
4332
|
return getMergedValue(undefined, a);
|
|
3852
4333
|
}
|
|
3853
4334
|
}
|
|
4335
|
+
function getMergedTransitionalOption(prop) {
|
|
4336
|
+
const transitional2 = utils$1.hasOwnProp(config2, 'transitional') ? config2.transitional : undefined;
|
|
4337
|
+
if (!utils$1.isUndefined(transitional2)) {
|
|
4338
|
+
if (utils$1.isPlainObject(transitional2)) {
|
|
4339
|
+
if (utils$1.hasOwnProp(transitional2, prop)) {
|
|
4340
|
+
return transitional2[prop];
|
|
4341
|
+
}
|
|
4342
|
+
} else {
|
|
4343
|
+
return undefined;
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
const transitional1 = utils$1.hasOwnProp(config1, 'transitional') ? config1.transitional : undefined;
|
|
4347
|
+
if (utils$1.isPlainObject(transitional1) && utils$1.hasOwnProp(transitional1, prop)) {
|
|
4348
|
+
return transitional1[prop];
|
|
4349
|
+
}
|
|
4350
|
+
return undefined;
|
|
4351
|
+
}
|
|
3854
4352
|
|
|
3855
4353
|
// eslint-disable-next-line consistent-return
|
|
3856
4354
|
function mergeDirectKeys(a, b, prop) {
|
|
@@ -3903,6 +4401,13 @@ function mergeConfig(config1, config2) {
|
|
|
3903
4401
|
const configValue = merge(a, b, prop);
|
|
3904
4402
|
utils$1.isUndefined(configValue) && merge !== mergeDirectKeys || (config[prop] = configValue);
|
|
3905
4403
|
});
|
|
4404
|
+
if (utils$1.hasOwnProp(config2, 'validateStatus') && utils$1.isUndefined(config2.validateStatus) && getMergedTransitionalOption('validateStatusUndefinedResolves') === false) {
|
|
4405
|
+
if (utils$1.hasOwnProp(config1, 'validateStatus')) {
|
|
4406
|
+
config.validateStatus = getMergedValue(undefined, config1.validateStatus);
|
|
4407
|
+
} else {
|
|
4408
|
+
delete config.validateStatus;
|
|
4409
|
+
}
|
|
4410
|
+
}
|
|
3906
4411
|
return config;
|
|
3907
4412
|
}
|
|
3908
4413
|
|
|
@@ -3912,7 +4417,7 @@ function setFormDataHeaders(headers, formHeaders, policy) {
|
|
|
3912
4417
|
headers.set(formHeaders);
|
|
3913
4418
|
return;
|
|
3914
4419
|
}
|
|
3915
|
-
Object.entries(formHeaders).forEach(([key, val]) => {
|
|
4420
|
+
Object.entries(formHeaders || {}).forEach(([key, val]) => {
|
|
3916
4421
|
if (FORM_DATA_CONTENT_HEADERS.includes(key.toLowerCase())) {
|
|
3917
4422
|
headers.set(key, val);
|
|
3918
4423
|
}
|
|
@@ -3927,8 +4432,8 @@ function setFormDataHeaders(headers, formHeaders, policy) {
|
|
|
3927
4432
|
*
|
|
3928
4433
|
* @returns {string} UTF-8 bytes as a Latin-1 string
|
|
3929
4434
|
*/
|
|
3930
|
-
const encodeUTF8 = str => encodeURIComponent(str).replace(/%([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
3931
|
-
|
|
4435
|
+
const encodeUTF8$1 = str => encodeURIComponent(str).replace(/%([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
4436
|
+
function resolveConfig(config) {
|
|
3932
4437
|
const newConfig = mergeConfig({}, config);
|
|
3933
4438
|
|
|
3934
4439
|
// Read only own properties to prevent prototype pollution gadgets
|
|
@@ -3944,15 +4449,21 @@ var resolveConfig = config => {
|
|
|
3944
4449
|
const allowAbsoluteUrls = own('allowAbsoluteUrls');
|
|
3945
4450
|
const url = own('url');
|
|
3946
4451
|
newConfig.headers = headers = AxiosHeaders.from(headers);
|
|
3947
|
-
newConfig.url = buildURL(buildFullPath(baseURL, url, allowAbsoluteUrls),
|
|
4452
|
+
newConfig.url = buildURL(buildFullPath(baseURL, url, allowAbsoluteUrls, newConfig), own('params'), own('paramsSerializer'));
|
|
3948
4453
|
|
|
3949
4454
|
// HTTP basic authentication
|
|
3950
4455
|
if (auth) {
|
|
3951
|
-
|
|
4456
|
+
const username = utils$1.getSafeProp(auth, 'username') || '';
|
|
4457
|
+
const password = utils$1.getSafeProp(auth, 'password') || '';
|
|
4458
|
+
try {
|
|
4459
|
+
headers.set('Authorization', 'Basic ' + btoa(username + ':' + (password ? encodeUTF8$1(password) : '')));
|
|
4460
|
+
} catch (e) {
|
|
4461
|
+
throw AxiosError.from(e, AxiosError.ERR_BAD_OPTION_VALUE, config);
|
|
4462
|
+
}
|
|
3952
4463
|
}
|
|
3953
4464
|
if (utils$1.isFormData(data)) {
|
|
3954
|
-
if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {
|
|
3955
|
-
headers.setContentType(undefined); // browser handles it
|
|
4465
|
+
if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv || utils$1.isReactNative(data)) {
|
|
4466
|
+
headers.setContentType(undefined); // browser/web worker/RN handles it
|
|
3956
4467
|
} else if (utils$1.isFunction(data.getHeaders)) {
|
|
3957
4468
|
// Node.js FormData (like form-data package)
|
|
3958
4469
|
setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
|
|
@@ -3980,7 +4491,7 @@ var resolveConfig = config => {
|
|
|
3980
4491
|
}
|
|
3981
4492
|
}
|
|
3982
4493
|
return newConfig;
|
|
3983
|
-
}
|
|
4494
|
+
}
|
|
3984
4495
|
|
|
3985
4496
|
const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';
|
|
3986
4497
|
var xhrAdapter = isXHRAdapterSupported && function (config) {
|
|
@@ -4102,7 +4613,7 @@ var xhrAdapter = isXHRAdapterSupported && function (config) {
|
|
|
4102
4613
|
|
|
4103
4614
|
// Add headers to the request
|
|
4104
4615
|
if ('setRequestHeader' in request) {
|
|
4105
|
-
utils$1.forEach(requestHeaders
|
|
4616
|
+
utils$1.forEach(toByteStringHeaderObject(requestHeaders), function setRequestHeader(val, key) {
|
|
4106
4617
|
request.setRequestHeader(key, val);
|
|
4107
4618
|
});
|
|
4108
4619
|
}
|
|
@@ -4149,6 +4660,7 @@ var xhrAdapter = isXHRAdapterSupported && function (config) {
|
|
|
4149
4660
|
const protocol = parseProtocol(_config.url);
|
|
4150
4661
|
if (protocol && !platform.protocols.includes(protocol)) {
|
|
4151
4662
|
reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));
|
|
4663
|
+
done();
|
|
4152
4664
|
return;
|
|
4153
4665
|
}
|
|
4154
4666
|
|
|
@@ -4158,41 +4670,43 @@ var xhrAdapter = isXHRAdapterSupported && function (config) {
|
|
|
4158
4670
|
};
|
|
4159
4671
|
|
|
4160
4672
|
const composeSignals = (signals, timeout) => {
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
if (timeout || length) {
|
|
4165
|
-
let controller = new AbortController();
|
|
4166
|
-
let aborted;
|
|
4167
|
-
const onabort = function (reason) {
|
|
4168
|
-
if (!aborted) {
|
|
4169
|
-
aborted = true;
|
|
4170
|
-
unsubscribe();
|
|
4171
|
-
const err = reason instanceof Error ? reason : this.reason;
|
|
4172
|
-
controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
|
|
4173
|
-
}
|
|
4174
|
-
};
|
|
4175
|
-
let timer = timeout && setTimeout(() => {
|
|
4176
|
-
timer = null;
|
|
4177
|
-
onabort(new AxiosError(`timeout of ${timeout}ms exceeded`, AxiosError.ETIMEDOUT));
|
|
4178
|
-
}, timeout);
|
|
4179
|
-
const unsubscribe = () => {
|
|
4180
|
-
if (signals) {
|
|
4181
|
-
timer && clearTimeout(timer);
|
|
4182
|
-
timer = null;
|
|
4183
|
-
signals.forEach(signal => {
|
|
4184
|
-
signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);
|
|
4185
|
-
});
|
|
4186
|
-
signals = null;
|
|
4187
|
-
}
|
|
4188
|
-
};
|
|
4189
|
-
signals.forEach(signal => signal.addEventListener('abort', onabort));
|
|
4190
|
-
const {
|
|
4191
|
-
signal
|
|
4192
|
-
} = controller;
|
|
4193
|
-
signal.unsubscribe = () => utils$1.asap(unsubscribe);
|
|
4194
|
-
return signal;
|
|
4673
|
+
signals = signals ? signals.filter(Boolean) : [];
|
|
4674
|
+
if (!timeout && !signals.length) {
|
|
4675
|
+
return;
|
|
4195
4676
|
}
|
|
4677
|
+
const controller = new AbortController();
|
|
4678
|
+
let aborted = false;
|
|
4679
|
+
const onabort = function (reason) {
|
|
4680
|
+
if (!aborted) {
|
|
4681
|
+
aborted = true;
|
|
4682
|
+
unsubscribe();
|
|
4683
|
+
const err = reason instanceof Error ? reason : this.reason;
|
|
4684
|
+
controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
|
|
4685
|
+
}
|
|
4686
|
+
};
|
|
4687
|
+
let timer = timeout && setTimeout(() => {
|
|
4688
|
+
timer = null;
|
|
4689
|
+
onabort(new AxiosError(`timeout of ${timeout}ms exceeded`, AxiosError.ETIMEDOUT));
|
|
4690
|
+
}, timeout);
|
|
4691
|
+
const unsubscribe = () => {
|
|
4692
|
+
if (!signals) {
|
|
4693
|
+
return;
|
|
4694
|
+
}
|
|
4695
|
+
timer && clearTimeout(timer);
|
|
4696
|
+
timer = null;
|
|
4697
|
+
signals.forEach(signal => {
|
|
4698
|
+
signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);
|
|
4699
|
+
});
|
|
4700
|
+
signals = null;
|
|
4701
|
+
};
|
|
4702
|
+
signals.forEach(signal => signal.addEventListener('abort', onabort, {
|
|
4703
|
+
once: true
|
|
4704
|
+
}));
|
|
4705
|
+
const {
|
|
4706
|
+
signal
|
|
4707
|
+
} = controller;
|
|
4708
|
+
signal.unsubscribe = () => utils$1.asap(unsubscribe);
|
|
4709
|
+
return signal;
|
|
4196
4710
|
};
|
|
4197
4711
|
|
|
4198
4712
|
const streamChunk = function* (chunk, chunkSize) {
|
|
@@ -4281,6 +4795,31 @@ const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
|
4281
4795
|
const {
|
|
4282
4796
|
isFunction
|
|
4283
4797
|
} = utils$1;
|
|
4798
|
+
|
|
4799
|
+
/**
|
|
4800
|
+
* Encode a UTF-8 string to a Latin-1 byte string for use with btoa().
|
|
4801
|
+
* This is a modern replacement for the deprecated unescape(encodeURIComponent(str)) pattern.
|
|
4802
|
+
*
|
|
4803
|
+
* @param {string} str The string to encode
|
|
4804
|
+
*
|
|
4805
|
+
* @returns {string} UTF-8 bytes as a Latin-1 string
|
|
4806
|
+
*/
|
|
4807
|
+
const encodeUTF8 = str => encodeURIComponent(str).replace(/%([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
4808
|
+
|
|
4809
|
+
// Node's WHATWG URL parser returns `username` and `password` percent-encoded.
|
|
4810
|
+
// Decode before composing the `auth` option so credentials such as
|
|
4811
|
+
// `my%40email.com:pass` are sent as `my@email.com:pass`. Falls back to the
|
|
4812
|
+
// original value for malformed input so a bad encoding never throws.
|
|
4813
|
+
const decodeURIComponentSafe = value => {
|
|
4814
|
+
if (!utils$1.isString(value)) {
|
|
4815
|
+
return value;
|
|
4816
|
+
}
|
|
4817
|
+
try {
|
|
4818
|
+
return decodeURIComponent(value);
|
|
4819
|
+
} catch (error) {
|
|
4820
|
+
return value;
|
|
4821
|
+
}
|
|
4822
|
+
};
|
|
4284
4823
|
const test = (fn, ...args) => {
|
|
4285
4824
|
try {
|
|
4286
4825
|
return !!fn(...args);
|
|
@@ -4288,9 +4827,16 @@ const test = (fn, ...args) => {
|
|
|
4288
4827
|
return false;
|
|
4289
4828
|
}
|
|
4290
4829
|
};
|
|
4830
|
+
const maybeWithAuthCredentials = url => {
|
|
4831
|
+
const protocolIndex = url.indexOf('://');
|
|
4832
|
+
let urlToCheck = url;
|
|
4833
|
+
if (protocolIndex !== -1) {
|
|
4834
|
+
urlToCheck = urlToCheck.slice(protocolIndex + 3);
|
|
4835
|
+
}
|
|
4836
|
+
return urlToCheck.includes('@') || urlToCheck.includes(':');
|
|
4837
|
+
};
|
|
4291
4838
|
const factory = env => {
|
|
4292
|
-
|
|
4293
|
-
const globalObject = (_utils$global = utils$1.global) !== null && _utils$global !== void 0 ? _utils$global : globalThis;
|
|
4839
|
+
const globalObject = utils$1.global !== undefined && utils$1.global !== null ? utils$1.global : globalThis;
|
|
4294
4840
|
const {
|
|
4295
4841
|
ReadableStream,
|
|
4296
4842
|
TextEncoder
|
|
@@ -4392,6 +4938,7 @@ const factory = env => {
|
|
|
4392
4938
|
} = resolveConfig(config);
|
|
4393
4939
|
const hasMaxContentLength = utils$1.isNumber(maxContentLength) && maxContentLength > -1;
|
|
4394
4940
|
const hasMaxBodyLength = utils$1.isNumber(maxBodyLength) && maxBodyLength > -1;
|
|
4941
|
+
const own = key => utils$1.hasOwnProp(config, key) ? config[key] : undefined;
|
|
4395
4942
|
let _fetch = envFetch || fetch;
|
|
4396
4943
|
responseType = responseType ? (responseType + '').toLowerCase() : 'text';
|
|
4397
4944
|
let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
|
|
@@ -4400,7 +4947,46 @@ const factory = env => {
|
|
|
4400
4947
|
composedSignal.unsubscribe();
|
|
4401
4948
|
});
|
|
4402
4949
|
let requestContentLength;
|
|
4950
|
+
|
|
4951
|
+
// AxiosError we raise while the request body is being streamed. Captured
|
|
4952
|
+
// by identity so the catch block can surface it directly, regardless of
|
|
4953
|
+
// how the runtime wraps the resulting fetch rejection (undici exposes it
|
|
4954
|
+
// as `err.cause`; some browsers drop the original error entirely).
|
|
4955
|
+
let pendingBodyError = null;
|
|
4956
|
+
const maxBodyLengthError = () => new AxiosError('Request body larger than maxBodyLength limit', AxiosError.ERR_BAD_REQUEST, config, request);
|
|
4403
4957
|
try {
|
|
4958
|
+
// HTTP basic authentication
|
|
4959
|
+
let auth = undefined;
|
|
4960
|
+
const configAuth = own('auth');
|
|
4961
|
+
if (configAuth) {
|
|
4962
|
+
const username = utils$1.getSafeProp(configAuth, 'username') || '';
|
|
4963
|
+
const password = utils$1.getSafeProp(configAuth, 'password') || '';
|
|
4964
|
+
auth = {
|
|
4965
|
+
username,
|
|
4966
|
+
password
|
|
4967
|
+
};
|
|
4968
|
+
}
|
|
4969
|
+
if (maybeWithAuthCredentials(url)) {
|
|
4970
|
+
const parsedURL = new URL(url, platform.origin);
|
|
4971
|
+
if (!auth && (parsedURL.username || parsedURL.password)) {
|
|
4972
|
+
const urlUsername = decodeURIComponentSafe(parsedURL.username);
|
|
4973
|
+
const urlPassword = decodeURIComponentSafe(parsedURL.password);
|
|
4974
|
+
auth = {
|
|
4975
|
+
username: urlUsername,
|
|
4976
|
+
password: urlPassword
|
|
4977
|
+
};
|
|
4978
|
+
}
|
|
4979
|
+
if (parsedURL.username || parsedURL.password) {
|
|
4980
|
+
parsedURL.username = '';
|
|
4981
|
+
parsedURL.password = '';
|
|
4982
|
+
url = parsedURL.href;
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
if (auth) {
|
|
4986
|
+
headers.delete('authorization');
|
|
4987
|
+
headers.set('Authorization', 'Basic ' + btoa(encodeUTF8((auth.username || '') + ':' + (auth.password || ''))));
|
|
4988
|
+
}
|
|
4989
|
+
|
|
4404
4990
|
// Enforce maxContentLength for data: URLs up-front so we never materialize
|
|
4405
4991
|
// an oversized payload. The HTTP adapter applies the same check (see http.js
|
|
4406
4992
|
// "if (protocol === 'data:')" branch).
|
|
@@ -4411,30 +4997,54 @@ const factory = env => {
|
|
|
4411
4997
|
}
|
|
4412
4998
|
}
|
|
4413
4999
|
|
|
4414
|
-
// Enforce maxBodyLength against
|
|
4415
|
-
//
|
|
4416
|
-
//
|
|
4417
|
-
//
|
|
5000
|
+
// Enforce maxBodyLength against known-size bodies before dispatch using
|
|
5001
|
+
// the body's *actual* size — never a caller-declared Content-Length,
|
|
5002
|
+
// which could under-report to slip an oversized body past the check.
|
|
5003
|
+
// Unknown-size streams return undefined here and are counted per-chunk
|
|
5004
|
+
// below as fetch consumes them.
|
|
4418
5005
|
if (hasMaxBodyLength && method !== 'get' && method !== 'head') {
|
|
4419
|
-
const outboundLength = await
|
|
4420
|
-
if (typeof outboundLength === 'number' && isFinite(outboundLength)
|
|
4421
|
-
|
|
5006
|
+
const outboundLength = await getBodyLength(data);
|
|
5007
|
+
if (typeof outboundLength === 'number' && isFinite(outboundLength)) {
|
|
5008
|
+
requestContentLength = outboundLength;
|
|
5009
|
+
if (outboundLength > maxBodyLength) {
|
|
5010
|
+
throw maxBodyLengthError();
|
|
5011
|
+
}
|
|
4422
5012
|
}
|
|
4423
5013
|
}
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
|
|
4432
|
-
headers.setContentType(contentTypeHeader);
|
|
5014
|
+
|
|
5015
|
+
// A streamed body under maxBodyLength must be counted as fetch consumes
|
|
5016
|
+
// it; its size is never trusted from a caller-declared Content-Length.
|
|
5017
|
+
const mustEnforceStreamBody = hasMaxBodyLength && (utils$1.isReadableStream(data) || utils$1.isStream(data));
|
|
5018
|
+
const trackRequestStream = (stream, onProgress, flush) => trackStream(stream, DEFAULT_CHUNK_SIZE, loadedBytes => {
|
|
5019
|
+
if (hasMaxBodyLength && loadedBytes > maxBodyLength) {
|
|
5020
|
+
throw pendingBodyError = maxBodyLengthError();
|
|
4433
5021
|
}
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
5022
|
+
onProgress && onProgress(loadedBytes);
|
|
5023
|
+
}, flush);
|
|
5024
|
+
if (supportsRequestStream && method !== 'get' && method !== 'head' && (onUploadProgress || mustEnforceStreamBody)) {
|
|
5025
|
+
requestContentLength = requestContentLength == null ? await resolveBodyLength(headers, data) : requestContentLength;
|
|
5026
|
+
|
|
5027
|
+
// A declared length of 0 is only trusted to skip the wrap when we are
|
|
5028
|
+
// not enforcing a stream limit (which must not rely on that header).
|
|
5029
|
+
if (requestContentLength !== 0 || mustEnforceStreamBody) {
|
|
5030
|
+
let _request = new Request(url, {
|
|
5031
|
+
method: 'POST',
|
|
5032
|
+
body: data,
|
|
5033
|
+
duplex: 'half'
|
|
5034
|
+
});
|
|
5035
|
+
let contentTypeHeader;
|
|
5036
|
+
if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
|
|
5037
|
+
headers.setContentType(contentTypeHeader);
|
|
5038
|
+
}
|
|
5039
|
+
if (_request.body) {
|
|
5040
|
+
const [onProgress, flush] = onUploadProgress && progressEventDecorator(requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress))) || [];
|
|
5041
|
+
data = trackRequestStream(_request.body, onProgress, flush);
|
|
5042
|
+
}
|
|
4437
5043
|
}
|
|
5044
|
+
} else if (mustEnforceStreamBody && !isRequestSupported && isReadableStreamSupported && method !== 'get' && method !== 'head') {
|
|
5045
|
+
data = trackRequestStream(data);
|
|
5046
|
+
} else if (mustEnforceStreamBody && isRequestSupported && !supportsRequestStream && method !== 'get' && method !== 'head') {
|
|
5047
|
+
throw new AxiosError('Stream request bodies are not supported by the current fetch implementation', AxiosError.ERR_NOT_SUPPORT, config, request);
|
|
4438
5048
|
}
|
|
4439
5049
|
if (!utils$1.isString(withCredentials)) {
|
|
4440
5050
|
withCredentials = withCredentials ? 'include' : 'omit';
|
|
@@ -4459,18 +5069,19 @@ const factory = env => {
|
|
|
4459
5069
|
...fetchOptions,
|
|
4460
5070
|
signal: composedSignal,
|
|
4461
5071
|
method: method.toUpperCase(),
|
|
4462
|
-
headers: headers.normalize()
|
|
5072
|
+
headers: toByteStringHeaderObject(headers.normalize()),
|
|
4463
5073
|
body: data,
|
|
4464
5074
|
duplex: 'half',
|
|
4465
5075
|
credentials: isCredentialsSupported ? withCredentials : undefined
|
|
4466
5076
|
};
|
|
4467
5077
|
request = isRequestSupported && new Request(url, resolvedOptions);
|
|
4468
5078
|
let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));
|
|
5079
|
+
const responseHeaders = AxiosHeaders.from(response.headers);
|
|
4469
5080
|
|
|
4470
5081
|
// Cheap pre-check: if the server honestly declares a content-length that
|
|
4471
5082
|
// already exceeds the cap, reject before we start streaming.
|
|
4472
5083
|
if (hasMaxContentLength) {
|
|
4473
|
-
const declaredLength = utils$1.toFiniteNumber(
|
|
5084
|
+
const declaredLength = utils$1.toFiniteNumber(responseHeaders.getContentLength());
|
|
4474
5085
|
if (declaredLength != null && declaredLength > maxContentLength) {
|
|
4475
5086
|
throw new AxiosError('maxContentLength size of ' + maxContentLength + ' exceeded', AxiosError.ERR_BAD_RESPONSE, config, request);
|
|
4476
5087
|
}
|
|
@@ -4481,7 +5092,7 @@ const factory = env => {
|
|
|
4481
5092
|
['status', 'statusText', 'headers'].forEach(prop => {
|
|
4482
5093
|
options[prop] = response[prop];
|
|
4483
5094
|
});
|
|
4484
|
-
const responseContentLength = utils$1.toFiniteNumber(
|
|
5095
|
+
const responseContentLength = utils$1.toFiniteNumber(responseHeaders.getContentLength());
|
|
4485
5096
|
const [onProgress, flush] = onDownloadProgress && progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true)) || [];
|
|
4486
5097
|
let bytesRead = 0;
|
|
4487
5098
|
const onChunkProgress = loadedBytes => {
|
|
@@ -4540,13 +5151,48 @@ const factory = env => {
|
|
|
4540
5151
|
const canceledError = composedSignal.reason;
|
|
4541
5152
|
canceledError.config = config;
|
|
4542
5153
|
request && (canceledError.request = request);
|
|
4543
|
-
err !== canceledError
|
|
5154
|
+
if (err !== canceledError) {
|
|
5155
|
+
// Non-enumerable to match native Error `cause` semantics so loggers
|
|
5156
|
+
// don't recurse into circular fetch internals (see #7205).
|
|
5157
|
+
Object.defineProperty(canceledError, 'cause', {
|
|
5158
|
+
__proto__: null,
|
|
5159
|
+
value: err,
|
|
5160
|
+
writable: true,
|
|
5161
|
+
enumerable: false,
|
|
5162
|
+
configurable: true
|
|
5163
|
+
});
|
|
5164
|
+
}
|
|
4544
5165
|
throw canceledError;
|
|
4545
5166
|
}
|
|
5167
|
+
|
|
5168
|
+
// Surface a maxBodyLength violation we raised while the request body was
|
|
5169
|
+
// being streamed. Matching by identity (rather than reading
|
|
5170
|
+
// `err.cause.isAxiosError`) keeps the error deterministic across runtimes
|
|
5171
|
+
// and avoids both prototype-pollution reads and mis-attributing a foreign
|
|
5172
|
+
// AxiosError that merely happened to land in `err.cause`.
|
|
5173
|
+
if (pendingBodyError) {
|
|
5174
|
+
request && !pendingBodyError.request && (pendingBodyError.request = request);
|
|
5175
|
+
throw pendingBodyError;
|
|
5176
|
+
}
|
|
5177
|
+
|
|
5178
|
+
// Re-throw AxiosErrors we raised synchronously (data: URL / content-length
|
|
5179
|
+
// pre-checks, response size enforcement) without re-wrapping them.
|
|
5180
|
+
if (err instanceof AxiosError) {
|
|
5181
|
+
request && !err.request && (err.request = request);
|
|
5182
|
+
throw err;
|
|
5183
|
+
}
|
|
4546
5184
|
if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
|
|
4547
|
-
|
|
4548
|
-
|
|
5185
|
+
const networkError = new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request, err && err.response);
|
|
5186
|
+
// Non-enumerable to match native Error `cause` semantics so loggers
|
|
5187
|
+
// don't recurse into circular fetch internals (see #7205).
|
|
5188
|
+
Object.defineProperty(networkError, 'cause', {
|
|
5189
|
+
__proto__: null,
|
|
5190
|
+
value: err.cause || err,
|
|
5191
|
+
writable: true,
|
|
5192
|
+
enumerable: false,
|
|
5193
|
+
configurable: true
|
|
4549
5194
|
});
|
|
5195
|
+
throw networkError;
|
|
4550
5196
|
}
|
|
4551
5197
|
throw AxiosError.from(err, err && err.code, config, request, err && err.response);
|
|
4552
5198
|
}
|
|
@@ -4665,7 +5311,7 @@ function getAdapter(adapters, config) {
|
|
|
4665
5311
|
if (!adapter) {
|
|
4666
5312
|
const reasons = Object.entries(rejectedReasons).map(([id, state]) => `adapter ${id} ` + (state === false ? 'is not supported by the environment' : 'is not available in the build'));
|
|
4667
5313
|
let s = length ? reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0]) : 'as no adapter specified';
|
|
4668
|
-
throw new AxiosError(`There is no suitable adapter to dispatch the request ` + s,
|
|
5314
|
+
throw new AxiosError(`There is no suitable adapter to dispatch the request ` + s, AxiosError.ERR_NOT_SUPPORT);
|
|
4669
5315
|
}
|
|
4670
5316
|
return adapter;
|
|
4671
5317
|
}
|
|
@@ -4808,7 +5454,7 @@ validators$1.spelling = function spelling(correctSpelling) {
|
|
|
4808
5454
|
*/
|
|
4809
5455
|
|
|
4810
5456
|
function assertOptions(options, schema, allowUnknown) {
|
|
4811
|
-
if (typeof options !== 'object') {
|
|
5457
|
+
if (typeof options !== 'object' || options === null) {
|
|
4812
5458
|
throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);
|
|
4813
5459
|
}
|
|
4814
5460
|
const keys = Object.keys(options);
|
|
@@ -4917,7 +5563,9 @@ class Axios {
|
|
|
4917
5563
|
silentJSONParsing: validators.transitional(validators.boolean),
|
|
4918
5564
|
forcedJSONParsing: validators.transitional(validators.boolean),
|
|
4919
5565
|
clarifyTimeoutError: validators.transitional(validators.boolean),
|
|
4920
|
-
legacyInterceptorReqResOrdering: validators.transitional(validators.boolean)
|
|
5566
|
+
legacyInterceptorReqResOrdering: validators.transitional(validators.boolean),
|
|
5567
|
+
advertiseZstdAcceptEncoding: validators.transitional(validators.boolean),
|
|
5568
|
+
validateStatusUndefinedResolves: validators.transitional(validators.boolean)
|
|
4921
5569
|
}, false);
|
|
4922
5570
|
}
|
|
4923
5571
|
if (paramsSerializer != null) {
|
|
@@ -5014,7 +5662,7 @@ class Axios {
|
|
|
5014
5662
|
}
|
|
5015
5663
|
getUri(config) {
|
|
5016
5664
|
config = mergeConfig(this.defaults, config);
|
|
5017
|
-
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
|
|
5665
|
+
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls, config);
|
|
5018
5666
|
return buildURL(fullPath, config.params, config.paramsSerializer);
|
|
5019
5667
|
}
|
|
5020
5668
|
}
|
|
@@ -5026,7 +5674,7 @@ utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoDa
|
|
|
5026
5674
|
return this.request(mergeConfig(config || {}, {
|
|
5027
5675
|
method,
|
|
5028
5676
|
url,
|
|
5029
|
-
data: (config
|
|
5677
|
+
data: config && utils$1.hasOwnProp(config, 'data') ? config.data : undefined
|
|
5030
5678
|
}));
|
|
5031
5679
|
};
|
|
5032
5680
|
});
|