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 @@
-
+
+
+
+
+ {{ i18n "reset" }}
+
+ {{ i18n "pages.xray.wireguard.secretKey" }}
+
+
+
+
-
+
+
+
+
[[ wds ]]
@@ -213,14 +227,13 @@
QUIC
gRPC
HTTPUpgrade
+ SplitHTTP
-
- outbound.stream.tcp.type = checked ? 'http' : 'none'">
-
-
+
+ outbound.stream.tcp.type = checked ? 'http' : 'none'">
+
@@ -334,9 +347,19 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/html/xui/form/stream/stream_settings.html b/web/html/xui/form/stream/stream_settings.html
index 0d1eaa23..f6fe6f23 100644
--- a/web/html/xui/form/stream/stream_settings.html
+++ b/web/html/xui/form/stream/stream_settings.html
@@ -11,6 +11,7 @@
QUIC
gRPC
HTTPUpgrade
+ SplitHTTP
@@ -50,6 +51,11 @@
{{template "form/streamHTTPUpgrade"}}
+
+
+ {{template "form/streamSplitHTTP"}}
+
+
{{template "form/streamSockopt"}}
diff --git a/web/html/xui/form/stream/stream_splithttp.html b/web/html/xui/form/stream/stream_splithttp.html
new file mode 100644
index 00000000..0dcab965
--- /dev/null
+++ b/web/html/xui/form/stream/stream_splithttp.html
@@ -0,0 +1,29 @@
+{{define "form/streamSplitHTTP"}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [[ index+1 ]]
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+{{end}}
diff --git a/web/html/xui/inbound_info_modal.html b/web/html/xui/inbound_info_modal.html
index b15f1830..a6f34001 100644
--- a/web/html/xui/inbound_info_modal.html
+++ b/web/html/xui/inbound_info_modal.html
@@ -34,7 +34,7 @@
[[ inbound.network ]]
-
+
| {{ i18n "host" }} |
|