@openclaw/slack 2026.6.11 → 2026.6.34

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 (102) hide show
  1. package/dist/account-inspect-api.js +1 -1
  2. package/dist/{account-inspect-DOtQbKkB.js → account-inspect-ldU97llt.js} +1 -1
  3. package/dist/{accounts-BPCiCe8y.js → accounts-C9Z3J3lT.js} +8 -1
  4. package/dist/accounts.runtime-4Xez0y2c.js +2 -0
  5. package/dist/{action-runtime-DfJK7zS0.js → action-runtime-z9j2PYiO.js} +4 -4
  6. package/dist/action-runtime.runtime-BuOQERTf.js +2 -0
  7. package/dist/{actions-OhnDIN4l.js → actions-CCTO1mVi.js} +3 -3
  8. package/dist/{actions.runtime-DkFXr3-k.js → actions.runtime-BaBCJbO3.js} +1 -1
  9. package/dist/api.js +12 -12
  10. package/dist/{approval-handler.runtime-CsFrthnF.js → approval-handler.runtime-Cw1Im48B.js} +2 -2
  11. package/dist/{channel-COCbJwom.js → channel-DLPyf4p_.js} +23 -17
  12. package/dist/channel-plugin-api.js +1 -1
  13. package/dist/{channel.setup-DYQGnKPK.js → channel.setup-RewyjVhG.js} +3 -3
  14. package/dist/{directory-config-DDVHDmrN.js → directory-config-NDOJRlhK.js} +1 -1
  15. package/dist/directory-contract-api.js +1 -1
  16. package/dist/{directory-live-DzOkmJVV.js → directory-live-CeVhaEVq.js} +1 -1
  17. package/dist/{interactive-replies-D-22gTp3.js → interactive-replies-BBZN1A9T.js} +1 -1
  18. package/dist/interactive-replies-api.js +1 -1
  19. package/dist/{message-tool-api--zYyTqrR.js → message-tool-api-OXkQLOkR.js} +2 -2
  20. package/dist/message-tool-api.js +1 -1
  21. package/dist/{monitor-Cy-0xYgF.js → monitor-CoF156tn.js} +3 -3
  22. package/dist/{outbound-adapter-CzX4D5K_.js → outbound-adapter-DqEIkSaa.js} +3 -3
  23. package/dist/{pipeline.runtime-5R4HgM_7.js → pipeline.runtime-Lp1AVrkR.js} +74 -59
  24. package/dist/{policy-Bi92bs5t.js → policy-hyhJMisM.js} +1 -1
  25. package/dist/{probe-BRsYAcGR.js → probe-PFduhlzL.js} +8 -2
  26. package/dist/{provider-7YKru1TZ.js → provider-CQvIQMod.js} +49 -31
  27. package/dist/{relay-source-42fP7Ktr.js → relay-source-Bv6k-bAg.js} +1 -1
  28. package/dist/{replies-Dlxge48k.js → replies-DM1Qi_1b.js} +3 -3
  29. package/dist/{reply-blocks-BT_sNsDQ.js → reply-blocks-0ofUZd6K.js} +1 -1
  30. package/dist/runtime-api.js +9 -9
  31. package/dist/{send-CRoD-UQw.js → send-CrC49d83.js} +3 -3
  32. package/dist/send.runtime-B_nPiIPk.js +2 -0
  33. package/dist/{setup-core-BCGzyZhx.js → setup-core-DPMX-Z6o.js} +2 -2
  34. package/dist/setup-plugin-api.js +1 -1
  35. package/dist/{setup-surface-D4GE34e2.js → setup-surface-BCB7d1mL.js} +3 -3
  36. package/dist/{shared-BtJS2bUx.js → shared-CQ2R9FGA.js} +4 -4
  37. package/dist/{slash-dispatch.runtime-D1qKAWNN.js → slash-dispatch.runtime-CCP3os2O.js} +1 -1
  38. package/node_modules/agent-base/README.md +145 -0
  39. package/node_modules/agent-base/dist/src/index.d.ts +78 -0
  40. package/node_modules/agent-base/dist/src/index.js +203 -0
  41. package/node_modules/agent-base/dist/src/index.js.map +1 -0
  42. package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
  43. package/node_modules/agent-base/dist/src/promisify.js +18 -0
  44. package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
  45. package/node_modules/agent-base/package.json +64 -0
  46. package/node_modules/agent-base/src/index.ts +345 -0
  47. package/node_modules/agent-base/src/promisify.ts +33 -0
  48. package/node_modules/axios/CHANGELOG.md +165 -1
  49. package/node_modules/axios/README.md +310 -247
  50. package/node_modules/axios/dist/axios.js +533 -197
  51. package/node_modules/axios/dist/axios.min.js +3 -3
  52. package/node_modules/axios/dist/axios.min.js.map +1 -1
  53. package/node_modules/axios/dist/browser/axios.cjs +564 -161
  54. package/node_modules/axios/dist/esm/axios.js +564 -161
  55. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  56. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  57. package/node_modules/axios/dist/node/axios.cjs +839 -281
  58. package/node_modules/axios/index.d.cts +11 -4
  59. package/node_modules/axios/index.d.ts +7 -2
  60. package/node_modules/axios/lib/adapters/fetch.js +196 -37
  61. package/node_modules/axios/lib/adapters/http.js +328 -185
  62. package/node_modules/axios/lib/adapters/xhr.js +2 -1
  63. package/node_modules/axios/lib/core/Axios.js +4 -2
  64. package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
  65. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  66. package/node_modules/axios/lib/core/mergeConfig.js +34 -0
  67. package/node_modules/axios/lib/defaults/transitional.js +2 -0
  68. package/node_modules/axios/lib/env/data.js +1 -1
  69. package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
  70. package/node_modules/axios/lib/helpers/buildURL.js +6 -4
  71. package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
  72. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  73. package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
  74. package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
  75. package/node_modules/axios/lib/helpers/fromDataURI.js +18 -5
  76. package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
  77. package/node_modules/axios/lib/helpers/resolveConfig.js +17 -9
  78. package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
  79. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  80. package/node_modules/axios/lib/helpers/toFormData.js +41 -11
  81. package/node_modules/axios/lib/utils.js +105 -19
  82. package/node_modules/axios/package.json +31 -13
  83. package/node_modules/https-proxy-agent/README.md +137 -0
  84. package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
  85. package/node_modules/https-proxy-agent/dist/agent.js +177 -0
  86. package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
  87. package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
  88. package/node_modules/https-proxy-agent/dist/index.js +14 -0
  89. package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
  90. package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
  91. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
  92. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
  93. package/node_modules/https-proxy-agent/package.json +56 -0
  94. package/npm-shrinkwrap.json +32 -6
  95. package/package.json +4 -4
  96. package/dist/accounts.runtime-CgWgzjLX.js +0 -2
  97. package/dist/action-runtime.runtime-CIYPRrNy.js +0 -2
  98. package/dist/send.runtime-C_y65BU0.js +0 -2
  99. package/node_modules/axios/dist/axios.js.map +0 -1
  100. package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
  101. package/node_modules/axios/dist/esm/axios.js.map +0 -1
  102. 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,53 @@ 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
