blob: 7ea91f886cba2409f7f4479dc33c924537354f7b [file] [log] [blame]
/**
* Module dependencies.
*/
require('./patch-core');
var extend = require('extend');
var inherits = require('util').inherits;
var EventEmitter = require('events').EventEmitter;
/**
* Module exports.
*/
module.exports = Agent;
/**
* Base `http.Agent` implementation.
* No pooling/keep-alive is implemented by default.
*
* @param {Function} callback
* @api public
*/
function Agent (callback) {
if (!(this instanceof Agent)) return new Agent(callback);
EventEmitter.call(this);
if ('function' === typeof callback) {
this.callback = callback;
}
}
inherits(Agent, EventEmitter);
Agent.prototype.callback = function callback (req, opts, fn) {
fn(new Error('"agent-base" has no default implementation, you must subclass and override `callback()`'));
};
/**
* Called by node-core's "_http_client.js" module when creating
* a new HTTP request with this Agent instance.
*
* @api public
*/
Agent.prototype.addRequest = function addRequest (req, host, port, localAddress) {
var opts;
if ('object' == typeof host) {
// >= v0.11.x API
opts = extend({}, req._options, host);
} else {
// <= v0.10.x API
opts = extend({}, req._options, { host: host, port: port });
if (null != localAddress) {
opts.localAddress = localAddress;
}
}
if (opts.host && opts.path) {
// if both a `host` and `path` are specified then it's most likely the
// result of a `url.parse()` call... we need to remove the `path` portion so
// that `net.connect()` doesn't attempt to open that as a unix socket file.
delete opts.path;
}
// set default `port` if none was explicitly specified
if (null == opts.port) {
opts.port = opts.secureEndpoint ? 443 : 80;
}
delete opts.agent;
delete opts.hostname;
delete opts._defaultAgent;
delete opts.defaultPort;
delete opts.createConnection;
// hint to use "Connection: close"
// XXX: non-documented `http` module API :(
req._last = true;
req.shouldKeepAlive = false;
// clean up a bit of memory since we're no longer using this
req._options = null;
// create the `net.Socket` instance
var sync = true;
this.callback(req, opts, function (err, socket) {
function emitErr () {
req.emit('error', err);
// For Safety. Some additional errors might fire later on
// and we need to make sure we don't double-fire the error event.
req._hadError = true;
}
if (err) {
if (sync) {
// need to defer the "error" event, when sync, because by now the `req`
// instance hasn't event been passed back to the user yet...
process.nextTick(emitErr);
} else {
emitErr();
}
} else {
req.onSocket(socket);
}
});
sync = false;
};