diff --git a/3DTank/tools/wss_server.js b/3DTank/tools/wss_server.js index 1d76140..9d25199 100644 --- a/3DTank/tools/wss_server.js +++ b/3DTank/tools/wss_server.js @@ -511,17 +511,27 @@ WsServer.on('connection', (Client, Req) => { let Upstream = null; const Pending = []; // 上游未就绪时暂存竞态帧(握手帧常比上游 TLS 建连更早到达),一连上立即按原序补发 - // 握手头:把客户端**真实的** Origin / User-Agent / Referer 透传给上游(与浏览器直连时一致)。 - // 不能用写死的 origin:真实服务器可能按 Origin 选择构建/配置,写死会让响应与本地构建对不上, - // 表现为客户端握手失败自行断开(close code 1005)。 - const UpHeaders = { - 'user-agent': Req.headers['user-agent'] || UPSTREAM_HEADERS['user-agent'], - origin: Req.headers['origin'] || UPSTREAM_HEADERS.origin, - referer: Req.headers['referer'] || UPSTREAM_HEADERS.referer, - }; + // 握手头:把客户端**真实**的握手请求头整包透传给上游(Cookie / Origin / User-Agent / Referer / + // Accept-Language / Sec-Fetch-* …),让上游看到的握手与「浏览器直连」完全一致。 + // 仅排除必须由 ws 自己生成/协商的:Host / Connection / Upgrade / Sec-WebSocket-* + // (其中子协议改走 protocols 选项,由 ws 负责协商与校验)。 + const UpHeaders = {}; + for (const K of Object.keys(Req.headers)) { + const L = K.toLowerCase(); + if (L === 'host' || L === 'connection' || L === 'upgrade') continue; + if (L.indexOf('sec-websocket-') === 0) continue; + UpHeaders[L] = Req.headers[K]; + } + if (!UpHeaders['user-agent']) UpHeaders['user-agent'] = UPSTREAM_HEADERS['user-agent']; + if (!UpHeaders['origin']) UpHeaders['origin'] = UPSTREAM_HEADERS.origin; + if (!UpHeaders['referer']) UpHeaders['referer'] = UPSTREAM_HEADERS.referer; + const ClientProto = Req.headers['sec-websocket-protocol']; + const UpProtocols = ClientProto + ? String(ClientProto).split(',').map(function (S) { return S.trim(); }).filter(Boolean) + : undefined; // 转发:客户端帧**原样直发**;上游未就绪时暂存,open 后按原序补发(不重放、不改字节)。 - Upstream = new Ws(UPSTREAM, { headers: UpHeaders, rejectUnauthorized: false }); + Upstream = new Ws(UPSTREAM, { headers: UpHeaders, protocols: UpProtocols, rejectUnauthorized: false }); Upstream.binaryType = 'nodebuffer'; Upstream.on('open', () => { State.Log('上游已连接: ' + UPSTREAM + ',补发暂存 ' + Pending.length + ' 帧');