| var tls = require('tls'); |
| var inherits = require('util').inherits; |
| var EventEmitter = require('events').EventEmitter; |
| var SocksClient = require('./socks-client.js'); |
| |
| function SocksAgent(options, secure, rejectUnauthorized) { |
| this.options = options; |
| this.secure = secure || false; |
| this.rejectUnauthorized = rejectUnauthorized; |
| |
| if (this.rejectUnauthorized === undefined) { |
| this.rejectUnauthorized = true; |
| } |
| } |
| |
| inherits(SocksAgent, EventEmitter); |
| |
| SocksAgent.prototype.createConnection = function(req, opts, fn) { |
| var handler = fn, host, self = this; |
| |
| this.options.target = this.options.target || {}; |
| |
| if (!this.options.target.host) { |
| this.options.target.host = opts.host; |
| } |
| |
| if (!this.options.target.port) { |
| this.options.target.port = opts.port; |
| } |
| |
| host = this.options.target.host; |
| |
| if (this.secure) { |
| handler = function(err, socket, info) { |
| var options, cleartext; |
| |
| if (err) { |
| return fn(err); |
| } |
| |
| // save encrypted socket |
| self.encryptedSocket = socket; |
| |
| options = { |
| socket: socket, |
| servername: host, |
| rejectUnauthorized: self.rejectUnauthorized |
| }; |
| |
| cleartext = tls.connect(options, function (err) { |
| return fn(err, this); |
| }); |
| cleartext.on('error', fn); |
| |
| socket.resume(); |
| } |
| } |
| |
| SocksClient.createConnection(this.options, handler); |
| }; |
| |
| /** |
| * @see https://www.npmjs.com/package/agent-base |
| */ |
| SocksAgent.prototype.addRequest = function(req, host, port, localAddress) { |
| var opts; |
| if ('object' === typeof host) { |
| // >= v0.11.x API |
| opts = host; |
| 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; |
| } |
| } else { |
| // <= v0.10.x API |
| opts = { host: host, port: port }; |
| if (null !== localAddress) { |
| opts.localAddress = localAddress; |
| } |
| } |
| |
| var sync = true; |
| |
| this.createConnection(req, opts, function (err, socket) { |
| function emitErr () { |
| req.emit('error', err); |
| } |
| 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); |
| //have to resume this socket when node 12 |
| socket.resume(); |
| } |
| }); |
| |
| sync = false; |
| }; |
| |
| exports.Agent = SocksAgent; |