mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-08-04 21:39:04 +00:00
@@ -11,11 +11,11 @@ const async = require('async'),
|
||||
util = require('./util'),
|
||||
wsServerMgr = require('./wsServerMgr'),
|
||||
co = require('co'),
|
||||
assert = require('assert'),
|
||||
constants = require('constants'),
|
||||
asyncTask = require('async-task-mgr');
|
||||
|
||||
const createSecureContext = tls.createSecureContext || crypto.createSecureContext;
|
||||
//using sni to avoid multiple ports
|
||||
function SNIPrepareCert(serverName, SNICallback) {
|
||||
let keyContent,
|
||||
crtContent,
|
||||
@@ -59,7 +59,6 @@ function SNIPrepareCert(serverName, SNICallback) {
|
||||
//config.port - port to start https server
|
||||
//config.handler - request handler
|
||||
|
||||
|
||||
/**
|
||||
* Create an https server
|
||||
*
|
||||
@@ -73,44 +72,11 @@ function createHttpsServer(config) {
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
certMgr.getCertificate('anyproxy_internal_https_server', (err, keyContent, crtContent) => {
|
||||
const server = https.createServer({
|
||||
secureOptions: constants.SSL_OP_NO_SSLv3 || constants.SSL_OP_NO_TLSv1,
|
||||
SNICallback: SNIPrepareCert,
|
||||
key: keyContent,
|
||||
cert: crtContent
|
||||
}, config.handler).listen(config.port);
|
||||
resolve(server);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* create an https server that serving on IP address
|
||||
* @param @required {object} config
|
||||
* @param @required {string} config.ip the IP address of the server
|
||||
* @param @required {number} config.port the port to listen on
|
||||
* @param @required {function} handler the handler of each connect
|
||||
*/
|
||||
function createIPHttpsServer(config) {
|
||||
if (!config || !config.port || !config.handler) {
|
||||
throw (new Error('please assign a port'));
|
||||
}
|
||||
|
||||
if (!config.ip) {
|
||||
throw (new Error('please assign an IP to create the https server'));
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
certMgr.getCertificate(config.ip, (err, keyContent, crtContent) => {
|
||||
const server = https.createServer({
|
||||
secureOptions: constants.SSL_OP_NO_SSLv3 || constants.SSL_OP_NO_TLSv1,
|
||||
key: keyContent,
|
||||
cert: crtContent
|
||||
}, config.handler).listen(config.port);
|
||||
|
||||
resolve(server);
|
||||
});
|
||||
const server = https.createServer({
|
||||
secureOptions: constants.SSL_OP_NO_SSLv3 || constants.SSL_OP_NO_TLSv1,
|
||||
SNICallback: SNIPrepareCert,
|
||||
}, config.handler).listen(config.port);
|
||||
resolve(server);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -124,20 +90,20 @@ function createIPHttpsServer(config) {
|
||||
*/
|
||||
class httpsServerMgr {
|
||||
constructor(config) {
|
||||
if (!config || !config.handler) {
|
||||
throw new Error('handler is required');
|
||||
}
|
||||
this.instanceDefaultHost = '127.0.0.1';
|
||||
this.httpsAsyncTask = new asyncTask();
|
||||
assert(config, 'config is required');
|
||||
assert(config.handler && config.wsHandler, 'handler and wsHandler are required');
|
||||
assert(config.hostname, 'hostname is required');
|
||||
this.hostname = config.hostname;
|
||||
this.handler = config.handler;
|
||||
this.wsHandler = config.wsHandler
|
||||
this.wsHandler = config.wsHandler;
|
||||
this.httpsAsyncTask = new asyncTask();
|
||||
this.asyncTaskName = `https_${Math.random()}`;
|
||||
this.httpsServer = null;
|
||||
}
|
||||
|
||||
getSharedHttpsServer(hostname) {
|
||||
// ip address will have a unique name
|
||||
const finalHost = util.isIpDomain(hostname) ? hostname : this.instanceDefaultHost;
|
||||
|
||||
getSharedHttpsServer() {
|
||||
const self = this;
|
||||
const finalHost = self.hostname;
|
||||
function prepareServer(callback) {
|
||||
let instancePort;
|
||||
co(util.getFreePort)
|
||||
@@ -145,19 +111,10 @@ class httpsServerMgr {
|
||||
instancePort = port;
|
||||
let httpsServer = null;
|
||||
|
||||
// if ip address passed in, will create an IP http server
|
||||
if (util.isIpDomain(hostname)) {
|
||||
httpsServer = yield createIPHttpsServer({
|
||||
ip: hostname,
|
||||
port,
|
||||
handler: self.handler
|
||||
});
|
||||
} else {
|
||||
httpsServer = yield createHttpsServer({
|
||||
port,
|
||||
handler: self.handler
|
||||
});
|
||||
}
|
||||
httpsServer = yield createHttpsServer({
|
||||
port,
|
||||
handler: self.handler
|
||||
});
|
||||
|
||||
wsServerMgr.getWsServer({
|
||||
server: httpsServer,
|
||||
@@ -168,6 +125,8 @@ class httpsServerMgr {
|
||||
logUtil.debug('will let WebSocket server to handle the upgrade event');
|
||||
});
|
||||
|
||||
self.httpsServer = httpsServer;
|
||||
|
||||
const result = {
|
||||
host: finalHost,
|
||||
port: instancePort,
|
||||
@@ -181,9 +140,7 @@ class httpsServerMgr {
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// each ip address will gain a unit task name,
|
||||
// while the domain address will share a common task name
|
||||
self.httpsAsyncTask.addTask(`createHttpsServer-${finalHost}`, prepareServer, (error, serverInfo) => {
|
||||
self.httpsAsyncTask.addTask(self.asyncTaskName, prepareServer, (error, serverInfo) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
@@ -192,6 +149,10 @@ class httpsServerMgr {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
close() {
|
||||
return this.httpsServer && this.httpsServer.close();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = httpsServerMgr;
|
||||
|
||||
@@ -129,7 +129,7 @@ function fetchRemoteResponse(protocol, options, reqData, config) {
|
||||
});
|
||||
} else if (isServerDeflated && originContentLen) {
|
||||
refactContentEncoding();
|
||||
zlib.inflateRaw(serverResData, (err, buff) => {
|
||||
zlib.inflate(serverResData, (err, buff) => {
|
||||
if (err) {
|
||||
rejectParsing(err);
|
||||
} else {
|
||||
@@ -689,7 +689,8 @@ class RequestHandler {
|
||||
|
||||
reqHandlerCtx.httpsServerMgr = new HttpsServerMgr({
|
||||
handler: reqHandlerCtx.userRequestHandler,
|
||||
wsHandler: reqHandlerCtx.wsHandler // websocket
|
||||
wsHandler: reqHandlerCtx.wsHandler, // websocket
|
||||
hostname: '127.0.0.1',
|
||||
});
|
||||
|
||||
this.connectReqHandler = getConnectReqHandler.apply(reqHandlerCtx, [userRule, recorder, reqHandlerCtx.httpsServerMgr]);
|
||||
|
||||
@@ -59,6 +59,7 @@ class wsServer {
|
||||
const self = this;
|
||||
self.config = config;
|
||||
self.recorder = recorder;
|
||||
self.checkBroadcastFlagTimer = null;
|
||||
}
|
||||
|
||||
start() {
|
||||
@@ -78,7 +79,7 @@ class wsServer {
|
||||
// the flat to indicate wheter to broadcast the record
|
||||
let broadcastFlag = true;
|
||||
|
||||
setInterval(() => {
|
||||
self.checkBroadcastFlagTimer = setInterval(() => {
|
||||
broadcastFlag = true;
|
||||
sendMultipleMessage();
|
||||
}, 50);
|
||||
@@ -161,6 +162,9 @@ class wsServer {
|
||||
|
||||
closeAll() {
|
||||
const self = this;
|
||||
if (self.checkBroadcastFlagTimer) {
|
||||
clearInterval(self.checkBroadcastFlagTimer);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
self.wss.close((e) => {
|
||||
if (e) {
|
||||
|
||||
Reference in New Issue
Block a user