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.finished = false;
this._headers = {};
this._headerNames = {};
}
util.inherits(OutgoingMessage, stream.Stream);
@ -507,6 +504,8 @@ OutgoingMessage.prototype.setHeader = function(name, value) {
}
var key = name.toLowerCase();
this._headers = this._headers || {};
this._headerNames = this._headerNames || {};
this._headers[key] = value;
this._headerNames[key] = name;
};
@ -521,6 +520,8 @@ OutgoingMessage.prototype.getHeader = function(name) {
throw new Error("Can't use mutable header APIs after sent.");
}
if (!this._headers) return;
var key = name.toLowerCase();
return this._headers[key];
};
@ -535,6 +536,8 @@ OutgoingMessage.prototype.removeHeader = function(name) {
throw new Error("Can't remove headers after they are sent.");
}
if (!this._headers) return;
var key = name.toLowerCase();
delete this._headers[key];
delete this._headerNames[key];
@ -545,6 +548,9 @@ OutgoingMessage.prototype._renderHeaders = function() {
if (this._header) {
throw new Error("Can't render headers after they are sent to the client.");
}
if (!this._headers) return {};
var headers = {};
var keys = Object.keys(this._headers);
for (var i = 0, l = keys.length; i < l; i++) {
@ -754,7 +760,7 @@ ServerResponse.prototype.writeContinue = function() {
};
ServerResponse.prototype._implicitHeader = function() {
this.writeHead(this.statusCode, this._renderHeaders());
this.writeHead(this.statusCode);
};
ServerResponse.prototype.writeHead = function(statusCode) {
@ -768,10 +774,36 @@ ServerResponse.prototype.writeHead = function(statusCode) {
headerIndex = 1;
}
if (typeof arguments[headerIndex] == 'object') {
headers = arguments[headerIndex];
var obj = 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 {
headers = {};
// only writeHead() called
headers = obj;
}
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');
assert.equal(res.getHeader('Transfer-Encoding'), 'chunked');
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;
@ -92,6 +98,13 @@ function nextTest () {
case 'transferEncoding':
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';
break;
@ -114,6 +127,6 @@ function nextTest () {
process.on('exit', function() {
assert.equal(3, testsComplete);
assert.equal(4, testsComplete);
});

Loading…
Cancel
Save