diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 5c04e06a..94a82bb3 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -32,7 +32,7 @@ jobs: images: ghcr.io/${{ github.repository }} - name: Build and push Docker image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . push: ${{ github.event_name != 'pull_request' }} diff --git a/README.es_ES.md b/README.es_ES.md index 1a669476..17fbcc48 100644 --- a/README.es_ES.md +++ b/README.es_ES.md @@ -29,10 +29,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh ## Instalar una Versión Personalizada -Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.3.4`: +Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.3.6`: ``` -bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.4 +bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.6 ``` ## Certificado SSL @@ -259,7 +259,7 @@ Nuestra plataforma ofrece compatibilidad con una amplia gama de arquitecturas y -## [Configuración WARP](https://gitlab.com/fscarmen/warp) +## Configuración WARP
Haz clic para detalles de la configuración WARP diff --git a/README.md b/README.md index 46dfe576..1e8c3e5d 100644 --- a/README.md +++ b/README.md @@ -107,10 +107,10 @@ apt update -y&&apt install -y curl&&apt install -y socat ------------ ## 安装指定版本 -若要安装指定的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.5`: +若要安装指定的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.6`: ``` -bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.5 +bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.6 ``` ------------ ## 若你的VPS默认有防火墙,请在安装完成之后放行指定端口 @@ -468,9 +468,11 @@ systemctl restart x-ui
+ ------------ ## [WARP 配置](https://gitlab.com/fscarmen/warp) +
点击查看 WARP 配置 diff --git a/README.zh.md b/README.zh.md index 42679596..f72cb746 100644 --- a/README.zh.md +++ b/README.zh.md @@ -28,11 +28,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh ## 安装指定版本 - -若需要安装指定的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.4`: +若需要安装指定的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.6`: ``` -bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.4 +bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.3.6 ``` ## SSL 认证 @@ -258,7 +257,7 @@ systemctl restart x-ui
-## [WARP 配置](https://gitlab.com/fscarmen/warp) +## WARP 配置
点击查看 WARP 配置 diff --git a/config/version b/config/version index 5cfa27a9..0501b79e 100644 --- a/config/version +++ b/config/version @@ -1 +1 @@ -2.3.5.3 +2.3.6 \ No newline at end of file diff --git a/sub/subJsonService.go b/sub/subJsonService.go index 76d0b126..742c403c 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -224,7 +224,6 @@ func (s *SubJsonService) streamData(stream string) map[string]interface{} { case "httpupgrade": streamSettings["httpupgradeSettings"] = s.removeAcceptProxy(streamSettings["httpupgradeSettings"]) } - return streamSettings } diff --git a/sub/subService.go b/sub/subService.go index 3ba0bda7..cc73c6a1 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -202,12 +202,11 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string { case "ws": ws, _ := stream["wsSettings"].(map[string]interface{}) obj["path"] = ws["path"].(string) - obj["host"] = ws["host"].(string) - if headers, ok := ws["headers"].(map[string]interface{}); ok { - hostFromHeaders := searchHost(headers) - if hostFromHeaders != "" { - obj["host"] = hostFromHeaders - } + if host, ok := ws["host"].(string); ok && len(host) > 0 { + obj["host"] = host + } else { + headers, _ := ws["headers"].(map[string]interface{}) + obj["host"] = searchHost(headers) } case "http": obj["net"] = "h2" @@ -230,12 +229,20 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string { case "httpupgrade": httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{}) obj["path"] = httpupgrade["path"].(string) - obj["host"] = httpupgrade["host"].(string) - if headers, ok := httpupgrade["headers"].(map[string]interface{}); ok { - hostFromHeaders := searchHost(headers) - if hostFromHeaders != "" { - obj["host"] = hostFromHeaders - } + if host, ok := httpupgrade["host"].(string); ok && len(host) > 0 { + obj["host"] = host + } else { + headers, _ := httpupgrade["headers"].(map[string]interface{}) + obj["host"] = searchHost(headers) + } + case "splithttp": + splithttp, _ := stream["splithttpSettings"].(map[string]interface{}) + obj["path"] = splithttp["path"].(string) + if host, ok := splithttp["host"].(string); ok && len(host) > 0 { + obj["host"] = host + } else { + headers, _ := splithttp["headers"].(map[string]interface{}) + obj["host"] = searchHost(headers) } } security, _ := stream["security"].(string) @@ -352,13 +359,11 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string { case "ws": ws, _ := stream["wsSettings"].(map[string]interface{}) params["path"] = ws["path"].(string) - params["host"] = ws["host"].(string) - headers, _ := ws["headers"].(map[string]interface{}) - if headers != nil { - hostFromHeaders := searchHost(headers) - if hostFromHeaders != "" { - params["host"] = hostFromHeaders - } + if host, ok := ws["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := ws["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) } case "http": http, _ := stream["httpSettings"].(map[string]interface{}) @@ -380,13 +385,20 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string { case "httpupgrade": httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{}) params["path"] = httpupgrade["path"].(string) - params["host"] = httpupgrade["host"].(string) - headers, _ := httpupgrade["headers"].(map[string]interface{}) - if headers != nil { - hostFromHeaders := searchHost(headers) - if hostFromHeaders != "" { - params["host"] = hostFromHeaders - } + if host, ok := httpupgrade["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := httpupgrade["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) + } + case "splithttp": + splithttp, _ := stream["splithttpSettings"].(map[string]interface{}) + params["path"] = splithttp["path"].(string) + if host, ok := splithttp["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := splithttp["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) } } security, _ := stream["security"].(string) @@ -581,13 +593,11 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string case "ws": ws, _ := stream["wsSettings"].(map[string]interface{}) params["path"] = ws["path"].(string) - params["host"] = ws["host"].(string) - headers, _ := ws["headers"].(map[string]interface{}) - if headers != nil { - hostFromHeaders := searchHost(headers) - if hostFromHeaders != "" { - params["host"] = hostFromHeaders - } + if host, ok := ws["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := ws["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) } case "http": http, _ := stream["httpSettings"].(map[string]interface{}) @@ -609,13 +619,20 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string case "httpupgrade": httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{}) params["path"] = httpupgrade["path"].(string) - params["host"] = httpupgrade["host"].(string) - headers, _ := httpupgrade["headers"].(map[string]interface{}) - if headers != nil { - hostFromHeaders := searchHost(headers) - if hostFromHeaders != "" { - params["host"] = hostFromHeaders - } + if host, ok := httpupgrade["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := httpupgrade["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) + } + case "splithttp": + splithttp, _ := stream["splithttpSettings"].(map[string]interface{}) + params["path"] = splithttp["path"].(string) + if host, ok := splithttp["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := splithttp["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) } } security, _ := stream["security"].(string) @@ -811,13 +828,11 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st case "ws": ws, _ := stream["wsSettings"].(map[string]interface{}) params["path"] = ws["path"].(string) - params["host"] = ws["host"].(string) - headers, _ := ws["headers"].(map[string]interface{}) - if headers != nil { - hostFromHeaders := searchHost(headers) - if hostFromHeaders != "" { - params["host"] = hostFromHeaders - } + if host, ok := ws["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := ws["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) } case "http": http, _ := stream["httpSettings"].(map[string]interface{}) @@ -839,13 +854,20 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st case "httpupgrade": httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{}) params["path"] = httpupgrade["path"].(string) - params["host"] = httpupgrade["host"].(string) - headers, _ := httpupgrade["headers"].(map[string]interface{}) - if headers != nil { - hostFromHeaders := searchHost(headers) - if hostFromHeaders != "" { - params["host"] = hostFromHeaders - } + if host, ok := httpupgrade["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := httpupgrade["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) + } + case "splithttp": + splithttp, _ := stream["splithttpSettings"].(map[string]interface{}) + params["path"] = splithttp["path"].(string) + if host, ok := splithttp["host"].(string); ok && len(host) > 0 { + params["host"] = host + } else { + headers, _ := splithttp["headers"].(map[string]interface{}) + params["host"] = searchHost(headers) } } diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js index ce924b73..e6555a9c 100644 --- a/web/assets/js/model/outbound.js +++ b/web/assets/js/model/outbound.js @@ -194,7 +194,7 @@ class WsStreamSettings extends CommonClass { static fromJson(json={}) { return new WsStreamSettings( json.path, - json.host + json.host, ); } @@ -202,7 +202,6 @@ class WsStreamSettings extends CommonClass { return { path: this.path, host: this.host, - headers: ObjectUtil.isEmpty(this.host) ? undefined : {Host: this.host}, }; } } @@ -288,7 +287,29 @@ class HttpUpgradeStreamSettings extends CommonClass { static fromJson(json={}) { return new HttpUpgradeStreamSettings( json.path, - json.host + json.host, + ); + } + + toJson() { + return { + path: this.path, + host: this.host, + }; + } +} + +class SplitHTTPStreamSettings extends CommonClass { + constructor(path='/', host='') { + super(); + this.path = path; + this.host = host; + } + + static fromJson(json={}) { + return new SplitHTTPStreamSettings( + json.path, + json.host, ); } @@ -296,7 +317,6 @@ class HttpUpgradeStreamSettings extends CommonClass { return { path: this.path, host: this.host, - headers: ObjectUtil.isEmpty(this.host) ? undefined : {Host: this.host}, }; } } @@ -404,6 +424,7 @@ class StreamSettings extends CommonClass { quicSettings=new QuicStreamSettings(), grpcSettings=new GrpcStreamSettings(), httpupgradeSettings=new HttpUpgradeStreamSettings(), + splithttpSettings=new SplitHTTPStreamSettings(), sockopt = undefined, ) { super(); @@ -418,6 +439,7 @@ class StreamSettings extends CommonClass { this.quic = quicSettings; this.grpc = grpcSettings; this.httpupgrade = httpupgradeSettings; + this.splithttp = splithttpSettings; this.sockopt = sockopt; } @@ -450,6 +472,7 @@ class StreamSettings extends CommonClass { QuicStreamSettings.fromJson(json.quicSettings), GrpcStreamSettings.fromJson(json.grpcSettings), HttpUpgradeStreamSettings.fromJson(json.httpupgradeSettings), + SplitHTTPStreamSettings.fromJson(json.splithttpSettings), SockoptStreamSettings.fromJson(json.sockopt), ); } @@ -468,6 +491,7 @@ class StreamSettings extends CommonClass { quicSettings: network === 'quic' ? this.quic.toJson() : undefined, grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined, httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined, + splithttpSettings: network === 'splithttp' ? this.splithttp.toJson() : undefined, sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined, }; } @@ -532,7 +556,7 @@ class Outbound extends CommonClass { canEnableTls() { if (![Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks].includes(this.protocol)) return false; - return ["tcp", "ws", "http", "quic", "grpc", "httpupgrade"].includes(this.stream.network); + return ["tcp", "ws", "http", "quic", "grpc", "httpupgrade" , "splithttp"].includes(this.stream.network); } //this is used for xtls-rprx-vision @@ -653,6 +677,8 @@ class Outbound extends CommonClass { stream.grpc = new GrpcStreamSettings(json.path, json.authority, json.type == 'multi'); } else if (network === 'httpupgrade') { stream.httpupgrade = new HttpUpgradeStreamSettings(json.path,json.host); + } else if (network === 'splithttp') { + stream.splithttp = new SplitHTTPStreamSettings(json.path,json.host); } if(json.tls && json.tls == 'tls'){ @@ -700,6 +726,8 @@ class Outbound extends CommonClass { url.searchParams.get('mode') == 'multi'); } else if (type === 'httpupgrade') { stream.httpupgrade = new HttpUpgradeStreamSettings(path,host); + } else if (type === 'splithttp') { + stream.splithttp = new SplitHTTPStreamSettings(path,host); } if(security == 'tls'){ @@ -1056,6 +1084,7 @@ Outbound.WireguardSettings = class extends CommonClass { super(); this.mtu = mtu; this.secretKey = secretKey; + this.pubKey = secretKey.length>0 ? Wireguard.generateKeypair(secretKey).publicKey : ''; this.address = address instanceof Array ? address.join(',') : address; this.workers = workers; this.domainStrategy = domainStrategy; diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js index 12dadd73..fc454bc2 100644 --- a/web/assets/js/model/xray.js +++ b/web/assets/js/model/xray.js @@ -241,15 +241,6 @@ TcpStreamSettings.TcpRequest = class extends XrayCommonClass { this.headers.push({ name: name, value: value }); } - getHeader(name) { - for (const header of this.headers) { - if (header.name.toLowerCase() === name.toLowerCase()) { - return header.value; - } - } - return null; - } - removeHeader(index) { this.headers.splice(index, 1); } @@ -379,15 +370,6 @@ class WsStreamSettings extends XrayCommonClass { this.headers.push({ name: name, value: value }); } - getHeader(name) { - for (const header of this.headers) { - if (header.name.toLowerCase() === name.toLowerCase()) { - return header.value; - } - } - return null; - } - removeHeader(index) { this.headers.splice(index, 1); } @@ -517,15 +499,6 @@ class HTTPUpgradeStreamSettings extends XrayCommonClass { this.headers.push({ name: name, value: value }); } - getHeader(name) { - for (const header of this.headers) { - if (header.name.toLowerCase() === name.toLowerCase()) { - return header.value; - } - } - return null; - } - removeHeader(index) { this.headers.splice(index, 1); } @@ -549,6 +522,45 @@ class HTTPUpgradeStreamSettings extends XrayCommonClass { } } +class SplitHTTPStreamSettings extends XrayCommonClass { + constructor(path='/', host='', headers=[] , maxUploadSize= 1, maxConcurrentUploads= 10) { + super(); + this.path = path; + this.host = host; + this.headers = headers; + this.maxUploadSize = maxUploadSize; + this.maxConcurrentUploads = maxConcurrentUploads; + } + + addHeader(name, value) { + this.headers.push({ name: name, value: value }); + } + + removeHeader(index) { + this.headers.splice(index, 1); + } + + static fromJson(json={}) { + return new SplitHTTPStreamSettings( + json.path, + json.host, + XrayCommonClass.toHeaders(json.headers), + json.maxUploadSize, + json.maxConcurrentUploads, + ); + } + + toJson() { + return { + path: this.path, + host: this.host, + headers: XrayCommonClass.toV2Headers(this.headers, false), + maxUploadSize: this.maxUploadSize, + maxConcurrentUploads: this.maxConcurrentUploads, + }; + } +} + class TlsStreamSettings extends XrayCommonClass { constructor(serverName='', minVersion = TLS_VERSION_OPTION.TLS12, @@ -1001,6 +1013,7 @@ class StreamSettings extends XrayCommonClass { quicSettings=new QuicStreamSettings(), grpcSettings=new GrpcStreamSettings(), httpupgradeSettings=new HTTPUpgradeStreamSettings(), + splithttpSettings=new SplitHTTPStreamSettings(), sockopt = undefined, ) { super(); @@ -1017,6 +1030,7 @@ class StreamSettings extends XrayCommonClass { this.quic = quicSettings; this.grpc = grpcSettings; this.httpupgrade = httpupgradeSettings; + this.splithttp = splithttpSettings; this.sockopt = sockopt; } @@ -1080,6 +1094,7 @@ class StreamSettings extends XrayCommonClass { QuicStreamSettings.fromJson(json.quicSettings), GrpcStreamSettings.fromJson(json.grpcSettings), HTTPUpgradeStreamSettings.fromJson(json.httpupgradeSettings), + SplitHTTPStreamSettings.fromJson(json.splithttpSettings), SockoptStreamSettings.fromJson(json.sockopt), ); } @@ -1100,6 +1115,7 @@ class StreamSettings extends XrayCommonClass { quicSettings: network === 'quic' ? this.quic.toJson() : undefined, grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined, httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined, + splithttpSettings: network === 'splithttp' ? this.splithttp.toJson() : undefined, sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined, }; } @@ -1228,6 +1244,10 @@ class Inbound extends XrayCommonClass { return this.network === "httpupgrade"; } + get isSplithttp() { + return this.network === "splithttp"; + } + // Shadowsocks get method() { switch (this.protocol) { @@ -1251,25 +1271,26 @@ class Inbound extends XrayCommonClass { return ""; } + getHeader(obj, name) { + for (const header of obj.headers) { + if (header.name.toLowerCase() === name.toLowerCase()) { + return header.value; + } + } + return ""; + } + get host() { if (this.isTcp) { - return this.stream.tcp.request.getHeader("Host"); + return this.getHeader(this.stream.tcp.request, 'host'); } else if (this.isWs) { - const hostHeader = this.stream.ws.getHeader("Host"); - if (hostHeader !== null) { - return hostHeader; - } else { - return this.stream.ws.host; - } + return this.stream.ws.host?.length>0 ? this.stream.ws.host : this.getHeader(this.stream.ws, 'host'); } else if (this.isH2) { return this.stream.http.host[0]; } else if (this.isHttpupgrade) { - const hostHeader = this.stream.httpupgrade.getHeader("Host"); - if (hostHeader !== null) { - return hostHeader; - } else { - return this.stream.httpupgrade.host; - } + return this.stream.httpupgrade.host?.length>0 ? this.stream.httpupgrade.host : this.getHeader(this.stream.httpupgrade, 'host'); + } else if (this.isSplithttp) { + return this.stream.splithttp.host?.length>0 ? this.stream.splithttp.host : this.getHeader(this.stream.splithttp, 'host'); } return null; } @@ -1283,6 +1304,8 @@ class Inbound extends XrayCommonClass { return this.stream.http.path; } else if (this.isHttpupgrade) { return this.stream.httpupgrade.path; + } else if (this.isSplithttp) { + return this.stream.splithttp.path; } return null; } @@ -1318,7 +1341,7 @@ class Inbound extends XrayCommonClass { canEnableTls() { if(![Protocols.VMESS, Protocols.VLESS, Protocols.TROJAN, Protocols.SHADOWSOCKS].includes(this.protocol)) return false; - return ["tcp", "ws", "http", "quic", "grpc", "httpupgrade"].includes(this.network); + return ["tcp", "ws", "http", "quic", "grpc", "httpupgrade" , "splithttp"].includes(this.network); } //this is used for xtls-rprx-vision @@ -1368,30 +1391,24 @@ class Inbound extends XrayCommonClass { type: 'none', tls: security, }; - let network = this.stream.network; + const network = this.stream.network; if (network === 'tcp') { - let tcp = this.stream.tcp; + const tcp = this.stream.tcp; obj.type = tcp.type; if (tcp.type === 'http') { - let request = tcp.request; + const request = tcp.request; obj.path = request.path.join(','); - let index = request.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (index >= 0) { - obj.host = request.headers[index].value; - } + const host = this.getHeader(request,'host'); + if (host) obj.host = host; } } else if (network === 'kcp') { - let kcp = this.stream.kcp; + const kcp = this.stream.kcp; obj.type = kcp.type; obj.path = kcp.seed; } else if (network === 'ws') { - let ws = this.stream.ws; + const ws = this.stream.ws; obj.path = ws.path; - obj.host = ws.host; - let index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (index >= 0) { - obj.host = ws.headers[index].value; - } + obj.host = ws.host?.length>0 ? ws.host : this.getHeader(ws, 'host'); } else if (network === 'http') { obj.net = 'h2'; obj.path = this.stream.http.path; @@ -1407,13 +1424,13 @@ class Inbound extends XrayCommonClass { obj.type = 'multi' } } else if (network === 'httpupgrade') { - let httpupgrade = this.stream.httpupgrade; + const httpupgrade = this.stream.httpupgrade; obj.path = httpupgrade.path; - obj.host = httpupgrade.host; - let index = httpupgrade.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (index >= 0) { - obj.host = httpupgrade.headers[index].value; - } + obj.host = httpupgrade.host?.length>0 ? httpupgrade.host : this.getHeader(httpupgrade, 'host'); + } else if (network === 'splithttp') { + const splithttp = this.stream.splithttp; + obj.path = splithttp.path; + obj.host = splithttp.host?.length>0 ? splithttp.host : this.getHeader(splithttp, 'host'); } if (security === 'tls') { @@ -1446,9 +1463,9 @@ class Inbound extends XrayCommonClass { if (tcp.type === 'http') { const request = tcp.request; params.set("path", request.path.join(',')); - const tcpIndex = request.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (tcpIndex >= 0) { - const host = request.headers[tcpIndex].value; + const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host'); + if (index >= 0) { + const host = request.headers[index].value; params.set("host", host); } params.set("headerType", 'http'); @@ -1462,12 +1479,7 @@ class Inbound extends XrayCommonClass { case "ws": const ws = this.stream.ws; params.set("path", ws.path); - params.set("host", ws.host); - const wsIndex = ws.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (wsIndex >= 0) { - const host = ws.headers[wsIndex].value; - params.set("host", host); - } + params.set("host", ws.host?.length>0 ? ws.host : this.getHeader(ws, 'host')); break; case "http": const http = this.stream.http; @@ -1489,14 +1501,14 @@ class Inbound extends XrayCommonClass { } break; case "httpupgrade": - const httpupgrade = this.stream.httpupgrade; - params.set("path", httpupgrade.path); - params.set("host", httpupgrade.host); - const httpupgradeIndex = httpupgrade.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (httpupgradeIndex >= 0) { - const host = httpupgrade.headers[httpupgradeIndex].value; - params.set("host", host); - } + const httpupgrade = this.stream.httpupgrade; + params.set("path", httpupgrade.path); + params.set("host", httpupgrade.host?.length>0 ? httpupgrade.host : this.getHeader(httpupgrade, 'host')); + break; + case "splithttp": + const splithttp = this.stream.splithttp; + params.set("path", splithttp.path); + params.set("host", splithttp.host?.length>0 ? splithttp.host : this.getHeader(splithttp, 'host')); break; } @@ -1572,9 +1584,9 @@ class Inbound extends XrayCommonClass { if (tcp.type === 'http') { const request = tcp.request; params.set("path", request.path.join(',')); - const tcpIndex = request.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (tcpIndex >= 0) { - const host = request.headers[tcpIndex].value; + const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host'); + if (index >= 0) { + const host = request.headers[index].value; params.set("host", host); } params.set("headerType", 'http'); @@ -1588,12 +1600,7 @@ class Inbound extends XrayCommonClass { case "ws": const ws = this.stream.ws; params.set("path", ws.path); - params.set("host", ws.host); - const wsIndex = ws.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (wsIndex >= 0) { - const host = ws.headers[wsIndex].value; - params.set("host", host); - } + params.set("host", ws.host?.length>0 ? ws.host : this.getHeader(ws, 'host')); break; case "http": const http = this.stream.http; @@ -1615,14 +1622,14 @@ class Inbound extends XrayCommonClass { } break; case "httpupgrade": - const httpupgrade = this.stream.httpupgrade; - params.set("path", httpupgrade.path); - params.set("host", httpupgrade.host); - const httpupgradeIndex = httpupgrade.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (httpupgradeIndex >= 0) { - const host = httpupgrade.headers[httpupgradeIndex].value; - params.set("host", host); - } + const httpupgrade = this.stream.httpupgrade; + params.set("path", httpupgrade.path); + params.set("host", httpupgrade.host?.length>0 ? httpupgrade.host : this.getHeader(httpupgrade, 'host')); + break; + case "splithttp": + const splithttp = this.stream.splithttp; + params.set("path", splithttp.path); + params.set("host", splithttp.host?.length>0 ? splithttp.host : this.getHeader(splithttp, 'host')); break; } @@ -1665,9 +1672,9 @@ class Inbound extends XrayCommonClass { if (tcp.type === 'http') { const request = tcp.request; params.set("path", request.path.join(',')); - const tcpIndex = request.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (tcpIndex >= 0) { - const host = request.headers[tcpIndex].value; + const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host'); + if (index >= 0) { + const host = request.headers[index].value; params.set("host", host); } params.set("headerType", 'http'); @@ -1681,12 +1688,7 @@ class Inbound extends XrayCommonClass { case "ws": const ws = this.stream.ws; params.set("path", ws.path); - params.set("host", ws.host); - const wsIndex = ws.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (wsIndex >= 0) { - const host = ws.headers[wsIndex].value; - params.set("host", host); - } + params.set("host", ws.host?.length>0 ? ws.host : this.getHeader(ws, 'host')); break; case "http": const http = this.stream.http; @@ -1708,14 +1710,14 @@ class Inbound extends XrayCommonClass { } break; case "httpupgrade": - const httpupgrade = this.stream.httpupgrade; - params.set("path", httpupgrade.path); - params.set("host", httpupgrade.host); - const httpUpgradeIndex = httpupgrade.headers.findIndex(header => header.name.toLowerCase() === 'host'); - if (httpUpgradeIndex >= 0) { - const host = httpupgrade.headers[httpUpgradeIndex].value; - params.set("host", host); - } + const httpupgrade = this.stream.httpupgrade; + params.set("path", httpupgrade.path); + params.set("host", httpupgrade.host?.length>0 ? httpupgrade.host : this.getHeader(httpupgrade, 'host')); + break; + case "splithttp": + const splithttp = this.stream.splithttp; + params.set("path", splithttp.path); + params.set("host", splithttp.host?.length>0 ? splithttp.host : this.getHeader(splithttp, 'host')); break; } diff --git a/web/html/xui/form/outbound.html b/web/html/xui/form/outbound.html index f59dc379..516a586c 100644 --- a/web/html/xui/form/outbound.html +++ b/web/html/xui/form/outbound.html @@ -83,9 +83,23 @@ - + + - + + + + [[ wds ]] @@ -213,14 +227,13 @@ QUIC gRPC HTTPUpgrade + SplitHTTP + + + + + + + + +