From a888775a2c2fabeb8b5cc4c5cbab4a3558664b57 Mon Sep 17 00:00:00 2001 From: Steven Marusa Date: Mon, 4 Oct 2021 14:51:32 -0400 Subject: [PATCH] Review comments. --- index.js | 31 +++++++++++++++---------------- test/test.js | 30 ++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/index.js b/index.js index e1cb4f1..5aaac2a 100644 --- a/index.js +++ b/index.js @@ -361,19 +361,28 @@ RedirectableRequest.prototype._processResponse = function (response) { } // Prefer previous host from Host header - var previousHost = getMatchingHeader(/^host$/i, this._options.headers) || - url.parse(this._currentUrl).host; + var currentUrlParts = url.parse(this._currentUrl); + var previousHost = removeMatchingHeaders(/^host$/i, this._options.headers) || + currentUrlParts.host; + + // If the redirect is relative, carry over the host of the last request + var locationWithHost = !url.parse(location).host ? + url.format({ + protocol: currentUrlParts.protocol, + auth: currentUrlParts.auth, + host: previousHost, + }) + location : + location; // Create the redirected request - var redirectUrl = url.resolve(this._currentUrl, location); + var redirectUrl = url.resolve(this._currentUrl, locationWithHost); debug("redirecting to", redirectUrl); this._isRedirect = true; var redirectUrlParts = url.parse(redirectUrl); Object.assign(this._options, redirectUrlParts); - // Drop the Host & Authorization header if redirecting to another host - if (redirectUrlParts.host !== previousHost && url.parse(location).host) { - removeMatchingHeaders(/^host$/i, this._options.headers); + // Drop the Authorization header if redirecting to another host + if (redirectUrlParts.host !== previousHost) { removeMatchingHeaders(/^authorization$/i, this._options.headers); } @@ -503,16 +512,6 @@ function urlToOptions(urlObject) { return options; } -function getMatchingHeader(regex, headers) { - var lastValue; - for (var header in headers) { - if (regex.test(header)) { - lastValue = headers[header]; - } - } - return lastValue; -} - function removeMatchingHeaders(regex, headers) { var lastValue; for (var header in headers) { diff --git a/test/test.js b/test/test.js index 67906b0..4f348fd 100644 --- a/test/test.js +++ b/test/test.js @@ -1243,7 +1243,7 @@ describe("follow-redirects", function () { }); }); - it("uses the existing host header if redirect host is the same", function () { + it("uses the location host if redirect host is the same", function () { app.get("/a", redirectsTo(302, "http://localhost:3600/b")); app.get("/b", function (req, res) { res.write(JSON.stringify(req.headers)); @@ -1282,7 +1282,7 @@ describe("follow-redirects", function () { })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.statusCode, 200); - assert.deepEqual(res.responseUrl, "http://127.0.0.1:3600/b"); + assert.deepEqual(res.responseUrl, "http://localhost:3600/b"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { @@ -1344,6 +1344,32 @@ describe("follow-redirects", function () { }); }); + it("drops the header when redirected to a different host (same hostname and different port)", function () { + app.get("/a", redirectsTo(302, "http://localhost:3600/b")); + app.get("/b", function (req, res) { + res.end(JSON.stringify(req.headers)); + }); + + var opts = url.parse("http://127.0.0.1:3600/a"); + opts.headers = { + host: "localhost", + authorization: "bearer my-token-1234", + }; + + return server.start(app) + .then(asPromise(function (resolve, reject) { + http.get(opts, resolve).on("error", reject); + })) + .then(asPromise(function (resolve, reject, res) { + res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); + })) + .then(function (str) { + var body = JSON.parse(str); + assert.equal(body.host, "localhost:3600"); + assert.equal(body.authorization, undefined); + }); + }); + it("drops the header when redirected to a different host", function () { app.get("/a", redirectsTo(302, "http://127.0.0.1:3600/b")); app.get("/b", function (req, res) {