mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-30 02:32:09 +08:00
fix: support VLESS xhttp and normalize IPv6 addresses
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
- 修复编辑订阅配置时清空 HTTP 请求超时会报错的问题
|
||||
- 修复纯 IP 连接的主机地址显示错误,并保留目标 IP 为空时的地址回退
|
||||
- 修复 Windows 管理员模式下启动 TUN 时因等待不可用 Service 导致延迟 30 秒的问题
|
||||
- 修复 VLESS xhttp 链接解析及 IPv6 地址格式问题
|
||||
|
||||
<details>
|
||||
<summary><strong> ✨ 新增功能 </strong></summary>
|
||||
|
||||
Vendored
+9
-1
@@ -353,6 +353,12 @@ interface GrpcOptions {
|
||||
'grpc-service-name'?: string
|
||||
}
|
||||
|
||||
interface XHttpOptions {
|
||||
path?: string
|
||||
host?: string
|
||||
mode?: string
|
||||
}
|
||||
|
||||
interface RealityOptions {
|
||||
'public-key'?: string
|
||||
'short-id'?: string
|
||||
@@ -367,7 +373,7 @@ type ClientFingerprint =
|
||||
| '360'
|
||||
| 'qq'
|
||||
| 'random'
|
||||
type NetworkType = 'ws' | 'http' | 'h2' | 'grpc' | 'tcp'
|
||||
type NetworkType = 'ws' | 'http' | 'h2' | 'grpc' | 'tcp' | 'xhttp'
|
||||
type CipherType =
|
||||
| 'none'
|
||||
| 'auto'
|
||||
@@ -599,6 +605,7 @@ interface IProxyVlessConfig extends IProxyBaseConfig {
|
||||
'h2-opts'?: H2Options
|
||||
'grpc-opts'?: GrpcOptions
|
||||
'ws-opts'?: WsOptions
|
||||
'xhttp-opts'?: XHttpOptions
|
||||
'ws-path'?: string
|
||||
'ws-headers'?: {
|
||||
[key: string]: string
|
||||
@@ -608,6 +615,7 @@ interface IProxyVlessConfig extends IProxyBaseConfig {
|
||||
servername?: string
|
||||
'client-fingerprint'?: ClientFingerprint
|
||||
smux?: boolean
|
||||
encryption?: string
|
||||
}
|
||||
// vmess
|
||||
interface IProxyVmessConfig extends IProxyBaseConfig {
|
||||
|
||||
@@ -193,6 +193,10 @@ export type UrlLikeParts = {
|
||||
fragment?: string
|
||||
}
|
||||
|
||||
export function normalizeHost(host: string): string {
|
||||
return host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host
|
||||
}
|
||||
|
||||
const URLLIKE_RE =
|
||||
/^(?:(?<auth>.*?)@)?(?<host>.*?)(?::(?<port>\d+))?\/?(?:\?(?<query>.*?))?(?:#(?<fragment>.*?))?$/
|
||||
|
||||
@@ -227,7 +231,7 @@ export function parseUrlLike(
|
||||
|
||||
const result: UrlLikeParts = {
|
||||
auth,
|
||||
host: groups.host,
|
||||
host: normalizeHost(groups.host),
|
||||
port: groups.port,
|
||||
query: groups.query,
|
||||
fragment: groups.fragment,
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
getCipher,
|
||||
getIfNotBlank,
|
||||
getIfPresent,
|
||||
normalizeHost,
|
||||
parseBoolOrPresence,
|
||||
parseQueryString,
|
||||
parseRequiredPort,
|
||||
@@ -37,7 +38,7 @@ export function URI_SS(line: string): IProxyShadowsocksConfig {
|
||||
if (portIdx === -1) {
|
||||
throw new Error('Invalid ss uri: missing port')
|
||||
}
|
||||
const server = serverAndPort.slice(0, portIdx)
|
||||
const server = normalizeHost(serverAndPort.slice(0, portIdx))
|
||||
const portRaw = serverAndPort.slice(portIdx + 1)
|
||||
const port = parseRequiredPort(portRaw, 'Invalid ss uri: invalid port')
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
decodeBase64OrOriginal,
|
||||
getCipher,
|
||||
getIfNotBlank,
|
||||
normalizeHost,
|
||||
parseQueryString,
|
||||
parseRequiredPort,
|
||||
stripUriScheme,
|
||||
@@ -27,7 +28,7 @@ export function URI_SSR(uri: string): IProxyshadowsocksRConfig {
|
||||
if (portIdx === -1) {
|
||||
throw new Error('Invalid ssr uri: missing port')
|
||||
}
|
||||
const server = serverAndPort.substring(0, portIdx)
|
||||
const server = normalizeHost(serverAndPort.substring(0, portIdx))
|
||||
const port = parseRequiredPort(
|
||||
serverAndPort.substring(portIdx + 1),
|
||||
'Invalid ssr uri: invalid port',
|
||||
|
||||
@@ -91,6 +91,8 @@ export function URI_VLESS(line: string): IProxyVlessConfig {
|
||||
uuid,
|
||||
}
|
||||
|
||||
proxy.encryption = params.encryption === 'none' ? '' : params.encryption
|
||||
|
||||
proxy.tls = (params.security && params.security !== 'none') || undefined
|
||||
if (isShadowrocket && parseBool(params.tls) === true) {
|
||||
proxy.tls = true
|
||||
@@ -131,7 +133,10 @@ export function URI_VLESS(line: string): IProxyVlessConfig {
|
||||
if (type === 'httpupgrade') {
|
||||
network = 'ws'
|
||||
httpupgrade = true
|
||||
} else if (type && ['tcp', 'ws', 'http', 'grpc', 'h2'].includes(type)) {
|
||||
} else if (
|
||||
type &&
|
||||
['tcp', 'ws', 'http', 'grpc', 'h2', 'xhttp'].includes(type)
|
||||
) {
|
||||
network = type as NetworkType
|
||||
} else {
|
||||
network = 'tcp'
|
||||
@@ -206,6 +211,19 @@ export function URI_VLESS(line: string): IProxyVlessConfig {
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'xhttp': {
|
||||
const xhttpOpts: XHttpOptions = {}
|
||||
const hostVal = getIfNotBlank(host)
|
||||
const pathVal = getIfNotBlank(path)
|
||||
const modeVal = getIfNotBlank(params.mode)
|
||||
if (hostVal) xhttpOpts.host = hostVal
|
||||
if (pathVal) xhttpOpts.path = pathVal
|
||||
if (modeVal) xhttpOpts.mode = modeVal
|
||||
if (Object.keys(xhttpOpts).length > 0) {
|
||||
proxy['xhttp-opts'] = xhttpOpts
|
||||
}
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
getIfNotBlank,
|
||||
getIfPresent,
|
||||
isPresent,
|
||||
normalizeHost,
|
||||
parseBool,
|
||||
parseRequiredPort,
|
||||
safeDecodeURIComponent,
|
||||
@@ -72,7 +73,7 @@ function parseVmessQuantumult(content: string): IProxyVmessConfig {
|
||||
const proxy: IProxyVmessConfig = {
|
||||
name: partitions[0].split('=')[0].trim(),
|
||||
type: 'vmess',
|
||||
server: partitions[1],
|
||||
server: normalizeHost(partitions[1]),
|
||||
port: parseRequiredPort(partitions[2], 'Invalid vmess uri: invalid port'),
|
||||
cipher: getCipher(getIfNotBlank(partitions[3], 'auto')),
|
||||
uuid: partitions[4].match(/^"(.*)"$/)?.[1] || '',
|
||||
@@ -118,7 +119,8 @@ export function URI_VMESS(line: string): IProxyVmessConfig {
|
||||
}
|
||||
|
||||
const params = parseVmessParams(content, raw)
|
||||
const server = params.add
|
||||
const server =
|
||||
typeof params.add === 'string' ? normalizeHost(params.add) : params.add
|
||||
const port = parseRequiredPort(params.port, 'Invalid vmess uri: invalid port')
|
||||
const tlsValue = params.tls
|
||||
const proxy: IProxyVmessConfig = {
|
||||
|
||||
Reference in New Issue
Block a user