socks-agent.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. var tls = require('tls');
  2. var inherits = require('util').inherits;
  3. var EventEmitter = require('events').EventEmitter;
  4. var SocksClient = require('./socks-client.js');
  5. function SocksAgent(options, secure, rejectUnauthorized) {
  6. this.options = options;
  7. this.secure = secure || false;
  8. this.rejectUnauthorized = rejectUnauthorized;
  9. if (this.rejectUnauthorized === undefined) {
  10. this.rejectUnauthorized = true;
  11. }
  12. }
  13. inherits(SocksAgent, EventEmitter);
  14. SocksAgent.prototype.createConnection = function(req, opts, fn) {
  15. var handler = fn, host, self = this;
  16. this.options.target = this.options.target || {};
  17. if (!this.options.target.host) {
  18. this.options.target.host = opts.host;
  19. }
  20. if (!this.options.target.port) {
  21. this.options.target.port = opts.port;
  22. }
  23. host = this.options.target.host;
  24. if (this.secure) {
  25. handler = function(err, socket, info) {
  26. var options, cleartext;
  27. if (err) {
  28. return fn(err);
  29. }
  30. // save encrypted socket
  31. self.encryptedSocket = socket;
  32. options = {
  33. socket: socket,
  34. servername: host,
  35. rejectUnauthorized: self.rejectUnauthorized
  36. };
  37. cleartext = tls.connect(options, function (err) {
  38. return fn(err, this);
  39. });
  40. cleartext.on('error', fn);
  41. socket.resume();
  42. }
  43. }
  44. SocksClient.createConnection(this.options, handler);
  45. };
  46. /**
  47. * @see https://www.npmjs.com/package/agent-base
  48. */
  49. SocksAgent.prototype.addRequest = function(req, host, port, localAddress) {
  50. var opts;
  51. if ('object' === typeof host) {
  52. // >= v0.11.x API
  53. opts = host;
  54. if (opts.host && opts.path) {
  55. // if both a `host` and `path` are specified then it's most likely the
  56. // result of a `url.parse()` call... we need to remove the `path` portion so
  57. // that `net.connect()` doesn't attempt to open that as a unix socket file.
  58. delete opts.path;
  59. }
  60. } else {
  61. // <= v0.10.x API
  62. opts = { host: host, port: port };
  63. if (null !== localAddress) {
  64. opts.localAddress = localAddress;
  65. }
  66. }
  67. var sync = true;
  68. this.createConnection(req, opts, function (err, socket) {
  69. function emitErr () {
  70. req.emit('error', err);
  71. }
  72. if (err) {
  73. if (sync) {
  74. // need to defer the "error" event, when sync, because by now the `req`
  75. // instance hasn't event been passed back to the user yet...
  76. process.nextTick(emitErr);
  77. } else {
  78. emitErr();
  79. }
  80. } else {
  81. req.onSocket(socket);
  82. //have to resume this socket when node 12
  83. socket.resume();
  84. }
  85. });
  86. sync = false;
  87. };
  88. exports.Agent = SocksAgent;