From e8b0b8c53d3fb0f8eb04c1691ebe14039b67d818 Mon Sep 17 00:00:00 2001 From: Maxime Bargiel Date: Tue, 10 May 2022 00:02:27 -0400 Subject: [PATCH] Fixing proxy beforeRedirect regression --- lib/adapters/http.js | 18 +++++++++++--- test/unit/adapters/http.js | 49 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/lib/adapters/http.js b/lib/adapters/http.js index bdf6d37f3a..20cdd24411 100755 --- a/lib/adapters/http.js +++ b/lib/adapters/http.js @@ -20,6 +20,18 @@ var isHttps = /https:?/; var supportedProtocols = [ 'http:', 'https:', 'file:' ]; +function appendBeforeRedirect(options, beforeRedirect) { + var previousBeforeRedirect = options.beforeRedirect; + if (previousBeforeRedirect) { + options.beforeRedirect = function (redirectOptions) { + previousBeforeRedirect(redirectOptions); + beforeRedirect(redirectOptions); + } + } else { + options.beforeRedirect = beforeRedirect; + } +} + /** * * @param {http.ClientRequestArgs} options @@ -59,11 +71,11 @@ function setProxy(options, configProxy, location) { } } - options.beforeRedirect = function beforeRedirect(redirectOptions) { + appendBeforeRedirect(options, 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); - }; + }); } /*eslint consistent-return:0*/ @@ -213,7 +225,7 @@ module.exports = function httpAdapter(config) { options.maxRedirects = config.maxRedirects; } if (config.beforeRedirect) { - options.beforeRedirect = config.beforeRedirect; + appendBeforeRedirect(options, config.beforeRedirect); } transport = isHttpsRequest ? httpsFollow : httpFollow; } diff --git a/test/unit/adapters/http.js b/test/unit/adapters/http.js index 5264f63362..4109e137b8 100644 --- a/test/unit/adapters/http.js +++ b/test/unit/adapters/http.js @@ -265,6 +265,55 @@ describe('supports http with nodejs', function () { }); }); + it('should support beforeRedirect and proxy with redirect', function (done) { + var requestCount = 0; + server = http.createServer(function (req, res) { + requestCount += 1; + if (requestCount === 1) { + res.setHeader('Location', '/redirected'); + 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 redirectCalled = false; + axios.get('http://localhost:4444/', { + proxy: { + host: 'localhost', + port: 4000 + }, + maxRedirects: 3, + beforeRedirect: function (options) { + redirectCalled = true; + } + }).then(function (res) { + assert.ok(redirectCalled, 'should invoke beforeRedirect option'); + assert.equal(2, proxyUseCount, 'should go through proxy after redirect'); + done(); + }).catch(done); + }); + }); + }); + it('should preserve the HTTP verb on redirect', function (done) { server = http.createServer(function (req, res) { if (req.method.toLowerCase() !== "head") {