| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- const events_1 = require("events");
- const url_1 = require("url");
- const axios_1 = __importDefault(require("axios"));
- const debug_1 = __importDefault(require("debug"));
- const TunnelCluster_1 = __importDefault(require("./TunnelCluster"));
- const debugLog = (0, debug_1.default)('localtunnel:client');
- class Tunnel extends events_1.EventEmitter {
- constructor(opts = {}) {
- super();
- this.opts = opts;
- this.closed = false;
- if (!this.opts.host) {
- this.opts.host = 'https://localtunnel.me';
- }
- }
- _getInfo(body) {
- const { id, ip, port, url, cached_url, max_conn_count } = body;
- const { host, port: local_port, local_host } = this.opts;
- const { local_https, local_cert, local_key, local_ca, allow_invalid_cert } = this.opts;
- return {
- name: id,
- url,
- cached_url,
- max_conn: max_conn_count || 1,
- remote_host: (0, url_1.parse)(host).hostname,
- remote_ip: ip,
- remote_port: port,
- local_port,
- local_host,
- local_https,
- local_cert,
- local_key,
- local_ca,
- allow_invalid_cert,
- };
- }
- _init(callback) {
- const opt = this.opts;
- const getInfo = this._getInfo.bind(this);
- const params = {
- responseType: 'json',
- };
- const baseUri = `${opt.host}/`;
- // no subdomain at first, maybe use requested domain
- const assignedDomain = opt.subdomain;
- // where to quest
- const uri = baseUri + (assignedDomain || '?new') +
- (opt.port ? `&port=${opt.port}` : '');
- debugLog('请求隧道服务器: %s', uri);
- const getUrl = () => {
- axios_1.default
- .get(uri, params)
- .then(res => {
- const body = res.data;
- debugLog('got tunnel information', body);
- if (res.status !== 200) {
- const err = new Error((body && body.message) || 'localtunnel server returned an error, please try again');
- return callback(err);
- }
- callback(null, getInfo(body));
- })
- .catch(err => {
- debugLog(`tunnel server offline: ${err.message}, retry 1s`);
- return setTimeout(getUrl, 1000);
- });
- };
- getUrl();
- }
- _establish(info) {
- // 为 max_conn 设置默认值
- const maxConn = info.max_conn || 1; // 如果 max_conn 未定义,默认为 1
- // increase max event listeners so that localtunnel consumers don't get
- // warning messages as soon as they setup even one listener. See #71
- this.setMaxListeners(maxConn + (events_1.EventEmitter.defaultMaxListeners || 10));
- this.tunnelCluster = new TunnelCluster_1.default(info);
- // only emit the url the first time
- this.tunnelCluster.once('open', () => {
- this.emit('url', info.url);
- });
- // re-emit socket error
- this.tunnelCluster.on('error', err => {
- debugLog('got socket error', err.message);
- this.emit('error', err);
- });
- let tunnelCount = 0;
- // track open count
- this.tunnelCluster.on('open', tunnel => {
- tunnelCount++;
- debugLog('tunnel open [total: %d]', tunnelCount);
- const closeHandler = () => {
- tunnel.destroy();
- };
- if (this.closed) {
- return closeHandler();
- }
- this.once('close', closeHandler);
- tunnel.once('close', () => {
- this.removeListener('close', closeHandler);
- });
- });
- // when a tunnel dies, open a new one
- this.tunnelCluster.on('dead', () => {
- var _a;
- tunnelCount--;
- debugLog('tunnel dead [total: %d]', tunnelCount);
- if (this.closed) {
- return;
- }
- (_a = this.tunnelCluster) === null || _a === void 0 ? void 0 : _a.open();
- });
- this.tunnelCluster.on('request', req => {
- this.emit('request', req);
- });
- // establish as many tunnels as allowed
- for (let count = 0; count < maxConn; ++count) { // 使用 maxConn 变量
- this.tunnelCluster.open();
- }
- }
- open(callback) {
- this._init((err, info) => {
- if (err) {
- return callback(err);
- }
- this.clientId = info.name;
- this.url = info.url;
- // `cached_url` is only returned by proxy servers that support resource caching.
- if (info.cached_url) {
- this.cachedUrl = info.cached_url;
- }
- this._establish(info);
- callback(null);
- });
- }
- close() {
- this.closed = true;
- this.emit('close');
- }
- }
- exports.default = Tunnel;
|