|
@ -937,6 +937,12 @@ Agent.prototype.appendMessage = function(options) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Agent.prototype._removeSocket = function(socket) { |
|
|
|
|
|
var i = this.sockets.indexOf(socket); |
|
|
|
|
|
if (i >= 0) this.sockets.splice(i, 1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Agent.prototype._establishNewConnection = function() { |
|
|
Agent.prototype._establishNewConnection = function() { |
|
|
var self = this; |
|
|
var self = this; |
|
|
assert(this.sockets.length < this.maxSockets); |
|
|
assert(this.sockets.length < this.maxSockets); |
|
@ -944,6 +950,7 @@ Agent.prototype._establishNewConnection = function() { |
|
|
// Grab a new "socket". Depending on the implementation of _getConnection
|
|
|
// Grab a new "socket". Depending on the implementation of _getConnection
|
|
|
// this could either be a raw TCP socket or a TLS stream.
|
|
|
// this could either be a raw TCP socket or a TLS stream.
|
|
|
var socket = this._getConnection(this.host, this.port, function () { |
|
|
var socket = this._getConnection(this.host, this.port, function () { |
|
|
|
|
|
self.emit('connect'); // mostly for the shim.
|
|
|
debug("Agent _getConnection callback"); |
|
|
debug("Agent _getConnection callback"); |
|
|
self._cycle(); |
|
|
self._cycle(); |
|
|
}); |
|
|
}); |
|
@ -985,8 +992,18 @@ Agent.prototype._establishNewConnection = function() { |
|
|
// in the upgradeHead from the closing lines of the headers
|
|
|
// in the upgradeHead from the closing lines of the headers
|
|
|
var upgradeHead = d.slice(start + bytesParsed + 1, end); |
|
|
var upgradeHead = d.slice(start + bytesParsed + 1, end); |
|
|
|
|
|
|
|
|
|
|
|
// Make sure we don't try to send HTTP requests to it.
|
|
|
|
|
|
self._removeSocket(socket); |
|
|
|
|
|
|
|
|
|
|
|
socket.on('end', function() { |
|
|
|
|
|
self.emit('end'); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// XXX free the parser?
|
|
|
|
|
|
|
|
|
if (self.listeners('upgrade').length) { |
|
|
if (self.listeners('upgrade').length) { |
|
|
self.emit('upgrade', res, res.socket, upgradeHead); |
|
|
// Emit 'upgrade' on the Agent.
|
|
|
|
|
|
self.emit('upgrade', res, socket, upgradeHead); |
|
|
} else { |
|
|
} else { |
|
|
// Got upgrade header, but have no handler.
|
|
|
// Got upgrade header, but have no handler.
|
|
|
socket.destroy(); |
|
|
socket.destroy(); |
|
@ -995,14 +1012,14 @@ Agent.prototype._establishNewConnection = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
socket.onend = function() { |
|
|
socket.onend = function() { |
|
|
|
|
|
self.emit('end'); // mostly for the shim.
|
|
|
parser.finish(); |
|
|
parser.finish(); |
|
|
socket.destroy(); |
|
|
socket.destroy(); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// When the socket closes remove it from the list of available sockets.
|
|
|
// When the socket closes remove it from the list of available sockets.
|
|
|
socket.on('close', function() { |
|
|
socket.on('close', function() { |
|
|
var i = self.sockets.indexOf(socket); |
|
|
self._removeSocket(socket); |
|
|
if (i >= 0) self.sockets.splice(i, 1); |
|
|
|
|
|
// unref the parser for easy gc
|
|
|
// unref the parser for easy gc
|
|
|
parsers.free(parser); |
|
|
parsers.free(parser); |
|
|
}); |
|
|
}); |
|
@ -1133,12 +1150,51 @@ exports.get = function(options, cb) { |
|
|
// Shims to old interface.
|
|
|
// Shims to old interface.
|
|
|
|
|
|
|
|
|
function Client(port, host) { |
|
|
function Client(port, host) { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
|
|
|
this.port = port; |
|
|
this.port = port; |
|
|
this.host = host; |
|
|
this.host = host; |
|
|
|
|
|
this.agent = getAgent(this.host, this.port); |
|
|
|
|
|
|
|
|
|
|
|
// proxy connect events upwards;
|
|
|
|
|
|
this.agent.on('connect', function() { |
|
|
|
|
|
self.emit('connect'); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.agent.on('end', function() { |
|
|
|
|
|
self.emit('end'); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// proxy upgrade events upwards;
|
|
|
|
|
|
this.agent.on('upgrade', function (res, socket, upgradeHead) { |
|
|
|
|
|
if (self.listeners('upgrade').length) { |
|
|
|
|
|
self.emit('upgrade', res, socket, upgradeHead); |
|
|
|
|
|
} else { |
|
|
|
|
|
socket.destroy(); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
util.inherits(Client, EventEmitter); |
|
|
util.inherits(Client, EventEmitter); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This method is used in a few tests to force the connections closed.
|
|
|
|
|
|
// Again - just a shim so as not to break code. Not really important.
|
|
|
|
|
|
Client.prototype.end = function() { |
|
|
|
|
|
for (var i = 0; i < this.agent.sockets.length; i++) { |
|
|
|
|
|
var socket = this.agent.sockets[i]; |
|
|
|
|
|
if (!socket._httpMessage && socket.writable) socket.end(); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Client.prototype.destroy = function(e) { |
|
|
|
|
|
for (var i = 0; i < this.agent.sockets.length; i++) { |
|
|
|
|
|
var socket = this.agent.sockets[i]; |
|
|
|
|
|
socket.destroy(e); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Client.prototype.request = function(method, path, headers) { |
|
|
Client.prototype.request = function(method, path, headers) { |
|
|
if (typeof(path) != 'string') { |
|
|
if (typeof(path) != 'string') { |
|
|
// assume method was omitted, shift arguments
|
|
|
// assume method was omitted, shift arguments
|
|
|