Skip to content

Instantly share code, notes, and snippets.

@joerussbowman
Created March 31, 2010 13:58
Show Gist options
  • Save joerussbowman/350341 to your computer and use it in GitHub Desktop.
Save joerussbowman/350341 to your computer and use it in GitHub Desktop.
Patches to node.js for working with headers as an array
/*
* BEGIN Custom patches
*/
// This is the content type I will return on most of my requests,
// so I'm adding it as the default. I can overwrite the headers
// to change it if necessary on the individual handlers.
http.ServerResponse.prototype.headers = ["Content-Type: text/html"];
http.ServerResponse.prototype.writeHeadArray = function(statusCode){
var reasonPhrase, headers, headerIndex;
if (typeof arguments[1] == 'string') {
reasonPhrase = arguments[1];
headerIndex = 2;
}
else {
reasonPhrase = http.STATUS_CODES[statusCode] || "unknown";
headerIndex = 1;
}
if (arguments[headerIndex] instanceof Array) {
headers = arguments[headerIndex];
}
else {
headers = [];
}
var status_line = "HTTP/1.1 " + statusCode.toString() + " " + reasonPhrase + "\r\n";
this.sendHeaderLinesArray(status_line, headers);
this.headWritten = true;
};
http.OutgoingMessage.prototype.sendHeaderLinesArray = function(first_line, headers){
var sent_connection_header = false;
var sent_content_length_header = false;
var sent_transfer_encoding_header = false;
// Got these from the http module, they were not exported.
var connection_expression = /Connection/i;
var transfer_encoding_expression = /Transfer-Encoding/i;
var close_expression = /close/i;
var chunk_expression = /chunk/i;
var content_length_expression = /Content-Length/i;
// first_line in the case of request is: "GET /index.html HTTP/1.1\r\n"
// in the case of response it is: "HTTP/1.1 200 OK\r\n"
var message_header = first_line;
var field, value;
for (var i in headers) {
sys.debug("HEADERS " + headers[i]);
// type check the header, as jsdom browser.js will pass
// a toString function here, instead of the result of
// that function. Haven't tracked down the cause of this
// yet to see if it's what "should" be happening or not.
if (typeof headers[i] === 'function') {
var spl = headers[i]().split(',', 1);
}
else {
var spl = headers[i].split(',', 1);
}
field = spl[0];
value = spl[1];
message_header += headers[i] + "\r\n";
if (connection_expression.test(field)) {
sent_connection_header = true;
if (close_expression.test(value)) {
this.closeOnFinish = true;
}
}
else
if (transfer_encoding_expression.test(field)) {
sent_transfer_encoding_header = true;
if (chunk_expression.test(value)) {
this.chunked_encoding = true;
}
}
else
if (content_length_expression.test(field)) {
sent_content_length_header = true;
}
}
// keep-alive logic
if (sent_connection_header === false) {
if (this.should_keep_alive &&
(sent_content_length_header || this.use_chunked_encoding_by_default)) {
message_header += "Connection: keep-alive\r\n";
}
else {
this.closeOnFinish = true;
message_header += "Connection: close\r\n";
}
}
if (sent_content_length_header === false && sent_transfer_encoding_header === false) {
if (this.use_chunked_encoding_by_default) {
message_header += "Transfer-Encoding: chunked\r\n";
this.chunked_encoding = true;
}
else {
this.closeOnFinish = true;
}
}
message_header += "\r\n";
this._send(message_header);
// wait until the first body chunk, or close(), is sent to flush.
};
/*
* END Custom patches
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment