-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Closed
Labels
Description
Summary
If a Host
header is provided to request
, and if the response is a 307 with a different host, the old host is reused, which causes a maxRedirects error. The test case below reproduces the issue.
Simplest Example to Reproduce
'use strict'
var http = require('http')
var request = require('../index')
var tape = require('tape')
// test data
var redirecter = 'test1.local.omg' // always resolves to 127.0.0.1
var responder = 'test2.local.omg' // this too.
var server = http.createServer(function (req, res) {
if (req.headers.host.indexOf(redirecter) === 0) {
res.setHeader('location', `http://${responder}:${port}/foo`)
res.statusCode = 307
return res.end('try again')
} else if (req.headers.host.indexOf(responder) === 0) {
res.statusCode = 200
return res.end('ok')
}
res.statusCode = 404
return res.end('not found')
})
var port
tape('setup', function (t) {
server.listen(0, function () {
port = this.address().port
t.end()
})
})
tape('307 redirect should work when host is set explicitly, but changes on redirect', function (t) {
var redirects = 0
request({
url: `http://${redirecter}:${port}/foo`,
headers: {
Host: redirecter
},
followAllRedirects: true,
followRedirect: true,
encoding: null,
lookup: function (hostname, options, callback) {
callback(null, '127.0.0.1', 4) // All hosts will resolve to 127.0.0.1
}
}, function (err, res, body) {
t.equal(err, null)
t.equal(body.toString(), 'ok')
t.equal(redirects, 1)
t.end()
}).on('redirect', function () {
redirects++
})
})
tape('cleanup', function (t) {
server.close(function () {
t.end()
})
})
Expected Behavior
The module should replace the host header with the new one.
Current Behavior
We see an error, Exceeded maxRedirects. Probably stuck in a redirect loop
.
Possible Solution
Add this code in redirect.js (right after computing uriPrev
):
// remove the host header if the response is a 307 & the host has changed.
// (the new host will be populated auto-magically).
// For other types of redirects, it's removed automatically (see code below)
if (response.statusCode === 307 && request.headers && uriPrev.host !== request.uri.host) {
request.removeHeader('host')
}
Context
Your Environment
software | version |
---|---|
request | * |
node | * |
npm | * |
Operating System | * |