Update server.js via upload script - 2026-08-01 16:58:15
This commit is contained in:
parent
090774f86d
commit
390e8744d7
30
server.js
30
server.js
|
|
@ -160,11 +160,21 @@ function tcpCheck(host, port, timeoutMs = 6000) {
|
||||||
// 1) Cloudflare的520/521/522/523/524是"源站不可达"专属状态码,能连上CDN但源站挂了会明确返回这几个码;
|
// 1) Cloudflare的520/521/522/523/524是"源站不可达"专属状态码,能连上CDN但源站挂了会明确返回这几个码;
|
||||||
// 2) 再做一次真正的WebSocket握手,直接对应Xray/sing-box监听WS的那一层,比单看状态码更准。
|
// 2) 再做一次真正的WebSocket握手,直接对应Xray/sing-box监听WS的那一层,比单看状态码更准。
|
||||||
// 两个都过才算正常。
|
// 两个都过才算正常。
|
||||||
function httpStatusCheck(host, wsPath, timeoutMs = 8000) {
|
// 注意:连接必须用line.addr(真实服务器/CDN边缘地址)+ line.port(真实端口,不能写死443,
|
||||||
|
// 很多自建线路会用非标准端口);但HTTP Host头和TLS SNI要用line.host/line.sni(伪装域名),
|
||||||
|
// 不能也用addr——如果源站是按Host头路由的(Nginx server_name/反代规则),Host发错了根本到不了
|
||||||
|
// 正确的源站,会拿到无关响应甚至连接失败,跟真实客户端的连接行为对不上。
|
||||||
|
function httpStatusCheck(line, timeoutMs = 8000) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
const routeName = line.host || line.sni || line.addr;
|
||||||
const req = https.request({
|
const req = https.request({
|
||||||
hostname: host, port: 443, path: wsPath || '/', method: 'GET', timeout: timeoutMs,
|
hostname: line.addr,
|
||||||
headers: { 'User-Agent': 'Mozilla/5.0' },
|
port: Number(line.port) || 443,
|
||||||
|
path: line.ws_path || '/',
|
||||||
|
method: 'GET',
|
||||||
|
timeout: timeoutMs,
|
||||||
|
servername: line.sni || routeName, // TLS SNI
|
||||||
|
headers: { 'User-Agent': 'Mozilla/5.0', Host: routeName },
|
||||||
}, (res) => {
|
}, (res) => {
|
||||||
res.resume();
|
res.resume();
|
||||||
const badGateway = [520, 521, 522, 523, 524].includes(res.statusCode);
|
const badGateway = [520, 521, 522, 523, 524].includes(res.statusCode);
|
||||||
|
|
@ -175,7 +185,7 @@ function httpStatusCheck(host, wsPath, timeoutMs = 8000) {
|
||||||
req.end();
|
req.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function wsHandshakeCheck(host, wsPath, timeoutMs = 8000) {
|
function wsHandshakeCheck(line, timeoutMs = 8000) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
let done = false;
|
let done = false;
|
||||||
let ws;
|
let ws;
|
||||||
|
|
@ -186,7 +196,13 @@ function wsHandshakeCheck(host, wsPath, timeoutMs = 8000) {
|
||||||
resolve(ok);
|
resolve(ok);
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
ws = new WebSocket(`wss://${host}${wsPath || '/'}`, { handshakeTimeout: timeoutMs });
|
const port = Number(line.port) || 443;
|
||||||
|
const routeName = line.host || line.sni || line.addr;
|
||||||
|
ws = new WebSocket(`wss://${line.addr}:${port}${line.ws_path || '/'}`, {
|
||||||
|
handshakeTimeout: timeoutMs,
|
||||||
|
headers: { Host: routeName },
|
||||||
|
servername: line.sni || routeName, // TLS SNI
|
||||||
|
});
|
||||||
ws.on('open', () => finish(true));
|
ws.on('open', () => finish(true));
|
||||||
ws.on('unexpected-response', () => finish(false));
|
ws.on('unexpected-response', () => finish(false));
|
||||||
ws.on('error', () => finish(false));
|
ws.on('error', () => finish(false));
|
||||||
|
|
@ -200,8 +216,8 @@ function wsHandshakeCheck(host, wsPath, timeoutMs = 8000) {
|
||||||
async function checkLineConnectivity(line) {
|
async function checkLineConnectivity(line) {
|
||||||
if (line.protocol === 'vless-cdn') {
|
if (line.protocol === 'vless-cdn') {
|
||||||
const [httpOk, wsOk] = await Promise.all([
|
const [httpOk, wsOk] = await Promise.all([
|
||||||
httpStatusCheck(line.addr, line.ws_path),
|
httpStatusCheck(line),
|
||||||
wsHandshakeCheck(line.addr, line.ws_path),
|
wsHandshakeCheck(line),
|
||||||
]);
|
]);
|
||||||
return httpOk && wsOk;
|
return httpOk && wsOk;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue