@openclaw/slack 2026.7.2-beta.3 → 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.
Files changed (152) hide show
  1. package/dist/account-inspect-api.js +1 -1
  2. package/dist/{account-inspect-Bvbtu3iH.js → account-inspect-jn1xLaVi.js} +2 -2
  3. package/dist/account-reply-mode-DrUXogvO.js +14 -0
  4. package/dist/{accounts-DQEbYKh9.js → accounts-BSr252c_.js} +6 -27
  5. package/dist/{accounts.runtime-BIKmJdtJ.js → accounts.runtime-CjULMLTa.js} +1 -1
  6. package/dist/{action-runtime-DqkRwO3Z.js → action-runtime-CFU52n4W.js} +7 -7
  7. package/dist/action-runtime.runtime-9-17zvKH.js +2 -0
  8. package/dist/{actions-CF0tUY5q.js → actions-D51foiwR.js} +5 -5
  9. package/dist/{actions.runtime-hCbx4RXg.js → actions.runtime-BMJwtf5C.js} +1 -1
  10. package/dist/api.js +15 -14
  11. package/dist/{approval-handler.runtime-Em8I1-8-.js → approval-handler.runtime-3b4-wxMl.js} +2 -2
  12. package/dist/{channel-4-TRi1D6.js → channel-Ds8NKvfr.js} +26 -24
  13. package/dist/channel-config-api.js +1 -1
  14. package/dist/channel-plugin-api.js +1 -1
  15. package/dist/{channel-type-Cu1yjNg2.js → channel-type-DXkUajFP.js} +3 -3
  16. package/dist/{channel.setup-CgkADtZg.js → channel.setup-DOSTEDfA.js} +6 -5
  17. package/dist/{config-schema-XjJGfwQC.js → config-schema-B4j4tCOI.js} +231 -26
  18. package/dist/{directory-config-Bv0lcUlH.js → directory-config-B08pm5ZT.js} +1 -1
  19. package/dist/directory-contract-api.js +1 -1
  20. package/dist/{directory-live-CzUIB7th.js → directory-live-DpPKzPrn.js} +2 -2
  21. package/dist/{doctor-contract-DKpe5VBr.js → doctor-contract-U6oVntbM.js} +60 -89
  22. package/dist/doctor-contract-api.js +1 -1
  23. package/dist/{group-policy-Bw-65m3V.js → group-policy-CdnQzQBI.js} +32 -5
  24. package/dist/{interactive-replies-Dm_t2R9S.js → interactive-replies-C3ffk6oN.js} +1 -1
  25. package/dist/interactive-replies-api.js +1 -1
  26. package/dist/{message-tool-api-C2pcf5du.js → message-tool-api-ByVyIVOh.js} +2 -2
  27. package/dist/message-tool-api.js +1 -1
  28. package/dist/{monitor-CNFeF30h.js → monitor-CnB_WKvF.js} +3 -3
  29. package/dist/{outbound-adapter-CVi2uok0.js → outbound-adapter-DuPz2HHt.js} +3 -3
  30. package/dist/{pipeline.runtime-CTvokbty.js → pipeline.runtime-5rRYZuX5.js} +110 -77
  31. package/dist/{policy-b_dOPDCq.js → policy-C31RYSuT.js} +1 -1
  32. package/dist/{probe-Borhn9PQ.js → probe-CVRuArHA.js} +1 -1
  33. package/dist/{provider-B-HVL5ZE.js → provider-htuIJGFD.js} +365 -200
  34. package/dist/{relay-source-Ea_P9VcO.js → relay-source-Df9EaiTF.js} +1 -1
  35. package/dist/{replies-B4bOdrYb.js → replies-Cgr2Gli4.js} +3 -3
  36. package/dist/{resolve-channels-KTc568SU.js → resolve-channels-DodP2TFx.js} +1 -1
  37. package/dist/{resolve-users-DeGJf1yp.js → resolve-users-M9eF8891.js} +1 -1
  38. package/dist/{runtime-api-BFfNpzDe.js → runtime-api-D5XYMMsf.js} +3 -2
  39. package/dist/runtime-api.js +11 -11
  40. package/dist/{scopes-lx08L56K.js → scopes-CJRpHkDC.js} +1 -1
  41. package/dist/{security-audit-CikQhBUY.js → security-audit-Cz6erklv.js} +0 -10
  42. package/dist/security-contract-api.js +1 -1
  43. package/dist/{send-KuTDky7i.js → send-BZ1tPv7-.js} +4 -4
  44. package/dist/{send.runtime-CXyxws1D.js → send.runtime-a2pilFor.js} +1 -1
  45. package/dist/{setup-core-CeiAVwQ3.js → setup-core-tPxMuFez.js} +138 -40
  46. package/dist/setup-plugin-api.js +1 -1
  47. package/dist/{setup-surface-DLA0vHXp.js → setup-surface-wV-S1dE_.js} +43 -27
  48. package/dist/{shared-C4yVB0Q-.js → shared-BfMskaMx.js} +9 -8
  49. package/dist/{slash-dispatch.runtime-BT-mMm-f.js → slash-dispatch.runtime-lfeIsXTX.js} +1 -1
  50. package/node_modules/@types/node/README.md +1 -1
  51. package/node_modules/@types/node/fs/promises.d.ts +16 -6
  52. package/node_modules/@types/node/package.json +2 -2
  53. package/node_modules/agent-base/README.md +145 -0
  54. package/node_modules/agent-base/dist/src/index.d.ts +78 -0
  55. package/node_modules/agent-base/dist/src/index.js +203 -0
  56. package/node_modules/agent-base/dist/src/index.js.map +1 -0
  57. package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
  58. package/node_modules/agent-base/dist/src/promisify.js +18 -0
  59. package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
  60. package/node_modules/agent-base/package.json +64 -0
  61. package/node_modules/agent-base/src/index.ts +345 -0
  62. package/node_modules/agent-base/src/promisify.ts +33 -0
  63. package/node_modules/axios/CHANGELOG.md +197 -1
  64. package/node_modules/axios/README.md +424 -256
  65. package/node_modules/axios/dist/axios.js +589 -204
  66. package/node_modules/axios/dist/axios.min.js +3 -3
  67. package/node_modules/axios/dist/axios.min.js.map +1 -1
  68. package/node_modules/axios/dist/browser/axios.cjs +630 -185
  69. package/node_modules/axios/dist/esm/axios.js +630 -185
  70. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  71. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  72. package/node_modules/axios/dist/node/axios.cjs +949 -301
  73. package/node_modules/axios/index.d.cts +28 -5
  74. package/node_modules/axios/index.d.ts +24 -3
  75. package/node_modules/axios/lib/adapters/adapters.js +1 -1
  76. package/node_modules/axios/lib/adapters/fetch.js +223 -49
  77. package/node_modules/axios/lib/adapters/http.js +408 -193
  78. package/node_modules/axios/lib/adapters/xhr.js +3 -1
  79. package/node_modules/axios/lib/core/Axios.js +4 -2
  80. package/node_modules/axios/lib/core/AxiosError.js +13 -1
  81. package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
  82. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  83. package/node_modules/axios/lib/core/mergeConfig.js +35 -0
  84. package/node_modules/axios/lib/defaults/transitional.js +2 -0
  85. package/node_modules/axios/lib/env/data.js +1 -1
  86. package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -3
  87. package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
  88. package/node_modules/axios/lib/helpers/buildURL.js +7 -4
  89. package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
  90. package/node_modules/axios/lib/helpers/cookies.js +5 -1
  91. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  92. package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
  93. package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
  94. package/node_modules/axios/lib/helpers/fromDataURI.js +20 -5
  95. package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
  96. package/node_modules/axios/lib/helpers/resolveConfig.js +26 -13
  97. package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
  98. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  99. package/node_modules/axios/lib/helpers/toFormData.js +48 -12
  100. package/node_modules/axios/lib/helpers/validator.js +1 -1
  101. package/node_modules/axios/lib/utils.js +105 -19
  102. package/node_modules/axios/package.json +31 -13
  103. package/node_modules/https-proxy-agent/README.md +137 -0
  104. package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
  105. package/node_modules/https-proxy-agent/dist/agent.js +177 -0
  106. package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
  107. package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
  108. package/node_modules/https-proxy-agent/dist/index.js +14 -0
  109. package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
  110. package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
  111. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
  112. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
  113. package/node_modules/https-proxy-agent/package.json +56 -0
  114. package/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
  115. package/node_modules/iconv-lite/encodings/utf32.js +10 -3
  116. package/node_modules/iconv-lite/package.json +2 -2
  117. package/node_modules/iconv-lite/types/encodings.d.ts +2 -0
  118. package/node_modules/path-to-regexp/Readme.md +3 -3
  119. package/node_modules/path-to-regexp/dist/index.js +135 -158
  120. package/node_modules/path-to-regexp/dist/index.js.map +1 -1
  121. package/node_modules/path-to-regexp/package.json +2 -2
  122. package/node_modules/qs/CHANGELOG.md +11 -0
  123. package/node_modules/qs/dist/qs.js +17 -17
  124. package/node_modules/qs/lib/parse.js +19 -8
  125. package/node_modules/qs/lib/utils.js +47 -8
  126. package/node_modules/qs/package.json +6 -5
  127. package/node_modules/qs/test/parse.js +230 -0
  128. package/node_modules/qs/test/utils.js +194 -0
  129. package/node_modules/typebox/build/compile/validator.d.mts +1 -4
  130. package/node_modules/typebox/build/guard/guard.d.mts +1 -1
  131. package/node_modules/typebox/build/guard/guard.mjs +5 -2
  132. package/node_modules/typebox/build/guard/string.mjs +16 -4
  133. package/node_modules/typebox/build/schema/engine/_functions.mjs +34 -15
  134. package/node_modules/typebox/build/type/action/readonly_object.d.mts +5 -0
  135. package/node_modules/typebox/build/type/action/readonly_object.mjs +8 -0
  136. package/node_modules/typebox/build/typebox.d.mts +1 -1
  137. package/node_modules/typebox/build/typebox.mjs +1 -1
  138. package/node_modules/typebox/package.json +1 -1
  139. package/node_modules/typebox/readme.md +29 -32
  140. package/node_modules/ws/lib/receiver.js +15 -32
  141. package/node_modules/ws/lib/websocket-server.js +4 -4
  142. package/node_modules/ws/lib/websocket.js +4 -4
  143. package/node_modules/ws/package.json +5 -1
  144. package/npm-shrinkwrap.json +54 -27
  145. package/openclaw.plugin.json +1759 -1908
  146. package/package.json +92 -14
  147. package/dist/action-runtime.runtime-DEWOcFM4.js +0 -2
  148. package/dist/config-api-Df9a1B8C.js +0 -3
  149. package/node_modules/axios/dist/axios.js.map +0 -1
  150. package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
  151. package/node_modules/axios/dist/esm/axios.js.map +0 -1
  152. package/node_modules/axios/dist/node/axios.cjs.map +0 -1