+
93
+ function getTunnelingAgent(agentOptions, userHttpsAgent) {
94
+ const key =
95
+ agentOptions.protocol +
96
+ '//' +
97
+ agentOptions.hostname +
98
+ ':' +
99
+ (agentOptions.port || '') +
100
+ '#' +
101
+ (agentOptions.auth || '');
102
+ const cache = userHttpsAgent
103
+ ? (tunnelingAgentCacheUser.get(userHttpsAgent) ||
104
+ tunnelingAgentCacheUser.set(userHttpsAgent, new Map()).get(userHttpsAgent))
105
+ : tunnelingAgentCache;
106
+ let agent = cache.get(key);
107
+ if (agent) return agent;
108
+ // Forward the user's TLS options (custom CA, rejectUnauthorized, client cert,
109
+ // etc.) into the tunneling agent so they apply to the origin TLS upgrade
110
+ // performed after CONNECT. Our proxy fields take precedence on conflict.
111
+ const merged = userHttpsAgent && userHttpsAgent.options
112
+ ? { ...userHttpsAgent.options, ...agentOptions }
113
+ : agentOptions;
114
+ agent = new HttpsProxyAgent(merged);
115
+ if (userHttpsAgent && userHttpsAgent.options) {
116
+ const originTLSOptions = { ...userHttpsAgent.options };
117
+ const callback = agent.callback;
118
+ agent.callback = function axiosTunnelingAgentCallback(req, opts) {
119
+ // HttpsProxyAgent v5 reads callback opts for the post-CONNECT origin TLS upgrade.
120
+ return callback.call(this, req, { ...originTLSOptions, ...opts });
121
+ };
122
+ }
123
+ agent[kAxiosInstalledTunnel] = true;
124
+ cache.set(key, agent);
125
+ return agent;
126
+ }
127
+
70
128
  const supportedProtocols = platform.protocols.map((protocol) => {
71
129
  return protocol + ':';
72
130
  });
