agent.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * Module dependencies.
  3. */
  4. require('./patch-core');
  5. var extend = require('extend');
  6. var inherits = require('util').inherits;
  7. var EventEmitter = require('events').EventEmitter;
  8. /**
  9. * Module exports.
  10. */
  11. module.exports = Agent;
  12. /**
  13. * Base `http.Agent` implementation.
  14. * No pooling/keep-alive is implemented by default.
  15. *
  16. * @param {Function} callback
  17. * @api public
  18. */
  19. function Agent (callback) {
  20. if (!(this instanceof Agent)) return new Agent(callback);
  21. EventEmitter.call(this);
  22. if ('function' === typeof callback) {
  23. this.callback = callback;
  24. }
  25. }
  26. inherits(Agent, EventEmitter);
  27. Agent.prototype.callback = function callback (req, opts, fn) {
  28. fn(new Error('"agent-base" has no default implementation, you must subclass and override `callback()`'));
  29. };
  30. /**
  31. * Called by node-core's "_http_client.js" module when creating
  32. * a new HTTP request with this Agent instance.
  33. *
  34. * @api public
  35. */
  36. Agent.prototype.addRequest = function addRequest (req, host, port, localAddress) {
  37. var opts;
  38. if ('object' == typeof host) {
  39. // >= v0.11.x API
  40. opts = extend({}, req._options, host);
  41. } else {
  42. // <= v0.10.x API
  43. opts = extend({}, req._options, { host: host, port: port });
  44. if (null != localAddress) {
  45. opts.localAddress = localAddress;
  46. }
  47. }
  48. if (opts.host && opts.path) {
  49. // if both a `host` and `path` are specified then it's most likely the
  50. // result of a `url.parse()` call... we need to remove the `path` portion so
  51. // that `net.connect()` doesn't attempt to open that as a unix socket file.
  52. delete opts.path;
  53. }
  54. // set default `port` if none was explicitly specified
  55. if (null == opts.port) {
  56. opts.port = opts.secureEndpoint ? 443 : 80;
  57. }
  58. delete opts.agent;
  59. delete opts.hostname;
  60. delete opts._defaultAgent;
  61. delete opts.defaultPort;
  62. delete opts.createConnection;
  63. // hint to use "Connection: close"
  64. // XXX: non-documented `http` module API :(
  65. req._last = true;
  66. req.shouldKeepAlive = false;
  67. // clean up a bit of memory since we're no longer using this
  68. req._options = null;
  69. // create the `net.Socket` instance
  70. var sync = true;
  71. this.callback(req, opts, function (err, socket) {
  72. function emitErr () {
  73. req.emit('error', err);
  74. // For Safety. Some additional errors might fire later on
  75. // and we need to make sure we don't double-fire the error event.
  76. req._hadError = true;
  77. }
  78. if (err) {
  79. if (sync) {
  80. // need to defer the "error" event, when sync, because by now the `req`
  81. // instance hasn't event been passed back to the user yet...
  82. process.nextTick(emitErr);
  83. } else {
  84. emitErr();
  85. }
  86. } else {
  87. req.onSocket(socket);
  88. }
  89. });
  90. sync = false;
  91. };