reroute.js
3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Domain routing and port forwarding
//
// Used for mapping hosts and domains to localhost, so you can open TCP
// connections with friendly hostnames to test against the local server.
//
// Can also map any source port to any destination port, so you can use port 80
// to access localhost server running on unprivileged port.
'use strict';
var _Map = require('babel-runtime/core-js/map')['default'];
var _Object$assign = require('babel-runtime/core-js/object/assign')['default'];
var assert = require('assert');
var Net = require('net');
// Routing table.
//
// key - Source host name or wildcard (e.g. "example.com", "*.example.com")
// value - Object that maps source port to target port
var routing = new _Map();
// Flip this from enableRerouting() so we only inject our code into
// Socket.connect once.
var enabled = false;
// If there's a route for host/port, returns destination port number.
//
// Called recursively to handle wildcards. Starting with the host
// www.example.com, it will attempt to match routes from most to least specific:
//
// www.example.com
// *.www.example.com
// *.example.com
// *.com
function findTargetPort(_x, _x2) {
var _again = true;
_function: while (_again) {
var hostname = _x,
port = _x2;
_again = false;
if (!hostname) return null;
var route = routing.get(hostname);
if (route) return route[port];
// This will first expand www.hostname.com to *.www.hostname.com,
// then contract it to *.hostname.com, *.com and finally *.
var wildcard = hostname.replace(/^(\*\.[^.]+(\.|$))?/, '*.');
if (wildcard !== '*.') {
_x = wildcard;
_x2 = port;
_again = true;
route = wildcard = undefined;
continue _function;
}
}
}
// Called once to hack Socket.connect
function enableRerouting() {
if (enabled) return;
enabled = true;
var connect = Net.Socket.prototype.connect;
Net.Socket.prototype.connect = function (options, callback) {
if (Array.isArray(options) && options.some(function (opts) {
return findTargetPort(opts.host, opts.port);
})) {
// we hackily update the array in place, because the array has already been extended with
// extra methods
options.forEach(function (opts, i) {
var port = findTargetPort(opts.host, opts.port);
if (port) options[i] = _Object$assign({}, opts, { host: 'localhost', port: port });
});
return connect.call(this, options, callback);
}
if (options && typeof options === 'object' && !Array.isArray(options)) {
var port = findTargetPort(options.host, options.port);
if (port) {
options = _Object$assign({}, options, { host: 'localhost', port: port });
return connect.call(this, options, callback);
}
}
return connect.apply(this, arguments);
};
}
// source - Hostname or host:port (default to port 80)
// target - Target port number
module.exports = function addRoute(source, target) {
assert(source, 'Expected source address of the form "host:port" or just "host"');
var sourceHost = source.split(':')[0];
var sourcePort = source.split(':')[1] || 80;
var route = routing.get(sourceHost) || {};
routing.set(sourceHost, route);
if (!route[sourcePort]) route[sourcePort] = target;
assert(route[sourcePort] === target, 'Already have routing from ' + source + ' to ' + route[sourcePort]);
// Enable Socket.connect routing
enableRerouting();
};
//# sourceMappingURL=reroute.js.map