@@ -93,114 +151,11 @@ const flushOnFinish = (stream, [throttled, flush]) => {
93
151
  return throttled;
94
152
  };
95
153
 
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
154
  const http2Sessions = new Http2Sessions();
200
155
 
201
156
  /**
202
- * If the proxy or config beforeRedirects functions are defined, call them with the options
203
- * object.
157
+ * If the proxy, auth, sensitive header, or config beforeRedirects functions are defined,
158
+ * call them with the options object.
204
159
  *
205
160
  * @param {Object<string, any>} options - The options object that was passed to the request.
206
161
  *
@@ -210,11 +165,42 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
210
165
  if (options.beforeRedirects.proxy) {
211
166
  options.beforeRedirects.proxy(options);
212
167
  }
168
+ if (options.beforeRedirects.auth) {
169
+ options.beforeRedirects.auth(options);
170
+ }
171
+ if (options.beforeRedirects.sensitiveHeaders) {
172
+ options.beforeRedirects.sensitiveHeaders(options, requestDetails);
173
+ }
213
174
  if (options.beforeRedirects.config) {
214
175
  options.beforeRedirects.config(options, responseDetails, requestDetails);
215
176
  }
216
177
  }
217
178
 
179
+ function stripMatchingHeaders(headers, sensitiveSet) {
180
+ if (!headers) {
181
+ return;
182
+ }
183
+
184
+ Object.keys(headers).forEach((header) => {
185
+ if (sensitiveSet.has(header.toLowerCase())) {
186
+ delete headers[header];
187
+ }
188
+ });
189
+ }
190
+
191
+ function isSameOriginRedirect(redirectOptions, requestDetails) {
192
+ if (!requestDetails) {
193
+ return false;
194
+ }
195
+
196
+ try {
197
+ return new URL(requestDetails.url).origin === new URL(redirectOptions.href).origin;
198
+ } catch (e) {
199
+ // If origin comparison fails, treat the redirect as unsafe.
200
+ return false;
201
+ }
202
+ }
203
+
218
204
  /**
219
205
  * If the proxy or config afterRedirects functions are defined, call them with the options
220
206
  *
@@ -224,7 +210,7 @@ function dispatchBeforeRedirect(options, responseDetails, requestDetails) {
224
210
  *
225
211
  * @returns {http.ClientRequestArgs}
226
212
  */
