diff --git a/cometd-nodejs-client.js b/cometd-nodejs-client.js index 4bdcc2f..0586677 100644 --- a/cometd-nodejs-client.js +++ b/cometd-nodejs-client.js @@ -19,7 +19,7 @@ module.exports = { var _agents = new https.Agent({ keepAlive: true }); - var _cookieStore = {}; + var _globalCookies = {}; function _secure(uri) { return /^https/i.test(uri.protocol); @@ -27,9 +27,42 @@ module.exports = { // Bare minimum XMLHttpRequest implementation that works with CometD. window.XMLHttpRequest = function() { + var _localCookies = {}; var _config; var _request; + function _storeCookie(cookieStore, value) { + var host = _config.hostname; + var jar = cookieStore[host]; + if (jar === undefined) { + cookieStore[host] = jar = {}; + } + var cookies = value.split(';'); + for (var i = 0; i < cookies.length; ++i) { + var cookie = cookies[i].trim(); + var equal = cookie.indexOf('='); + if (equal > 0) { + jar[cookie.substring(0, equal)] = cookie; + } + } + } + + function _concatCookies(cookieStore) { + var cookies = ''; + var jar = cookieStore[_config.hostname]; + if (jar) { + for (var name in jar) { + if (jar.hasOwnProperty(name)) { + if (cookies) { + cookies += '; '; + } + cookies += jar[name]; + } + } + } + return cookies; + } + this.status = 0; this.statusText = ''; this.readyState = window.XMLHttpRequest.UNSENT; @@ -44,28 +77,24 @@ module.exports = { }; this.setRequestHeader = function(name, value) { - _config.headers[name] = value; + if (/^cookie$/i.test(name)) { + _storeCookie(_localCookies, value) + } else { + _config.headers[name] = value; + } }; this.send = function(data) { - var cookieStore = this.context && this.context.cookieStore; - if (!cookieStore) { - cookieStore = _cookieStore; + var globalCookies = this.context && this.context.cookieStore; + if (!globalCookies) { + globalCookies = _globalCookies; } - var jar = cookieStore[_config.hostname]; - if (jar) { - var cookies = ''; - for (var name in jar) { - if (jar.hasOwnProperty(name)) { - if (cookies) { - cookies += '; '; - } - cookies += jar[name]; - } - } - if (cookies) { - _config.headers['Cookie'] = cookies; - } + var cookies1 = _concatCookies(globalCookies); + var cookies2 = _concatCookies(_localCookies); + var delim = (cookies1 && cookies2) ? '; ' : ''; + var cookies = cookies1 + delim + cookies2; + if (cookies) { + _config.headers['Cookie'] = cookies; } var self = this; @@ -84,17 +113,7 @@ module.exports = { var whole = header[i]; var parts = whole.split(';'); var cookie = parts[0]; - - var host = _config.hostname; - var jar = cookieStore[host]; - if (jar === undefined) { - cookieStore[host] = jar = {}; - } - - var equal = cookie.indexOf('='); - if (equal > 0) { - jar[cookie.substring(0, equal)] = cookie; - } + _storeCookie(globalCookies, cookie); } } } diff --git a/test/cookies.js b/test/cookies.js index 097e4df..91a1a31 100644 --- a/test/cookies.js +++ b/test/cookies.js @@ -183,4 +183,49 @@ describe('cookies', function() { xhr1.send(); }); }); + + it('handles cookies as request headers', function(done) { + _server = http.createServer(function(request, response) { + var cookies = request.headers['cookie']; + if (/\/1$/.test(request.url)) { + response.setHeader('Set-Cookie', 'a=b'); + response.end(); + } else if (/\/2$/.test(request.url)) { + assert.ok(cookies.indexOf('a=b') >= 0); + assert.ok(cookies.indexOf('c=d') >= 0); + assert.ok(cookies.indexOf('e=f') >= 0); + response.end(); + } else if (/\/3$/.test(request.url)) { + assert.ok(cookies.indexOf('a=b') >= 0); + assert.ok(cookies.indexOf('c=d') < 0); + assert.ok(cookies.indexOf('e=f') < 0); + response.end(); + } + }); + _server.listen(0, 'localhost', function() { + var port = _server.address().port; + console.log('listening on localhost:' + port); + + var xhr1 = new window.XMLHttpRequest(); + xhr1.open('GET', 'http://localhost:' + port + '/1'); + xhr1.onload = function() { + assert.strictEqual(xhr1.status, 200); + var xhr2 = new window.XMLHttpRequest(); + xhr2.open('GET', 'http://localhost:' + port + '/2'); + xhr2.setRequestHeader('cookie', 'c=d; e=f'); + xhr2.onload = function() { + assert.strictEqual(xhr2.status, 200); + var xhr3 = new window.XMLHttpRequest(); + xhr3.open('GET', 'http://localhost:' + port + '/3'); + xhr3.onload = function() { + assert.strictEqual(xhr3.status, 200); + done(); + }; + xhr3.send(); + }; + xhr2.send(); + }; + xhr1.send(); + }); + }); });