@@ -3,6 +3,7 @@ import settle from '../core/settle.js';
3
3
  import buildFullPath from '../core/buildFullPath.js';
4
4
  import buildURL from '../helpers/buildURL.js';
5
5
  import { getProxyForUrl } from 'proxy-from-env';
6
+ import HttpsProxyAgent from 'https-proxy-agent';
6
7
  import http from 'http';
7
8
  import https from 'https';
8
9
  import http2 from 'http2';
@@ -23,8 +24,10 @@ import { EventEmitter } from 'events';
23
24
  import formDataToStream from '../helpers/formDataToStream.js';
24
25
  import readBlob from '../helpers/readBlob.js';
25
26
  import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';
27
+ import Http2Sessions from '../helpers/Http2Sessions.js';
26
28
  import callbackify from '../helpers/callbackify.js';
27
29
  import shouldBypassProxy from '../helpers/shouldBypassProxy.js';
30
+ import { toByteStringHeaderObject } from '../helpers/sanitizeHeaderValue.js';
28
31
  import {
29
32
  progressEventReducer,
30
33
  progressEventDecorator,
@@ -42,7 +45,15 @@ const brotliOptions = {
42
45
  finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH,
43
46
  };
44
47
 
48
+ const zstdOptions = {
49
+ flush: zlib.constants.ZSTD_e_flush,
50
+ finishFlush: zlib.constants.ZSTD_e_flush,
51
+ };
52
+
45
53
  const isBrotliSupported = utils.isFunction(zlib.createBrotliDecompress);
54
+ const isZstdSupported = utils.isFunction(zlib.createZstdDecompress);
55
+ const ACCEPT_ENCODING = 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : '');
56
+ const ACCEPT_ENCODING_WITH_ZSTD = ACCEPT_ENCODING + (isZstdSupported ? ', zstd' : '');
46
57
 
