Skip to content

Commit

Permalink
Clear the host header on redirect.
Browse files Browse the repository at this point in the history
Fixes #53, closes #54.
  • Loading branch information
RubenVerborgh committed Mar 9, 2017
1 parent 9b59b53 commit 31c82d0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
13 changes: 11 additions & 2 deletions index.js
Expand Up @@ -117,17 +117,26 @@ RedirectableRequest.prototype._processResponse = function (response) {
// that the target resource resides temporarily under a different URI
// and the user agent MUST NOT change the request method
// if it performs an automatic redirection to that URI.
var header;
var headers = this._options.headers;
if (response.statusCode !== 307 && !(this._options.method in safeMethods)) {
this._options.method = 'GET';
// Drop a possible entity and headers related to it
this._bufferedWrites = [];
for (var header in this._options.headers) {
for (header in headers) {
if (/^content-/i.test(header)) {
delete this._options.headers[header];
delete headers[header];
}
}
}

// Drop the Host header, as the redirect might lead to a different host
for (header in headers) {
if (/^host$/i.test(header)) {
delete headers[header];
}
}

// Perform the redirected request
var redirectUrl = url.resolve(this._currentUrl, location);
debug('redirecting to', redirectUrl);
Expand Down
27 changes: 27 additions & 0 deletions test/test-with-server.js
Expand Up @@ -572,6 +572,33 @@ describe('follow-redirects ', function () {
itDropsBodyAndHeaders('PUT');
});

describe('when redirecting to a different host while the host header is set', function () {
it('uses the new host header', function (done) {
app.get('/a', redirectsTo(302, 'http://localhost:3600/b'));
app.get('/b', function (req, res) {
res.write(JSON.stringify(req.headers));
req.pipe(res); // will invalidate JSON if non-empty
});

server.start(app)
.then(asPromise(function (resolve, reject) {
var opts = url.parse('http://localhost:3600/a');
opts.headers = {hOsT: 'otherhost.com'};
http.get(opts, resolve).on('error', reject);
}))
.then(asPromise(function (resolve, reject, res) {
assert.deepEqual(res.statusCode, 200);
assert.deepEqual(res.responseUrl, 'http://localhost:3600/b');
res.pipe(concat({encoding: 'string'}, resolve)).on('error', reject);
}))
.then(function (str) {
var body = JSON.parse(str);
assert.equal(body.host, 'localhost:3600');
})
.nodeify(done);
});
});

describe('when the followRedirects option is set to false', function () {
it('does not redirect', function (done) {
app.get('/a', redirectsTo(302, '/b'));
Expand Down

0 comments on commit 31c82d0

Please sign in to comment.