Skip to content

Commit

Permalink
Optimize, clean up net2 net.js and http2.js
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Jan 28, 2010
1 parent c328f3e commit aadce8e
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 150 deletions.
178 changes: 96 additions & 82 deletions lib/http2.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,78 +270,6 @@ ClientRequest.prototype.finish = function (responseListener) {
};


function createIncomingMessageStream (socket, cb) {
var incoming, field, value;

socket._parser.onMessageBegin = function () {
incoming = new IncomingMessage(socket);
field = null;
value = null;
};

// Only servers will get URL events.
socket._parser.onURL = function (b, start, len) {
var slice = b.asciiSlice(start, start+len);
if (incoming.url) {
incoming.url += slice;
} else {
// Almost always will branch here.
incoming.url = slice;
}
};

socket._parser.onHeaderField = function (b, start, len) {
var slice = b.asciiSlice(start, start+len).toLowerCase();
if (value) {
incoming._addHeaderLine(field, value);
field = null;
value = null;
}
if (field) {
field += slice;
} else {
field = slice;
}
};

socket._parser.onHeaderValue = function (b, start, len) {
var slice = b.asciiSlice(start, start+len);
if (value) {
value += slice;
} else {
value = slice;
}
};

socket._parser.onHeadersComplete = function (info) {
if (field && value) {
incoming._addHeaderLine(field, value);
}

incoming.httpVersionMajor = info.versionMajor;
incoming.httpVersionMinor = info.versionMinor;

if (info.method) {
// server only
incoming.method = info.method;
} else {
// client only
incoming.statusCode = info.statusCode;
}

cb(incoming, info.shouldKeepAlive);
};

socket._parser.onBody = function (b, start, len) {
incoming.emit("data", b.slice(start, start+len));
};

socket._parser.onMessageComplete = function () {
incoming.emit("eof");
};
}


/* Returns true if the message queue is finished and the socket
* should be closed. */
function flushMessageQueue (socket, queue) {
Expand All @@ -368,24 +296,106 @@ function flushMessageQueue (socket, queue) {
}


var parserFreeList = [];

function newParser (type) {
var parser;
if (parserFreeList.length) {
parser = parserFreeList.shift();
parser.reinitialize(type);
} else {
parser = new process.HTTPParser(type);

parser.onMessageBegin = function () {
parser.incoming = new IncomingMessage(parser.socket);
parser.field = null;
parser.value = null;
};

// Only servers will get URL events.
parser.onURL = function (b, start, len) {
var slice = b.asciiSlice(start, start+len);
if (parser.incoming.url) {
parser.incoming.url += slice;
} else {
// Almost always will branch here.
parser.incoming.url = slice;
}
};

parser.onHeaderField = function (b, start, len) {
var slice = b.asciiSlice(start, start+len).toLowerCase();
if (parser.value) {
parser.incoming._addHeaderLine(parser.field, parser.value);
parser.field = null;
parser.value = null;
}
if (parser.field) {
parser.field += slice;
} else {
parser.field = slice;
}
};

parser.onHeaderValue = function (b, start, len) {
var slice = b.asciiSlice(start, start+len);
if (parser.value) {
parser.value += slice;
} else {
parser.value = slice;
}
};

parser.onHeadersComplete = function (info) {
if (parser.field && parser.value) {
parser.incoming._addHeaderLine(parser.field, parser.value);
}

parser.incoming.httpVersionMajor = info.versionMajor;
parser.incoming.httpVersionMinor = info.versionMinor;

if (info.method) {
// server only
parser.incoming.method = info.method;
} else {
// client only
parser.incoming.statusCode = info.statusCode;
}

parser.onIncoming(parser.incoming, info.shouldKeepAlive);
};

parser.onBody = function (b, start, len) {
parser.incoming.emit("data", b.slice(start, start+len));
};

parser.onMessageComplete = function () {
parser.incoming.emit("eof");
};
}
return parser;
}

function freeParser (parser) {
if (parserFreeList.length < 1000) parserFreeList.push(parser);
}

function connectionListener (socket) {
var self = this;
if (socket._parser) throw new Error("socket already has a parser?");
socket._parser = new process.HTTPParser('request');
var parser = newParser('request');
// An array of responses for each socket. In pipelined connections
// we need to keep track of the order they were sent.
var responses = [];

socket.addListener('data', function (d) {
socket._parser.execute(d, 0, d.length);
socket.addListener('dataLite', function (d, start, end) {
parser.execute(d, start, end - start);
});

// is this really needed?
socket.addListener('eof', function () {
socket._parser.finish();
parser.finish();
// unref the parser for easy gc
socket._parser.host = null;
socket._parser = null;
freeParser(parser);

if (responses.length == 0) {
socket.close();
Expand All @@ -394,10 +404,14 @@ function connectionListener (socket) {
}
});

createIncomingMessageStream(socket, function (incoming, shouldKeepAlive) {
parser.socket = socket;
// The following callback is issued after the headers have been read on a
// new message. In this callback we setup the response object and pass it
// to the user.
parser.onIncoming = function (incoming, shouldKeepAlive) {
var req = incoming;

var res = new ServerResponse(req);

res.shouldKeepAlive = shouldKeepAlive;
res.addListener('flush', function () {
if (flushMessageQueue(socket, responses)) {
Expand All @@ -407,7 +421,7 @@ function connectionListener (socket) {
responses.push(res);

self.emit('request', req, res);
});
};
}


Expand Down
Loading

0 comments on commit aadce8e

Please sign in to comment.