From 47bad7c73af5f775a2bb3e7ad4ddeefa118747eb Mon Sep 17 00:00:00 2001 From: Maxime Bargiel Date: Tue, 10 May 2022 00:15:08 -0400 Subject: [PATCH] Fixing proxy beforeRedirect regression --- lib/adapters/http.js | 17 ++++++++++-- test/unit/adapters/http.js | 56 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/lib/adapters/http.js b/lib/adapters/http.js index 66aa3f27b1..3a27c7a3c0 100755 --- a/lib/adapters/http.js +++ b/lib/adapters/http.js @@ -20,6 +20,15 @@ var isHttps = /https:?/; var supportedProtocols = [ 'http:', 'https:', 'file:' ]; +function dispatchBeforeRedirect(options) { + if (options.beforeRedirects.proxy) { + options.beforeRedirects.proxy(options); + } + if (options.beforeRedirects.config) { + options.beforeRedirects.config(options); + } +} + /** * * @param {http.ClientRequestArgs} options @@ -59,7 +68,7 @@ function setProxy(options, configProxy, location) { } } - options.beforeRedirect = function beforeRedirect(redirectOptions) { + options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) { // Configure proxy for redirected request, passing the original config proxy to apply // the exact same logic as if the redirected request was performed by axios directly. setProxy(redirectOptions, configProxy, redirectOptions.href); @@ -190,7 +199,9 @@ module.exports = function httpAdapter(config) { headers: headers, agents: { http: config.httpAgent, https: config.httpsAgent }, auth: auth, - protocol: protocol + protocol: protocol, + beforeRedirect: dispatchBeforeRedirect, + beforeRedirects: {} }; if (config.socketPath) { @@ -213,7 +224,7 @@ module.exports = function httpAdapter(config) { options.maxRedirects = config.maxRedirects; } if (config.beforeRedirect) { - options.beforeRedirect = config.beforeRedirect; + options.beforeRedirects.config = config.beforeRedirect; } transport = isHttpsRequest ? httpsFollow : httpFollow; } diff --git a/test/unit/adapters/http.js b/test/unit/adapters/http.js index c92e0afd2d..315a3ffd7c 100644 --- a/test/unit/adapters/http.js +++ b/test/unit/adapters/http.js @@ -204,7 +204,7 @@ describe('supports http with nodejs', function () { assert.equal(res.data, str); assert.equal(res.request.path, '/two'); done(); - }).catch(done);; + }).catch(done); }); }); @@ -223,7 +223,7 @@ describe('supports http with nodejs', function () { assert.equal(res.status, 302); assert.equal(res.headers['location'], '/foo'); done(); - }).catch(done);; + }).catch(done); }); }); @@ -241,7 +241,7 @@ describe('supports http with nodejs', function () { assert.equal(error.code, AxiosError.ERR_FR_TOO_MANY_REDIRECTS); assert.equal(error.message, 'Maximum number of redirects exceeded'); done(); - }); + }).catch(done); }); }); @@ -263,6 +263,56 @@ describe('supports http with nodejs', function () { }).catch(function (error) { assert.equal(error.message, 'Provided path is not allowed'); done(); + }).catch(done); + }); + }); + + it('should support beforeRedirect and proxy with redirect', function (done) { + var requestCount = 0; + var totalRedirectCount = 5; + server = http.createServer(function (req, res) { + requestCount += 1; + if (requestCount <= totalRedirectCount) { + res.setHeader('Location', 'http://localhost:4444'); + res.writeHead(302); + } + res.end(); + }).listen(4444, function () { + var proxyUseCount = 0; + proxy = http.createServer(function (request, response) { + proxyUseCount += 1; + var parsed = url.parse(request.url); + var opts = { + host: parsed.hostname, + port: parsed.port, + path: parsed.path + }; + + http.get(opts, function (res) { + response.writeHead(res.statusCode, res.headers); + res.on('data', function (data) { + response.write(data) + }); + res.on('end', function () { + response.end(); + }); + }); + }).listen(4000, function () { + var configBeforeRedirectCount = 0; + axios.get('http://localhost:4444/', { + proxy: { + host: 'localhost', + port: 4000 + }, + maxRedirects: totalRedirectCount, + beforeRedirect: function (options) { + configBeforeRedirectCount += 1; + } + }).then(function (res) { + assert.equal(totalRedirectCount, configBeforeRedirectCount, 'should invoke config.beforeRedirect option on every redirect'); + assert.equal(totalRedirectCount + 1, proxyUseCount, 'should go through proxy on every redirect'); + done(); + }).catch(done); }); }); });