From 412d3bd6078433dda4a7eb4d86e021dbc57fdeb2 Mon Sep 17 00:00:00 2001 From: Zoran Kokeza Date: Mon, 7 Mar 2022 18:46:08 +0100 Subject: [PATCH] Adding support for beforeRedirect config option (#3852) * Adding support for beforeRedirect config option * Adding tests for beforeRedirect * Update README.md Co-authored-by: Prabodh Meshram * fix types Co-authored-by: Prabodh Meshram Co-authored-by: Jay --- README.md | 13 ++++++++++++- index.d.ts | 2 +- lib/adapters/http.js | 5 ++++- lib/core/mergeConfig.js | 1 + test/unit/adapters/http.js | 20 ++++++++++++++++++++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a230416d4f..c5d64d0f93 100755 --- a/README.md +++ b/README.md @@ -414,7 +414,18 @@ These are the available config options for making requests. Only the `url` is re // `maxRedirects` defines the maximum number of redirects to follow in node.js. // If set to 0, no redirects will be followed. - maxRedirects: 5, // default + maxRedirects: 21, // default + + // `beforeRedirect` defines a function that will be called before redirect. + // Use this to adjust the request options upon redirecting, + // to inspect the latest response headers, + // or to cancel the request by throwing an error + // If maxRedirects is set to 0, `beforeRedirect` is not used. + beforeRedirect: (options, { headers }) => { + if (options.hostname === "example.com") { + options.auth = "user:password"; + } + }; // `socketPath` defines a UNIX Socket to be used in node.js. // e.g. '/var/run/docker.sock' to send requests to the docker daemon. diff --git a/index.d.ts b/index.d.ts index b681915e16..c028ca4b66 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,5 +1,4 @@ // TypeScript Version: 3.0 - export type AxiosRequestHeaders = Record; export type AxiosResponseHeaders = Record & { @@ -98,6 +97,7 @@ export interface AxiosRequestConfig { validateStatus?: ((status: number) => boolean) | null; maxBodyLength?: number; maxRedirects?: number; + beforeRedirect?: (options: Record, responseDetails: {headers: Record}) => void; socketPath?: string | null; httpAgent?: any; httpsAgent?: any; diff --git a/lib/adapters/http.js b/lib/adapters/http.js index 28317c1055..a6d7cddc22 100755 --- a/lib/adapters/http.js +++ b/lib/adapters/http.js @@ -227,6 +227,9 @@ module.exports = function httpAdapter(config) { if (config.maxRedirects) { options.maxRedirects = config.maxRedirects; } + if (config.beforeRedirect) { + options.beforeRedirect = config.beforeRedirect; + } transport = isHttpsProxy ? httpsFollow : httpFollow; } @@ -326,7 +329,7 @@ module.exports = function httpAdapter(config) { // Handle errors req.on('error', function handleRequestError(err) { - if (req.aborted && err.code !== 'ERR_FR_TOO_MANY_REDIRECTS') return; + if (req.aborted && err.code !== 'ERR_FR_TOO_MANY_REDIRECTS') reject(err); reject(enhanceError(err, config, null, req)); }); diff --git a/lib/core/mergeConfig.js b/lib/core/mergeConfig.js index 05d1438805..eb7aa390b6 100644 --- a/lib/core/mergeConfig.js +++ b/lib/core/mergeConfig.js @@ -80,6 +80,7 @@ module.exports = function mergeConfig(config1, config2) { 'decompress': defaultToConfig2, 'maxContentLength': defaultToConfig2, 'maxBodyLength': defaultToConfig2, + 'beforeRedirect': defaultToConfig2, 'transport': defaultToConfig2, 'httpAgent': defaultToConfig2, 'httpsAgent': defaultToConfig2, diff --git a/test/unit/adapters/http.js b/test/unit/adapters/http.js index 018c2fc6cc..b0cca236df 100644 --- a/test/unit/adapters/http.js +++ b/test/unit/adapters/http.js @@ -241,6 +241,26 @@ describe('supports http with nodejs', function () { }); }); + it('should support beforeRedirect', function (done) { + server = http.createServer(function (req, res) { + res.setHeader('Location', '/foo'); + res.statusCode = 302; + res.end(); + }).listen(4444, function () { + axios.get('http://localhost:4444/', { + maxRedirects: 3, + beforeRedirect: function (options) { + if (options.path === '/foo') { + throw new Error('path not allowed'); + } + } + }).catch(function (error) { + assert.equal(error.toJSON().message, 'path not allowed') + done(); + }); + }); + }); + it('should preserve the HTTP verb on redirect', function (done) { server = http.createServer(function (req, res) { if (req.method.toLowerCase() !== "head") {