mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-08-04 21:39:04 +00:00
add multi rules
This commit is contained in:
@@ -252,13 +252,13 @@ function getUserReqHandler(userRule, recorder) {
|
||||
};
|
||||
|
||||
/**
|
||||
* send response to client
|
||||
*
|
||||
* @param {object} finalResponseData
|
||||
* @param {number} finalResponseData.statusCode
|
||||
* @param {object} finalResponseData.header
|
||||
* @param {buffer|string} finalResponseData.body
|
||||
*/
|
||||
* send response to client
|
||||
*
|
||||
* @param {object} finalResponseData
|
||||
* @param {number} finalResponseData.statusCode
|
||||
* @param {object} finalResponseData.header
|
||||
* @param {buffer|string} finalResponseData.body
|
||||
*/
|
||||
const sendFinalResponse = (finalResponseData) => {
|
||||
const responseInfo = finalResponseData.response;
|
||||
const resHeader = responseInfo.header;
|
||||
@@ -297,7 +297,7 @@ function getUserReqHandler(userRule, recorder) {
|
||||
if (!global._throttle
|
||||
&& transferEncoding !== 'chunked'
|
||||
&& !(responseBody instanceof CommonReadableStream)
|
||||
) {
|
||||
) {
|
||||
resHeader['Content-Length'] = util.getByteSize(responseBody);
|
||||
}
|
||||
|
||||
@@ -479,119 +479,119 @@ function getConnectReqHandler(userRule, recorder, httpsServerMgr) {
|
||||
shouldIntercept = yield userRule.beforeDealHttpsRequest(requestDetail);
|
||||
}
|
||||
})
|
||||
.then(() =>
|
||||
new Promise((resolve) => {
|
||||
// mark socket connection as established, to detect the request protocol
|
||||
cltSocket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', resolve);
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
new Promise((resolve, reject) => {
|
||||
let resolved = false;
|
||||
cltSocket.on('data', (chunk) => {
|
||||
requestStream.push(chunk);
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
try {
|
||||
const chunkString = chunk.toString();
|
||||
if (chunkString.indexOf('GET ') === 0) {
|
||||
shouldIntercept = false; //websocket
|
||||
.then(() =>
|
||||
new Promise((resolve) => {
|
||||
// mark socket connection as established, to detect the request protocol
|
||||
cltSocket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', resolve);
|
||||
})
|
||||
)
|
||||
.then(() =>
|
||||
new Promise((resolve, reject) => {
|
||||
let resolved = false;
|
||||
cltSocket.on('data', (chunk) => {
|
||||
requestStream.push(chunk);
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
try {
|
||||
const chunkString = chunk.toString();
|
||||
if (chunkString.indexOf('GET ') === 0) {
|
||||
shouldIntercept = false; //websocket
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
resolve();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
cltSocket.on('end', () => {
|
||||
requestStream.push(null);
|
||||
});
|
||||
})
|
||||
)
|
||||
.then((result) => {
|
||||
// log and recorder
|
||||
if (shouldIntercept) {
|
||||
logUtil.printLog('will forward to local https server');
|
||||
} else {
|
||||
logUtil.printLog('will bypass the man-in-the-middle proxy');
|
||||
}
|
||||
|
||||
//record
|
||||
if (recorder) {
|
||||
resourceInfo = {
|
||||
host,
|
||||
method: req.method,
|
||||
path: '',
|
||||
url: 'https://' + host,
|
||||
req,
|
||||
startTime: new Date().getTime()
|
||||
};
|
||||
resourceInfoId = recorder.appendRecord(resourceInfo);
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// determine the request target
|
||||
if (!shouldIntercept) {
|
||||
return {
|
||||
host,
|
||||
port: (targetPort === 80) ? 443 : targetPort,
|
||||
}
|
||||
});
|
||||
cltSocket.on('end', () => {
|
||||
requestStream.push(null);
|
||||
} else {
|
||||
return httpsServerMgr.getSharedHttpsServer(host).then(serverInfo => ({ host: serverInfo.host, port: serverInfo.port }));
|
||||
}
|
||||
})
|
||||
.then((serverInfo) => {
|
||||
if (!serverInfo.port || !serverInfo.host) {
|
||||
throw new Error('failed to get https server info');
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const conn = net.connect(serverInfo.port, serverInfo.host, () => {
|
||||
//throttle for direct-foward https
|
||||
if (global._throttle && !shouldIntercept) {
|
||||
requestStream.pipe(conn);
|
||||
conn.pipe(global._throttle.throttle()).pipe(cltSocket);
|
||||
} else {
|
||||
requestStream.pipe(conn);
|
||||
conn.pipe(cltSocket);
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
|
||||
conn.on('error', (e) => {
|
||||
reject(e);
|
||||
});
|
||||
|
||||
reqHandlerCtx.conns.set(serverInfo.host + ':' + serverInfo.port, conn)
|
||||
reqHandlerCtx.cltSockets.set(serverInfo.host + ':' + serverInfo.port, cltSocket)
|
||||
});
|
||||
})
|
||||
)
|
||||
.then((result) => {
|
||||
// log and recorder
|
||||
if (shouldIntercept) {
|
||||
logUtil.printLog('will forward to local https server');
|
||||
} else {
|
||||
logUtil.printLog('will bypass the man-in-the-middle proxy');
|
||||
}
|
||||
.then(() => {
|
||||
if (recorder) {
|
||||
resourceInfo.endTime = new Date().getTime();
|
||||
resourceInfo.statusCode = '200';
|
||||
resourceInfo.resHeader = {};
|
||||
resourceInfo.resBody = '';
|
||||
resourceInfo.length = 0;
|
||||
|
||||
//record
|
||||
if (recorder) {
|
||||
resourceInfo = {
|
||||
host,
|
||||
method: req.method,
|
||||
path: '',
|
||||
url: 'https://' + host,
|
||||
req,
|
||||
startTime: new Date().getTime()
|
||||
};
|
||||
resourceInfoId = recorder.appendRecord(resourceInfo);
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// determine the request target
|
||||
if (!shouldIntercept) {
|
||||
return {
|
||||
host,
|
||||
port: (targetPort === 80) ? 443 : targetPort,
|
||||
recorder && recorder.updateRecord(resourceInfoId, resourceInfo);
|
||||
}
|
||||
} else {
|
||||
return httpsServerMgr.getSharedHttpsServer(host).then(serverInfo => ({ host: serverInfo.host, port: serverInfo.port }));
|
||||
}
|
||||
})
|
||||
.then((serverInfo) => {
|
||||
if (!serverInfo.port || !serverInfo.host) {
|
||||
throw new Error('failed to get https server info');
|
||||
}
|
||||
})
|
||||
.catch(co.wrap(function *(error) {
|
||||
logUtil.printLog(util.collectErrorLog(error), logUtil.T_ERR);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const conn = net.connect(serverInfo.port, serverInfo.host, () => {
|
||||
//throttle for direct-foward https
|
||||
if (global._throttle && !shouldIntercept) {
|
||||
requestStream.pipe(conn);
|
||||
conn.pipe(global._throttle.throttle()).pipe(cltSocket);
|
||||
} else {
|
||||
requestStream.pipe(conn);
|
||||
conn.pipe(cltSocket);
|
||||
}
|
||||
try {
|
||||
yield userRule.onConnectError(requestDetail, error);
|
||||
} catch (e) { }
|
||||
|
||||
resolve();
|
||||
});
|
||||
|
||||
conn.on('error', (e) => {
|
||||
reject(e);
|
||||
});
|
||||
|
||||
reqHandlerCtx.conns.set(serverInfo.host + ':' + serverInfo.port, conn)
|
||||
reqHandlerCtx.cltSockets.set(serverInfo.host + ':' + serverInfo.port, cltSocket)
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
if (recorder) {
|
||||
resourceInfo.endTime = new Date().getTime();
|
||||
resourceInfo.statusCode = '200';
|
||||
resourceInfo.resHeader = {};
|
||||
resourceInfo.resBody = '';
|
||||
resourceInfo.length = 0;
|
||||
|
||||
recorder && recorder.updateRecord(resourceInfoId, resourceInfo);
|
||||
}
|
||||
})
|
||||
.catch(co.wrap(function *(error) {
|
||||
logUtil.printLog(util.collectErrorLog(error), logUtil.T_ERR);
|
||||
|
||||
try {
|
||||
yield userRule.onConnectError(requestDetail, error);
|
||||
} catch (e) { }
|
||||
|
||||
try {
|
||||
let errorHeader = 'Proxy-Error: true\r\n';
|
||||
errorHeader += 'Proxy-Error-Message: ' + (error || 'null') + '\r\n';
|
||||
errorHeader += 'Content-Type: text/html\r\n';
|
||||
cltSocket.write('HTTP/1.1 502\r\n' + errorHeader + '\r\n\r\n');
|
||||
} catch (e) { }
|
||||
}));
|
||||
try {
|
||||
let errorHeader = 'Proxy-Error: true\r\n';
|
||||
errorHeader += 'Proxy-Error-Message: ' + (error || 'null') + '\r\n';
|
||||
errorHeader += 'Content-Type: text/html\r\n';
|
||||
cltSocket.write('HTTP/1.1 502\r\n' + errorHeader + '\r\n\r\n');
|
||||
} catch (e) { }
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user