From 7f2c11220f2d27ac1ad3fdc343b06dd77edd28f1 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Tue, 18 Jun 2024 12:49:20 +0200 Subject: [PATCH] new - splithttp transport splithttp inbound splithttp outbound change priority host for ws - httpupgrade (host>>headers) --- sub/subJsonService.go | 3 +- sub/subService.go | 130 ++++++----- web/assets/js/model/outbound.js | 38 ++- web/assets/js/model/xray.js | 218 +++++++++--------- web/html/xui/form/outbound.html | 11 + web/html/xui/form/stream/stream_settings.html | 6 + .../xui/form/stream/stream_splithttp.html | 29 +++ web/html/xui/inbound_info_modal.html | 2 +- 8 files changed, 268 insertions(+), 169 deletions(-) create mode 100644 web/html/xui/form/stream/stream_splithttp.html diff --git a/sub/subJsonService.go b/sub/subJsonService.go index 76d0b1264..7b072b953 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -223,8 +223,9 @@ func (s *SubJsonService) streamData(stream string) map[string]interface{} { streamSettings["wsSettings"] = s.removeAcceptProxy(streamSettings["wsSettings"]) case "httpupgrade": streamSettings["httpupgradeSettings"] = s.removeAcceptProxy(streamSettings["httpupgradeSettings"]) + case "splithttp": + streamSettings["splithttpSettings"] = s.removeAcceptProxy(streamSettings["splithttpSettings"]) } - return streamSettings } diff --git a/sub/subService.go b/sub/subService.go index 3ba0bda75..cc73c6a13 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 2f2a5ea25..ee954fc1f 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'){ diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js index 70f4f6685..acbe4034b 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 @@ -1370,15 +1393,13 @@ class Inbound extends XrayCommonClass { }; let 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; @@ -1387,11 +1408,7 @@ class Inbound extends XrayCommonClass { } else if (network === 'ws') { let 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; @@ -1409,11 +1426,11 @@ class Inbound extends XrayCommonClass { } else if (network === 'httpupgrade') { let 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') { + let 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 c8b08321c..a61f5c447 100644 --- a/web/html/xui/form/outbound.html +++ b/web/html/xui/form/outbound.html @@ -204,6 +204,7 @@ QUIC gRPC HTTPUpgrade + SplitHTTP + + + diff --git a/web/html/xui/form/stream/stream_settings.html b/web/html/xui/form/stream/stream_settings.html index 0d1eaa234..f6fe6f232 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"}} + + +