From 7f2c11220f2d27ac1ad3fdc343b06dd77edd28f1 Mon Sep 17 00:00:00 2001 From: mhsanaei Date: Tue, 18 Jun 2024 12:49:20 +0200 Subject: new - splithttp transport splithttp inbound splithttp outbound change priority host for ws - httpupgrade (host>>headers) --- web/assets/js/model/outbound.js | 38 ++++++- web/assets/js/model/xray.js | 218 ++++++++++++++++++++-------------------- 2 files changed, 143 insertions(+), 113 deletions(-) (limited to 'web/assets') diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js index 2f2a5ea2..ee954fc1 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 70f4f668..acbe4034 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; } -- cgit v1.2.3