Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Griess <pg@std.in>2010-06-21 22:53:17 +0400
committerRyan Dahl <ry@tinyclouds.org>2010-06-21 23:01:50 +0400
commit51bd1b4483f60d85ee19274aab98505a0b5c9105 (patch)
tree2b357ea0e987f2e65c07c11c5f1194d35dfa5be6
parent545e10f2399dd748f6261919ed3db177d02ef008 (diff)
Only concatenate some incoming HTTP headers.
- Concatenate 'accept', 'accept-charset', 'accept-encoding', 'accept-language', 'connection', 'cookie', and 'x-*' headers. - For all others, drop duplicates.
-rw-r--r--lib/http.js32
-rw-r--r--test/simple/test-http-server-multiheaders.js36
2 files changed, 63 insertions, 5 deletions
diff --git a/lib/http.js b/lib/http.js
index 5f051ed96b8..e3ebf75a8b3 100644
--- a/lib/http.js
+++ b/lib/http.js
@@ -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;
}
};
diff --git a/test/simple/test-http-server-multiheaders.js b/test/simple/test-http-server-multiheaders.js
new file mode 100644
index 00000000000..3133c67f897
--- /dev/null
+++ b/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();
+});