From 2982e75a0b98a0c6707db2f0f6e7ed740b78a6be Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Sat, 21 Aug 2010 16:34:38 -0700 Subject: [PATCH] set-cookies header is an array of values. always --- lib/http.js | 57 ++++++++++++++-------- test/simple/test-http-set-cookies.js | 71 ++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 test/simple/test-http-set-cookies.js diff --git a/lib/http.js b/lib/http.js index 5b67e43817..5fbc5921a4 100644 --- a/lib/http.js +++ b/lib/http.js @@ -235,27 +235,44 @@ IncomingMessage.prototype.resume = function () { // 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)) { - 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; + // Array headers: + case 'set-cookie': + if (field in this.headers) { + this.headers[field].push(value); + } else { + this.headers[field] = [value]; + } + break; + + // Comma separate. Maybe make these arrays? + case 'accept': + case 'accept-charset': + case 'accept-encoding': + case 'accept-language': + case 'connection': + case 'cookie': + if (field in this.headers) { + this.headers[field] += ', ' + value; + } else { + this.headers[field] = value; + } + break; + + + default: + if (field.slice(0,2) == 'x-') { + // except for x- + if (field in this.headers) { + this.headers[field] += ', ' + value; + } else { + this.headers[field] = value; + } + } else { + // drop duplicates + if (!(field in this.headers)) this.headers[field] = value; + } + break; } }; diff --git a/test/simple/test-http-set-cookies.js b/test/simple/test-http-set-cookies.js new file mode 100644 index 0000000000..e242da875a --- /dev/null +++ b/test/simple/test-http-set-cookies.js @@ -0,0 +1,71 @@ +common = require("../common"); +assert = common.assert; +http = require("http"); + +nresponses = 0; + +var server = http.createServer(function(req, res) { + if (req.url == '/one') { + res.writeHead(200, [ ['set-cookie', 'A'], + ['content-type', 'text/plain'] ]); + res.end("one\n"); + } else { + res.writeHead(200, [ ['set-cookie', 'A'], + ['set-cookie', 'B'], + ['content-type', 'text/plain'] ]); + res.end("two\n"); + } +}); +server.listen(common.PORT); + +server.addListener("listening", function() { + // + // one set-cookie header + // + var client = http.createClient(common.PORT); + var req = client.request('GET', '/one'); + req.end(); + + req.addListener('response', function(res) { + // set-cookie headers are always return in an array. + // even if there is only one. + assert.deepEqual(['A'], res.headers['set-cookie']); + assert.equal('text/plain', res.headers['content-type']); + + res.addListener('data', function(chunk) { + console.log(chunk.toString()); + }); + + res.addListener('end', function() { + if (++nresponses == 2) { + server.close(); + } + }); + }); + + // two set-cookie headers + + var client = http.createClient(common.PORT); + var req = client.request('GET', '/two'); + req.end(); + + req.addListener('response', function(res) { + assert.deepEqual(['A', 'B'], res.headers['set-cookie']); + assert.equal('text/plain', res.headers['content-type']); + + res.addListener('data', function(chunk) { + console.log(chunk.toString()); + }); + + res.addListener('end', function() { + if (++nresponses == 2) { + server.close(); + } + }); + }); + +}); + +process.addListener("exit", function () { + assert.equal(2, nresponses); +});