Permalink
Browse files

http: close connection on 204 and chunked encoding

This is similar to commit 2cbf458 but this time for 204 No Content
instead of 304 Not Modified responses.

When the user sends a 204 response with a Transfer-Encoding: chunked
header, suppress sending the zero chunk and force the connection to
close.
  • Loading branch information...
1 parent 2cbf458 commit 424bb2779c19e8b7505a92dbec206cf2ccda3ca6 @bnoordhuis committed Jan 23, 2013
Showing with 40 additions and 28 deletions.
  1. +11 −7 lib/http.js
  2. +29 −21 test/simple/test-http-chunked-304.js
View
18 lib/http.js
@@ -564,18 +564,22 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
state.messageHeader += 'Date: ' + utcDate() + CRLF;
}
- // Force the connection to close when the response is a 304 Not Modified
- // and the user has set a "Transfer-Encoding: chunked" header.
+ // Force the connection to close when the response is a 204 No Content or
+ // a 304 Not Modified and the user has set a "Transfer-Encoding: chunked"
+ // header.
//
- // RFC 2616 mandates that 304 responses MUST NOT have a body but node.js
- // used to send out a zero chunk anyway to accommodate clients that don't
- // have special handling for 304 responses.
+ // RFC 2616 mandates that 204 and 304 responses MUST NOT have a body but
+ // node.js used to send out a zero chunk anyway to accommodate clients
+ // that don't have special handling for those responses.
//
// It was pointed out that this might confuse reverse proxies to the point
// of creating security liabilities, so suppress the zero chunk and force
// the connection to close.
- if (this.statusCode === 304 && this.chunkedEncoding === true) {
- debug('304 response should not use chunked encoding, closing connection.');
+ var statusCode = this.statusCode;
+ if ((statusCode == 204 || statusCode === 304) &&
+ this.chunkedEncoding === true) {
+ debug(statusCode + ' response should not use chunked encoding,' +
+ ' closing connection.');
this.chunkedEncoding = false;
this.shouldKeepAlive = false;
}
View
50 test/simple/test-http-chunked-304.js
@@ -24,32 +24,40 @@ var assert = require('assert');
var http = require('http');
var net = require('net');
-// RFC 2616, section 10.3.5:
+// RFC 2616, section 10.2.5:
//
-// The 304 response MUST NOT contain a message-body, and thus is always
+// The 204 response MUST NOT contain a message-body, and thus is always
// terminated by the first empty line after the header fields.
//
-// Verify that no empty chunk is sent when the user explicitly sets
-// a Transfer-Encoding header.
-var server = http.createServer(function(req, res) {
- res.writeHead(304, { 'Transfer-Encoding': 'chunked' });
- res.end();
- server.close();
+// Likewise for 304 responses. Verify that no empty chunk is sent when
+// the user explicitly sets a Transfer-Encoding header.
+
+test(204, function() {
+ test(304);
});
-server.listen(common.PORT, function() {
- var conn = net.createConnection(common.PORT, function() {
- conn.write('GET / HTTP/1.1\r\n\r\n');
+function test(statusCode, next) {
+ var server = http.createServer(function(req, res) {
+ res.writeHead(statusCode, { 'Transfer-Encoding': 'chunked' });
+ res.end();
+ server.close();
+ });
- var resp = '';
- conn.setEncoding('utf8');
- conn.on('data', function(data) {
- resp += data;
- });
+ server.listen(common.PORT, function() {
+ var conn = net.createConnection(common.PORT, function() {
+ conn.write('GET / HTTP/1.1\r\n\r\n');
- conn.on('end', common.mustCall(function() {
- assert.equal(/^Connection: close\r\n$/m.test(resp), true);
- assert.equal(/^0\r\n$/m.test(resp), false);
- }));
+ var resp = '';
+ conn.setEncoding('utf8');
+ conn.on('data', function(data) {
+ resp += data;
+ });
+
+ conn.on('end', common.mustCall(function() {
+ assert.equal(/^Connection: close\r\n$/m.test(resp), true);
+ assert.equal(/^0\r\n$/m.test(resp), false);
+ if (next) process.nextTick(next);
+ }));
+ });
});
-});
+}

0 comments on commit 424bb27

Please sign in to comment.