227
- function setProxy(options, configProxy, location, isRedirect) {
213
+ function setProxy(options, configProxy, location, isRedirect, configHttpsAgent) {
228
214
  let proxy = configProxy;
229
215
  if (!proxy && proxy !== false) {
230
216
  const proxyUrl = getProxyForUrl(location);
@@ -245,6 +231,13 @@ function setProxy(options, configProxy, location, isRedirect) {
245
231
  }
246
232
  }
247
233
  }
234
+ // Strip any tunneling agent we installed for the previous hop so a redirect
235
+ // that drops the proxy or crosses an HTTPS↔HTTP boundary doesn't reuse a
236
+ // stale one. Match on our Symbol marker so a user-supplied HttpsProxyAgent
237
+ // (which won't carry the marker) is left alone.
238
+ if (isRedirect && options.agent && options.agent[kAxiosInstalledTunnel]) {
239
+ options.agent = undefined;
240
+ }
248
241
  if (proxy) {
249
242
  // Read proxy fields without traversing the prototype chain. URL instances expose
250
243
  // username/password/hostname/host/port/protocol via getters on URL.prototype (so
@@ -281,40 +274,96 @@ function setProxy(options, configProxy, location, isRedirect) {
281
274
  } else if (authIsObject) {
282
275
  throw new AxiosError('Invalid proxy authorization', AxiosError.ERR_BAD_OPTION, { proxy });
283
276
  }
284
-
285
- const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64');
286
-
287
- options.headers['Proxy-Authorization'] = 'Basic ' + base64;
288
277
  }
289
278
 
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;
279
+ const targetIsHttps = isHttps.test(options.protocol);
280
+
281
+ if (targetIsHttps) {
282
+ // CONNECT-tunneling path for HTTPS targets. Preserves end-to-end TLS to
283
+ // the origin so the proxy cannot inspect the URL, headers, or body — the
284
+ // behavior already promised by THREATMODEL.md (T-R9). HttpsProxyAgent
285
+ // sends Proxy-Authorization on the CONNECT request only, never on the
286
+ // wrapped TLS request, which is why we don't stamp it onto
287
+ // options.headers here. If the user already supplied an HttpsProxyAgent,
288
+ // they own tunneling end-to-end and we leave them alone; otherwise we
289
+ // install our own tunneling agent and forward their TLS options (if any)
290
+ // so a custom httpsAgent for cert pinning / rejectUnauthorized still
291
+ // applies to the origin TLS upgrade.
292
+ if (!(configHttpsAgent instanceof HttpsProxyAgent)) {
293
+ const proxyHost = readProxyField('hostname') || readProxyField('host');
294
+ const proxyPort = readProxyField('port');
295
+ const rawProxyProtocol = readProxyField('protocol');
296
+ const normalizedProtocol = rawProxyProtocol
297
+ ? rawProxyProtocol.includes(':')
298
+ ? rawProxyProtocol
299
+ : `${rawProxyProtocol}:`
300
+ : 'http:';
301
+ // Bracket IPv6 literals for URL parsing; URL.hostname strips the
302
+ // brackets again on read so the agent receives the raw form.
303
+ const proxyHostForURL =
304
+ proxyHost && proxyHost.includes(':') && !proxyHost.startsWith('[')
305
+ ? `[${proxyHost}]`
306
+ : proxyHost;
307
+ const proxyURL = new URL(
308
+ `${normalizedProtocol}//${proxyHostForURL}${proxyPort ? ':' + proxyPort : ''}`
309
+ );
310
+ const agentOptions = {
311
+ protocol: proxyURL.protocol,
312
+ hostname: proxyURL.hostname.replace(/^\[|\]$/g, ''),
313
+ port: proxyURL.port,
314
+ auth: proxyAuth && typeof proxyAuth === 'string' ? proxyAuth : undefined,
315
+ };
316
+ if (proxyURL.protocol === 'https:') {
317
+ agentOptions.ALPNProtocols = ['http/1.1'];
318
+ }
319
+ const tunnelingAgent = getTunnelingAgent(agentOptions, configHttpsAgent);
320
+ // Set both: `options.agent` is consumed by the native https.request path
321
+ // (maxRedirects === 0); `options.agents.https` is consumed by
322
+ // follow-redirects, which ignores `options.agent` when `options.agents`
323
+ // is present.
324
+ options.agent = tunnelingAgent;
325
+ if (options.agents) {
326
+ options.agents.https = tunnelingAgent;
327
+ }
328
+ }
329
+ } else {
330
+ // Forward-proxy mode for plaintext HTTP targets. The request line carries
331
+ // the absolute URL and the proxy sees everything — acceptable for plain
332
+ // HTTP since the wire was already plaintext.
333
+ if (proxyAuth) {
334
+ const base64 = Buffer.from(proxyAuth, 'utf8').toString('base64');
335
+ options.headers['Proxy-Authorization'] = 'Basic ' + base64;
336
+ }
337
+
338
+ // Preserve a user-supplied Host header (case-insensitive) so callers can override
339
+ // the value forwarded to the proxy; otherwise default to the request URL's host.
340
+ let hasUserHostHeader = false;
341
+ for (const name of Object.keys(options.headers)) {
342
+ if (name.toLowerCase() === 'host') {
343
+ hasUserHostHeader = true;
344
+ break;
345
+ }
346
+ }
347
+ if (!hasUserHostHeader) {
348
+ options.headers.host = options.hostname + (options.port ? ':' + options.port : '');
349
+ }
350
+ const proxyHost = readProxyField('hostname') || readProxyField('host');
351
+ options.hostname = proxyHost;
352
+ // Replace 'host' since options is not a URL object
353
+ options.host = proxyHost;
354
+ options.port = readProxyField('port');
355
+ options.path = location;
356
+ const proxyProtocol = readProxyField('protocol');
357
+ if (proxyProtocol) {
358
+ options.protocol = proxyProtocol.includes(':') ? proxyProtocol : `${proxyProtocol}:`;
297
359
  }
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
360
  }
312
361
  }
313
362
 
314
363
  options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {
315
364
  // Configure proxy for redirected request, passing the original config proxy to apply
316
365
  // the exact same logic as if the redirected request was performed by axios directly.
317
- setProxy(redirectOptions, configProxy, redirectOptions.href, true);
366
+ setProxy(redirectOptions, configProxy, redirectOptions.href, true, configHttpsAgent);
318
367
  };
319
368
  }
320
369
 
