From 94bc55f572036ba108424eacb80b0a467fb6c2af Mon Sep 17 00:00:00 2001 From: Jacob Wright Date: Fri, 8 Aug 2014 12:47:25 -0600 Subject: [PATCH 1/2] Fixes request headers to conform to spec more closely. I've made the request headers case insensitive for setting and getting by creating a mapping hash to map the insensitive names with the ones used in setting. I've also fixed setRequestHeader to append values to existing ones as per the spec. Because of this I needed to set the defaults on send if they haven't been set previously (user-agent obviously can't because it's in the restricted list). --- lib/XMLHttpRequest.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/XMLHttpRequest.js b/lib/XMLHttpRequest.js index 4b7cab4..8ea63e8 100644 --- a/lib/XMLHttpRequest.js +++ b/lib/XMLHttpRequest.js @@ -40,7 +40,8 @@ exports.XMLHttpRequest = function() { "Accept": "*/*", }; - var headers = defaultHeaders; + var headers = {}; + var headersCase = {}; // These headers are not user setable. // The following are allowed but banned in the spec: @@ -177,7 +178,7 @@ exports.XMLHttpRequest = function() { }; /** - * Sets a header for the request. + * Sets a header for the request or appends the value if one is already set. * * @param string header Header name * @param string value Header value @@ -193,7 +194,9 @@ exports.XMLHttpRequest = function() { if (sendFlag) { throw "INVALID_STATE_ERR: send flag is true"; } - headers[header] = value; + header = headersCase[header.toLowerCase()] || header; + headersCase[header.toLowerCase()] = header; + headers[header] = headers[header] ? headers[header] + ', ' + value : value; }; /** @@ -243,9 +246,8 @@ exports.XMLHttpRequest = function() { * @return string Returns the request header or empty string if not set */ this.getRequestHeader = function(name) { - // @TODO Make this case insensitive - if (typeof name === "string" && headers[name]) { - return headers[name]; + if (typeof name === "string" && headersCase[name.toLowerCase()]) { + return headers[headersCase[name.toLowerCase()]]; } return ""; @@ -325,6 +327,13 @@ exports.XMLHttpRequest = function() { // Add query string if one is used var uri = url.pathname + (url.search ? url.search : ''); + // Set the defaults if they haven't been set + for (var name in defaultHeaders) { + if (!headersCase[name.toLowerCase()]) { + headers[name] = defaultHeaders[name]; + } + } + // Set the Host header or the server may reject the request headers["Host"] = host; if (!((ssl && port === 443) || port === 80)) { From 4610298f2688fcbf001ca494049f8f86f740b19a Mon Sep 17 00:00:00 2001 From: Jacob Wright Date: Fri, 8 Aug 2014 12:54:09 -0600 Subject: [PATCH 2/2] Updates tests to test header changes. --- tests/test-headers.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test-headers.js b/tests/test-headers.js index 76454f1..23a419e 100644 --- a/tests/test-headers.js +++ b/tests/test-headers.js @@ -56,12 +56,16 @@ try { xhr.open("GET", "http://localhost:8000/"); // Valid header xhr.setRequestHeader("X-Test", "Foobar"); + xhr.setRequestHeader("X-Test2", "Foobar1"); + xhr.setRequestHeader("X-Test2", "Foobar2"); // Invalid header xhr.setRequestHeader("Content-Length", 0); // Allowed header outside of specs xhr.setRequestHeader("user-agent", "node-XMLHttpRequest-test"); // Test getRequestHeader assert.equal("Foobar", xhr.getRequestHeader("X-Test")); + assert.equal("Foobar", xhr.getRequestHeader("x-tEST")); + assert.equal("Foobar1, Foobar2", xhr.getRequestHeader("x-test2")); // Test invalid header assert.equal("", xhr.getRequestHeader("Content-Length"));