mirror of
https://github.com/avwo/whistle.git
synced 2026-10-28 22:59:50 +08:00
chore: eslint fix
This commit is contained in:
+98
-98
@@ -16,14 +16,14 @@ var ROOT_KEY, ROOT_CRT;
|
||||
|
||||
|
||||
function getMacAddress() {
|
||||
var ifaces = os.networkInterfaces();
|
||||
for (var i in ifaces) {
|
||||
var addrList = ifaces[i];
|
||||
if (addrList) {
|
||||
for (var j = 0, len = addrList.length; j< len; j++) {
|
||||
var addr = addrList[j];
|
||||
if (addr && !addr.internal && addr.family == 'IPv4') {
|
||||
return addr.mac || addr.address;
|
||||
var ifaces = os.networkInterfaces();
|
||||
for (var i in ifaces) {
|
||||
var addrList = ifaces[i];
|
||||
if (addrList) {
|
||||
for (var j = 0, len = addrList.length; j< len; j++) {
|
||||
var addr = addrList[j];
|
||||
if (addr && !addr.internal && addr.family == 'IPv4') {
|
||||
return addr.mac || addr.address;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,144 +31,144 @@ function getMacAddress() {
|
||||
}
|
||||
|
||||
function createCertificate(hostname) {
|
||||
var cert = cachePairs[hostname];
|
||||
if (cert) {
|
||||
return cert;
|
||||
var cert = cachePairs[hostname];
|
||||
if (cert) {
|
||||
return cert;
|
||||
}
|
||||
cert = createCert(pki.setRsaPublicKey(ROOT_KEY.n, ROOT_KEY.e),
|
||||
cert = createCert(pki.setRsaPublicKey(ROOT_KEY.n, ROOT_KEY.e),
|
||||
crypto.createHash('sha1')
|
||||
.update(hostname, 'binary')
|
||||
.digest('hex'));
|
||||
|
||||
cert.setSubject([{
|
||||
name: 'commonName',
|
||||
value: hostname
|
||||
cert.setSubject([{
|
||||
name: 'commonName',
|
||||
value: hostname
|
||||
}]);
|
||||
|
||||
cert.setIssuer(ROOT_CRT.subject.attributes);
|
||||
cert.sign(ROOT_KEY, forge.md.sha256.create());
|
||||
cert = cachePairs[hostname] = {
|
||||
key: pki.privateKeyToPem(ROOT_KEY),
|
||||
cert: pki.certificateToPem(cert)
|
||||
cert.setIssuer(ROOT_CRT.subject.attributes);
|
||||
cert.sign(ROOT_KEY, forge.md.sha256.create());
|
||||
cert = cachePairs[hostname] = {
|
||||
key: pki.privateKeyToPem(ROOT_KEY),
|
||||
cert: pki.certificateToPem(cert)
|
||||
};
|
||||
return cert;
|
||||
return cert;
|
||||
}
|
||||
|
||||
function createRootCA() {
|
||||
if (ROOT_KEY && ROOT_CRT) {
|
||||
return;
|
||||
if (ROOT_KEY && ROOT_CRT) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ROOT_KEY = fs.readFileSync(ROOT_KEY_FILE);
|
||||
ROOT_CRT = fs.readFileSync(ROOT_CRT_FILE);
|
||||
try {
|
||||
ROOT_KEY = fs.readFileSync(ROOT_KEY_FILE);
|
||||
ROOT_CRT = fs.readFileSync(ROOT_CRT_FILE);
|
||||
} catch (e) {
|
||||
ROOT_KEY = ROOT_CRT = null;
|
||||
ROOT_KEY = ROOT_CRT = null;
|
||||
}
|
||||
|
||||
if (ROOT_KEY && ROOT_CRT && ROOT_KEY.length && ROOT_CRT.length) {
|
||||
ROOT_KEY = pki.privateKeyFromPem(ROOT_KEY);
|
||||
ROOT_CRT = pki.certificateFromPem(ROOT_CRT);
|
||||
if (ROOT_KEY && ROOT_CRT && ROOT_KEY.length && ROOT_CRT.length) {
|
||||
ROOT_KEY = pki.privateKeyFromPem(ROOT_KEY);
|
||||
ROOT_CRT = pki.certificateFromPem(ROOT_CRT);
|
||||
} else {
|
||||
var cert = createCACert();
|
||||
ROOT_CRT = cert.cert;
|
||||
ROOT_KEY = cert.key;
|
||||
fs.writeFileSync(ROOT_KEY_FILE, pki.privateKeyToPem(ROOT_KEY).toString());
|
||||
fs.writeFileSync(ROOT_CRT_FILE, pki.certificateToPem(ROOT_CRT).toString());
|
||||
var cert = createCACert();
|
||||
ROOT_CRT = cert.cert;
|
||||
ROOT_KEY = cert.key;
|
||||
fs.writeFileSync(ROOT_KEY_FILE, pki.privateKeyToPem(ROOT_KEY).toString());
|
||||
fs.writeFileSync(ROOT_CRT_FILE, pki.certificateToPem(ROOT_CRT).toString());
|
||||
}
|
||||
|
||||
exports.DEFAULT_CERT_CTX = createSecureContext({
|
||||
key: ROOT_KEY,
|
||||
cert: ROOT_CRT
|
||||
exports.DEFAULT_CERT_CTX = createSecureContext({
|
||||
key: ROOT_KEY,
|
||||
cert: ROOT_CRT
|
||||
});
|
||||
}
|
||||
|
||||
function createCACert() {
|
||||
var keys = pki.rsa.generateKeyPair(1024);
|
||||
var cert = createCert(keys.publicKey);
|
||||
var name = [];
|
||||
if (config.homeDirname) {
|
||||
try {
|
||||
var keys = pki.rsa.generateKeyPair(1024);
|
||||
var cert = createCert(keys.publicKey);
|
||||
var name = [];
|
||||
if (config.homeDirname) {
|
||||
try {
|
||||
//避免特殊字符导致根证书无法安装
|
||||
name.push(encodeURIComponent(config.homeDirname.slice(0, 20)));
|
||||
name.push(encodeURIComponent(config.homeDirname.slice(0, 20)));
|
||||
} catch(e) {}
|
||||
}
|
||||
if (MAC_ADDR) {
|
||||
name.push(MAC_ADDR);
|
||||
if (MAC_ADDR) {
|
||||
name.push(MAC_ADDR);
|
||||
}
|
||||
name = name.join('@');
|
||||
name = 'WHISTLE' + (name ? '(' + name + ')' : '');
|
||||
var attrs = [ {
|
||||
name : 'commonName',
|
||||
value : name
|
||||
name = name.join('@');
|
||||
name = 'WHISTLE' + (name ? '(' + name + ')' : '');
|
||||
var attrs = [ {
|
||||
name : 'commonName',
|
||||
value : name
|
||||
}, {
|
||||
name : 'countryName',
|
||||
value : 'CN'
|
||||
name : 'countryName',
|
||||
value : 'CN'
|
||||
}, {
|
||||
shortName : 'ST',
|
||||
value : 'ZJ'
|
||||
shortName : 'ST',
|
||||
value : 'ZJ'
|
||||
}, {
|
||||
name : 'localityName',
|
||||
value : 'HZ'
|
||||
name : 'localityName',
|
||||
value : 'HZ'
|
||||
}, {
|
||||
name : 'organizationName',
|
||||
value : name
|
||||
name : 'organizationName',
|
||||
value : name
|
||||
}, {
|
||||
shortName : 'OU',
|
||||
value : 'WPROXY'
|
||||
shortName : 'OU',
|
||||
value : 'WPROXY'
|
||||
} ];
|
||||
|
||||
cert.setSubject(attrs);
|
||||
cert.setIssuer(attrs);
|
||||
cert.setExtensions([ {
|
||||
name : 'basicConstraints',
|
||||
cA : true
|
||||
cert.setSubject(attrs);
|
||||
cert.setIssuer(attrs);
|
||||
cert.setExtensions([ {
|
||||
name : 'basicConstraints',
|
||||
cA : true
|
||||
}, {
|
||||
name : 'keyUsage',
|
||||
keyCertSign : true,
|
||||
digitalSignature : true,
|
||||
nonRepudiation : true,
|
||||
keyEncipherment : true,
|
||||
dataEncipherment : true
|
||||
name : 'keyUsage',
|
||||
keyCertSign : true,
|
||||
digitalSignature : true,
|
||||
nonRepudiation : true,
|
||||
keyEncipherment : true,
|
||||
dataEncipherment : true
|
||||
}, {
|
||||
name : 'extKeyUsage',
|
||||
serverAuth : true,
|
||||
clientAuth : true,
|
||||
codeSigning : true,
|
||||
emailProtection : true,
|
||||
timeStamping : true
|
||||
name : 'extKeyUsage',
|
||||
serverAuth : true,
|
||||
clientAuth : true,
|
||||
codeSigning : true,
|
||||
emailProtection : true,
|
||||
timeStamping : true
|
||||
}, {
|
||||
name : 'nsCertType',
|
||||
client : true,
|
||||
server : true,
|
||||
email : true,
|
||||
objsign : true,
|
||||
sslCA : true,
|
||||
emailCA : true,
|
||||
objCA : true
|
||||
name : 'nsCertType',
|
||||
client : true,
|
||||
server : true,
|
||||
email : true,
|
||||
objsign : true,
|
||||
sslCA : true,
|
||||
emailCA : true,
|
||||
objCA : true
|
||||
} ]);
|
||||
|
||||
cert.sign(keys.privateKey, forge.md.sha256.create());
|
||||
cert.sign(keys.privateKey, forge.md.sha256.create());
|
||||
|
||||
return {
|
||||
key: keys.privateKey,
|
||||
cert: cert
|
||||
return {
|
||||
key: keys.privateKey,
|
||||
cert: cert
|
||||
};
|
||||
}
|
||||
|
||||
function createCert(publicKey, serialNumber) {
|
||||
var cert = pki.createCertificate();
|
||||
cert.publicKey = publicKey;
|
||||
cert.serialNumber = serialNumber || '01';
|
||||
cert.validity.notBefore = new Date();
|
||||
cert.validity.notAfter = new Date();
|
||||
cert.validity.notAfter
|
||||
var cert = pki.createCertificate();
|
||||
cert.publicKey = publicKey;
|
||||
cert.serialNumber = serialNumber || '01';
|
||||
cert.validity.notBefore = new Date();
|
||||
cert.validity.notAfter = new Date();
|
||||
cert.validity.notAfter
|
||||
.setFullYear(cert.validity.notBefore.getFullYear() + 10);
|
||||
return cert;
|
||||
return cert;
|
||||
}
|
||||
|
||||
function getRootCAFile() {
|
||||
return ROOT_CRT_FILE;
|
||||
return ROOT_CRT_FILE;
|
||||
}
|
||||
|
||||
createRootCA();//启动生成ca
|
||||
|
||||
+196
-196
@@ -16,41 +16,41 @@ var index = 0;
|
||||
var proxy;
|
||||
|
||||
function handleWebsocket(socket, clientIp, callback) {
|
||||
var wss = clientIp !== false;
|
||||
var reqEmitter = new EventEmitter();
|
||||
var headers = socket.headers;
|
||||
var fullUrl = socket.fullUrl = (wss ? 'wss:' : 'ws:') + '//' + headers.host + socket.url;
|
||||
var _rules = socket.rules = rules.resolveRules(fullUrl);
|
||||
var filter = socket.filter = rules.resolveFilter(fullUrl);
|
||||
var now = Date.now();
|
||||
var reqData = {
|
||||
ip: util.removeIPV6Prefix(clientIp || socket.remoteAddress),
|
||||
method: util.toUpperCase(socket.method) || 'GET',
|
||||
httpVersion: socket.httpVersion || '1.1',
|
||||
headers: headers
|
||||
var wss = clientIp !== false;
|
||||
var reqEmitter = new EventEmitter();
|
||||
var headers = socket.headers;
|
||||
var fullUrl = socket.fullUrl = (wss ? 'wss:' : 'ws:') + '//' + headers.host + socket.url;
|
||||
var _rules = socket.rules = rules.resolveRules(fullUrl);
|
||||
var filter = socket.filter = rules.resolveFilter(fullUrl);
|
||||
var now = Date.now();
|
||||
var reqData = {
|
||||
ip: util.removeIPV6Prefix(clientIp || socket.remoteAddress),
|
||||
method: util.toUpperCase(socket.method) || 'GET',
|
||||
httpVersion: socket.httpVersion || '1.1',
|
||||
headers: headers
|
||||
};
|
||||
var resData = {};
|
||||
var data = reqEmitter.data = {
|
||||
url: fullUrl,
|
||||
startTime: now,
|
||||
rules: _rules,
|
||||
req: reqData,
|
||||
res: resData
|
||||
var resData = {};
|
||||
var data = reqEmitter.data = {
|
||||
url: fullUrl,
|
||||
startTime: now,
|
||||
rules: _rules,
|
||||
req: reqData,
|
||||
res: resData
|
||||
};
|
||||
socket.clientIp = reqData.ip;
|
||||
socket.reqId = data.reqId = ++index;
|
||||
socket.clientIp = reqData.ip;
|
||||
socket.reqId = data.reqId = ++index;
|
||||
|
||||
var reqSocket, options, plugin, pluginRules, matchedUrl, done;
|
||||
var pluginHomePage = plugin = pluginMgr.getPluginByHomePage(fullUrl);
|
||||
var timeout = util.setTimeout(function() {
|
||||
destroy(new Error('Timeout'));
|
||||
var reqSocket, options, plugin, pluginRules, matchedUrl, done;
|
||||
var pluginHomePage = plugin = pluginMgr.getPluginByHomePage(fullUrl);
|
||||
var timeout = util.setTimeout(function() {
|
||||
destroy(new Error('Timeout'));
|
||||
});
|
||||
|
||||
if (pluginHomePage) {
|
||||
return connect();
|
||||
if (pluginHomePage) {
|
||||
return connect();
|
||||
}
|
||||
|
||||
plugin = pluginMgr.resolvePluginRule(socket);
|
||||
plugin = pluginMgr.resolvePluginRule(socket);
|
||||
pluginMgr.getRules(socket, function(rulesMgr) {
|
||||
if (pluginRules = rulesMgr) {
|
||||
util.handlePluginRules(socket, rulesMgr);
|
||||
@@ -97,10 +97,10 @@ function handleWebsocket(socket, clientIp, callback) {
|
||||
var onConnect = function(proxySocket) {
|
||||
if (wss) {
|
||||
proxySocket = tls.connect({
|
||||
rejectUnauthorized: false,
|
||||
socket: proxySocket,
|
||||
servername: dstOptions.hostname
|
||||
}).on('error', execCallback);
|
||||
rejectUnauthorized: false,
|
||||
socket: proxySocket,
|
||||
servername: dstOptions.hostname
|
||||
}).on('error', execCallback);
|
||||
}
|
||||
|
||||
reqSocket = proxySocket;
|
||||
@@ -127,115 +127,115 @@ function handleWebsocket(socket, clientIp, callback) {
|
||||
});
|
||||
});
|
||||
|
||||
function connect() {
|
||||
options = url.parse(fullUrl);
|
||||
!pluginHomePage && !filter.hide && proxy.emit('request', reqEmitter);
|
||||
function connect() {
|
||||
options = url.parse(fullUrl);
|
||||
!pluginHomePage && !filter.hide && proxy.emit('request', reqEmitter);
|
||||
|
||||
if (plugin) {
|
||||
pluginMgr.loadPlugin(plugin, function(err, ports) {
|
||||
if (err) {
|
||||
return execCallback(err);
|
||||
if (plugin) {
|
||||
pluginMgr.loadPlugin(plugin, function(err, ports) {
|
||||
if (err) {
|
||||
return execCallback(err);
|
||||
}
|
||||
|
||||
if (pluginHomePage && !ports.uiPort) {
|
||||
return execCallback(new Error('Not implemented'));
|
||||
if (pluginHomePage && !ports.uiPort) {
|
||||
return execCallback(new Error('Not implemented'));
|
||||
}
|
||||
|
||||
var headers = socket.headers;
|
||||
headers[pluginMgr.FULL_URL_HEADER] = encodeURIComponent(fullUrl);
|
||||
if (options.protocol == 'wss:') {
|
||||
options.protocol = 'ws:';
|
||||
headers[pluginMgr.SSL_FLAG_HEADER] = 'true';
|
||||
var headers = socket.headers;
|
||||
headers[pluginMgr.FULL_URL_HEADER] = encodeURIComponent(fullUrl);
|
||||
if (options.protocol == 'wss:') {
|
||||
options.protocol = 'ws:';
|
||||
headers[pluginMgr.SSL_FLAG_HEADER] = 'true';
|
||||
}
|
||||
var ruleValue = _rules.rule && util.removeProtocol(_rules.rule.matcher, true);
|
||||
if (ruleValue) {
|
||||
headers[pluginMgr.RULE_VALUE_HEADER] = encodeURIComponent(ruleValue);
|
||||
var ruleValue = _rules.rule && util.removeProtocol(_rules.rule.matcher, true);
|
||||
if (ruleValue) {
|
||||
headers[pluginMgr.RULE_VALUE_HEADER] = encodeURIComponent(ruleValue);
|
||||
}
|
||||
|
||||
if (socket.reqId) {
|
||||
headers[pluginMgr.REQ_ID_HEADER] = socket.reqId;
|
||||
}
|
||||
if (socket.clientIP) {
|
||||
headers[pluginMgr.CLIENT_IP_HEADER] = socket.clientIP;
|
||||
if (socket.reqId) {
|
||||
headers[pluginMgr.REQ_ID_HEADER] = socket.reqId;
|
||||
}
|
||||
if (socket.clientIP) {
|
||||
headers[pluginMgr.CLIENT_IP_HEADER] = socket.clientIP;
|
||||
}
|
||||
options.port = pluginHomePage ? ports.uiPort : ports.port;
|
||||
if (!pluginHomePage) {
|
||||
data.realUrl = util.changePort(fullUrl, options.port);
|
||||
options.port = pluginHomePage ? ports.uiPort : ports.port;
|
||||
if (!pluginHomePage) {
|
||||
data.realUrl = util.changePort(fullUrl, options.port);
|
||||
}
|
||||
|
||||
if (!options.port) {
|
||||
return execCallback(new Error(pluginHomePage ? 'Not implemented' : 'No plugin.server'));
|
||||
}
|
||||
if (!options.port) {
|
||||
return execCallback(new Error(pluginHomePage ? 'Not implemented' : 'No plugin.server'));
|
||||
}
|
||||
|
||||
var localHost = _rules.host;
|
||||
if (localHost) {
|
||||
headers[pluginMgr.LOCAL_HOST_HEADER] = encodeURIComponent(util.removeProtocol(localHost.matcher, true));
|
||||
if (localHost.port) {
|
||||
headers[pluginMgr.HOST_PORT_HEADER] = localHost.port;
|
||||
var localHost = _rules.host;
|
||||
if (localHost) {
|
||||
headers[pluginMgr.LOCAL_HOST_HEADER] = encodeURIComponent(util.removeProtocol(localHost.matcher, true));
|
||||
if (localHost.port) {
|
||||
headers[pluginMgr.HOST_PORT_HEADER] = localHost.port;
|
||||
}
|
||||
}
|
||||
|
||||
_connect();
|
||||
_connect();
|
||||
});
|
||||
} else {
|
||||
_connect();
|
||||
_connect();
|
||||
}
|
||||
}
|
||||
|
||||
function _connect() {
|
||||
resolveHost(fullUrl, function(ip, port) {
|
||||
var isWss = options.protocol == 'wss:';
|
||||
resData.ip = port ? ip + ':' + port : ip;
|
||||
reqSocket = (isWss ? tls : net).connect({
|
||||
rejectUnauthorized: false,
|
||||
host: ip,
|
||||
port: port || options.port || (isWss ? 443 : 80)
|
||||
function _connect() {
|
||||
resolveHost(fullUrl, function(ip, port) {
|
||||
var isWss = options.protocol == 'wss:';
|
||||
resData.ip = port ? ip + ':' + port : ip;
|
||||
reqSocket = (isWss ? tls : net).connect({
|
||||
rejectUnauthorized: false,
|
||||
host: ip,
|
||||
port: port || options.port || (isWss ? 443 : 80)
|
||||
}, pipeData);
|
||||
abortIfUnavailable(reqSocket);
|
||||
abortIfUnavailable(reqSocket);
|
||||
});
|
||||
}
|
||||
|
||||
function pipeData() {
|
||||
clearTimeout(timeout);
|
||||
var headers = socket.headers;
|
||||
var origin;
|
||||
if (matchedUrl) {
|
||||
headers.host = options.host;
|
||||
origin = headers.origin;
|
||||
headers.origin = (options.protocol == 'wss:' ? 'https://' : 'http://') + options.host;
|
||||
function pipeData() {
|
||||
clearTimeout(timeout);
|
||||
var headers = socket.headers;
|
||||
var origin;
|
||||
if (matchedUrl) {
|
||||
headers.host = options.host;
|
||||
origin = headers.origin;
|
||||
headers.origin = (options.protocol == 'wss:' ? 'https://' : 'http://') + options.host;
|
||||
}
|
||||
|
||||
if (_rules.hostname) {
|
||||
headers.host = util.getMatcherValue(_rules.hostname);
|
||||
if (_rules.hostname) {
|
||||
headers.host = util.getMatcherValue(_rules.hostname);
|
||||
}
|
||||
|
||||
reqSocket.write(socket.getBuffer((plugin || matchedUrl || _rules.hostname) ? headers : null));
|
||||
socket.pipe(reqSocket);
|
||||
util.parseReq(reqSocket, function(err, res) {
|
||||
if (err) {
|
||||
return execCallback(err);
|
||||
reqSocket.write(socket.getBuffer((plugin || matchedUrl || _rules.hostname) ? headers : null));
|
||||
socket.pipe(reqSocket);
|
||||
util.parseReq(reqSocket, function(err, res) {
|
||||
if (err) {
|
||||
return execCallback(err);
|
||||
}
|
||||
|
||||
headers = res.headers;
|
||||
if (matchedUrl) {
|
||||
headers['access-control-allow-origin'] = origin;
|
||||
headers = res.headers;
|
||||
if (matchedUrl) {
|
||||
headers['access-control-allow-origin'] = origin;
|
||||
}
|
||||
socket.write(res.getBuffer(matchedUrl ? headers : null));
|
||||
res.pipe(socket);
|
||||
resData.headers = headers;
|
||||
resData.statusCode = res.statusCode;
|
||||
reqEmitter.emit('response', data);
|
||||
execCallback(null, reqSocket);
|
||||
socket.write(res.getBuffer(matchedUrl ? headers : null));
|
||||
res.pipe(socket);
|
||||
resData.headers = headers;
|
||||
resData.statusCode = res.statusCode;
|
||||
reqEmitter.emit('response', data);
|
||||
execCallback(null, reqSocket);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function resolveHost(url, callback) {
|
||||
data.status = 'requestEnd';
|
||||
pluginMgr.postStatus(socket.pluginMgr, data);
|
||||
if (plugin) {
|
||||
function resolveHost(url, callback) {
|
||||
data.status = 'requestEnd';
|
||||
pluginMgr.postStatus(socket.pluginMgr, data);
|
||||
if (plugin) {
|
||||
return callback(LOCALHOST);
|
||||
}
|
||||
rules.resolveHost(url, function(err, ip, port, host) {
|
||||
rules.resolveHost(url, function(err, ip, port, host) {
|
||||
if (err) {
|
||||
return execCallback(err);
|
||||
}
|
||||
@@ -249,93 +249,93 @@ function handleWebsocket(socket, clientIp, callback) {
|
||||
reqEmitter.emit('send', data);
|
||||
callback(ip, port);
|
||||
}, pluginRules);
|
||||
}
|
||||
}
|
||||
|
||||
function abortIfUnavailable(socket) {
|
||||
return socket.on('error', destroy)
|
||||
function abortIfUnavailable(socket) {
|
||||
return socket.on('error', destroy)
|
||||
.on('close', destroy);
|
||||
}
|
||||
|
||||
function destroy(err) {
|
||||
socket.destroy();
|
||||
reqSocket && reqSocket.destroy();
|
||||
execCallback(err);
|
||||
err && logger.error(fullUrl + '\n' + err.stack);
|
||||
function destroy(err) {
|
||||
socket.destroy();
|
||||
reqSocket && reqSocket.destroy();
|
||||
execCallback(err);
|
||||
err && logger.error(fullUrl + '\n' + err.stack);
|
||||
}
|
||||
|
||||
function execCallback(err, _socket) {
|
||||
if (done) {
|
||||
return;
|
||||
function execCallback(err, _socket) {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
done = true;
|
||||
clearTimeout(timeout);
|
||||
data.responseTime = data.endTime = Date.now();
|
||||
resData.ip = resData.ip || LOCALHOST;
|
||||
var status;
|
||||
if (!err && !_socket) {
|
||||
err = new Error('Aborted');
|
||||
data.reqError = true;
|
||||
resData.statusCode ='aborted';
|
||||
reqData.body = util.getErrorStack(err);
|
||||
reqEmitter.emit('abort', data);
|
||||
status = 'aborted';
|
||||
done = true;
|
||||
clearTimeout(timeout);
|
||||
data.responseTime = data.endTime = Date.now();
|
||||
resData.ip = resData.ip || LOCALHOST;
|
||||
var status;
|
||||
if (!err && !_socket) {
|
||||
err = new Error('Aborted');
|
||||
data.reqError = true;
|
||||
resData.statusCode ='aborted';
|
||||
reqData.body = util.getErrorStack(err);
|
||||
reqEmitter.emit('abort', data);
|
||||
status = 'aborted';
|
||||
} else if (err) {
|
||||
data.resError = true;
|
||||
resData.statusCode = resData.statusCode || 502;
|
||||
resData.body = util.getErrorStack(err);
|
||||
util.emitError(reqEmitter, data);
|
||||
status = 'error';
|
||||
data.resError = true;
|
||||
resData.statusCode = resData.statusCode || 502;
|
||||
resData.body = util.getErrorStack(err);
|
||||
util.emitError(reqEmitter, data);
|
||||
status = 'error';
|
||||
} else {
|
||||
reqEmitter.emit('end', data);
|
||||
status = 'responseEnd';
|
||||
reqEmitter.emit('end', data);
|
||||
status = 'responseEnd';
|
||||
}
|
||||
|
||||
callback(err, _socket);
|
||||
data.status = status;
|
||||
pluginMgr.postStatus(socket.pluginMgr, data);
|
||||
callback(err, _socket);
|
||||
data.status = status;
|
||||
pluginMgr.postStatus(socket.pluginMgr, data);
|
||||
}
|
||||
}
|
||||
|
||||
function handleTlsSocket(socket, hostname) {
|
||||
var reqSocket;
|
||||
function destroy(err) {
|
||||
socket.destroy();
|
||||
reqSocket && reqSocket.destroy();
|
||||
err && logger.error(hostname + '\n' + err.stack);
|
||||
var reqSocket;
|
||||
function destroy(err) {
|
||||
socket.destroy();
|
||||
reqSocket && reqSocket.destroy();
|
||||
err && logger.error(hostname + '\n' + err.stack);
|
||||
}
|
||||
|
||||
function abortIfUnavailable(socket) {
|
||||
return socket.on('error', destroy)
|
||||
function abortIfUnavailable(socket) {
|
||||
return socket.on('error', destroy)
|
||||
.on('close', destroy);
|
||||
}
|
||||
|
||||
abortIfUnavailable(socket);
|
||||
util.parseReq(socket, function(err, socket) {
|
||||
if (err) {
|
||||
return destroy(err);
|
||||
abortIfUnavailable(socket);
|
||||
util.parseReq(socket, function(err, socket) {
|
||||
if (err) {
|
||||
return destroy(err);
|
||||
}
|
||||
//wss
|
||||
var clientIp = ports[socket.remotePort];
|
||||
var headers = socket.headers;
|
||||
if (headers.upgrade && headers.upgrade.toLowerCase() == 'websocket') {
|
||||
handleWebsocket(socket, clientIp, function(err, req) {
|
||||
if (err) {
|
||||
return destroy(err);
|
||||
var clientIp = ports[socket.remotePort];
|
||||
var headers = socket.headers;
|
||||
if (headers.upgrade && headers.upgrade.toLowerCase() == 'websocket') {
|
||||
handleWebsocket(socket, clientIp, function(err, req) {
|
||||
if (err) {
|
||||
return destroy(err);
|
||||
}
|
||||
reqSocket = req;
|
||||
abortIfUnavailable(reqSocket);
|
||||
reqSocket = req;
|
||||
abortIfUnavailable(reqSocket);
|
||||
});
|
||||
} else {
|
||||
//https
|
||||
socket.pause();
|
||||
reqSocket = net.connect(config.port, LOCALHOST, function() {
|
||||
headers[config.HTTPS_FIELD] = 1;
|
||||
headers[config.CLIENT_IP_HEAD] = clientIp;
|
||||
reqSocket.write(socket.getBuffer(headers));
|
||||
socket.resume();
|
||||
socket.pipe(reqSocket).pipe(socket);
|
||||
socket.pause();
|
||||
reqSocket = net.connect(config.port, LOCALHOST, function() {
|
||||
headers[config.HTTPS_FIELD] = 1;
|
||||
headers[config.CLIENT_IP_HEAD] = clientIp;
|
||||
reqSocket.write(socket.getBuffer(headers));
|
||||
socket.resume();
|
||||
socket.pipe(reqSocket).pipe(socket);
|
||||
});
|
||||
abortIfUnavailable(reqSocket);
|
||||
abortIfUnavailable(reqSocket);
|
||||
}
|
||||
}, true);
|
||||
|
||||
@@ -343,54 +343,54 @@ function handleTlsSocket(socket, hostname) {
|
||||
}
|
||||
|
||||
module.exports = function dispatch(socket, hostname, _proxy) {
|
||||
proxy = _proxy;
|
||||
proxy = _proxy;
|
||||
|
||||
var reqSocket;
|
||||
function destroy(err) {
|
||||
socket.destroy();
|
||||
reqSocket && reqSocket.destroy();
|
||||
err && logger.error(hostname + '\n' + err.stack);
|
||||
var reqSocket;
|
||||
function destroy(err) {
|
||||
socket.destroy();
|
||||
reqSocket && reqSocket.destroy();
|
||||
err && logger.error(hostname + '\n' + err.stack);
|
||||
}
|
||||
|
||||
function abortIfUnavailable(socket) {
|
||||
return socket.on('error', destroy)
|
||||
function abortIfUnavailable(socket) {
|
||||
return socket.on('error', destroy)
|
||||
.on('close', destroy);
|
||||
}
|
||||
|
||||
abortIfUnavailable(socket);
|
||||
socket.on('data', request);
|
||||
socket.on('end', request);
|
||||
abortIfUnavailable(socket);
|
||||
socket.on('data', request);
|
||||
socket.on('end', request);
|
||||
|
||||
|
||||
function request(chunk) {
|
||||
socket.removeListener('data', request);
|
||||
socket.removeListener('end', request);
|
||||
if (!chunk) {//没有数据
|
||||
return destroy();
|
||||
function request(chunk) {
|
||||
socket.removeListener('data', request);
|
||||
socket.removeListener('end', request);
|
||||
if (!chunk) {//没有数据
|
||||
return destroy();
|
||||
}
|
||||
|
||||
if (/upgrade\s*:\s*websocket/i.test(chunk.toString())) { //ws
|
||||
util.parseReq(socket, function(err, socket) {
|
||||
if (err) {
|
||||
return destroy(err);
|
||||
if (/upgrade\s*:\s*websocket/i.test(chunk.toString())) { //ws
|
||||
util.parseReq(socket, function(err, socket) {
|
||||
if (err) {
|
||||
return destroy(err);
|
||||
}
|
||||
handleWebsocket(socket, false, function(err, req) {
|
||||
if (err) {
|
||||
return destroy(err);
|
||||
handleWebsocket(socket, false, function(err, req) {
|
||||
if (err) {
|
||||
return destroy(err);
|
||||
}
|
||||
abortIfUnavailable(reqSocket = req);
|
||||
abortIfUnavailable(reqSocket = req);
|
||||
});
|
||||
}, chunk, true);
|
||||
} else {
|
||||
serverAgent.createServer(hostname, function(socket) {
|
||||
handleTlsSocket(socket, hostname);
|
||||
serverAgent.createServer(hostname, function(socket) {
|
||||
handleTlsSocket(socket, hostname);
|
||||
}, function(port) {
|
||||
reqSocket = net.connect(port, LOCALHOST, function() {
|
||||
ports[reqSocket.localPort] = socket.remoteAddress;
|
||||
reqSocket.write(chunk);
|
||||
reqSocket.pipe(socket).pipe(reqSocket);
|
||||
reqSocket = net.connect(port, LOCALHOST, function() {
|
||||
ports[reqSocket.localPort] = socket.remoteAddress;
|
||||
reqSocket.write(chunk);
|
||||
reqSocket.pipe(socket).pipe(reqSocket);
|
||||
});
|
||||
abortIfUnavailable(reqSocket);
|
||||
abortIfUnavailable(reqSocket);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+75
-75
@@ -8,94 +8,94 @@ var TIMEOUT = 6000;
|
||||
var DELAY = 600;
|
||||
|
||||
function ServerAgent() {
|
||||
this._cache = {};
|
||||
this._serverCount = 0;
|
||||
this._cache = {};
|
||||
this._serverCount = 0;
|
||||
}
|
||||
|
||||
var proto = ServerAgent.prototype;
|
||||
|
||||
proto.createServer = function createServer(hostname, secureConnectionListener, callback) {
|
||||
var self = this;
|
||||
var cache = self._cache;
|
||||
var self = this;
|
||||
var cache = self._cache;
|
||||
|
||||
var promise = cache[hostname];
|
||||
var defer;
|
||||
var promise = cache[hostname];
|
||||
var defer;
|
||||
|
||||
if (!promise) {
|
||||
defer = Q.defer();
|
||||
cache[hostname] = promise = defer.promise;
|
||||
if (!promise) {
|
||||
defer = Q.defer();
|
||||
cache[hostname] = promise = defer.promise;
|
||||
}
|
||||
|
||||
promise.done(callback);
|
||||
promise.done(callback);
|
||||
|
||||
if (!defer) {
|
||||
return ;
|
||||
if (!defer) {
|
||||
return ;
|
||||
}
|
||||
|
||||
self.freeServer();
|
||||
getServer(ca.createCertificate(hostname), secureConnectionListener,
|
||||
self.freeServer();
|
||||
getServer(ca.createCertificate(hostname), secureConnectionListener,
|
||||
function(port, server) {
|
||||
var removeServer = function() {
|
||||
self.removeServer(hostname);
|
||||
var removeServer = function() {
|
||||
self.removeServer(hostname);
|
||||
};
|
||||
server.on('error', removeServer);
|
||||
setTimeout(function() {
|
||||
promise.server = server;
|
||||
var timeout = setTimeout(removeServer, TIMEOUT);
|
||||
server.once('secureConnection', function() {
|
||||
clearTimeout(timeout);
|
||||
server.on('error', removeServer);
|
||||
setTimeout(function() {
|
||||
promise.server = server;
|
||||
var timeout = setTimeout(removeServer, TIMEOUT);
|
||||
server.once('secureConnection', function() {
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
defer.resolve(port);
|
||||
defer.resolve(port);
|
||||
}, DELAY);
|
||||
});
|
||||
self._serverCount++;
|
||||
self._serverCount++;
|
||||
|
||||
return self;
|
||||
return self;
|
||||
};
|
||||
|
||||
proto.removeServer = function removeServer(hostname) {
|
||||
var self = this;
|
||||
var cache = self._cache;
|
||||
var promise = cache[hostname];
|
||||
if (!promise) {
|
||||
return;
|
||||
var self = this;
|
||||
var cache = self._cache;
|
||||
var promise = cache[hostname];
|
||||
if (!promise) {
|
||||
return;
|
||||
}
|
||||
delete cache[hostname];
|
||||
--self._serverCount;
|
||||
setTimeout(function() {
|
||||
try {
|
||||
promise.server.close();
|
||||
delete cache[hostname];
|
||||
--self._serverCount;
|
||||
setTimeout(function() {
|
||||
try {
|
||||
promise.server.close();
|
||||
} catch(e) {} //重复关闭会导致异常
|
||||
}, TIMEOUT);
|
||||
};
|
||||
|
||||
proto.freeServer = function() {
|
||||
var self = this;
|
||||
if (self._serverCount < MAX_SERVERS) {
|
||||
return;
|
||||
var self = this;
|
||||
if (self._serverCount < MAX_SERVERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cache = self._cache;
|
||||
for (var i in cache) {
|
||||
destroy(i);
|
||||
var cache = self._cache;
|
||||
for (var i in cache) {
|
||||
destroy(i);
|
||||
}
|
||||
|
||||
function destroy(hostname) {
|
||||
var promise = cache[hostname];
|
||||
if (promise._pending) {
|
||||
return;
|
||||
function destroy(hostname) {
|
||||
var promise = cache[hostname];
|
||||
if (promise._pending) {
|
||||
return;
|
||||
}
|
||||
promise._pending = true;
|
||||
promise.done(function(port) {
|
||||
var server = promise.server;
|
||||
server.getConnections(function(err, count) {
|
||||
promise._pending = false;
|
||||
if (!err && !count && self._serverCount > MAX_SERVERS) {
|
||||
delete cache[hostname];
|
||||
--self._serverCount;
|
||||
setTimeout(function() {
|
||||
try {
|
||||
server.close();
|
||||
promise._pending = true;
|
||||
promise.done(function(port) {
|
||||
var server = promise.server;
|
||||
server.getConnections(function(err, count) {
|
||||
promise._pending = false;
|
||||
if (!err && !count && self._serverCount > MAX_SERVERS) {
|
||||
delete cache[hostname];
|
||||
--self._serverCount;
|
||||
setTimeout(function() {
|
||||
try {
|
||||
server.close();
|
||||
} catch(e) {} //重复关闭会导致异常
|
||||
}, DELAY);
|
||||
}
|
||||
@@ -105,15 +105,15 @@ proto.freeServer = function() {
|
||||
};
|
||||
|
||||
proto.destroy = function destroy() {
|
||||
var cache = this._cache;
|
||||
this._cache = {};
|
||||
this._serverCount = 0;
|
||||
for (var i in cache) {
|
||||
var promise = cache[i];
|
||||
promise.done(function() {
|
||||
setTimeout(function() {
|
||||
try {
|
||||
promise.server.close();
|
||||
var cache = this._cache;
|
||||
this._cache = {};
|
||||
this._serverCount = 0;
|
||||
for (var i in cache) {
|
||||
var promise = cache[i];
|
||||
promise.done(function() {
|
||||
setTimeout(function() {
|
||||
try {
|
||||
promise.server.close();
|
||||
} catch(e) {} //重复关闭会导致异常
|
||||
}, DELAY);
|
||||
});
|
||||
@@ -121,20 +121,20 @@ proto.destroy = function destroy() {
|
||||
};
|
||||
|
||||
function getServer(options, secureConnectionListener, callback) {
|
||||
if (curPort > MAX_PORT) {
|
||||
curPort = 40000;
|
||||
if (curPort > MAX_PORT) {
|
||||
curPort = 40000;
|
||||
}
|
||||
|
||||
var server = tls.createServer(options, secureConnectionListener);
|
||||
var next = function() {
|
||||
getServer(options, secureConnectionListener, callback);
|
||||
var server = tls.createServer(options, secureConnectionListener);
|
||||
var next = function() {
|
||||
getServer(options, secureConnectionListener, callback);
|
||||
};
|
||||
server.on('error', next);
|
||||
server.on('error', next);
|
||||
|
||||
var port = curPort++;
|
||||
server.listen(port, function() {
|
||||
server.removeListener('error', next);
|
||||
callback(port, server);
|
||||
var port = curPort++;
|
||||
server.listen(port, function() {
|
||||
server.removeListener('error', next);
|
||||
callback(port, server);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user