|
1 | | -import { isPresent, Result } from './utils'; |
| 1 | +import { isPresent, isShadowsocksOverTls, Result } from './utils'; |
2 | 2 |
|
3 | 3 | const targetPlatform = 'QX'; |
4 | 4 |
|
@@ -54,10 +54,24 @@ export default function QX_Producer() { |
54 | 54 | }; |
55 | 55 | } |
56 | 56 |
|
| 57 | +function getQxHttpObfs(proxy) { |
| 58 | + // QX accepts multiple http-obfs spellings for ss/vmess/vless. Preserve |
| 59 | + // the original token for round-trip output, including "vemss-http". |
| 60 | + return [ |
| 61 | + 'http', |
| 62 | + 'vmess-http', |
| 63 | + 'vemss-http', |
| 64 | + 'shadowsocks-http', |
| 65 | + ].includes(proxy._qx_obfs_http) |
| 66 | + ? proxy._qx_obfs_http |
| 67 | + : 'http'; |
| 68 | +} |
| 69 | + |
57 | 70 | function shadowsocks(proxy) { |
58 | 71 | const result = new Result(proxy); |
59 | 72 | const append = result.append.bind(result); |
60 | 73 | const appendIfPresent = result.appendIfPresent.bind(result); |
| 74 | + const isSSOverTls = isShadowsocksOverTls(proxy); |
61 | 75 | if (!proxy.cipher) { |
62 | 76 | proxy.cipher = 'none'; |
63 | 77 | } |
@@ -98,10 +112,23 @@ function shadowsocks(proxy) { |
98 | 112 | if (needTls(proxy)) { |
99 | 113 | proxy.tls = true; |
100 | 114 | } |
101 | | - if (isPresent(proxy, 'plugin')) { |
| 115 | + if (isSSOverTls) { |
| 116 | + append(`,obfs=over-tls`); |
| 117 | + if (isPresent(proxy, 'sni')) { |
| 118 | + append(`,obfs-host=${proxy.sni}`); |
| 119 | + } else { |
| 120 | + appendIfPresent(`,obfs-host=${proxy.servername}`, 'servername'); |
| 121 | + } |
| 122 | + } else if (isPresent(proxy, 'plugin')) { |
102 | 123 | if (proxy.plugin === 'obfs') { |
103 | 124 | const opts = proxy['plugin-opts']; |
104 | | - append(`,obfs=${opts.mode}`); |
| 125 | + if (opts.mode === 'http') { |
| 126 | + // Keep the original QX http-obfs token instead of collapsing |
| 127 | + // it back to plain "http". |
| 128 | + append(`,obfs=${getQxHttpObfs(proxy)}`); |
| 129 | + } else { |
| 130 | + append(`,obfs=${opts.mode}`); |
| 131 | + } |
105 | 132 | } else if ( |
106 | 133 | proxy.plugin === 'v2ray-plugin' && |
107 | 134 | proxy['plugin-opts'].mode === 'websocket' |
@@ -147,7 +174,9 @@ function shadowsocks(proxy) { |
147 | 174 | `,tls-verification=${!proxy['skip-cert-verify']}`, |
148 | 175 | 'skip-cert-verify', |
149 | 176 | ); |
150 | | - appendIfPresent(`,tls-host=${proxy.sni}`, 'sni'); |
| 177 | + if (!isSSOverTls) { |
| 178 | + appendIfPresent(`,tls-host=${proxy.sni}`, 'sni'); |
| 179 | + } |
151 | 180 | } |
152 | 181 |
|
153 | 182 | // tfo |
@@ -325,7 +354,7 @@ function vmess(proxy) { |
325 | 354 | if (proxy.tls) append(`,obfs=wss`); |
326 | 355 | else append(`,obfs=ws`); |
327 | 356 | } else if (proxy.network === 'http') { |
328 | | - append(`,obfs=http`); |
| 357 | + append(`,obfs=${getQxHttpObfs(proxy)}`); |
329 | 358 | } else if (['tcp'].includes(proxy.network)) { |
330 | 359 | if (proxy.tls) append(`,obfs=over-tls`); |
331 | 360 | } else if (!['tcp'].includes(proxy.network)) { |
@@ -431,7 +460,7 @@ function vless(proxy) { |
431 | 460 | if (proxy.tls) append(`,obfs=wss`); |
432 | 461 | else append(`,obfs=ws`); |
433 | 462 | } else if (proxy.network === 'http') { |
434 | | - append(`,obfs=http`); |
| 463 | + append(`,obfs=${getQxHttpObfs(proxy)}`); |
435 | 464 | } else if (['tcp'].includes(proxy.network)) { |
436 | 465 | if (proxy.tls) append(`,obfs=over-tls`); |
437 | 466 | } else if (!['tcp'].includes(proxy.network)) { |
|
0 commit comments