@@ -413,7 +462,13 @@ const http2Transport = {
413
462
  export default isHttpAdapterSupported &&
414
463
  function httpAdapter(config) {
415
464
  return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
416
- const own = (key) => (utils.hasOwnProp(config, key) ? config[key] : undefined);
465
+ // Read config pollution-safely: own properties and members inherited from
466
+ // a non-Object.prototype source (e.g. an Object.create(defaults) template)
467
+ // are honored, but values injected onto a polluted Object.prototype are
468
+ // ignored. All behavior-affecting reads in this adapter go through own()
469
+ // so the protection boundary stays consistent.
470
+ const own = (key) => utils.getSafeProp(config, key);
471
+ const transitional = own('transitional') || transitionalDefaults;
417
472
  let data = own('data');
418
473
  let lookup = own('lookup');
419
474
  let family = own('family');
@@ -422,7 +477,13 @@ export default isHttpAdapterSupported &&
422
477
  let http2Options = own('http2Options');
423
478
  const responseType = own('responseType');
424
479
  const responseEncoding = own('responseEncoding');
425
- const method = config.method.toUpperCase();
480
+ const httpAgent = own('httpAgent');
481
+ const httpsAgent = own('httpsAgent');
482
+ const method = own('method').toUpperCase();
483
+ const maxRedirects = own('maxRedirects');
484
+ const maxBodyLength = own('maxBodyLength');
485
+ const maxContentLength = own('maxContentLength');
486
+ const decompress = own('decompress');
426
487
  let isDone;
427
488
  let rejected = false;
428
489
  let req;
@@ -467,7 +528,7 @@ export default isHttpAdapterSupported &&
467
528
  !reason || reason.type ? new CanceledError(null, config, req) : reason
468
529
  );
469
530
  } catch (err) {
470
- console.warn('emit error', err);
531
+ // ignore emit errors
471
532
  }
472
533
  }
473
534
 
@@ -479,12 +540,13 @@ export default isHttpAdapterSupported &&
479
540
  }
480
541
 
