@@ -129,8 +129,10 @@ describe('Proxy structured producers', function () {
129129
130130 expect ( internal , platform ) . to . have . length ( 1 ) ;
131131 expect ( internal [ 0 ] . name , platform ) . to . equal ( 'WS' ) ;
132- expect ( external . proxies . map ( ( proxy ) => proxy . name ) , platform ) . to
133- . deep . equal ( [ 'WS' , 'QUIC' ] ) ;
132+ expect (
133+ external . proxies . map ( ( proxy ) => proxy . name ) ,
134+ platform ,
135+ ) . to . deep . equal ( [ 'WS' , 'QUIC' ] ) ;
134136 }
135137 } ) ;
136138
@@ -395,6 +397,117 @@ describe('Proxy structured producers', function () {
395397 expect ( external . trim ( ) ) . to . equal ( 'proxies:' ) ;
396398 } ) ;
397399
400+ it ( 'keeps VLESS xhttp proxy when download-settings reality-opts has empty public-key and main reality is valid' , function ( ) {
401+ // 上行(主代理)有合法 reality-opts,下行(download-settings)用
402+ // reality-opts: { public-key: '' } 取消继承上行 Reality,合法配置。
403+ const proxy = {
404+ type : 'vless' ,
405+ name : 'XHTTP Reality Cancel' ,
406+ server : 'vless-xhttp.example.com' ,
407+ port : 443 ,
408+ uuid : UUID ,
409+ tls : true ,
410+ sni : 'sni.example.com' ,
411+ network : 'xhttp' ,
412+ 'reality-opts' : {
413+ 'public-key' : 'pubkey' ,
414+ 'short-id' : '08' ,
415+ } ,
416+ 'xhttp-opts' : {
417+ path : '/xhttp' ,
418+ mode : 'stream-up' ,
419+ 'download-settings' : {
420+ server : 'download.example.com' ,
421+ port : 8443 ,
422+ tls : true ,
423+ servername : 'download-sni.example.com' ,
424+ 'reality-opts' : { 'public-key' : '' } ,
425+ } ,
426+ } ,
427+ } ;
428+
429+ const internal = produceInternal ( 'Mihomo' , proxy ) ;
430+ expect ( internal ) . to . have . length ( 1 ) ;
431+ expect ( internal [ 0 ] . name ) . to . equal ( 'XHTTP Reality Cancel' ) ;
432+ } ) ;
433+
434+ it ( 'filters out VLESS xhttp proxy when download-settings reality-opts is empty object (broken URI) even with valid main reality' , function ( ) {
435+ // 下行 download-settings.reality-opts 为 {} (没有 public-key 字段),
436+ // 代表 URI 里声明了 security=reality 但 pbk 缺失,属于残缺配置,应过滤。
437+ const proxy = {
438+ type : 'vless' ,
439+ name : 'XHTTP Broken Reality' ,
440+ server : 'vless-xhttp.example.com' ,
441+ port : 443 ,
442+ uuid : UUID ,
443+ tls : true ,
444+ sni : 'sni.example.com' ,
445+ network : 'xhttp' ,
446+ 'reality-opts' : {
447+ 'public-key' : 'pubkey' ,
448+ 'short-id' : '08' ,
449+ } ,
450+ 'xhttp-opts' : {
451+ path : '/xhttp' ,
452+ mode : 'stream-up' ,
453+ 'download-settings' : {
454+ server : 'download.example.com' ,
455+ port : 8443 ,
456+ tls : true ,
457+ 'reality-opts' : { } ,
458+ } ,
459+ } ,
460+ } ;
461+
462+ const internal = produceInternal ( 'Mihomo' , proxy ) ;
463+ expect ( internal ) . to . have . length ( 0 ) ;
464+ } ) ;
465+
466+ it ( 'filters out VLESS xhttp proxy when download-settings reality-opts has empty public-key and main has no valid reality' , function ( ) {
467+ // 下行 download-settings 有 reality-opts: { public-key: '' },
468+ // 但上行主代理本身没有合法 Reality,属于无效配置,应被过滤。
469+ const proxy = {
470+ type : 'vless' ,
471+ name : 'XHTTP Invalid Reality' ,
472+ server : 'vless-xhttp.example.com' ,
473+ port : 443 ,
474+ uuid : UUID ,
475+ tls : true ,
476+ sni : 'sni.example.com' ,
477+ network : 'xhttp' ,
478+ 'xhttp-opts' : {
479+ path : '/xhttp' ,
480+ mode : 'stream-up' ,
481+ 'download-settings' : {
482+ server : 'download.example.com' ,
483+ port : 8443 ,
484+ tls : true ,
485+ 'reality-opts' : { 'public-key' : '' } ,
486+ } ,
487+ } ,
488+ } ;
489+
490+ const internal = produceInternal ( 'Mihomo' , proxy ) ;
491+ expect ( internal ) . to . have . length ( 0 ) ;
492+ } ) ;
493+
494+ it ( 'filters out VLESS proxy when main reality-opts has empty public-key' , function ( ) {
495+ // 主代理 reality-opts.public-key 为空,无论下行如何,都应被过滤。
496+ const proxy = {
497+ type : 'vless' ,
498+ name : 'Reality Empty Key' ,
499+ server : 'vless.example.com' ,
500+ port : 443 ,
501+ uuid : UUID ,
502+ tls : true ,
503+ network : 'tcp' ,
504+ 'reality-opts' : { 'public-key' : '' } ,
505+ } ;
506+
507+ const internal = produceInternal ( 'Mihomo' , proxy ) ;
508+ expect ( internal ) . to . have . length ( 0 ) ;
509+ } ) ;
510+
398511 it ( 'normalizes Stash TUIC defaults and external yaml wrapper' , function ( ) {
399512 const proxy = {
400513 type : 'tuic' ,
@@ -1843,5 +1956,4 @@ describe('Proxy structured producers', function () {
18431956
18441957 expect ( internal . map ( ( p ) => p . name ) ) . to . deep . equal ( [ 'VLESS WS' ] ) ;
18451958 } ) ;
1846-
18471959} ) ;
0 commit comments