pass through all the valid headers when proxing the WebSocket, and adds related test cases

This commit is contained in:
砚然
2018-03-23 15:42:38 +08:00
parent 11e68100a4
commit aae5c9b039
6 changed files with 115 additions and 46 deletions

View File

@@ -212,18 +212,39 @@ function fetchRemoteResponse(protocol, options, reqData, config) {
@param @required wsClient the ws client of WebSocket
*
*/
function getWsReqInfo(wsClient) {
const upgradeReq = wsClient.upgradeReq || {};
const header = upgradeReq.headers || {};
const host = header.host;
function getWsReqInfo(wsReq) {
const headers = wsReq.headers || {};
const host = headers.host;
const hostName = host.split(':')[0];
const port = host.split(':')[1];
// TODO 如果是windows机器url是不是全路径需要对其过滤取出
const path = upgradeReq.url || '/';
const path = wsReq.url || '/';
const isEncript = true && wsReq.connection && wsReq.connection.encrypted;
/**
* construct the request headers based on original connection,
* but delete the `sec-websocket-*` headers as they are already consumed by AnyProxy
*/
const getNoWsHeaders = () => {
const originHeaders = Object.assign({}, headers);
const originHeaderKeys = Object.keys(originHeaders);
originHeaderKeys.forEach((key) => {
// if the key matchs 'sec-websocket', delete it
if (/sec-websocket/ig.test(key)) {
delete originHeaders[key];
}
});
delete originHeaders.connection;
delete originHeaders.upgrade;
return originHeaders;
}
const isEncript = true && upgradeReq.connection && upgradeReq.connection.encrypted;
return {
headers: headers, // the full headers of origin ws connection
noWsHeaders: getNoWsHeaders(),
hostName: hostName,
port: port,
path: path,
@@ -664,7 +685,7 @@ function getConnectReqHandler(userRule, recorder, httpsServerMgr) {
* get a websocket event handler
@param @required {object} wsClient
*/
function getWsHandler(userRule, recorder, wsClient) {
function getWsHandler(userRule, recorder, wsClient, wsReq) {
const self = this;
try {
let resourceInfoId = -1;
@@ -672,10 +693,11 @@ function getWsHandler(userRule, recorder, wsClient) {
wsMessages: [] // all ws messages go through AnyProxy
};
const clientMsgQueue = [];
const serverInfo = getWsReqInfo(wsClient);
const serverInfo = getWsReqInfo(wsReq);
const wsUrl = `${serverInfo.protocol}://${serverInfo.hostName}:${serverInfo.port}${serverInfo.path}`;
const proxyWs = new WebSocket(wsUrl, '', {
rejectUnauthorized: !self.dangerouslyIgnoreUnauthorized
rejectUnauthorized: !self.dangerouslyIgnoreUnauthorized,
headers: serverInfo.noWsHeaders
});
if (recorder) {
@@ -684,7 +706,7 @@ function getWsHandler(userRule, recorder, wsClient) {
method: 'WebSocket',
path: serverInfo.path,
url: wsUrl,
req: wsClient.upgradeReq || {},
req: wsReq,
startTime: new Date().getTime()
});
resourceInfoId = recorder.appendRecord(resourceInfo);
@@ -763,8 +785,9 @@ function getWsHandler(userRule, recorder, wsClient) {
}
// this event is fired when the connection is build and headers is returned
proxyWs.on('headers', (headers, response) => {
proxyWs.on('upgrade', (response) => {
resourceInfo.endTime = new Date().getTime();
const headers = response.headers;
resourceInfo.res = { //construct a self-defined res object
statusCode: response.statusCode,
headers: headers,