From 08d046ddef9f2e14ac7b3a7c2a3b71522a2f59eb Mon Sep 17 00:00:00 2001 From: mhzed Date: Sun, 3 Mar 2019 14:14:26 +0800 Subject: [PATCH] Add/fix support for socks|http|https proxies. --- bin/wstunnel.js | 91 ++--- lib/WsStream.js | 6 - lib/WstClient.js | 107 ++---- lib/WstServer.js | 2 +- lib/httpSetup.js | 103 ------ lib/httptunnel/ClientConn.js | 40 ++- lib/tunnelAgent.js | 237 ------------ lib/wst.js | 3 +- package-lock.json | 680 ++++++++++++++++------------------- package.json | 6 +- test/test.js | 3 +- 11 files changed, 431 insertions(+), 847 deletions(-) delete mode 100644 lib/httpSetup.js delete mode 100644 lib/tunnelAgent.js diff --git a/bin/wstunnel.js b/bin/wstunnel.js index 9a53e98..1017573 100755 --- a/bin/wstunnel.js +++ b/bin/wstunnel.js @@ -1,4 +1,6 @@ -const globalTunnel = require('global-tunnel-ng'); +const SocksProxyAgent = require('socks-proxy-agent'); +const HttpProxyAgent = require('http-proxy-agent'); +const HttpsProxyAgent = require('https-proxy-agent'); var urlParse = require('url').parse; const Help = ` @@ -7,7 +9,7 @@ Run websocket tunnel server or client. To run client: wstunnel -t localport:host:port ws[s]://wshost:wsport Or client via proxy: wstunnel -t localport:host:port -p http://[user:pass@]host:port ws[s]://wshost:wsport -Now connecting to localhost:localport is same as connecting to host:port on wshost +Connecting to localhost:localport is the same as connecting to host:port on wshost For security, you can "lock" the tunnel destination on server side, for eample: wstunnel -s 0.0.0.0:8080 -t host:port @@ -40,8 +42,10 @@ module.exports = (Server, Client) => { .default('c', false) .describe('s', 'run as server, listen on [localip:]localport, default localip is 127.0.0.1') .describe('tunnel', 'run as tunnel client, specify [localip:]localport:host:port') - .describe("proxy", "connect via a http proxy server in client mode") + .describe("proxy", "connect via a http or socks proxy server in client mode, " + + "format: socks://ip:port or http[s]://host:port") .describe("c", "accept any certificates") + .describe("http", "force to use http tunnel") .argv; if (argv.s) { @@ -54,20 +58,7 @@ module.exports = (Server, Client) => { } server.start(argv.s, (err) => err ? console.log(` Server is listening on ${argv.s}`) : null) } else if (argv.t || argv.uuid !== undefined) { - // client mode - function tryParse(url) { - if (!url) { - return null; - } - var parsed = urlParse(url); - return { - protocol: parsed.protocol, - host: parsed.hostname, - port: parseInt(parsed.port, 10), - proxyAuth: parsed.auth - }; - } - + // client mode const uuid = require("machine-uuid"); uuid((machineId) => { if (argv.uuid === true) { // --uuid without param @@ -76,52 +67,62 @@ module.exports = (Server, Client) => { } else if (argv.uuid){ machineId = argv.uuid; } - let conf = {}; + if (argv.c) { + process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; + } + let client = new Client() + let wsHostUrl = argv._[0] + if ( argv.proxy ) { - conf = tryParse( argv.proxy ); - if ( argv.c ) { - conf.proxyHttpsOptions = {rejectUnauthorized: false}; - process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; + const conf = urlParse(argv.proxy ); + if (conf.protocol === "socks:") { + client.setAgentMaker((c) => new SocksProxyAgent(Object.assign({}, c, conf))); + } else if (conf.protocol === "https:" || conf.protocol === "http:") { + const p = urlParse(wsHostUrl).protocol; + if ('wss:' === p || 'https:' === p) + client.setAgentMaker((c) => new HttpsProxyAgent(Object.assign({}, c, conf))); + else if ('ws:' === p || 'http:' === p) + client.setAgentMaker((c) => new HttpProxyAgent(Object.assign({}, c, conf))); + else { + console.log("Invalid target " + wsHostUrl); + process.exit(1); + } + } else { + console.log("Invalid proxy " + argv.proxy); + process.exit(1); } - globalTunnel.initialize(conf); - } else { - require("../lib/httpSetup").config(argv.proxy, argv.c) } - - let client = new Client() if (argv.http) { client.setHttpOnly(true) } - - let wsHostUrl = argv._[0] client.verbose() - let DefaultLocalIp = "127.0.0.1" - let localAddr - let remoteAddr + let localHost = "127.0.0.1", localPort; + let remoteAddr; let toks = argv.t.split(":") if (toks.length === 4) { - localAddr = `${toks[0]}:${toks[1]}` + [localHost, localPort] = toks; remoteAddr = `${toks[2]}:${toks[3]}` } else if (toks.length === 3) { remoteAddr = `${toks[1]}:${toks[2]}` if (toks[0] === 'stdio') { - client.startStdio(wsHostUrl, remoteAddr, {'x-wstclient': machineId}, (err) => { - if (err) { - console.error(err) - process.exit(1) - } - }) - return + localHost = toks[0]; } else { - localAddr = `${DefaultLocalIp}:${toks[0]}` + localPort = toks[0]; } - } else if (toks.length === 1) { - localAddr = `${DefaultLocalIp}:${toks[0]}` + } else { + console.log("Invalid tunnel option " + argv.t); + console.log(optimist.help()); + process.exit(1); + } + localPort = parseInt(localPort); + if (localHost === "stdio") { + client.startStdio(wsHostUrl, remoteAddr, {'x-wstclient': machineId}); + } else { + client.start(localHost, localPort, wsHostUrl, remoteAddr, {'x-wstclient': machineId}); } - client.start(localAddr, wsHostUrl, remoteAddr, {'x-wstclient': machineId}); }) } else { - return console.log(optimist.help()); + console.log(optimist.help()); } } diff --git a/lib/WsStream.js b/lib/WsStream.js index 1678882..3fea1c9 100644 --- a/lib/WsStream.js +++ b/lib/WsStream.js @@ -1,11 +1,5 @@ -let WsStream; const stream = require("stream"); -const assert = require("assert"); -const log = require("lawg"); -const util = require("util"); -const future = require("phuture"); -const domain = require("domain"); // Stream wrapper for http://github.com/Worlize/WebSocket-Node.git version 1.0.8 module.exports = (WsStream = class WsStream extends stream.Duplex { diff --git a/lib/WstClient.js b/lib/WstClient.js index ed1a64e..943d042 100644 --- a/lib/WstClient.js +++ b/lib/WstClient.js @@ -1,11 +1,10 @@ -let wst_client; const net = require("net"); const WsStream = require("./WsStream"); const url = require('url'); const log = require("lawg"); const ClientConn = require("./httptunnel/ClientConn"); -const etagHeader = require("./etagHeader"); +const bindStream = require("./bindStream"); const createWsClient = () => new (require('websocket').client)(); module.exports = (wst_client = class wst_client extends require('events').EventEmitter { @@ -22,10 +21,12 @@ module.exports = (wst_client = class wst_client extends require('events').EventE } verbose() { - this.on('tunnel', (ws, sock) => { + this.on('tunnel', (sock, ws) => { if (ws instanceof WsStream) { log('Websocket tunnel established'); - } else { log('Http tunnel established'); } + } else { + log('Http tunnel established'); + } return sock.on('close', () => log('Tunnel closed')); }); this.on('connectHttpFailed', error => log(`HTTP connect error: ${error.toString()}`)); @@ -35,59 +36,23 @@ module.exports = (wst_client = class wst_client extends require('events').EventE setHttpOnly(httpOnly) { this.httpOnly = httpOnly; } - - // example: start(8081, "wss://ws.domain.com:454", "dst.domain.com:22") - // meaning: tunnel *:localport to remoteAddr by using websocket connection to wsHost - // or start("localhost:8081", "wss://ws.domain.com:454", "dst.domain.com:22") + // example: start("localhost", 8081, "wss://ws.domain.com:454", "dst.domain.com:22") + // meaning: tunnel localhost:8081 to remoteAddr by using websocket connection to wsHost // @wsHostUrl: ws:// denotes standard socket, wss:// denotes ssl socket // may be changed at any time to change websocket server info - start(localAddr, wsHostUrl, remoteAddr, optionalHeaders, cb) { - let localHost, localPort; + start(localHost, localPort, wsHostUrl, remoteAddr, optionalHeaders, cb) { this.wsHostUrl = wsHostUrl; - if (typeof optionalHeaders === 'function') { - cb = optionalHeaders; - optionalHeaders = {}; - } - - if (typeof localAddr === 'number') { - localPort = localAddr; - } else { - [localHost, localPort] = Array.from(localAddr.split(':')); - if (/^\d+$/.test(localHost)) { - localPort = localHost; - localHost = null; - } - localPort = parseInt(localPort); - } - if (localHost == null) { localHost = '127.0.0.1'; } this.tcpServer.listen(localPort, localHost, cb); - return this.tcpServer.on("connection", tcpConn => { - const bind = (s, tcp) => { - require("./bindStream")(s, tcp); - return this.emit('tunnel', s, tcp); + this.tcpServer.on("connection", tcpConn => { + const bind = (tcp, s) => { + bindStream(tcp, s); + this.emit('tunnel', tcp, s); }; - - if (this.httpOnly) { - return this._httpConnect(this.wsHostUrl, remoteAddr, optionalHeaders, (err, httpConn) => { - if (!err) { - return bind(httpConn, tcpConn); - } else { return tcpConn.end(); } - }); - } else { - return this._wsConnect(this.wsHostUrl, remoteAddr, optionalHeaders, (error, wsStream) => { - if (!error) { - return bind(wsStream, tcpConn); - } else { - this.emit('connectFailed', error); - return this._httpConnect(this.wsHostUrl, remoteAddr, optionalHeaders, (err, httpConn) => { - if (!err) { - return bind(httpConn, tcpConn); - } else { return tcpConn.end(); } - }); - } - }); - } + this._connect(this.wsHostUrl, remoteAddr, optionalHeaders, (err, stream)=>{ + if (err) this.emit('connectFailed', err); + else bind(tcpConn, stream); + }) }); } @@ -97,34 +62,37 @@ module.exports = (wst_client = class wst_client extends require('events').EventE process.stdin.pipe(s); s.pipe(process.stdout); s.on('close', () => process.exit(0)); - return s.on('finish', () => process.exit(0)); + s.on('finish', () => process.exit(0)); }; + this._connect(this.wsHostUrl, remoteAddr, optionalHeaders, (err, stream)=>{ + if (err) this.emit('connectFailed', err); + else bind(stream); + if (cb) cb(err); + }) + } + _connect(wsHostUrl, remoteAddr, optionalHeaders, cb) { if (this.httpOnly) { - return this._httpConnect(this.wsHostUrl, remoteAddr, optionalHeaders, (err, httpConn) => { - if (!err) { bind(httpConn); } - return cb(err); - }); + return this._httpConnect(wsHostUrl, remoteAddr, optionalHeaders, cb); } else { - return this._wsConnect(this.wsHostUrl, remoteAddr, optionalHeaders, (error, wsStream) => { - if (!error) { - bind(wsStream); - return cb(); + return this._wsConnect(wsHostUrl, remoteAddr, optionalHeaders, (err, wsStream) => { + if (!err) { + cb(err, wsStream); } else { - this.emit('connectFailed', error); - return this._httpConnect(this.wsHostUrl, remoteAddr, optionalHeaders, (err, httpConn) => { - if (!err) { bind(httpConn); } - return cb(err); - }); + this.emit('connectFailed', err); + return this._httpConnect(wsHostUrl, remoteAddr, optionalHeaders, cb); } }); - } + } + } + setAgentMaker(maker) { + this.agentMaker = maker; } _httpConnect(url, remoteAddr, optionalHeaders, cb) { let tunurl = url.replace(/^ws/, 'http'); if (remoteAddr) { tunurl += `?dst=${remoteAddr}`; } - const httpConn = new ClientConn(tunurl); + const httpConn = new ClientConn(tunurl, this.agentMaker); return httpConn.connect(optionalHeaders, err => { if (err) { this.emit('connectHttpFailed', err); @@ -136,6 +104,7 @@ module.exports = (wst_client = class wst_client extends require('events').EventE } _wsConnect(wsHostUrl, remoteAddr, optionalHeaders, cb) { + wsHostUrl = wsHostUrl.replace(/^http/, 'ws'); let wsurl; if (remoteAddr) { wsurl = `${wsHostUrl}/?dst=${remoteAddr}`; } else { wsurl = `${wsHostUrl}`; } const wsClient = createWsClient(); @@ -143,8 +112,8 @@ module.exports = (wst_client = class wst_client extends require('events').EventE if (urlo.auth) { optionalHeaders.Authorization = `Basic ${(new Buffer(urlo.auth)).toString('base64')}`; } - wsClient.connect(wsurl, 'tunnel-protocol', undefined, optionalHeaders - , { agent: null } ); + wsClient.connect(wsurl, 'tunnel-protocol', undefined, optionalHeaders, + {agent: this.agentMaker ? this.agentMaker(): null}); wsClient.on('connectFailed', error => cb(error)); return wsClient.on('connect', wsConn => { const wsStream = new WsStream(wsConn); diff --git a/lib/WstServer.js b/lib/WstServer.js index a026904..ed4c9fe 100644 --- a/lib/WstServer.js +++ b/lib/WstServer.js @@ -1,4 +1,4 @@ -let wst_server; + const WebSocketServer = require('websocket').server; const http = require('http'); const url = require("url"); diff --git a/lib/httpSetup.js b/lib/httpSetup.js deleted file mode 100644 index a7576d4..0000000 --- a/lib/httpSetup.js +++ /dev/null @@ -1,103 +0,0 @@ -// override nodejs http/https request methods, for proxies - -const https = require("https"); -const http = require("http"); -const url = require("url"); -const tunnel = require("./tunnelAgent"); - -const old_https_request = https.request; -const old_http_request = http.request; - -var thisHttpSetup = null; -// proxyUrl is http[s]://user:pass@host:port/ -// if anyCert is true, rejectUnauthorized is set to false, including for https proxy server -module.exports = (thisHttpSetup = { - - createHttpsAgent(options) { - return new https.Agent(options); - }, - - config(proxyUrl, anyCert) { - let proxy; - if (proxyUrl) { proxy = url.parse(proxyUrl); } - if (!proxy && !anyCert) { return; } // nothing to do - - if (anyCert && !proxy) { - https.request = function() { - let options = arguments[0]; - // if typeof options.agent == 'object' - // options.agent.rejectUnauthorized = false - if (typeof options === 'string') { options = url.parse(options); } - options.rejectUnauthorized = false; // default to accept all ssl certificate - return old_https_request.apply(undefined, Array.apply(null, arguments)); - }; - thisHttpSetup.createHttpsAgent = function(options) { - options.rejectUnauthorized = false; - return new https.Agent(options); - }; - return; - } - - // use tunnel agent for https requests - const _m = { - 'https:': 'Https', - 'http:': 'Http' - }; - const tunnelOptions = { - proxy: { - host: proxy.hostname, - port: +proxy.port, - proxyAuth: proxy.auth - }, - rejectUnauthorized: (anyCert ? false : true) - }; - const tunnelName = `httpsOver${_m[proxy.protocol]}`; - - thisHttpSetup.createHttpsAgent = function(options) { - for (let k in tunnelOptions) { - const v = tunnelOptions[k]; - options[k] = v; - } - const ret = tunnel[tunnelName](options); - return ret; - }; - - const httpsAgent = tunnel[tunnelName](tunnelOptions); - - // must override default request() at the end, tunnel uses old impls - https.request = function() { - let options = arguments[0]; - if (typeof options === 'string') { - options = url.parse(options); - arguments[0] = options; - } - if (anyCert) { options.rejectUnauthorized = false; } - if (options.agent == null) { options.agent = httpsAgent; } - return old_https_request.apply(undefined, Array.apply(null, arguments)); - }; - - // for http request, no tunnel agent is used - return http.request = function() { - let options = arguments[0]; - if (typeof options === 'string') { - options = url.parse(options); - arguments[0] = options; - } - // ensure Host header is set properly - if (options.headers == null) { options.headers = {}; } - if (!options.headers.Host) { - options.headers.Host = `${options.hostname}`; - if (options.port !== 80) { options.headers.Host += `:${options.port}`; } - } - // ensure path is full url path - if (!/^http/.test(options.path)) { - options.path = `http://${options.headers.Host}${options.path}`; - } - // override target to be proxy - options.hostname = proxy.hostname; - options.port = proxy.port; - return old_http_request.apply(undefined, Array.apply(null, arguments)); - }; - } - -}); diff --git a/lib/httptunnel/ClientConn.js b/lib/httptunnel/ClientConn.js index 9b37f27..3601cfc 100644 --- a/lib/httptunnel/ClientConn.js +++ b/lib/httptunnel/ClientConn.js @@ -5,9 +5,7 @@ const http = require("http"); const url = require("url"); const log = require("lawg"); const future = require("phuture"); -const httpSetup = require("../httpSetup"); const debug = require("../debug"); - const { BlockSize, AutoSealDelayMs, ReqOpenIntervalMs } = require("./Constants"); /* @@ -20,9 +18,9 @@ Example: conn.pipe(socket).pipe(conn) How it works: - Client maintains two persistent outstanding http request: persistent so that each request reuses the same socket. - For send request: client is responsible to end request - For recv request: sever is responsible to end request + Client maintains two persistent outstanding http request: keep alive and reuse socket. + One request is for sending data: client is responsible to end request + One request is for recving data: sever is responsible to end request */ if (debug.isDebug) { @@ -33,29 +31,37 @@ if (debug.isDebug) { module.exports = class ClientConn extends require("stream").Duplex { - constructor(urlEndPoint) { + constructor(urlEndPoint, agentMaker) { super({}); this.urlEndPoint = urlEndPoint; this._sig = "httpCli"; this.url = url.parse(this.urlEndPoint); + this.connAgent = agentMaker ? agentMaker() : null; + const opts = {maxSockets: 1, keepAlive: true, keepAliveMsecs: 10000}; if (this.url.protocol === 'https:') { this.doHttp = https; if (!this.url.port) { this.url.port = 443; } - this.sendAgent = httpSetup.createHttpsAgent({maxSockets: 1, keepAlive: true, keepAliveMsecs: 10000}); - this.recvAgent = httpSetup.createHttpsAgent({maxSockets: 1, keepAlive: true, keepAliveMsecs: 10000}); + if (agentMaker) { + this.sendAgent = agentMaker(opts); + this.recvAgent = agentMaker(opts); + } else { + this.sendAgent = new https.Agent(opts); + this.recvAgent = new https.Agent(opts); + } } else { this.doHttp = http; if (!this.url.port) { this.url.port = 80; } - this.sendAgent = new http.Agent({maxSockets: 1, keepAlive: true, keepAliveMsecs: 10000}); - this.recvAgent = new http.Agent({maxSockets: 1, keepAlive: true, keepAliveMsecs: 10000}); - } + if (agentMaker) { + this.sendAgent = agentMaker(opts); + this.recvAgent = agentMaker(opts); + } else { + this.sendAgent = new http.Agent(opts); + this.recvAgent = new http.Agent(opts); + } + } } - // headers is optional - connect(...args1) { - const args = args1.slice(0, args1.length - 1), cb = args1[args1.length - 1]; - let [headers] = Array.from(args); - if (headers == null) { headers = {}; } + connect(headers, cb) { headers['x-htundir'] = 'conn'; headers['Connection'] = 'keep-alive'; const req = this.doHttp.request({ @@ -63,7 +69,7 @@ module.exports = class ClientConn extends require("stream").Duplex { port: this.url.port, path: this.url.path, method: 'GET', - agent: null, + agent: this.connAgent, headers }); req.on('response', res => { diff --git a/lib/tunnelAgent.js b/lib/tunnelAgent.js deleted file mode 100644 index fac1714..0000000 --- a/lib/tunnelAgent.js +++ /dev/null @@ -1,237 +0,0 @@ -'use strict' - -var tls = require('tls'), - http = require('http'), - https = require('https'), - events = require('events'), - assert = require('assert'), - util = require('util') - ; - -exports.httpOverHttp = httpOverHttp -exports.httpsOverHttp = httpsOverHttp -exports.httpOverHttps = httpOverHttps -exports.httpsOverHttps = httpsOverHttps - -var httpRequest = http.request - -function httpOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = httpRequest - return agent -} - -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options) - agent.request = httpRequest - agent.createSocket = createSecureSocket - return agent -} - -function httpOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - return agent -} - -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options) - agent.request = https.request - agent.createSocket = createSecureSocket - return agent -} - -function TunnelingAgent(options) { - var self = this - self.options = options || {} - self.proxyOptions = self.options.proxy || {} - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets - self.requests = [] - self.sockets = [] - - self.on('free', function onFree(socket, host, port) { - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i] - if (pending.host === host && pending.port === port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1) - pending.request.onSocket(socket) - return - } - } - socket.destroy() - self.removeSocket(socket) - }) -} -util.inherits(TunnelingAgent, events.EventEmitter) - -TunnelingAgent.prototype.addRequest = function addRequest(req, options) { - var self = this - - // Legacy API: addRequest(req, host, port, path) - if (typeof options === 'string') { - options = { - host: options, - port: arguments[2], - path: arguments[3] - }; - } - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push({host: options.host, port: options.port, request: req}) - return - } - - // If we are under maxSockets create a new one. - self.createConnection({host: options.host, port: options.port, request: req}) -} - -TunnelingAgent.prototype.createConnection = function createConnection(pending) { - var self = this - - self.createSocket(pending, function(socket) { - socket.on('free', onFree) - socket.on('close', onCloseOrRemove) - socket.on('agentRemove', onCloseOrRemove) - pending.request.onSocket(socket) - - function onFree() { - self.emit('free', socket, pending.host, pending.port) - } - - function onCloseOrRemove(err) { - self.removeSocket(socket) - socket.removeListener('free', onFree) - socket.removeListener('close', onCloseOrRemove) - socket.removeListener('agentRemove', onCloseOrRemove) - } - }) -} - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this - var placeholder = {} - self.sockets.push(placeholder) - var connectOptions = mergeOptions({}, self.proxyOptions, - { method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false - } - ) - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {} - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64') - } - - debug('making CONNECT request') - var connectReq = self.request(connectOptions) - connectReq.useChunkedEncodingByDefault = false // for v0.6 - connectReq.once('response', onResponse) // for v0.6 - connectReq.once('upgrade', onUpgrade) // for v0.6 - connectReq.once('connect', onConnect) // for v0.7 or later - connectReq.once('error', onError) - connectReq.end() - - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true - } - - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head) - }) - } - - function onConnect(res, socket, head) { - connectReq.removeAllListeners() - socket.removeAllListeners() - - if (res.statusCode === 200) { - assert.equal(head.length, 0) - debug('tunneling connection has established') - self.sockets[self.sockets.indexOf(placeholder)] = socket - cb(socket) - } else { - debug('tunneling socket could not be established, statusCode=%d', res.statusCode) - var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } - } - - function onError(cause) { - connectReq.removeAllListeners() - - debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack) - var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message) - error.code = 'ECONNRESET' - options.request.emit('error', error) - self.removeSocket(placeholder) - } -} - -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) return - - this.sockets.splice(pos, 1) - - var pending = this.requests.shift() - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createConnection(pending) - } -} - -function createSecureSocket(options, cb) { - var self = this - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, mergeOptions({}, self.options, - { servername: options.host, - socket: socket - } - )) - self.sockets[self.sockets.indexOf(socket)] = secureSocket - cb(secureSocket) - }) -} - -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i] - if (typeof overrides === 'object') { - var keys = Object.keys(overrides) - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j] - if (overrides[k] !== undefined) { - target[k] = overrides[k] - } - } - } - } - return target -} - -var debug -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments) - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0] - } else { - args.unshift('TUNNEL:') - } - console.error.apply(console, args) - } -} else { - debug = function() {} -} -exports.debug = debug // for test diff --git a/lib/wst.js b/lib/wst.js index 008505b..f6e0390 100644 --- a/lib/wst.js +++ b/lib/wst.js @@ -1,6 +1,5 @@ module.exports = { server: require("./WstServer"), client: require("./WstClient"), - bin: require("../bin/wstunnel"), - httpSetup: require("./httpSetup") + bin: require("../bin/wstunnel") }; diff --git a/package-lock.json b/package-lock.json index f219c44..fe1bb55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "wstunnel", - "version": "1.2.7", + "version": "1.2.8", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,24 +14,16 @@ } }, "@babel/generator": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.0.tgz", - "integrity": "sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", + "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", "dev": true, "requires": { - "@babel/types": "^7.2.0", + "@babel/types": "^7.3.4", "jsesc": "^2.5.1", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "source-map": "^0.5.0", "trim-right": "^1.0.1" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - } } }, "@babel/helper-function-name": { @@ -75,54 +67,48 @@ } }, "@babel/parser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.0.tgz", - "integrity": "sha512-M74+GvK4hn1eejD9lZ7967qAwvqTZayQa3g10ag4s9uewgR7TKjeaT0YMyoq+gVfKYABiWZ4MQD701/t5e1Jhg==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", "dev": true }, "@babel/template": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz", - "integrity": "sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.1.2", - "@babel/types": "^7.1.2" + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" } }, "@babel/traverse": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.1.6.tgz", - "integrity": "sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", + "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.1.6", + "@babel/generator": "^7.3.4", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.1.6", - "@babel/types": "^7.1.6", + "@babel/parser": "^7.3.4", + "@babel/types": "^7.3.4", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.10" + "lodash": "^4.17.11" }, "dependencies": { "debug": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", - "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -132,22 +118,22 @@ } }, "@babel/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.0.tgz", - "integrity": "sha512-b4v7dyfApuKDvmPb+O488UlGuR1WbwMXFsO/cyqMrnfvRAChZKJAYeeglWTjUO1b9UghKKgepAQM5tsvBJca6A==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", + "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", "dev": true, "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - } + } + }, + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "requires": { + "es6-promisify": "^5.0.0" } }, "ajv": { @@ -281,9 +267,9 @@ "dev": true }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -414,6 +400,19 @@ "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", "dev": true }, + "es6-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -530,19 +529,10 @@ "path-is-absolute": "^1.0.0" } }, - "global-tunnel-ng": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.1.0.tgz", - "integrity": "sha1-biozHrEqlLD7GK6PBANq72jqkVs=", - "requires": { - "lodash": "^4.17.0", - "tunnel": "^0.0.4" - } - }, "globals": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz", - "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", "dev": true }, "graceful-fs": { @@ -579,6 +569,25 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -590,6 +599,30 @@ "sshpk": "^1.7.0" } }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -612,6 +645,11 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -637,15 +675,15 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", "dev": true }, "istanbul-lib-instrument": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz", - "integrity": "sha512-eQY9vN9elYjdgN9Iv6NS/00bptm02EBBk70lRMaVjeA6QYocQgenVrSgC28TJurdnZa80AGO3ASdFN+w/njGiQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", "dev": true, "requires": { "@babel/generator": "^7.0.0", @@ -653,7 +691,7 @@ "@babel/template": "^7.0.0", "@babel/traverse": "^7.0.0", "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.1", + "istanbul-lib-coverage": "^2.0.3", "semver": "^5.5.0" } }, @@ -729,7 +767,8 @@ "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true }, "log-driver": { "version": "1.2.7", @@ -846,53 +885,37 @@ } }, "nyc": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.1.0.tgz", - "integrity": "sha512-3GyY6TpQ58z9Frpv4GMExE1SV2tAgYqC7HSy2omEhNiCT3mhT9NyiOvIE8zkbuJVFzmvvNTnE4h/7/wQae7xLg==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz", + "integrity": "sha512-P+FwIuro2aFG6B0Esd9ZDWUd51uZrAEoGutqZxzrVmYl3qSfkLgcQpBPBjtDFsUQLFY1dvTQJPOyeqr8S9GF8w==", "dev": true, "requires": { "archy": "^1.0.0", "arrify": "^1.0.1", - "caching-transform": "^2.0.0", + "caching-transform": "^3.0.1", "convert-source-map": "^1.6.0", - "debug-log": "^1.0.1", "find-cache-dir": "^2.0.0", "find-up": "^3.0.0", "foreground-child": "^1.5.6", "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.1", - "istanbul-lib-hook": "^2.0.1", - "istanbul-lib-instrument": "^3.0.0", - "istanbul-lib-report": "^2.0.2", - "istanbul-lib-source-maps": "^2.0.1", - "istanbul-reports": "^2.0.1", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.1.0", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.1", "make-dir": "^1.3.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", - "rimraf": "^2.6.2", + "rimraf": "^2.6.3", "signal-exit": "^3.0.2", "spawn-wrap": "^1.4.2", - "test-exclude": "^5.0.0", + "test-exclude": "^5.1.0", "uuid": "^3.3.2", - "yargs": "11.1.0", - "yargs-parser": "^9.0.2" + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" }, "dependencies": { - "align-text": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "amdefine": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, "ansi-regex": { "version": "3.0.0", "bundled": true, @@ -917,9 +940,12 @@ "dev": true }, "async": { - "version": "1.5.2", + "version": "2.6.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "lodash": "^4.17.11" + } }, "balanced-match": { "version": "1.0.0", @@ -935,55 +961,30 @@ "concat-map": "0.0.1" } }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, "caching-transform": { - "version": "2.0.0", + "version": "3.0.1", "bundled": true, "dev": true, "requires": { - "make-dir": "^1.0.0", - "md5-hex": "^2.0.0", - "package-hash": "^2.0.0", - "write-file-atomic": "^2.0.0" + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" } }, "camelcase": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true - }, - "center-align": { - "version": "0.1.3", + "version": "5.0.0", "bundled": true, - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } + "dev": true }, "cliui": { - "version": "2.1.0", + "version": "4.1.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "bundled": true, - "dev": true, - "optional": true - } + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" } }, "code-point-at": { @@ -991,6 +992,12 @@ "bundled": true, "dev": true }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, "commondir": { "version": "1.0.1", "bundled": true, @@ -1019,18 +1026,13 @@ } }, "debug": { - "version": "3.1.0", + "version": "4.1.1", "bundled": true, "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "debug-log": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, "decamelize": { "version": "1.2.0", "bundled": true, @@ -1044,6 +1046,14 @@ "strip-bom": "^3.0.0" } }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "error-ex": { "version": "1.3.2", "bundled": true, @@ -1058,12 +1068,12 @@ "dev": true }, "execa": { - "version": "0.7.0", + "version": "1.0.0", "bundled": true, "dev": true, "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", @@ -1072,11 +1082,13 @@ }, "dependencies": { "cross-spawn": { - "version": "5.1.0", + "version": "6.0.5", "bundled": true, "dev": true, "requires": { - "lru-cache": "^4.0.1", + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } @@ -1121,9 +1133,12 @@ "dev": true }, "get-stream": { - "version": "3.0.0", + "version": "4.1.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "pump": "^3.0.0" + } }, "glob": { "version": "7.1.3", @@ -1139,28 +1154,25 @@ } }, "graceful-fs": { - "version": "4.1.11", + "version": "4.1.15", "bundled": true, "dev": true }, "handlebars": { - "version": "4.0.11", + "version": "4.1.0", "bundled": true, "dev": true, "requires": { - "async": "^1.4.0", + "async": "^2.5.0", "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" }, "dependencies": { "source-map": { - "version": "0.4.4", + "version": "0.6.1", "bundled": true, - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } + "dev": true } } }, @@ -1169,6 +1181,14 @@ "bundled": true, "dev": true }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, "hosted-git-info": { "version": "2.7.1", "bundled": true, @@ -1194,7 +1214,7 @@ "dev": true }, "invert-kv": { - "version": "1.0.0", + "version": "2.0.0", "bundled": true, "dev": true }, @@ -1203,19 +1223,6 @@ "bundled": true, "dev": true }, - "is-buffer": { - "version": "1.1.6", - "bundled": true, - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "bundled": true, @@ -1232,12 +1239,12 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "2.0.1", + "version": "2.0.3", "bundled": true, "dev": true }, "istanbul-lib-hook": { - "version": "2.0.1", + "version": "2.0.3", "bundled": true, "dev": true, "requires": { @@ -1245,22 +1252,32 @@ } }, "istanbul-lib-report": { - "version": "2.0.2", + "version": "2.0.4", "bundled": true, "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.1", + "istanbul-lib-coverage": "^2.0.3", "make-dir": "^1.3.0", - "supports-color": "^5.4.0" + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "istanbul-lib-source-maps": { - "version": "2.0.1", + "version": "3.0.2", "bundled": true, "dev": true, "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^2.0.1", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", "make-dir": "^1.3.0", "rimraf": "^2.6.2", "source-map": "^0.6.1" @@ -1274,11 +1291,11 @@ } }, "istanbul-reports": { - "version": "2.0.1", + "version": "2.1.1", "bundled": true, "dev": true, "requires": { - "handlebars": "^4.0.11" + "handlebars": "^4.1.0" } }, "json-parse-better-errors": { @@ -1286,26 +1303,12 @@ "bundled": true, "dev": true }, - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "optional": true - }, "lcid": { - "version": "1.0.0", + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "invert-kv": "^1.0.0" + "invert-kv": "^2.0.0" } }, "load-json-file": { @@ -1328,18 +1331,18 @@ "path-exists": "^3.0.0" } }, - "lodash.flattendeep": { - "version": "4.4.0", + "lodash": { + "version": "4.17.11", "bundled": true, "dev": true }, - "longest": { - "version": "1.0.1", + "lodash.flattendeep": { + "version": "4.4.0", "bundled": true, "dev": true }, "lru-cache": { - "version": "4.1.3", + "version": "4.1.5", "bundled": true, "dev": true, "requires": { @@ -1355,25 +1358,22 @@ "pify": "^3.0.0" } }, - "md5-hex": { - "version": "2.0.0", + "map-age-cleaner": { + "version": "0.1.3", "bundled": true, "dev": true, "requires": { - "md5-o-matic": "^0.1.1" + "p-defer": "^1.0.0" } }, - "md5-o-matic": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, "mem": { - "version": "1.1.0", + "version": "4.1.0", "bundled": true, "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" } }, "merge-source-map": { @@ -1425,17 +1425,22 @@ } }, "ms": { - "version": "2.0.0", + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", "bundled": true, "dev": true }, "normalize-package-data": { - "version": "2.4.0", + "version": "2.5.0", "bundled": true, "dev": true, "requires": { "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", + "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } @@ -1476,23 +1481,33 @@ "dev": true }, "os-locale": { - "version": "2.1.0", + "version": "3.1.0", "bundled": true, "dev": true, "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, "p-finally": { "version": "1.0.0", "bundled": true, "dev": true }, - "p-limit": { + "p-is-promise": { "version": "2.0.0", "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, "dev": true, "requires": { "p-try": "^2.0.0" @@ -1512,13 +1527,13 @@ "dev": true }, "package-hash": { - "version": "2.0.0", + "version": "3.0.0", "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.11", + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", "lodash.flattendeep": "^4.4.0", - "md5-hex": "^2.0.0", "release-zalgo": "^1.0.0" } }, @@ -1546,6 +1561,11 @@ "bundled": true, "dev": true }, + "path-parse": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, "path-type": { "version": "3.0.0", "bundled": true, @@ -1572,6 +1592,15 @@ "bundled": true, "dev": true }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "read-pkg": { "version": "3.0.0", "bundled": true, @@ -1599,11 +1628,6 @@ "es6-error": "^4.0.1" } }, - "repeat-string": { - "version": "1.6.1", - "bundled": true, - "dev": true - }, "require-directory": { "version": "2.1.1", "bundled": true, @@ -1614,26 +1638,25 @@ "bundled": true, "dev": true }, - "resolve-from": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "right-align": { - "version": "0.1.3", + "resolve": { + "version": "1.10.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "align-text": "^0.1.1" + "path-parse": "^1.0.6" } }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { @@ -1642,7 +1665,7 @@ "dev": true }, "semver": { - "version": "5.5.0", + "version": "5.6.0", "bundled": true, "dev": true }, @@ -1669,12 +1692,6 @@ "bundled": true, "dev": true }, - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true, - "optional": true - }, "spawn-wrap": { "version": "1.4.2", "bundled": true, @@ -1689,7 +1706,7 @@ } }, "spdx-correct": { - "version": "3.0.0", + "version": "3.1.0", "bundled": true, "dev": true, "requires": { @@ -1698,7 +1715,7 @@ } }, "spdx-exceptions": { - "version": "2.1.0", + "version": "2.2.0", "bundled": true, "dev": true }, @@ -1712,7 +1729,7 @@ } }, "spdx-license-ids": { - "version": "3.0.0", + "version": "3.0.3", "bundled": true, "dev": true }, @@ -1743,16 +1760,8 @@ "bundled": true, "dev": true }, - "supports-color": { - "version": "5.4.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, "test-exclude": { - "version": "5.0.0", + "version": "5.1.0", "bundled": true, "dev": true, "requires": { @@ -1763,43 +1772,30 @@ } }, "uglify-js": { - "version": "2.8.29", + "version": "3.4.9", "bundled": true, "dev": true, "optional": true, "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "commander": "~2.17.1", + "source-map": "~0.6.1" }, "dependencies": { - "yargs": { - "version": "3.10.0", + "source-map": { + "version": "0.6.1", "bundled": true, "dev": true, - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } + "optional": true } } }, - "uglify-to-browserify": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, "uuid": { "version": "3.3.2", "bundled": true, "dev": true }, "validate-npm-package-license": { - "version": "3.0.3", + "version": "3.0.4", "bundled": true, "dev": true, "requires": { @@ -1820,12 +1816,6 @@ "bundled": true, "dev": true }, - "window-size": { - "version": "0.1.0", - "bundled": true, - "dev": true, - "optional": true - }, "wordwrap": { "version": "0.0.3", "bundled": true, @@ -1879,7 +1869,7 @@ "dev": true }, "write-file-atomic": { - "version": "2.3.0", + "version": "2.4.2", "bundled": true, "dev": true, "requires": { @@ -1889,7 +1879,7 @@ } }, "y18n": { - "version": "3.2.1", + "version": "4.0.0", "bundled": true, "dev": true }, @@ -1899,87 +1889,31 @@ "dev": true }, "yargs": { - "version": "11.1.0", + "version": "12.0.5", "bundled": true, "dev": true, "requires": { "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", + "os-locale": "^3.0.0", "require-directory": "^2.1.1", "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", "string-width": "^2.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "cliui": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "bundled": true, - "dev": true - } + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" } }, "yargs-parser": { - "version": "9.0.2", + "version": "11.1.1", "bundled": true, "dev": true, "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - } + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -2166,6 +2100,29 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "smart-buffer": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", + "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==" + }, + "socks": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.3.tgz", + "integrity": "sha512-+2r83WaRT3PXYoO/1z+RDEBE7Z2f9YcdQnJ0K/ncXXbV5gJ6wYfNAebYFYiiUjM6E4JyXnPY8cimwyvFYHVUUA==", + "requires": { + "ip": "^1.1.5", + "smart-buffer": "4.0.2" + } + }, + "socks-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", + "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", + "requires": { + "agent-base": "~4.2.0", + "socks": "~2.2.0" + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -2376,11 +2333,6 @@ "integrity": "sha512-jxyxgKVKa4Bh5dPcO42TJL22lIvfd9LOVJwdovKOnJa4TLLrHxquK+DlGm4rkGmrcur+GRx+x4oW00O2pY/fFw==", "dev": true }, - "tunnel": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", - "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/package.json b/package.json index 15cbede..9f558fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wstunnel", - "version": "1.2.8", + "version": "1.3.0", "description": "tunnel over websocket", "main": "./lib/wst.js", "scripts": { @@ -22,12 +22,14 @@ "node": "*" }, "dependencies": { - "global-tunnel-ng": "^2.1.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.1", "lawg": "1.0.3", "machine-uuid": "^1.2.0", "node-uuid": "^1.4.8", "optimist": "0.3.5", "phuture": "^1.0.7", + "socks-proxy-agent": "^4.0.1", "underscore": "1.4.4", "websocket": "^1.0.28" }, diff --git a/test/test.js b/test/test.js index 9edf5bd..626abff 100644 --- a/test/test.js +++ b/test/test.js @@ -33,7 +33,8 @@ module.exports["setup ws tunnel"] = test => server.start(config.ws_port, function(err) { test.ifError(err); log('ws server is setup'); - return client.start(config.s_port, `ws://localhost:${config.ws_port}`, `localhost:${config.t_port}`, function(err) { + return client.start("localhost", config.s_port, `ws://localhost:${config.ws_port}`, + `localhost:${config.t_port}`, {}, function(err) { test.ifError(err); log("tunnel is setup"); return test.done();