Browse Source

Fixed field merging with progressive fields on writeHead()

v0.7.4-release
Tj Holowaychuk 14 years ago
committed by Ryan Dahl
parent
commit
fe838611f6
  1. 46
      lib/http.js
  2. 15
      test/simple/test-http-mutable-headers.js

46
lib/http.js

@ -303,9 +303,6 @@ function OutgoingMessage() {
this._trailer = ''; this._trailer = '';
this.finished = false; this.finished = false;
this._headers = {};
this._headerNames = {};
} }
util.inherits(OutgoingMessage, stream.Stream); util.inherits(OutgoingMessage, stream.Stream);
@ -507,6 +504,8 @@ OutgoingMessage.prototype.setHeader = function(name, value) {
} }
var key = name.toLowerCase(); var key = name.toLowerCase();
this._headers = this._headers || {};
this._headerNames = this._headerNames || {};
this._headers[key] = value; this._headers[key] = value;
this._headerNames[key] = name; this._headerNames[key] = name;
}; };
@ -521,6 +520,8 @@ OutgoingMessage.prototype.getHeader = function(name) {
throw new Error("Can't use mutable header APIs after sent."); throw new Error("Can't use mutable header APIs after sent.");
} }
if (!this._headers) return;
var key = name.toLowerCase(); var key = name.toLowerCase();
return this._headers[key]; return this._headers[key];
}; };
@ -535,6 +536,8 @@ OutgoingMessage.prototype.removeHeader = function(name) {
throw new Error("Can't remove headers after they are sent."); throw new Error("Can't remove headers after they are sent.");
} }
if (!this._headers) return;
var key = name.toLowerCase(); var key = name.toLowerCase();
delete this._headers[key]; delete this._headers[key];
delete this._headerNames[key]; delete this._headerNames[key];
@ -545,6 +548,9 @@ OutgoingMessage.prototype._renderHeaders = function() {
if (this._header) { if (this._header) {
throw new Error("Can't render headers after they are sent to the client."); throw new Error("Can't render headers after they are sent to the client.");
} }
if (!this._headers) return {};
var headers = {}; var headers = {};
var keys = Object.keys(this._headers); var keys = Object.keys(this._headers);
for (var i = 0, l = keys.length; i < l; i++) { for (var i = 0, l = keys.length; i < l; i++) {
@ -754,7 +760,7 @@ ServerResponse.prototype.writeContinue = function() {
}; };
ServerResponse.prototype._implicitHeader = function() { ServerResponse.prototype._implicitHeader = function() {
this.writeHead(this.statusCode, this._renderHeaders()); this.writeHead(this.statusCode);
}; };
ServerResponse.prototype.writeHead = function(statusCode) { ServerResponse.prototype.writeHead = function(statusCode) {
@ -768,10 +774,36 @@ ServerResponse.prototype.writeHead = function(statusCode) {
headerIndex = 1; headerIndex = 1;
} }
if (typeof arguments[headerIndex] == 'object') { var obj = arguments[headerIndex];
headers = arguments[headerIndex];
if (obj && this._headers) {
// Slow-case: when progressive API and header fields are passed.
headers = this._renderHeaders();
if (Array.isArray(obj)) {
// handle array case
// TODO: remove when array is no longer accepted
var field;
for (var i = 0, len = obj.length; i < len; ++i) {
field = obj[i][0];
if (field in headers) {
obj.push([field, headers[field]]);
}
}
headers = obj;
} else {
// handle object case
for (var k in obj) {
if (k) headers[k] = obj[k];
}
}
} else if (this._headers) {
// only progressive api is used
headers = this._renderHeaders();
} else { } else {
headers = {}; // only writeHead() called
headers = obj;
} }
var statusLine = 'HTTP/1.1 ' + statusCode.toString() + ' ' + var statusLine = 'HTTP/1.1 ' + statusCode.toString() + ' ' +

15
test/simple/test-http-mutable-headers.js

@ -48,6 +48,12 @@ var s = http.createServer(function(req, res) {
res.setHeader('transfer-encoding', 'chunked'); res.setHeader('transfer-encoding', 'chunked');
assert.equal(res.getHeader('Transfer-Encoding'), 'chunked'); assert.equal(res.getHeader('Transfer-Encoding'), 'chunked');
break; break;
case 'writeHead':
res.statusCode = 404;
res.setHeader('x-foo', 'keyboard cat');
res.writeHead(200, { 'x-foo': 'bar', 'x-bar': 'baz' });
break;
} }
res.statusCode = 201; res.statusCode = 201;
@ -92,6 +98,13 @@ function nextTest () {
case 'transferEncoding': case 'transferEncoding':
assert.equal(response.headers['transfer-encoding'], 'chunked'); assert.equal(response.headers['transfer-encoding'], 'chunked');
test = 'writeHead';
break;
case 'writeHead':
assert.equal(response.headers['x-foo'], 'bar');
assert.equal(response.headers['x-bar'], 'baz');
assert.equal(200, response.statusCode);
test = 'end'; test = 'end';
break; break;
@ -114,6 +127,6 @@ function nextTest () {
process.on('exit', function() { process.on('exit', function() {
assert.equal(3, testsComplete); assert.equal(4, testsComplete);
}); });

Loading…
Cancel
Save