1- const Version = '2026-07-11 19:02:35 ' ;
1+ const Version = '2026-07-22 19:14:26 ' ;
22let config_JSON , 缓存SOCKS5白名单 = null , 调试日志打印 = false ;
33let SOCKS5白名单 = [ '*tapecontent.net' , '*cloudatacdn.com' , '*loadshare.org' , '*cdn-centaurus.com' , 'scholar.google.com' ] ;
44const Pages静态页面 = 'https://edt-pages.github.io' ;
@@ -538,7 +538,14 @@ async function 处理XHTTP请求(request, yourUUID, 反代上下文 = {}) {
538538 }
539539 if ( isSpeedTestSite ( 首包 . hostname ) ) {
540540 try { reader . releaseLock ( ) } catch ( e ) { }
541- return new Response ( 'Forbidden' , { status : 403 } ) ;
541+ return new Response ( 构造本地204响应 ( 首包 . respHeader ) , {
542+ status : 200 ,
543+ headers : {
544+ 'Content-Type' : 'application/octet-stream' ,
545+ 'X-Accel-Buffering' : 'no' ,
546+ 'Cache-Control' : 'no-store'
547+ }
548+ } ) ;
542549 }
543550 if ( 首包 . isUDP && 首包 . 协议 !== 'trojan' && 首包 . port !== 53 ) {
544551 try { reader . releaseLock ( ) } catch ( e ) { }
@@ -1052,7 +1059,10 @@ async function 处理gRPC请求(request, yourUUID, 反代上下文 = {}) {
10521059 if ( 解析结果 ?. hasError ) throw new Error ( 解析结果 . message || 'Invalid trojan request' ) ;
10531060 const { port, hostname, rawClientData, isUDP } = 解析结果 ;
10541061 log ( `[gRPC] 木马首包: ${ hostname } :${ port } | UDP: ${ isUDP ? '是' : '否' } ` ) ;
1055- if ( isSpeedTestSite ( hostname ) ) throw new Error ( 'Speedtest site is blocked' ) ;
1062+ if ( isSpeedTestSite ( hostname ) ) {
1063+ grpcBridge . send ( 构造本地204响应 ( ) ) ;
1064+ return ;
1065+ }
10561066 if ( isUDP ) {
10571067 isDnsQuery = true ;
10581068 木马UDP上下文 . 目标主机 = hostname ;
@@ -1068,12 +1078,15 @@ async function 处理gRPC请求(request, yourUUID, 反代上下文 = {}) {
10681078 if ( 解析结果 ?. hasError ) throw new Error ( 解析结果 . message || 'Invalid 魏烈思 request' ) ;
10691079 const { port, hostname, version, isUDP, rawClientData } = 解析结果 ;
10701080 log ( `[gRPC] 魏烈思首包: ${ hostname } :${ port } | UDP: ${ isUDP ? '是' : '否' } ` ) ;
1071- if ( isSpeedTestSite ( hostname ) ) throw new Error ( 'Speedtest site is blocked' ) ;
1081+ const respHeader = new Uint8Array ( [ version , 0 ] ) ;
1082+ if ( isSpeedTestSite ( hostname ) ) {
1083+ grpcBridge . send ( 构造本地204响应 ( respHeader ) ) ;
1084+ return ;
1085+ }
10721086 if ( isUDP ) {
10731087 if ( port !== 53 ) throw new Error ( 'UDP is not supported' ) ;
10741088 isDnsQuery = true ;
10751089 }
1076- const respHeader = new Uint8Array ( [ version , 0 ] ) ;
10771090 grpcBridge . send ( respHeader ) ;
10781091 const rawData = rawClientData ;
10791092 if ( isDnsQuery ) {
@@ -1170,6 +1183,52 @@ async function 处理WS请求(request, yourUUID, url, 反代上下文 = {}) {
11701183 let WS显式队列字节 = 0 , WS显式队列条目 = 0 ;
11711184 let 判断协议类型 = null , 当前写入Socket = null , 远端写入器 = null ;
11721185 let ss上下文 = null , ss初始化任务 = null ;
1186+ let WS本地测速模式 = false , WS本地测速回包Socket = null ;
1187+ let WS本地测速请求缓存 = new Uint8Array ( 0 ) ;
1188+ let WS本地测速首包响应头 = null ;
1189+ const WS本地测速请求上限 = 64 * 1024 ;
1190+
1191+ const 发送WS本地测速响应 = async ( ) => {
1192+ if ( ! WS本地测速回包Socket ) return ;
1193+ const respHeader = WS本地测速首包响应头 ;
1194+ WS本地测速首包响应头 = null ;
1195+ await WebSocket发送并等待 ( WS本地测速回包Socket , 构造WS本地204响应 ( respHeader ) ) ;
1196+ } ;
1197+
1198+ const 查找HTTP请求头结尾 = ( data ) => {
1199+ for ( let i = 0 ; i <= data . byteLength - 4 ; i ++ ) {
1200+ if ( data [ i ] === 0x0d && data [ i + 1 ] === 0x0a && data [ i + 2 ] === 0x0d && data [ i + 3 ] === 0x0a ) return i + 4 ;
1201+ }
1202+ return - 1 ;
1203+ } ;
1204+
1205+ const 处理WS本地测速数据 = async ( data ) => {
1206+ const chunk = 数据转Uint8Array ( data ) ;
1207+ if ( ! chunk . byteLength ) return ;
1208+ if ( WS本地测速请求缓存 . byteLength + chunk . byteLength > WS本地测速请求上限 ) throw new Error ( 'WS local speed-test request is too large' ) ;
1209+ WS本地测速请求缓存 = 拼接字节数据 ( WS本地测速请求缓存 , chunk ) ;
1210+
1211+ while ( WS本地测速请求缓存 . byteLength ) {
1212+ const headerEnd = 查找HTTP请求头结尾 ( WS本地测速请求缓存 ) ;
1213+ if ( headerEnd === - 1 ) return ;
1214+ const headerText = VLESS文本解码器 . decode ( WS本地测速请求缓存 . subarray ( 0 , headerEnd ) ) ;
1215+ const contentLengthMatch = headerText . match ( / (?: ^ | \r \n ) c o n t e n t - l e n g t h \s * : \s * ( \d + ) / i) ;
1216+ const contentLength = contentLengthMatch ? Number ( contentLengthMatch [ 1 ] ) : 0 ;
1217+ const requestLength = headerEnd + contentLength ;
1218+ if ( ! Number . isSafeInteger ( contentLength ) || requestLength > WS本地测速请求上限 ) throw new Error ( 'WS local speed-test request body is too large' ) ;
1219+ if ( WS本地测速请求缓存 . byteLength < requestLength ) return ;
1220+ WS本地测速请求缓存 = WS本地测速请求缓存 . slice ( requestLength ) ;
1221+ await 发送WS本地测速响应 ( ) ;
1222+ }
1223+ } ;
1224+
1225+ const 启用WS本地测速模式 = async ( 回包Socket , respHeader = null , 首请求数据 = null ) => {
1226+ WS本地测速模式 = true ;
1227+ WS本地测速回包Socket = 回包Socket ;
1228+ WS本地测速请求缓存 = new Uint8Array ( 0 ) ;
1229+ WS本地测速首包响应头 = respHeader ;
1230+ if ( 有效数据长度 ( 首请求数据 ) > 0 ) await 处理WS本地测速数据 ( 首请求数据 ) ;
1231+ } ;
11731232
11741233 const 释放远端写入器 = ( ) => {
11751234 if ( 远端写入器 ) {
@@ -1395,6 +1454,10 @@ async function 处理WS请求(request, yourUUID, url, 反代上下文 = {}) {
13951454 throw err ;
13961455 }
13971456 for ( const 明文块 of 明文块数组 ) {
1457+ if ( WS本地测速模式 ) {
1458+ await 处理WS本地测速数据 ( 明文块 ) ;
1459+ continue ;
1460+ }
13981461 let 已写入 = false ;
13991462 try {
14001463 已写入 = await 写入远端 ( 明文块 , false ) ;
@@ -1437,7 +1500,10 @@ async function 处理WS请求(request, yourUUID, url, 反代上下文 = {}) {
14371500 const port = ( 明文数据 [ cursor ] << 8 ) | 明文数据 [ cursor + 1 ] ;
14381501 cursor += 2 ;
14391502 const rawClientData = 明文数据 . subarray ( cursor ) ;
1440- if ( isSpeedTestSite ( hostname ) ) throw new Error ( 'Speedtest site is blocked' ) ;
1503+ if ( isSpeedTestSite ( hostname ) ) {
1504+ await 启用WS本地测速模式 ( 上下文 . 回包Socket , null , rawClientData ) ;
1505+ return ;
1506+ }
14411507 上下文 . 首包已建立 = true ;
14421508 上下文 . 目标主机 = hostname ;
14431509 上下文 . 目标端口 = port ;
@@ -1455,6 +1521,10 @@ async function 处理WS请求(request, yourUUID, url, 反代上下文 = {}) {
14551521 await 处理SS数据 ( chunk ) ;
14561522 return ;
14571523 }
1524+ if ( WS本地测速模式 ) {
1525+ await 处理WS本地测速数据 ( chunk ) ;
1526+ return ;
1527+ }
14581528 if ( await 写入远端 ( chunk ) ) return ;
14591529
14601530 if ( 判断协议类型 === null ) {
@@ -1477,7 +1547,10 @@ async function 处理WS请求(request, yourUUID, url, 反代上下文 = {}) {
14771547 const 解析结果 = 解析木马请求 ( chunk , yourUUID ) ;
14781548 if ( 解析结果 ?. hasError ) throw new Error ( 解析结果 . message || 'Invalid trojan request' ) ;
14791549 const { port, hostname, rawClientData, isUDP } = 解析结果 ;
1480- if ( isSpeedTestSite ( hostname ) ) throw new Error ( 'Speedtest site is blocked' ) ;
1550+ if ( isSpeedTestSite ( hostname ) ) {
1551+ await 启用WS本地测速模式 ( serverSock , null , rawClientData ) ;
1552+ return ;
1553+ }
14811554 if ( isUDP ) {
14821555 isDnsQuery = true ;
14831556 木马UDP上下文 . 目标主机 = hostname ;
@@ -1494,12 +1567,15 @@ async function 处理WS请求(request, yourUUID, url, 反代上下文 = {}) {
14941567 const 解析结果 = 解析魏烈思请求 ( bytes , yourUUID ) ;
14951568 if ( 解析结果 ?. hasError ) throw new Error ( 解析结果 . message || 'Invalid 魏烈思 request' ) ;
14961569 const { port, hostname, version, isUDP, rawClientData } = 解析结果 ;
1497- if ( isSpeedTestSite ( hostname ) ) throw new Error ( 'Speedtest site is blocked' ) ;
1570+ const respHeader = new Uint8Array ( [ version , 0 ] ) ;
1571+ if ( isSpeedTestSite ( hostname ) ) {
1572+ await 启用WS本地测速模式 ( serverSock , respHeader , rawClientData ) ;
1573+ return ;
1574+ }
14981575 if ( isUDP ) {
14991576 if ( port === 53 ) isDnsQuery = true ;
15001577 else throw new Error ( 'UDP is not supported' ) ;
15011578 }
1502- const respHeader = new Uint8Array ( [ version , 0 ] ) ;
15031579 const rawData = rawClientData ;
15041580 if ( isDnsQuery ) {
15051581 if ( 判断是否是木马 ) return 转发木马UDP数据 ( rawData , serverSock , 木马UDP上下文 , request ) ;
@@ -2608,17 +2684,40 @@ async function connectStreams(remoteSocket, webSocket, headerData, retryFunc) {
26082684}
26092685
26102686function isSpeedTestSite ( hostname ) {
2611- const speedTestDomains = [ atob ( 'c3BlZWQuY2xvdWRmbGFyZS5jb20=' ) ] ;
2612- if ( speedTestDomains . includes ( hostname ) ) {
2613- return true ;
2614- }
2687+ const speedTestDomains = [ 'speed.cloudflare.com' , 'cp.cloudflare.com' ] ;
2688+ hostname = hostname . toLowerCase ( ) ;
2689+ return speedTestDomains . some ( domain => hostname === domain || hostname . endsWith ( '.' + domain ) ) ;
2690+ }
26152691
2616- for ( const domain of speedTestDomains ) {
2617- if ( hostname . endsWith ( '.' + domain ) || hostname === domain ) {
2618- return true ;
2619- }
2620- }
2621- return false ;
2692+ function 构造本地204响应 ( respHeader = null ) {
2693+ const 本地204响应 = new TextEncoder ( ) . encode (
2694+ 'HTTP/1.1 204 No Content\r\n' +
2695+ 'Content-Length: 0\r\n' +
2696+ 'Connection: close\r\n' +
2697+ '\r\n'
2698+ ) ;
2699+ if ( 有效数据长度 ( respHeader ) === 0 ) return 本地204响应 ;
2700+ const 协议响应头 = 数据转Uint8Array ( respHeader ) ;
2701+ const response = new Uint8Array ( 协议响应头 . byteLength + 本地204响应 . byteLength ) ;
2702+ response . set ( 协议响应头 , 0 ) ;
2703+ response . set ( 本地204响应 , 协议响应头 . byteLength ) ;
2704+ log ( `[TCP转发] 构造本地204响应: ${ response . byteLength } B` ) ;
2705+ return response ;
2706+ }
2707+
2708+ function 构造WS本地204响应 ( respHeader = null ) {
2709+ const WS本地204响应 = new TextEncoder ( ) . encode (
2710+ 'HTTP/1.1 204 No Content\r\n' +
2711+ 'Content-Length: 0\r\n' +
2712+ 'Connection: keep-alive\r\n' +
2713+ '\r\n'
2714+ ) ;
2715+ if ( 有效数据长度 ( respHeader ) === 0 ) return WS本地204响应 ;
2716+ const 协议响应头 = 数据转Uint8Array ( respHeader ) ;
2717+ const response = new Uint8Array ( 协议响应头 . byteLength + WS本地204响应 . byteLength ) ;
2718+ response . set ( 协议响应头 , 0 ) ;
2719+ response . set ( WS本地204响应 , 协议响应头 . byteLength ) ;
2720+ return response ;
26222721}
26232722
26242723///////////////////////////////////////////////////////SOCKS5/HTTP函数///////////////////////////////////////////////
0 commit comments