Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Explicitly remove Transfer-Encoding header from 204 and 304 responses #1451

Merged
merged 1 commit into from

2 participants

@aweeks

I ran into this issue with responses that set the Transfer-Encoding header, and are then fetched using a conditional get. Express caches the response, and determines whether it should respond with a 304. In those cases, the Content-Type and Content-Length headers are removed, but the Transfer-Encoding is not.

Upon a call to response.end(), node recognizes that the Transfer-Encoding: chunked header was set, and inserts an empty terminating chunk. For example:

HTTP/1.1 304 Not Modified
Transfer-Encoding: chunked
Date: Wed, 19 Dec 2012 00:05:09 GMT
Connection: keep-alive

0

But, per RFC 2616 §10.3.6 & §10.2.5 "The [204/304] response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields." This response it invalid.

I first brought this up with node (issue #4437), but they do not wish to modify headers as part of the HTTP module. However, this behavior can be prevented by removing the Transfer-Encoding header in express.

@aweeks aweeks Explicitly remove Transfer-Encoding header from 204 and 304 responses
Per RFC 2616 §10.3.6 & §10.2.5 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) "The [204/304] response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields."
a1e42ac
@tj
tj commented

nice catch thanks man

@tj tj merged commit 3c4fd57 into strongloop:master

1 check passed

Details default The Travis build passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 19, 2012
  1. @aweeks

    Explicitly remove Transfer-Encoding header from 204 and 304 responses

    aweeks authored
    Per RFC 2616 §10.3.6 & §10.2.5 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) "The [204/304] response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields."
This page is out of date. Refresh to see the latest.
Showing with 7 additions and 4 deletions.
  1. +1 −0  lib/response.js
  2. +6 −4 test/res.send.js
View
1  lib/response.js
@@ -141,6 +141,7 @@ res.send = function(body){
if (204 == this.statusCode || 304 == this.statusCode) {
this.removeHeader('Content-Type');
this.removeHeader('Content-Length');
+ this.removeHeader('Transfer-Encoding');
body = '';
}
View
10 test/res.send.js
@@ -206,11 +206,11 @@ describe('res', function(){
})
describe('when .statusCode is 204', function(){
- it('should strip Content-* fields & body', function(done){
+ it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
var app = express();
app.use(function(req, res){
- res.status(204).send('foo');
+ res.status(204).set('Transfer-Encoding', 'chunked').send('foo');
});
request(app)
@@ -218,6 +218,7 @@ describe('res', function(){
.end(function(err, res){
res.headers.should.not.have.property('content-type');
res.headers.should.not.have.property('content-length');
+ res.headers.should.not.have.property('transfer-encoding');
res.text.should.equal('');
done();
})
@@ -225,11 +226,11 @@ describe('res', function(){
})
describe('when .statusCode is 304', function(){
- it('should strip Content-* fields & body', function(done){
+ it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
var app = express();
app.use(function(req, res){
- res.status(304).send('foo');
+ res.status(304).set('Transfer-Encoding', 'chunked').send('foo');
});
request(app)
@@ -237,6 +238,7 @@ describe('res', function(){
.end(function(err, res){
res.headers.should.not.have.property('content-type');
res.headers.should.not.have.property('content-length');
+ res.headers.should.not.have.property('transfer-encoding');
res.text.should.equal('');
done();
})
Something went wrong with that request. Please try again.