From 1337845ea3395045ef2a88da05dd4cd34d9247eb Mon Sep 17 00:00:00 2001 From: Jay Date: Wed, 20 May 2026 18:30:26 +0200 Subject: [PATCH] feat(http): add zstd decompression support (#10920) * fix(http): move zstd advertising flag to transitional * sec: add has own prop to the transitional Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --- PRE_RELEASE_CHANGELOG.md | 6 +++--- index.d.cts | 2 +- index.d.ts | 2 +- lib/adapters/http.js | 5 +++-- lib/core/Axios.js | 1 + lib/core/mergeConfig.js | 1 - lib/defaults/transitional.js | 1 + tests/unit/adapters/http.test.js | 6 ++++-- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/PRE_RELEASE_CHANGELOG.md b/PRE_RELEASE_CHANGELOG.md index eae2bf3a..33908c59 100644 --- a/PRE_RELEASE_CHANGELOG.md +++ b/PRE_RELEASE_CHANGELOG.md @@ -4,10 +4,10 @@ ## New Features -- **HTTP Adapter - Zstandard:** Added automatic zstd decompression on Node.js versions that support it. `zstd` is only advertised in the default `Accept-Encoding` header when `advertiseZstd: true` is set. (**#6792**) +- **HTTP Adapter - Zstandard:** Added automatic zstd decompression on Node.js versions that support it. `zstd` is only advertised in the default `Accept-Encoding` header when `transitional.advertiseZstdAcceptEncoding: true` is set. (**#6792**) ## Release Documentation TODO -- Update `README.md` request config docs for `advertiseZstd` and zstd decompression support. -- Update `docs/pages/advanced/request-config.md` for `advertiseZstd` and zstd decompression support. +- Update `README.md` request config docs for `transitional.advertiseZstdAcceptEncoding` and zstd decompression support. +- Update `docs/pages/advanced/request-config.md` for `transitional.advertiseZstdAcceptEncoding` and zstd decompression support. - Update decompression-bomb security guidance in `README.md` and `docs/pages/misc/security.md` to mention zstd. diff --git a/index.d.cts b/index.d.cts index b434400d..2bcae97d 100644 --- a/index.d.cts +++ b/index.d.cts @@ -392,6 +392,7 @@ declare namespace axios { forcedJSONParsing?: boolean; clarifyTimeoutError?: boolean; legacyInterceptorReqResOrdering?: boolean; + advertiseZstdAcceptEncoding?: boolean; } interface GenericAbortSignal { @@ -512,7 +513,6 @@ declare namespace axios { proxy?: AxiosProxyConfig | false; cancelToken?: CancelToken | undefined; decompress?: boolean; - advertiseZstd?: boolean; transitional?: TransitionalOptions; signal?: GenericAbortSignal; insecureHTTPParser?: boolean; diff --git a/index.d.ts b/index.d.ts index b6e4da26..a43f3865 100644 --- a/index.d.ts +++ b/index.d.ts @@ -281,6 +281,7 @@ export interface TransitionalOptions { forcedJSONParsing?: boolean; clarifyTimeoutError?: boolean; legacyInterceptorReqResOrdering?: boolean; + advertiseZstdAcceptEncoding?: boolean; } export interface GenericAbortSignal { @@ -410,7 +411,6 @@ export interface AxiosRequestConfig { proxy?: AxiosProxyConfig | false; cancelToken?: CancelToken | undefined; decompress?: boolean; - advertiseZstd?: boolean; transitional?: TransitionalOptions; signal?: GenericAbortSignal; insecureHTTPParser?: boolean; diff --git a/lib/adapters/http.js b/lib/adapters/http.js index 37a87fdc..e8adf13b 100755 --- a/lib/adapters/http.js +++ b/lib/adapters/http.js @@ -526,6 +526,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) { return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) { const own = (key) => (utils.hasOwnProp(config, key) ? config[key] : undefined); + const transitional = own('transitional') || transitionalDefaults; let data = own('data'); let lookup = own('lookup'); let family = own('family'); @@ -594,7 +595,6 @@ export default isHttpAdapterSupported && let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded'; - const transitional = config.transitional || transitionalDefaults; if (config.timeoutErrorMessage) { timeoutErrorMessage = config.timeoutErrorMessage; } @@ -869,7 +869,8 @@ export default isHttpAdapterSupported && headers.set( 'Accept-Encoding', - own('advertiseZstd') === true ? ACCEPT_ENCODING_WITH_ZSTD : ACCEPT_ENCODING, + utils.hasOwnProp(transitional, 'advertiseZstdAcceptEncoding') && + transitional.advertiseZstdAcceptEncoding === true ? ACCEPT_ENCODING_WITH_ZSTD : ACCEPT_ENCODING, false ); diff --git a/lib/core/Axios.js b/lib/core/Axios.js index 903249a8..3f71e9a6 100644 --- a/lib/core/Axios.js +++ b/lib/core/Axios.js @@ -101,6 +101,7 @@ class Axios { forcedJSONParsing: validators.transitional(validators.boolean), clarifyTimeoutError: validators.transitional(validators.boolean), legacyInterceptorReqResOrdering: validators.transitional(validators.boolean), + advertiseZstdAcceptEncoding: validators.transitional(validators.boolean), }, false ); diff --git a/lib/core/mergeConfig.js b/lib/core/mergeConfig.js index eaa00493..760f5ad7 100644 --- a/lib/core/mergeConfig.js +++ b/lib/core/mergeConfig.js @@ -96,7 +96,6 @@ export default function mergeConfig(config1, config2) { onUploadProgress: defaultToConfig2, onDownloadProgress: defaultToConfig2, decompress: defaultToConfig2, - advertiseZstd: defaultToConfig2, maxContentLength: defaultToConfig2, maxBodyLength: defaultToConfig2, beforeRedirect: defaultToConfig2, diff --git a/lib/defaults/transitional.js b/lib/defaults/transitional.js index 714b6644..de2c0d92 100644 --- a/lib/defaults/transitional.js +++ b/lib/defaults/transitional.js @@ -5,4 +5,5 @@ export default { forcedJSONParsing: true, clarifyTimeoutError: false, legacyInterceptorReqResOrdering: true, + advertiseZstdAcceptEncoding: false, }; diff --git a/tests/unit/adapters/http.test.js b/tests/unit/adapters/http.test.js index b8867cd7..6bc6c584 100644 --- a/tests/unit/adapters/http.test.js +++ b/tests/unit/adapters/http.test.js @@ -850,7 +850,7 @@ describe('supports http with nodejs', () => { } }); - it('should advertise zstd when enabled and supported', async () => { + it('should advertise zstd when enabled through transitional config and supported', async () => { if (!isZstdSupported) { return; } @@ -867,7 +867,9 @@ describe('supports http with nodejs', () => { try { await axios.get(`http://localhost:${server.address().port}/`, { - advertiseZstd: true, + transitional: { + advertiseZstdAcceptEncoding: true, + }, }); assert.strictEqual(acceptEncoding.includes('zstd'), true); } finally {