|
|
@ -339,11 +339,19 @@ function connectionListener(socket) { |
|
|
|
parser.maxHeaderPairs = 2000; |
|
|
|
} |
|
|
|
|
|
|
|
socket.addListener('error', function(e) { |
|
|
|
socket.addListener('error', socketOnError); |
|
|
|
socket.addListener('close', serverSocketCloseListener); |
|
|
|
parser.onIncoming = parserOnIncoming; |
|
|
|
socket.on('end', socketOnEnd); |
|
|
|
socket.on('data', socketOnData); |
|
|
|
|
|
|
|
// TODO(isaacs): Move all these functions out of here
|
|
|
|
function socketOnError(e) { |
|
|
|
self.emit('clientError', e, this); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
socket.ondata = function(d) { |
|
|
|
function socketOnData(d) { |
|
|
|
debug('SERVER socketOnData %d', d.length); |
|
|
|
var ret = parser.execute(d); |
|
|
|
if (ret instanceof Error) { |
|
|
|
debug('parse error'); |
|
|
@ -352,26 +360,32 @@ function connectionListener(socket) { |
|
|
|
// Upgrade or CONNECT
|
|
|
|
var bytesParsed = ret; |
|
|
|
var req = parser.incoming; |
|
|
|
debug('SERVER upgrade or connect', req.method); |
|
|
|
|
|
|
|
socket.ondata = null; |
|
|
|
socket.onend = null; |
|
|
|
socket.removeListener('data', socketOnData); |
|
|
|
socket.removeListener('end', socketOnEnd); |
|
|
|
socket.removeListener('close', serverSocketCloseListener); |
|
|
|
parser.finish(); |
|
|
|
freeParser(parser, req); |
|
|
|
|
|
|
|
var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; |
|
|
|
if (EventEmitter.listenerCount(self, eventName) > 0) { |
|
|
|
debug('SERVER have listener for %s', eventName); |
|
|
|
var bodyHead = d.slice(bytesParsed, d.length); |
|
|
|
|
|
|
|
self.emit(eventName, req, req.socket, bodyHead); |
|
|
|
// TODO(isaacs): Need a way to reset a stream to fresh state
|
|
|
|
// IE, not flowing, and not explicitly paused.
|
|
|
|
socket._readableState.flowing = null; |
|
|
|
self.emit(eventName, req, socket, bodyHead); |
|
|
|
} else { |
|
|
|
// Got upgrade header or CONNECT method, but have no handler.
|
|
|
|
socket.destroy(); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
socket.onend = function() { |
|
|
|
function socketOnEnd() { |
|
|
|
var socket = this; |
|
|
|
var ret = parser.finish(); |
|
|
|
|
|
|
|
if (ret instanceof Error) { |
|
|
@ -390,14 +404,14 @@ function connectionListener(socket) { |
|
|
|
} else { |
|
|
|
if (socket.writable) socket.end(); |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
socket.addListener('close', serverSocketCloseListener); |
|
|
|
|
|
|
|
// 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(req, shouldKeepAlive) { |
|
|
|
|
|
|
|
function parserOnIncoming(req, shouldKeepAlive) { |
|
|
|
incoming.push(req); |
|
|
|
|
|
|
|
var res = new ServerResponse(req); |
|
|
@ -415,7 +429,8 @@ function connectionListener(socket) { |
|
|
|
|
|
|
|
// When we're finished writing the response, check if this is the last
|
|
|
|
// respose, if so destroy the socket.
|
|
|
|
res.on('finish', function() { |
|
|
|
res.on('finish', resOnFinish); |
|
|
|
function resOnFinish() { |
|
|
|
// Usually the first incoming element should be our request. it may
|
|
|
|
// be that in the case abortIncoming() was called that the incoming
|
|
|
|
// array will be empty.
|
|
|
@ -440,7 +455,7 @@ function connectionListener(socket) { |
|
|
|
m.assignSocket(socket); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
if (!util.isUndefined(req.headers.expect) && |
|
|
|
(req.httpVersionMajor == 1 && req.httpVersionMinor == 1) && |
|
|
@ -456,6 +471,6 @@ function connectionListener(socket) { |
|
|
|
self.emit('request', req, res); |
|
|
|
} |
|
|
|
return false; // Not a HEAD response. (Not even a response!)
|
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
exports._connectionListener = connectionListener; |
|
|
|