Skip to content

Commit aa98a45

Browse files
committed
fix(res.redirect): add Content-Length only if Transfer-Encoding is not present
res.redirect() always set Content-Length, even when Transfer-Encoding was already set. That is the same conflict #4893 fixed for res.send(), and Node's HTTP client rejects such responses with a parse error. Apply the same guard as res.send(): Content-Length is only set when no Transfer-Encoding header is present. Fixes #7506.
1 parent 0dee2c5 commit aa98a45

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

‎lib/response.js‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,11 @@ res.redirect = function redirect(url) {
857857

858858
// Respond
859859
this.status(status);
860-
this.set('Content-Length', Buffer.byteLength(body));
860+
// Because Content-Length and Transfer-Encoding can't be present in the response headers together,
861+
// Content-Length should be added only if there is no Transfer-Encoding header
862+
if (!this.get('Transfer-Encoding')) {
863+
this.set('Content-Length', Buffer.byteLength(body));
864+
}
861865

862866
if (this.req.method === 'HEAD') {
863867
this.end();

‎test/res.redirect.js‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,32 @@ describe('res', function(){
7878
})
7979
})
8080

81+
describe('when Transfer-Encoding header is present', function(){
82+
var transferEncodings = [
83+
'chunked',
84+
'compress',
85+
'deflate',
86+
'gzip'
87+
];
88+
89+
transferEncodings.forEach(function(encoding){
90+
it('should not add Content-Length header if Transfer-Encoding header is equal to ' + encoding, function(done){
91+
var app = express();
92+
93+
app.use(function(req, res){
94+
res.set('Transfer-Encoding', encoding).redirect('http://google.com');
95+
});
96+
97+
request(app)
98+
.get('/')
99+
.expect(utils.shouldNotHaveHeader('Content-Length'))
100+
.expect(utils.shouldHaveHeader('Transfer-Encoding'))
101+
.expect('Location', 'http://google.com')
102+
.expect(302, done);
103+
})
104+
})
105+
})
106+
81107
describe('when accepting html', function(){
82108
it('should respond with html', function(done){
83109
var app = express();

0 commit comments

Comments
 (0)