Permalink
Browse files

Only concatenate some incoming HTTP headers.

- Concatenate 'accept', 'accept-charset', 'accept-encoding',
  'accept-language', 'connection', 'cookie', and 'x-*' headers.
- For all others, drop duplicates.
  • Loading branch information...
1 parent 545e10f commit 51bd1b4483f60d85ee19274aab98505a0b5c9105 @pgriess pgriess committed with ry Jun 21, 2010
Showing with 63 additions and 5 deletions.
  1. +27 −5 lib/http.js
  2. +36 −0 test/simple/test-http-server-multiheaders.js
View
@@ -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;
}
};
@@ -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.