Skip to content

Commit

Permalink
Only concatenate some incoming HTTP headers.
Browse files Browse the repository at this point in the history
- Concatenate 'accept', 'accept-charset', 'accept-encoding',
  'accept-language', 'connection', 'cookie', and 'x-*' headers.
- For all others, drop duplicates.
  • Loading branch information
pgriess authored and ry committed Jun 21, 2010
1 parent 545e10f commit 51bd1b4
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
32 changes: 27 additions & 5 deletions lib/http.js
Expand Up @@ -227,13 +227,35 @@ IncomingMessage.prototype.resume = function () {
this.socket.resume();
};

// Add the given (field, value) pair to the message
//
// Per RFC2616, section 4.2 it is acceptable to join multiple instances of the
// same header with a ', ' if the header in question supports specification of
// multiple values this way. If not, we declare the first instance the winner
// and drop the second. Extended header fields (those beginning with 'x-') are
// always joined.
IncomingMessage.prototype._addHeaderLine = function (field, value) {
if (field in this.headers) {
// TODO Certain headers like 'Content-Type' should not be concatinated.
// See https://www.google.com/reader/view/?tab=my#overview-page
this.headers[field] += ", " + value;
} else {
if (!(field in this.headers)) {
this.headers[field] = value;
return;
}

// If this field already exists in the request, use duplicate-resolution
// logic from RFC2616.
switch (field) {
case 'accept':
case 'accept-charset':
case 'accept-encoding':
case 'accept-language':
case 'connection':
case 'cookie':
this.headers[field] += ', ' + value;
break;

default:
if (field[0] !== 'x' || field[1] !== '-') break;
this.headers[field] += ', ' + value;
break;
}
};

Expand Down
36 changes: 36 additions & 0 deletions test/simple/test-http-server-multiheaders.js
@@ -0,0 +1,36 @@
// Verify that the HTTP server implementation handles multiple instances
// of the same header as per RFC2616: joining the handful of fields by ', '
// that support it, and dropping duplicates for other fields.

require('../common');
var http = require('http');

var srv = http.createServer(function(req, res) {
assert.equal(req.headers.accept, 'abc, def, ghijklmnopqrst');
assert.equal(req.headers.host, 'foo');
assert.equal(req.headers['x-foo'], 'bingo');
assert.equal(req.headers['x-bar'], 'banjo, bango');

res.writeHead(200, {'Content-Type' : 'text/plain'});
res.end('EOF');

srv.close();
});

srv.listen(PORT, function () {
var hc = http.createClient(PORT, 'localhost');
var hr = hc.request('/',
[
['accept', 'abc'],
['accept', 'def'],
['Accept', 'ghijklmnopqrst'],
['host', 'foo'],
['Host', 'bar'],
['hOst', 'baz'],
['x-foo', 'bingo'],
['x-bar', 'banjo'],
['x-bar', 'bango']
]
);
hr.end();
});

0 comments on commit 51bd1b4

Please sign in to comment.