481
542
  function createTimeoutError() {
482
- let timeoutErrorMessage = config.timeout
483
- ? 'timeout of ' + config.timeout + 'ms exceeded'
543
+ const configTimeout = own('timeout');
544
+ let timeoutErrorMessage = configTimeout
545
+ ? 'timeout of ' + configTimeout + 'ms exceeded'
484
546
  : 'timeout exceeded';
485
- const transitional = config.transitional || transitionalDefaults;
486
- if (config.timeoutErrorMessage) {
487
- timeoutErrorMessage = config.timeoutErrorMessage;
547
+ const configTimeoutErrorMessage = own('timeoutErrorMessage');
548
+ if (configTimeoutErrorMessage) {
549
+ timeoutErrorMessage = configTimeoutErrorMessage;
488
550
  }
489
551
  return new AxiosError(
490
552
  timeoutErrorMessage,
@@ -540,21 +602,21 @@ export default isHttpAdapterSupported &&
540
602
  });
541
603
 
542
604
  // Parse url
543
- const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
605
+ const fullPath = buildFullPath(own('baseURL'), own('url'), own('allowAbsoluteUrls'), config);
544
606
  const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
545
607
  const protocol = parsed.protocol || supportedProtocols[0];
546
608
 
547
609
  if (protocol === 'data:') {
548
610
  // 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 || '');
611
+ if (maxContentLength > -1) {
612
+ // Use the exact string passed to fromDataURI (the configured url); fall back to fullPath if needed.
613
+ const dataUrl = String(own('url') || fullPath || '');
552
614
  const estimated = estimateDataURLDecodedBytes(dataUrl);
553
615
 
554
- if (estimated > config.maxContentLength) {
616
+ if (estimated > maxContentLength) {
555
617
  return reject(
556
618
  new AxiosError(
557
- 'maxContentLength size of ' + config.maxContentLength + ' exceeded',
619
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
558
620
  AxiosError.ERR_BAD_RESPONSE,
559
621
  config
560
622
  )
@@ -574,7 +636,7 @@ export default isHttpAdapterSupported &&
574
636
  }
575
637
 
576
638
  try {
577
- convertedData = fromDataURI(config.url, responseType === 'blob', {
639
+ convertedData = fromDataURI(own('url'), responseType === 'blob', {
578
640
  Blob: config.env && config.env.Blob,
579
641
  });
580
642
  } catch (err) {
@@ -674,7 +736,7 @@ export default isHttpAdapterSupported &&
674
736
  // Add Content-Length header if data exists
675
737
  headers.setContentLength(data.length, false);
676
738
 
677
- if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {
739
+ if (maxBodyLength > -1 && data.length > maxBodyLength) {
678
740
  return reject(
679
741
  new AxiosError(
680
742
  'Request body larger than maxBodyLength limit',
@@ -726,12 +788,12 @@ export default isHttpAdapterSupported &&
726
788
  let auth = undefined;
727
789
  const configAuth = own('auth');
728
790
  if (configAuth) {
729
- const username = configAuth.username || '';
730
- const password = configAuth.password || '';
791
+ const username = utils.getSafeProp(configAuth, 'username') || '';
792
+ const password = utils.getSafeProp(configAuth, 'password') || '';
731
793
  auth = username + ':' + password;
732
794
  }
733
795
 
734
- if (!auth && parsed.username) {
796
+ if (!auth && (parsed.username || parsed.password)) {
735
797
  const urlUsername = decodeURIComponentSafe(parsed.username);
736
798
  const urlPassword = decodeURIComponentSafe(parsed.password);
737
799
  auth = urlUsername + ':' + urlPassword;
@@ -744,20 +806,21 @@ export default isHttpAdapterSupported &&
744
806
  try {
745
807
  path = buildURL(
746
808
  parsed.pathname + parsed.search,
747
- config.params,
748
- config.paramsSerializer
809
+ own('params'),
810
+ own('paramsSerializer')
749
811
  ).replace(/^\?/, '');
750
812
  } catch (err) {
751
813
  const customErr = new Error(err.message);
752
814
  customErr.config = config;
753
- customErr.url = config.url;
815
+ customErr.url = own('url');
754
816
  customErr.exists = true;
755
817
  return reject(customErr);
756
818
  }
757
819
 
758
820
  headers.set(
759
821
  'Accept-Encoding',
760
- 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''),
822
+ utils.hasOwnProp(transitional, 'advertiseZstdAcceptEncoding') &&
823
+ transitional.advertiseZstdAcceptEncoding === true ? ACCEPT_ENCODING_WITH_ZSTD : ACCEPT_ENCODING,
761
824
  false
762
825
  );
763
826
 
@@ -766,8 +829,8 @@ export default isHttpAdapterSupported &&
766
829
  const options = Object.assign(Object.create(null), {
767
830
  path,
768
831
  method: method,
769
- headers: headers.toJSON(),
770
- agents: { http: config.httpAgent, https: config.httpsAgent },
832
+ headers: toByteStringHeaderObject(headers),
833
+ agents: { http: httpAgent, https: httpsAgent },
771
834
  auth,
772
835
  protocol,
773
836
  family,
@@ -779,19 +842,21 @@ export default isHttpAdapterSupported &&
779
842
  // cacheable-lookup integration hotfix
780
843
  !utils.isUndefined(lookup) && (options.lookup = lookup);
781
844
 
782
- if (config.socketPath) {
783
- if (typeof config.socketPath !== 'string') {
845
+ const socketPath = own('socketPath');
846
+ if (socketPath) {
847
+ if (typeof socketPath !== 'string') {
784
848
  return reject(
785
849
  new AxiosError('socketPath must be a string', AxiosError.ERR_BAD_OPTION_VALUE, config)
786
850
  );
787
851
  }
788
852
 
789
- if (config.allowedSocketPaths != null) {
790
- const allowed = Array.isArray(config.allowedSocketPaths)
791
- ? config.allowedSocketPaths
792
- : [config.allowedSocketPaths];
853
+ const allowedSocketPaths = own('allowedSocketPaths');
854
+ if (allowedSocketPaths != null) {
855
+ const allowed = Array.isArray(allowedSocketPaths)
856
+ ? allowedSocketPaths
857
+ : [allowedSocketPaths];
793
858
 
794
- const resolvedSocket = resolvePath(config.socketPath);
859
+ const resolvedSocket = resolvePath(socketPath);
795
860
  const isAllowed = allowed.some(
796
861
  (entry) => typeof entry === 'string' && resolvePath(entry) === resolvedSocket
797
862
  );
@@ -799,7 +864,7 @@ export default isHttpAdapterSupported &&
799
864
  if (!isAllowed) {
800
865
  return reject(
801
866
  new AxiosError(
802
- `socketPath "${config.socketPath}" is not permitted by allowedSocketPaths`,
867
+ `socketPath "${socketPath}" is not permitted by allowedSocketPaths`,
803
868
  AxiosError.ERR_BAD_OPTION_VALUE,
804
869
  config
805
870
  )
@@ -807,7 +872,7 @@ export default isHttpAdapterSupported &&
807
872
  }
808
873
  }
809
874
 
810
- options.socketPath = config.socketPath;
875
+ options.socketPath = socketPath;
811
876
  } else {
812
877
  options.hostname = parsed.hostname.startsWith('[')
813
878
  ? parsed.hostname.slice(1, -1)
@@ -815,14 +880,25 @@ export default isHttpAdapterSupported &&
815
880
  options.port = parsed.port;
816
881
  setProxy(
817
882
  options,
818
- config.proxy,
819
- protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path
883
+ own('proxy'),
884
+ protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path,
885
+ false,
886
+ httpsAgent
820
887
  );
821
888
  }
822
889
  let transport;
823
890
  let isNativeTransport = false;
891
+ // True only for the follow-redirects transport, which applies
892
+ // options.maxBodyLength itself. Every other transport (http2, native
893
+ // http/https, a user-supplied custom transport) needs the explicit
894
+ // byte-counting pipeline below to enforce maxBodyLength on streamed uploads.
895
+ let transportEnforcesMaxBodyLength = false;
824
896
  const isHttpsRequest = isHttps.test(options.protocol);
825
- options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
897
+ // Don't clobber a CONNECT-tunneling agent installed by setProxy() for an
898
+ // HTTPS target.
899
+ if (options.agent == null) {
900
+ options.agent = isHttpsRequest ? httpsAgent : httpAgent;
901
+ }
826
902
 
827
903
  if (isHttp2) {
828
904
  transport = http2Transport;
@@ -830,23 +906,81 @@ export default isHttpAdapterSupported &&
830
906
  const configTransport = own('transport');
831
907
  if (configTransport) {
832
908
  transport = configTransport;
833
- } else if (config.maxRedirects === 0) {
909
+ } else if (maxRedirects === 0) {
834
910
  transport = isHttpsRequest ? https : http;
835
911
  isNativeTransport = true;
836
912
  } else {
837
- if (config.maxRedirects) {
838
- options.maxRedirects = config.maxRedirects;
913
+ transportEnforcesMaxBodyLength = true;
914
+ options.sensitiveHeaders = [];
915
+ if (maxRedirects) {
916
+ options.maxRedirects = maxRedirects;
839
917
  }
840
918
  const configBeforeRedirect = own('beforeRedirect');
841
919
  if (configBeforeRedirect) {
842
920
  options.beforeRedirects.config = configBeforeRedirect;
843
921
  }
922
+ if (auth) {
923
+ // Restore HTTP Basic credentials on same-origin redirects only.
924
+ // follow-redirects >= 1.15.8 strips Authorization on every redirect (see #6929);
925
+ // cross-origin stripping is the documented mitigation for T-R2 in THREATMODEL.md
926
+ // and is preserved by deliberately not restoring on origin change.
927
+ const requestOrigin = parsed.origin;
928
+ const authToRestore = auth;
929
+ options.beforeRedirects.auth = function beforeRedirectAuth(redirectOptions) {
930
+ try {
931
+ if (new URL(redirectOptions.href).origin === requestOrigin) {
932
+ redirectOptions.auth = authToRestore;
933
+ }
934
+ } catch (e) {
935
+ // ignore malformed URL: leaving auth stripped is fail-safe
936
+ }
937
+ };
938
+ }
939
+ const sensitiveHeaders = own('sensitiveHeaders');
940
+ if (sensitiveHeaders != null) {
941
+ if (!utils.isArray(sensitiveHeaders)) {
942
+ return reject(
943
+ new AxiosError(
944
+ 'sensitiveHeaders must be an array of strings',
945
+ AxiosError.ERR_BAD_OPTION_VALUE,
946
+ config
947
+ )
948
+ );
949
+ }
950
+
951
+ const sensitiveSet = new Set();
952
+ for (const header of sensitiveHeaders) {
953
+ if (!utils.isString(header)) {
954
+ return reject(
955
+ new AxiosError(
956
+ 'sensitiveHeaders must be an array of strings',
957
+ AxiosError.ERR_BAD_OPTION_VALUE,
958
+ config
959
+ )
960
+ );
961
+ }
962
+
963
+ sensitiveSet.add(header.toLowerCase());
964
+ }
965
+
966
+ if (sensitiveSet.size) {
967
+ options.sensitiveHeaders = Array.from(sensitiveSet);
968
+ options.beforeRedirects.sensitiveHeaders = function beforeRedirectSensitiveHeaders(
969
+ redirectOptions,
970
+ requestDetails
971
+ ) {
972
+ if (!isSameOriginRedirect(redirectOptions, requestDetails)) {
973
+ stripMatchingHeaders(redirectOptions.headers, sensitiveSet);
974
+ }
975
+ };
976
+ }
977
+ }
844
978
  transport = isHttpsRequest ? httpsFollow : httpFollow;
845
979
  }
846
980
  }
847
981
 
848
- if (config.maxBodyLength > -1) {
849
- options.maxBodyLength = config.maxBodyLength;
982
+ if (maxBodyLength > -1) {
983
+ options.maxBodyLength = maxBodyLength;
850
984
  } else {
851
985
  // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
852
986
  options.maxBodyLength = Infinity;
@@ -894,7 +1028,7 @@ export default isHttpAdapterSupported &&
894
1028
  const lastRequest = res.req || req;
895
1029
 
896
1030
  // if decompress disabled we should not decompress
897
- if (config.decompress !== false && res.headers['content-encoding']) {
1031
+ if (decompress !== false && res.headers['content-encoding']) {
898
1032
  // if no content, but headers still say that it is encoded,
899
1033
  // remove the header not confuse downstream operations
900
1034
  if (method === 'HEAD' || res.statusCode === 204) {
@@ -927,6 +1061,13 @@ export default isHttpAdapterSupported &&
927
1061
  streams.push(zlib.createBrotliDecompress(brotliOptions));
928
1062
  delete res.headers['content-encoding'];
929
1063
  }
1064
+ break;
1065
+ case 'zstd':
1066
+ if (isZstdSupported) {
1067
+ streams.push(zlib.createZstdDecompress(zstdOptions));
1068
+ delete res.headers['content-encoding'];
1069
+ }
1070
+ break;
930
1071
  }
931
1072
  }
932
1073
 
@@ -943,8 +1084,8 @@ export default isHttpAdapterSupported &&
943
1084
  if (responseType === 'stream') {
944
1085
  // Enforce maxContentLength on streamed responses; previously this
945
1086
  // was applied only to buffered responses.
946
- if (config.maxContentLength > -1) {
947
- const limit = config.maxContentLength;
1087
+ if (maxContentLength > -1) {
1088
+ const limit = maxContentLength;
948
1089
  const source = responseStream;
949
1090
  async function* enforceMaxContentLength() {
950
1091
  let totalResponseBytes = 0;
@@ -976,13 +1117,13 @@ export default isHttpAdapterSupported &&
976
1117
  totalResponseBytes += chunk.length;
977
1118
 
978
1119
  // make sure the content length is not over the maxContentLength if specified
979
- if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
1120
+ if (maxContentLength > -1 && totalResponseBytes > maxContentLength) {
980
1121
  // stream.destroy() emit aborted event before calling reject() on Node.js v16
981
1122
  rejected = true;
982
1123
  responseStream.destroy();
983
1124
  abort(
984
1125
  new AxiosError(
985
- 'maxContentLength size of ' + config.maxContentLength + ' exceeded',
1126
+ 'maxContentLength size of ' + maxContentLength + ' exceeded',
986
1127
  AxiosError.ERR_BAD_RESPONSE,
987
1128
  config,
988
1129
  lastRequest
@@ -1097,9 +1238,9 @@ export default isHttpAdapterSupported &&
1097
1238
  });
1098
1239
 
1099
1240
  // Handle request timeout
1100
- if (config.timeout) {
1241
+ if (own('timeout')) {
1101
1242
  // 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);
1243
+ const timeout = parseInt(own('timeout'), 10);
1103
1244
 
1104
1245
  if (Number.isNaN(timeout)) {
1105
1246
  abort(
@@ -1157,12 +1298,13 @@ export default isHttpAdapterSupported &&
1157
1298
  }
1158
1299
  });
1159
1300
 
1160
- // Enforce maxBodyLength for streamed uploads on the native http/https
1161
- // transport (maxRedirects === 0); follow-redirects enforces it on the
1162
- // other path.
1301
+ // Enforce maxBodyLength for streamed uploads on every transport that
1302
+ // does not apply options.maxBodyLength itself (native http/https, http2,
1303
+ // and user-supplied custom transports). The follow-redirects transport
1304
+ // enforces it on the redirected HTTP/1 path.
1163
1305
  let uploadStream = data;
1164
- if (config.maxBodyLength > -1 && config.maxRedirects === 0) {
1165
- const limit = config.maxBodyLength;
1306
+ if (maxBodyLength > -1 && !transportEnforcesMaxBodyLength) {
1307
+ const limit = maxBodyLength;
1166
1308
  let bytesSent = 0;
1167
1309
  uploadStream = stream.pipeline(
1168
1310
  [
@@ -1200,3 +1342,4 @@ export default isHttpAdapterSupported &&
1200
1342
  };
1201
1343
 
1202
1344
  export const __setProxy = setProxy;
1345
+ export const __isSameOriginRedirect = isSameOriginRedirect;