47
58
  const { http: httpFollow, https: httpsFollow } = followRedirects;
48
59
 
@@ -67,6 +78,100 @@ function setFormDataHeaders(headers, formHeaders, policy) {
67
78
  const kAxiosSocketListener = Symbol('axios.http.socketListener');
68
79
  const kAxiosCurrentReq = Symbol('axios.http.currentReq');
69
80
 
81
+ // Tags HttpsProxyAgent instances installed by setProxy() so the redirect path
82
+ // can strip them without clobbering a user-supplied agent that happens to be
83
+ // an HttpsProxyAgent.
84
+ const kAxiosInstalledTunnel = Symbol('axios.http.installedTunnel');
85
+
86
+ // Cache of CONNECT-tunneling agents keyed by proxy config so repeat requests
87
+ // through the same proxy reuse a single agent (and its socket pool). The
88
+ // keyspace is bounded by the set of distinct proxy configs the process uses,
89
+ // so unbounded growth is not a concern in practice.
90
+ const tunnelingAgentCache = new Map();
91
+ const tunnelingAgentCacheUser = new WeakMap();
92
+ // Minimum minor versions where Node's HTTP Agent supports native proxyEnv
93
+ // handling. Checking the selected agent below also covers startup modes such
94
+ // as NODE_OPTIONS=--use-env-proxy and --no-use-env-proxy precedence.
95
+ const NODE_NATIVE_ENV_PROXY_SUPPORT = {
96
+ 22: 21,
97
+ 24: 5,
98
+ };
99
+
100
+ function isNodeNativeEnvProxySupported(nodeVersion = process.versions && process.versions.node) {
101
+ if (!nodeVersion) {
102
+ return false;
103
+ }
104
+
105
+ const [major, minor] = nodeVersion.split('.').map((part) => Number(part));
106
+
107
+ if (!Number.isInteger(major) || !Number.isInteger(minor)) {
108
+ return false;
109
+ }
110
+
111
+ if (major > 24) {
112
+ return true;
113
+ }
114
+
115
+ return (
116
+ NODE_NATIVE_ENV_PROXY_SUPPORT[major] != null && minor >= NODE_NATIVE_ENV_PROXY_SUPPORT[major]
117
+ );
118
+ }
119
+
120
+ function isNodeEnvProxyEnabled(agent, nodeVersion = process.versions && process.versions.node) {
121
+ if (!isNodeNativeEnvProxySupported(nodeVersion)) {
122
+ return false;
123
+ }
124
+
125
+ const agentOptions = agent && agent.options;
126
+
127
+ return Boolean(
128
+ agentOptions &&
129
+ utils.hasOwnProp(agentOptions, 'proxyEnv') &&
130
+ agentOptions.proxyEnv != null
131
+ );
132
+ }
133
+
134
+ function getProxyEnvAgent(options, configHttpAgent, configHttpsAgent) {
135
+ return isHttps.test(options.protocol)
136
+ ? (configHttpsAgent || https.globalAgent)
137
+ : (configHttpAgent || http.globalAgent);
138
+ }
139
+
140
+ function getTunnelingAgent(agentOptions, userHttpsAgent) {
141
+ const key =
142
+ agentOptions.protocol +
143
+ '//' +
144
+ agentOptions.hostname +
145
+ ':' +
146
+ (agentOptions.port || '') +
147
+ '#' +
148
+ (agentOptions.auth || '');
149
+ const cache = userHttpsAgent
150
+ ? (tunnelingAgentCacheUser.get(userHttpsAgent) ||
151
+ tunnelingAgentCacheUser.set(userHttpsAgent, new Map()).get(userHttpsAgent))
152
+ : tunnelingAgentCache;
153
+ let agent = cache.get(key);
154
+ if (agent) return agent;
155
+ // Forward the user's TLS options (custom CA, rejectUnauthorized, client cert,
156
+ // etc.) into the tunneling agent so they apply to the origin TLS upgrade
157
+ // performed after CONNECT. Our proxy fields take precedence on conflict.
158
+ const merged = userHttpsAgent && userHttpsAgent.options
159
+ ? { ...userHttpsAgent.options, ...agentOptions }
160
+ : agentOptions;
161
+ agent = new HttpsProxyAgent(merged);
162
+ if (userHttpsAgent && userHttpsAgent.options) {
163
+ const originTLSOptions = { ...userHttpsAgent.options };
164
+ const callback = agent.callback;
165
+ agent.callback = function axiosTunnelingAgentCallback(req, opts) {
166
+ // HttpsProxyAgent v5 reads callback opts for the post-CONNECT origin TLS upgrade.
167
+ return callback.call(this, req, { ...originTLSOptions, ...opts });
168
+ };
169
+ }
170
+ agent[kAxiosInstalledTunnel] = true;
171
+ cache.set(key, agent);
172
+ return agent;
173
+ }
174
+
70
175
  const supportedProtocols = platform.protocols.map((protocol) => {
71
176
  return protocol + ':';
72
177
  });
@@ -93,114 +198,11 @@ const flushOnFinish = (stream, [throttled, flush]) => {
93
198
  return throttled;
94
199
  };
95
200
 
96
- class Http2Sessions {
97
- constructor() {
98
- this.sessions = Object.create(null);
99
- }
100
-
101
- getSession(authority, options) {
102
- options = Object.assign(
103
- {
104
- sessionTimeout: 1000,
105
- },
106
- options
107
- );
108
-
109
- let authoritySessions = this.sessions[authority];
110
-
111
- if (authoritySessions) {
112
- let len = authoritySessions.length;
113
-
114
- for (let i = 0; i < len; i++) {
115
- const [sessionHandle, sessionOptions] = authoritySessions[i];
116
- if (
117
- !sessionHandle.destroyed &&
118
- !sessionHandle.closed &&
119
- util.isDeepStrictEqual(sessionOptions, options)
120
- ) {
121
- return sessionHandle;
122
- }
123
- }
124
- }
125
-
126
- const session = http2.connect(authority, options);
127
-
128
- let removed;
129
-
130
- const removeSession = () => {
131
- if (removed) {
132
- return;
133
- }
134
-
135
- removed = true;
136
-
137
- let entries = authoritySessions,
138
- len = entries.length,
139
- i = len;
140
-
141
- while (i--) {
142
- if (entries[i][0] === session) {
143
- if (len === 1) {
144
- delete this.sessions[authority];
145
- } else {
146
- entries.splice(i, 1);
147
- }
148
- if (!session.closed) {
149
- session.close();
150
- }
151
- return;
152
- }
153
- }
154
- };
155
-
156
- const originalRequestFn = session.request;
157
-
158
- const { sessionTimeout } = options;
159
-
160
- if (sessionTimeout != null) {
161
- let timer;
162
- let streamsCount = 0;
163
-
164
- session.request = function () {
165
- const stream = originalRequestFn.apply(this, arguments);
166
-
167
- streamsCount++;
168
-
169
- if (timer) {
170
- clearTimeout(timer);
171
- timer = null;
172
- }
173
-
174
- stream.once('close', () => {
175
- if (!--streamsCount) {
176
- timer = setTimeout(() => {
177
- timer = null;
178
- removeSession();
179
- }, sessionTimeout);
180
- }
181
- });
182
-
183
- return stream;
184
- };
185
- }
186
-
187
- session.once('close', removeSession);
188
-
189
- let entry = [session, options];
190
-
191
- authoritySessions
192
- ? authoritySessions.push(entry)
193
- : (authoritySessions = this.sessions[authority] = [entry]);
194
-
195
- return session;
196
- }
197
- }
198
-
199
201
  const http2Sessions = new Http2Sessions();
200
202
 
201
203
  /**
202
- * If the proxy or config beforeRedirects functions are defined, call them with the options
203
- * object.
204
+ * If the proxy, auth, sensitive header, or config beforeRedirects functions are defined,
205
+ * call them with the options object.
204
206
  *
205
207
  * @param {Object<string, any>} options - The options object that was passed to the request.
206
208
  *
@@ -210,11 +212,42 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
210
212
  if (options.beforeRedirects.proxy) {
211
213
  options.beforeRedirects.proxy(options);
212
214
  }
215
+ if (options.beforeRedirects.auth) {
216
+ options.beforeRedirects.auth(options);
217
+ }
218
+ if (options.beforeRedirects.sensitiveHeaders) {
219
+ options.beforeRedirects.sensitiveHeaders(options, requestDetails);
220
+ }
213
221
  if (options.beforeRedirects.config) {
214
222
  options.beforeRedirects.config(options, responseDetails, requestDetails);
215
223
  }
216
224
  }
217
225
 
226
+ function stripMatchingHeaders(headers, sensitiveSet) {
227
+ if (!headers) {
228
+ return;
229
+ }
230
+
231
+ Object.keys(headers).forEach((header) => {
232
+ if (sensitiveSet.has(header.toLowerCase())) {
233
+ delete headers[header];
234
+ }
235
+ });
236
+ }
237
+
238
+ function isSameOriginRedirect(redirectOptions, requestDetails) {
239
+ if (!requestDetails) {
240
+ return false;
241
+ }
242
+
243
+ try {
244
+ return new URL(requestDetails.url).origin === new URL(redirectOptions.href).origin;
245
+ } catch (e) {
246
+ // If origin comparison fails, treat the redirect as unsafe.
247
+ return false;
248
+ }
249
+ }
250
+
218
251
  /**
219
252
  * If the proxy or config afterRedirects functions are defined, call them with the options
220
253
  *
@@ -224,9 +257,10 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
224
257
  *
225
258
  * @returns {http.ClientRequestArgs}
226
259
  */
227
- function setProxy(options, configProxy, location, isRedirect) {
260
+ function setProxy(options, configProxy, location, isRedirect, configHttpsAgent, configHttpAgent) {
228
261
  let proxy = configProxy;
229
- if (!proxy && proxy !== false) {
262
+ const proxyEnvAgent = getProxyEnvAgent(options, configHttpAgent, configHttpsAgent);
263
+ if (!proxy && proxy !== false && !isNodeEnvProxyEnabled(proxyEnvAgent)) {
230
264
  const proxyUrl = getProxyForUrl(location);
231
265
  if (proxyUrl) {
232
266
  if (!shouldBypassProxy(location)) {
@@ -245,6 +279,13 @@ function setProxy(options, configProxy, location, isRedirect) {
245
279
  }
246
280
  }
247
281
  }
282
+ // Strip any tunneling agent we installed for the previous hop so a redirect
283
+ // that drops the proxy or crosses an HTTPS↔HTTP boundary doesn't reuse a
284
+ // stale one. Match on our Symbol marker so a user-supplied HttpsProxyAgent
285
+ // (which won't carry the marker) is left alone.
286
+ if (isRedirect && options.agent && options.agent[kAxiosInstalledTunnel]) {
287
+ options.agent = undefined;
288
+ }
248
289
  if (proxy) {
249
290
  // Read proxy fields without traversing the prototype chain. URL instances expose
250
291
  // username/password/hostname/host/port/protocol via getters on URL.prototype (so
@@ -281,40 +322,103 @@ function setProxy(options, configProxy, location, isRedirect) {
281
322
  } else if (authIsObject) {
282
323
  throw new AxiosError('Invalid proxy authorization', AxiosError.ERR_BAD_OPTION, { proxy });
283
324
  }
284
-
285
- const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64');
286
-
287
- options.headers['Proxy-Authorization'] = 'Basic ' + base64;
288
325
  }
289
326
 
290
- // Preserve a user-supplied Host header (case-insensitive) so callers can override
291
- // the value forwarded to the proxy; otherwise default to the request URL's host.
292
- let hasUserHostHeader = false;
293
- for (const name of Object.keys(options.headers)) {
294
- if (name.toLowerCase() === 'host') {
295
- hasUserHostHeader = true;
296
- break;
327
+ const targetIsHttps = isHttps.test(options.protocol);
328
+
329
+ if (targetIsHttps) {
330
+ // CONNECT-tunneling path for HTTPS targets. Preserves end-to-end TLS to
331
+ // the origin so the proxy cannot inspect the URL, headers, or body — the
332
+ // behavior already promised by THREATMODEL.md (T-R9). HttpsProxyAgent
333
+ // sends Proxy-Authorization on the CONNECT request only, never on the
334
+ // wrapped TLS request, which is why we don't stamp it onto
335
+ // options.headers here. If the user already supplied an HttpsProxyAgent,
336
+ // they own tunneling end-to-end and we leave them alone; otherwise we
337
+ // install our own tunneling agent and forward their TLS options (if any)
338
+ // so a custom httpsAgent for cert pinning / rejectUnauthorized still
339
+ // applies to the origin TLS upgrade.
340
+ if (!(configHttpsAgent instanceof HttpsProxyAgent)) {
341
+ const proxyHost = readProxyField('hostname') || readProxyField('host');
342
+ const proxyPort = readProxyField('port');
343
+ const rawProxyProtocol = readProxyField('protocol');
344
+ const normalizedProtocol = rawProxyProtocol
345
+ ? rawProxyProtocol.includes(':')
346
+ ? rawProxyProtocol
347
+ : `${rawProxyProtocol}:`
348
+ : 'http:';
349
+ // Bracket IPv6 literals for URL parsing; URL.hostname strips the
350
+ // brackets again on read so the agent receives the raw form.
351
+ const proxyHostForURL =
352
+ proxyHost && proxyHost.includes(':') && !proxyHost.startsWith('[')
353
+ ? `[${proxyHost}]`
354
+ : proxyHost;
355
+ const proxyURL = new URL(
356
+ `${normalizedProtocol}//${proxyHostForURL}${proxyPort ? ':' + proxyPort : ''}`
357
+ );
358
+ const agentOptions = {
359
+ protocol: proxyURL.protocol,
360
+ hostname: proxyURL.hostname.replace(/^\[|\]$/g, ''),
361
+ port: proxyURL.port,
362
+ auth: proxyAuth && typeof proxyAuth === 'string' ? proxyAuth : undefined,
363
+ };
364
+ if (proxyURL.protocol === 'https:') {
365
+ agentOptions.ALPNProtocols = ['http/1.1'];
366
+ }
367
+ const tunnelingAgent = getTunnelingAgent(agentOptions, configHttpsAgent);
368
+ // Set both: `options.agent` is consumed by the native https.request path
369
+ // (maxRedirects === 0); `options.agents.https` is consumed by
370
+ // follow-redirects, which ignores `options.agent` when `options.agents`
371
+ // is present.
372
+ options.agent = tunnelingAgent;
373
+ if (options.agents) {
374
+ options.agents.https = tunnelingAgent;
375
+ }
376
+ }
377
+ } else {
378
+ // Forward-proxy mode for plaintext HTTP targets. The request line carries
379
+ // the absolute URL and the proxy sees everything — acceptable for plain
380
+ // HTTP since the wire was already plaintext.
381
+ if (proxyAuth) {
382
+ const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64');
383
+ options.headers['Proxy-Authorization'] = 'Basic ' + base64;
384
+ }
385
+
386
+ // Preserve a user-supplied Host header (case-insensitive) so callers can override
387
+ // the value forwarded to the proxy; otherwise default to the request URL's host.
388
+ let hasUserHostHeader = false;
389
+ for (const name of Object.keys(options.headers)) {
390
+ if (name.toLowerCase() === 'host') {
391
+ hasUserHostHeader = true;
392
+ break;
393
+ }
394
+ }
395
+ if (!hasUserHostHeader) {
396
+ options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
397
+ }
398
+ const proxyHost = readProxyField('hostname') || readProxyField('host');
399
+ options.hostname = proxyHost;
400
+ // Replace 'host' since options is not a URL object
401
+ options.host = proxyHost;
402
+ options.port = readProxyField('port');
403
+ options.path = location;
404
+ const proxyProtocol = readProxyField('protocol');
405
+ if (proxyProtocol) {
406
+ options.protocol = proxyProtocol.includes(':') ? proxyProtocol : `${proxyProtocol}:`;
297
407
  }
298
- }
299
- if (!hasUserHostHeader) {
300
- options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
301
- }
302
- const proxyHost = readProxyField('hostname') || readProxyField('host');
303
- options.hostname = proxyHost;
304
- // Replace 'host' since options is not a URL object
305
- options.host = proxyHost;
306
- options.port = readProxyField('port');
307
- options.path = location;
308
- const proxyProtocol = readProxyField('protocol');
309
- if (proxyProtocol) {
310
- options.protocol = proxyProtocol.includes(':') ? proxyProtocol : `${proxyProtocol}:`;
311
408
  }
312
409
  }
313
410
 
314
411
  options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {
315
412
  // Configure proxy for redirected request, passing the original config proxy to apply
316
413
  // the exact same logic as if the redirected request was performed by axios directly.
317
- setProxy(redirectOptions, configProxy, redirectOptions.href, true);
414
+ setProxy(
415
+ redirectOptions,
416
+ configProxy,
417
+ redirectOptions.href,
418
+ true,
419
+ configHttpsAgent,
420
+ configHttpAgent
421
+ );
318
422
  };
319
423
  }
320
424
 
@@ -413,16 +517,30 @@ const http2Transport = {
413
517
  export default isHttpAdapterSupported &&
414
518
  function httpAdapter(config) {
415
519
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
416
- const own = (key) => (utils.hasOwnProp(config, key) ? config[key] : undefined);
520
+ // Read config pollution-safely: own properties and members inherited from
521
+ // a non-Object.prototype source (e.g. an Object.create(defaults) template)
522
+ // are honored, but values injected onto a polluted Object.prototype are
523
+ // ignored. All behavior-affecting reads in this adapter go through own()
524
+ // so the protection boundary stays consistent.
525
+ const own = (key) => utils.getSafeProp(config, key);
526
+ const transitional = own('transitional') || transitionalDefaults;
417
527
  let data = own('data');
418
528
  let lookup = own('lookup');
419
529
  let family = own('family');
420
530
  let httpVersion = own('httpVersion');
421
531
  if (httpVersion === undefined) httpVersion = 1;
422
532
  let http2Options = own('http2Options');
533
+ const httpAgent = own('httpAgent');
534
+ const httpsAgent = own('httpsAgent');
535
+ const configProxy = own('proxy');
423
536
  const responseType = own('responseType');
424
537
  const responseEncoding = own('responseEncoding');
425
- const method = config.method.toUpperCase();
538
+ const socketPath = own('socketPath');
539
+ const method = own('method').toUpperCase();
540
+ const maxRedirects = own('maxRedirects');
541
+ const maxBodyLength = own('maxBodyLength');
542
+ const maxContentLength = own('maxContentLength');
543
+ const decompress = own('decompress');
426
544
  let isDone;
427
545
  let rejected = false;
428
546
  let req;
@@ -467,7 +585,7 @@ export default isHttpAdapterSupported &&
467
585
  !reason || reason.type ? new CanceledError(null, config, req) : reason
468
586
  );
469
587
  } catch (err) {
470
- console.warn('emit error', err);
588
+ // ignore emit errors
471
589
  }
472
590
  }
473
591
 
@@ -479,12 +597,13 @@ export default isHttpAdapterSupported &&
479
597
  }
480
598
 
481
599
  function createTimeoutError() {
482
- let timeoutErrorMessage = config.timeout
483
- ? 'timeout of ' + config.timeout + 'ms exceeded'
600
+ const configTimeout = own('timeout');
601
+ let timeoutErrorMessage = configTimeout
602
+ ? 'timeout of ' + configTimeout + 'ms exceeded'
484
603
  : 'timeout exceeded';
485
- const transitional = config.transitional || transitionalDefaults;
486
- if (config.timeoutErrorMessage) {
487
- timeoutErrorMessage = config.timeoutErrorMessage;
604
+ const configTimeoutErrorMessage = own('timeoutErrorMessage');
605
+ if (configTimeoutErrorMessage) {
606
+ timeoutErrorMessage = configTimeoutErrorMessage;
488
607
  }
489
608
  return new AxiosError(
490
609
  timeoutErrorMessage,
@@ -540,21 +659,28 @@ export default isHttpAdapterSupported &&
540
659
  });
541
660
 
542
661
  // Parse url
543
- const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
544
- const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
662
+ const fullPath = buildFullPath(own('baseURL'), own('url'), own('allowAbsoluteUrls'), config);
663
+ // Unix-socket requests (own socketPath) commonly pass a path-only url
664
+ // like '/foo'; supply a synthetic base so new URL() can still parse it.
665
+ // Use the own-property value (not config.socketPath) so a polluted
666
+ // prototype cannot influence URL base selection.
667
+ const urlBase = socketPath
668
+ ? 'http://localhost'
669
+ : (platform.hasBrowserEnv ? platform.origin : undefined);
670
+ const parsed = new URL(fullPath, urlBase);
545
671
  const protocol = parsed.protocol || supportedProtocols[0];
546
672
 
547
673
  if (protocol === 'data:') {
548
674
  // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
549
- if (config.maxContentLength > -1) {
550
- // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.
551
- const dataUrl = String(config.url || fullPath || '');
675
+ if (maxContentLength > -1) {
676
+ // Use the exact string passed to fromDataURI (the configured url); fall back to fullPath if needed.
677
+ const dataUrl = String(own('url') || fullPath || '');
552
678
  const estimated = estimateDataURLDecodedBytes(dataUrl);
553
679
 
554
- if (estimated > config.maxContentLength) {
680
+ if (estimated > maxContentLength) {
555
681
  return reject(
556
682
  new AxiosError(
557
- 'maxContentLength size of ' + config.maxContentLength + ' exceeded',
683
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
558
684
  AxiosError.ERR_BAD_RESPONSE,
559
685
  config
560
686
  )
@@ -574,7 +700,7 @@ export default isHttpAdapterSupported &&
574
700
  }
575
701
 
576
702
  try {
577
- convertedData = fromDataURI(config.url, responseType === 'blob', {
703
+ convertedData = fromDataURI(own('url'), responseType === 'blob', {
578
704
  Blob: config.env && config.env.Blob,
579
705
  });
580
706
  } catch (err) {
@@ -674,7 +800,7 @@ export default isHttpAdapterSupported &&
674
800
  // Add Content-Length header if data exists
675
801
  headers.setContentLength(data.length, false);
676
802
 
677
- if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
803
+ if (maxBodyLength > -1 && data.length > maxBodyLength) {
678
804
  return reject(
679
805
  new AxiosError(
680
806
  'Request body larger than maxBodyLength limit',
@@ -726,12 +852,12 @@ export default isHttpAdapterSupported &&
726
852
  let auth = undefined;
727
853
  const configAuth = own('auth');
728
854
  if (configAuth) {
729
- const username = configAuth.username || '';
730
- const password = configAuth.password || '';
855
+ const username = utils.getSafeProp(configAuth, 'username') || '';
856
+ const password = utils.getSafeProp(configAuth, 'password') || '';
731
857
  auth = username + ':' + password;
732
858
  }
733
859
 
734
- if (!auth && parsed.username) {
860
+ if (!auth && (parsed.username || parsed.password)) {
735
861
  const urlUsername = decodeURIComponentSafe(parsed.username);
736
862
  const urlPassword = decodeURIComponentSafe(parsed.password);
737
863
  auth = urlUsername + ':' + urlPassword;
@@ -744,20 +870,22 @@ export default isHttpAdapterSupported &&
744
870
  try {
745
871
  path = buildURL(
746
872
  parsed.pathname + parsed.search,
747
- config.params,
748
- config.paramsSerializer
873
+ own('params'),
874
+ own('paramsSerializer')
749
875
  ).replace(/^\?/, '');
750
876
  } catch (err) {
751
- const customErr = new Error(err.message);
752
- customErr.config = config;
753
- customErr.url = config.url;
754
- customErr.exists = true;
755
- return reject(customErr);
877
+ return reject(
878
+ AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config, null, null, {
879
+ url: own('url'),
880
+ exists: true
881
+ })
882
+ );
756
883
  }
757
884
 
758
885
  headers.set(
759
886
  'Accept-Encoding',
760
- 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''),
887
+ utils.hasOwnProp(transitional, 'advertiseZstdAcceptEncoding') &&
888
+ transitional.advertiseZstdAcceptEncoding === true ? ACCEPT_ENCODING_WITH_ZSTD : ACCEPT_ENCODING,
761
889
  false
762
890
  );
763
891
 
@@ -766,8 +894,8 @@ export default isHttpAdapterSupported &&
766
894
  const options = Object.assign(Object.create(null), {
767
895
  path,
768
896
  method: method,
769
- headers: headers.toJSON(),
770
- agents: { http: config.httpAgent, https: config.httpsAgent },
897
+ headers: toByteStringHeaderObject(headers),
898
+ agents: { http: httpAgent, https: httpsAgent },
771
899
  auth,
772
900
  protocol,
773
901
  family,
@@ -779,19 +907,20 @@ export default isHttpAdapterSupported &&
779
907
  // cacheable-lookup integration hotfix
780
908
  !utils.isUndefined(lookup) && (options.lookup = lookup);
781
909
 
782
- if (config.socketPath) {
783
- if (typeof config.socketPath !== 'string') {
910
+ if (socketPath) {
911
+ if (typeof socketPath !== 'string') {
784
912
  return reject(
785
913
  new AxiosError('socketPath must be a string', AxiosError.ERR_BAD_OPTION_VALUE, config)
786
914
  );
787
915
  }
788
916
 
789
- if (config.allowedSocketPaths != null) {
790
- const allowed = Array.isArray(config.allowedSocketPaths)
791
- ? config.allowedSocketPaths
792
- : [config.allowedSocketPaths];
917
+ const allowedSocketPaths = own('allowedSocketPaths');
918
+ if (allowedSocketPaths != null) {
919
+ const allowed = Array.isArray(allowedSocketPaths)
920
+ ? allowedSocketPaths
921
+ : [allowedSocketPaths];
793
922
 
794
- const resolvedSocket = resolvePath(config.socketPath);
923
+ const resolvedSocket = resolvePath(socketPath);
795
924
  const isAllowed = allowed.some(
796
925
  (entry) => typeof entry === 'string' && resolvePath(entry) === resolvedSocket
797
926
  );
@@ -799,7 +928,7 @@ export default isHttpAdapterSupported &&
799
928
  if (!isAllowed) {
800
929
  return reject(
801
930
  new AxiosError(
802
- `socketPath "${config.socketPath}" is not permitted by allowedSocketPaths`,
931
+ `socketPath "${socketPath}" is not permitted by allowedSocketPaths`,
803
932
  AxiosError.ERR_BAD_OPTION_VALUE,
804
933
  config
805
934
  )
@@ -807,7 +936,7 @@ export default isHttpAdapterSupported &&
807
936
  }
808
937
  }
809
938
 
810
- options.socketPath = config.socketPath;
939
+ options.socketPath = socketPath;
811
940
  } else {
812
941
  options.hostname = parsed.hostname.startsWith('[')
813
942
  ? parsed.hostname.slice(1, -1)
@@ -815,14 +944,26 @@ export default isHttpAdapterSupported &&
815
944
  options.port = parsed.port;
816
945
  setProxy(
817
946
  options,
818
- config.proxy,
819
- protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path
947
+ configProxy,
948
+ protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path,
949
+ false,
950
+ httpsAgent,
951
+ httpAgent
820
952
  );
821
953
  }
822
954
  let transport;
823
955
  let isNativeTransport = false;
956
+ // True only for the follow-redirects transport, which applies
957
+ // options.maxBodyLength itself. Every other transport (http2, native
958
+ // http/https, a user-supplied custom transport) needs the explicit
959
+ // byte-counting pipeline below to enforce maxBodyLength on streamed uploads.
960
+ let transportEnforcesMaxBodyLength = false;
824
961
  const isHttpsRequest = isHttps.test(options.protocol);
825
- options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
962
+ // Don't clobber a CONNECT-tunneling agent installed by setProxy() for an
963
+ // HTTPS target.
964
+ if (options.agent == null) {
965
+ options.agent = isHttpsRequest ? httpsAgent : httpAgent;
966
+ }
826
967
 
827
968
  if (isHttp2) {
828
969
  transport = http2Transport;
@@ -830,25 +971,85 @@ export default isHttpAdapterSupported &&
830
971
  const configTransport = own('transport');
831
972
  if (configTransport) {
832
973
  transport = configTransport;
833
- } else if (config.maxRedirects === 0) {
974
+ } else if (maxRedirects === 0) {
834
975
  transport = isHttpsRequest ? https : http;
835
976
  isNativeTransport = true;
836
977
  } else {
837
- if (config.maxRedirects) {
838
- options.maxRedirects = config.maxRedirects;
978
+ transportEnforcesMaxBodyLength = true;
979
+ options.sensitiveHeaders = [];
980
+ if (maxRedirects) {
981
+ options.maxRedirects = maxRedirects;
839
982
  }
840
983
  const configBeforeRedirect = own('beforeRedirect');
841
984
  if (configBeforeRedirect) {
842
985
  options.beforeRedirects.config = configBeforeRedirect;
843
986
  }
987
+ if (auth) {
988
+ // Restore HTTP Basic credentials on same-origin redirects only.
989
+ // follow-redirects >= 1.15.8 strips Authorization on every redirect (see #6929);
990
+ // cross-origin stripping is the documented mitigation for T-R2 in THREATMODEL.md
991
+ // and is preserved by deliberately not restoring on origin change.
992
+ const requestOrigin = parsed.origin;
993
+ const authToRestore = auth;
994
+ options.beforeRedirects.auth = function beforeRedirectAuth(redirectOptions) {
995
+ try {
996
+ if (new URL(redirectOptions.href).origin === requestOrigin) {
997
+ redirectOptions.auth = authToRestore;
998
+ }
999
+ } catch (e) {
1000
+ // ignore malformed URL: leaving auth stripped is fail-safe
1001
+ }
1002
+ };
1003
+ }
1004
+ const sensitiveHeaders = own('sensitiveHeaders');
1005
+ if (sensitiveHeaders != null) {
1006
+ if (!utils.isArray(sensitiveHeaders)) {
1007
+ return reject(
1008
+ new AxiosError(
1009
+ 'sensitiveHeaders must be an array of strings',
1010
+ AxiosError.ERR_BAD_OPTION_VALUE,
1011
+ config
1012
+ )
1013
+ );
1014
+ }
1015
+
1016
+ const sensitiveSet = new Set();
1017
+ for (const header of sensitiveHeaders) {
1018
+ if (!utils.isString(header)) {
1019
+ return reject(
1020
+ new AxiosError(
1021
+ 'sensitiveHeaders must be an array of strings',
1022
+ AxiosError.ERR_BAD_OPTION_VALUE,
1023
+ config
1024
+ )
1025
+ );
1026
+ }
1027
+
1028
+ sensitiveSet.add(header.toLowerCase());
1029
+ }
1030
+
1031
+ if (sensitiveSet.size) {
1032
+ options.sensitiveHeaders = Array.from(sensitiveSet);
1033
+ options.beforeRedirects.sensitiveHeaders = function beforeRedirectSensitiveHeaders(
1034
+ redirectOptions,
1035
+ requestDetails
1036
+ ) {
1037
+ if (!isSameOriginRedirect(redirectOptions, requestDetails)) {
1038
+ stripMatchingHeaders(redirectOptions.headers, sensitiveSet);
1039
+ }
1040
+ };
1041
+ }
1042
+ }
844
1043
  transport = isHttpsRequest ? httpsFollow : httpFollow;
845
1044
  }
846
1045
  }
847
1046
 
848
- if (config.maxBodyLength > -1) {
849
- options.maxBodyLength = config.maxBodyLength;
1047
+ // Set an explicit maxBodyLength option for transports that inspect it.
1048
+ // When maxBodyLength is -1 (default/unlimited), use Infinity so
1049
+ // follow-redirects does not fall back to its own 10MB default.
1050
+ if (maxBodyLength > -1) {
1051
+ options.maxBodyLength = maxBodyLength;
850
1052
  } else {
851
- // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
852
1053
  options.maxBodyLength = Infinity;
853
1054
  }
854
1055
 
@@ -894,7 +1095,7 @@ export default isHttpAdapterSupported &&
894
1095
  const lastRequest = res.req || req;
895
1096
 
896
1097
  // if decompress disabled we should not decompress
897
- if (config.decompress !== false && res.headers['content-encoding']) {
1098
+ if (decompress !== false && res.headers['content-encoding']) {
898
1099
  // if no content, but headers still say that it is encoded,
899
1100
  // remove the header not confuse downstream operations
900
1101
  if (method === 'HEAD' || res.statusCode === 204) {
@@ -927,6 +1128,13 @@ export default isHttpAdapterSupported &&
927
1128
  streams.push(zlib.createBrotliDecompress(brotliOptions));
928
1129
  delete res.headers['content-encoding'];
929
1130
  }
1131
+ break;
1132
+ case 'zstd':
1133
+ if (isZstdSupported) {
1134
+ streams.push(zlib.createZstdDecompress(zstdOptions));
1135
+ delete res.headers['content-encoding'];
1136
+ }
1137
+ break;
930
1138
  }
931
1139
  }
932
1140
 
@@ -943,8 +1151,8 @@ export default isHttpAdapterSupported &&
943
1151
  if (responseType === 'stream') {
944
1152
  // Enforce maxContentLength on streamed responses; previously this
945
1153
  // was applied only to buffered responses.
946
- if (config.maxContentLength > -1) {
947
- const limit = config.maxContentLength;
1154
+ if (maxContentLength > -1) {
1155
+ const limit = maxContentLength;
948
1156
  const source = responseStream;
949
1157
  async function* enforceMaxContentLength() {
950
1158
  let totalResponseBytes = 0;
@@ -976,13 +1184,13 @@ export default isHttpAdapterSupported &&
976
1184
  totalResponseBytes += chunk.length;
977
1185
 
978
1186
  // make sure the content length is not over the maxContentLength if specified
979
- if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
1187
+ if (maxContentLength > -1 && totalResponseBytes > maxContentLength) {
980
1188
  // stream.destroy() emit aborted event before calling reject() on Node.js v16
981
1189
  rejected = true;
982
1190
  responseStream.destroy();
983
1191
  abort(
984
1192
  new AxiosError(
985
- 'maxContentLength size of ' + config.maxContentLength + ' exceeded',
1193
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
986
1194
  AxiosError.ERR_BAD_RESPONSE,
987
1195
  config,
988
1196
  lastRequest
@@ -1064,7 +1272,11 @@ export default isHttpAdapterSupported &&
1064
1272
 
1065
1273
  req.on('socket', function handleRequestSocket(socket) {
1066
1274
  // default interval of sending ack packet is 1 minute
1067
- socket.setKeepAlive(true, 1000 * 60);
1275
+ // proxy agents (e.g. agent-base) may return a generic Duplex stream
1276
+ // that doesn't have setKeepAlive, so guard before calling
1277
+ if (typeof socket.setKeepAlive === 'function') {
1278
+ socket.setKeepAlive(true, 1000 * 60);
1279
+ }
1068
1280
 
1069
1281
  // Install a single 'error' listener per socket (not per request) to avoid
1070
1282
  // accumulating listeners on pooled keep-alive sockets that get reassigned
@@ -1097,9 +1309,9 @@ export default isHttpAdapterSupported &&
1097
1309
  });
1098
1310
 
1099
1311
  // Handle request timeout
1100
- if (config.timeout) {
1312
+ if (own('timeout')) {
1101
1313
  // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
1102
- const timeout = parseInt(config.timeout, 10);
1314
+ const timeout = parseInt(own('timeout'), 10);
1103
1315
 
1104
1316
  if (Number.isNaN(timeout)) {
1105
1317
  abort(
@@ -1157,12 +1369,13 @@ export default isHttpAdapterSupported &&
1157
1369
  }
1158
1370
  });
1159
1371
 
1160
- // Enforce maxBodyLength for streamed uploads on the native http/https
1161
- // transport (maxRedirects === 0); follow-redirects enforces it on the
1162
- // other path.
1372
+ // Enforce maxBodyLength for streamed uploads on every transport that
1373
+ // does not apply options.maxBodyLength itself (native http/https, http2,
1374
+ // and user-supplied custom transports). The follow-redirects transport
1375
+ // enforces it on the redirected HTTP/1 path.
1163
1376
  let uploadStream = data;
1164
- if (config.maxBodyLength > -1 && config.maxRedirects === 0) {
1165
- const limit = config.maxBodyLength;
1377
+ if (maxBodyLength > -1 && !transportEnforcesMaxBodyLength) {
1378
+ const limit = maxBodyLength;
1166
1379
  let bytesSent = 0;
1167
1380
  uploadStream = stream.pipeline(
1168
1381
  [
@@ -1200,3 +1413,5 @@ export default isHttpAdapterSupported &&
1200
1413
  };
1201
1414
 
1202
1415
  export const __setProxy = setProxy;
1416
+ export const __isNodeEnvProxyEnabled = isNodeEnvProxyEnabled;
1417
+ export const __isSameOriginRedirect = isSameOriginRedirect;