diff options
| -rw-r--r-- | sub/subJsonService.go | 2 | ||||
| -rw-r--r-- | sub/subService.go | 16 | ||||
| -rw-r--r-- | web/assets/js/model/outbound.js | 32 | ||||
| -rw-r--r-- | web/assets/js/model/xray.js | 57 | ||||
| -rw-r--r-- | web/html/xui/form/outbound.html | 64 | ||||
| -rw-r--r-- | web/html/xui/form/stream/stream_httpupgrade.html | 13 | ||||
| -rw-r--r-- | web/html/xui/form/stream/stream_settings.html | 9 | ||||
| -rw-r--r-- | web/html/xui/inbound_info_modal.html | 2 |
8 files changed, 164 insertions, 31 deletions
diff --git a/sub/subJsonService.go b/sub/subJsonService.go index 9320306e..de4be680 100644 --- a/sub/subJsonService.go +++ b/sub/subJsonService.go @@ -200,6 +200,8 @@ func (s *SubJsonService) streamData(stream string) map[string]interface{} { streamSettings["tcpSettings"] = s.removeAcceptProxy(streamSettings["tcpSettings"]) case "ws": streamSettings["wsSettings"] = s.removeAcceptProxy(streamSettings["wsSettings"]) + case "httpupgrade": + streamSettings["httpupgradeSettings"] = s.removeAcceptProxy(streamSettings["httpupgradeSettings"]) } return streamSettings diff --git a/sub/subService.go b/sub/subService.go index 5363149a..8aa9b026 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -216,6 +216,10 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string { if grpc["multiMode"].(bool) { obj["type"] = "multi" } + case "httpupgrade": + httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{}) + obj["path"] = httpupgrade["path"].(string) + obj["host"] = httpupgrade["host"].(string) } security, _ := stream["security"].(string) @@ -350,6 +354,10 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string { if grpc["multiMode"].(bool) { params["mode"] = "multi" } + case "httpupgrade": + httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{}) + params["path"] = httpupgrade["path"].(string) + params["host"] = httpupgrade["host"].(string) } security, _ := stream["security"].(string) @@ -566,6 +574,10 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string if grpc["multiMode"].(bool) { params["mode"] = "multi" } + case "httpupgrade": + httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{}) + params["path"] = httpupgrade["path"].(string) + params["host"] = httpupgrade["host"].(string) } security, _ := stream["security"].(string) @@ -783,6 +795,10 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st if grpc["multiMode"].(bool) { params["mode"] = "multi" } + case "httpupgrade": + httpupgrade, _ := stream["httpupgradeSettings"].(map[string]interface{}) + params["path"] = httpupgrade["path"].(string) + params["host"] = httpupgrade["host"].(string) } security, _ := stream["security"].(string) diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js index 05248b77..c5b0348b 100644 --- a/web/assets/js/model/outbound.js +++ b/web/assets/js/model/outbound.js @@ -268,6 +268,28 @@ class GrpcStreamSettings extends CommonClass { } } +class HttpUpgradeStreamSettings extends CommonClass { + constructor(path='/', host='') { + super(); + this.path = path; + this.host = host; + } + + static fromJson(json={}) { + return new HttpUpgradeStreamSettings( + json.path, + json.Host, + ); + } + + toJson() { + return { + path: this.path, + host: this.host, + }; + } +} + class TlsStreamSettings extends CommonClass { constructor(serverName='', alpn=[], @@ -339,6 +361,7 @@ class StreamSettings extends CommonClass { httpSettings=new HttpStreamSettings(), quicSettings=new QuicStreamSettings(), grpcSettings=new GrpcStreamSettings(), + httpupgradeSettings=new HttpUpgradeStreamSettings(), ) { super(); this.network = network; @@ -351,6 +374,7 @@ class StreamSettings extends CommonClass { this.http = httpSettings; this.quic = quicSettings; this.grpc = grpcSettings; + this.httpupgrade = httpupgradeSettings; } get isTls() { @@ -373,6 +397,7 @@ class StreamSettings extends CommonClass { HttpStreamSettings.fromJson(json.httpSettings), QuicStreamSettings.fromJson(json.quicSettings), GrpcStreamSettings.fromJson(json.grpcSettings), + HttpUpgradeStreamSettings.fromJson(json.httpupgradeSettings), ); } @@ -389,6 +414,7 @@ class StreamSettings extends CommonClass { httpSettings: network === 'http' ? this.http.toJson() : undefined, quicSettings: network === 'quic' ? this.quic.toJson() : undefined, grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined, + httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined, }; } } @@ -419,7 +445,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"].includes(this.stream.network); + return ["tcp", "ws", "http", "quic", "grpc", "httpupgrade"].includes(this.stream.network); } //this is used for xtls-rprx-vision @@ -523,6 +549,8 @@ class Outbound extends CommonClass { json.type ? json.type : 'none'); } else if (network === 'grpc') { stream.grpc = new GrpcStreamSettings(json.path, json.type == 'multi'); + } else if (network === 'httpupgrade') { + stream.httpupgrade = new HttpUpgradeStreamSettings(json.path,json.host); } if(json.tls && json.tls == 'tls'){ @@ -564,6 +592,8 @@ class Outbound extends CommonClass { headerType ?? 'none'); } else if (type === 'grpc') { stream.grpc = new GrpcStreamSettings(url.searchParams.get('serviceName') ?? '', url.searchParams.get('mode') == 'multi'); + } else if (type === 'httpupgrade') { + stream.httpupgrade = new HttpUpgradeStreamSettings(path,host); } if(security == 'tls'){ diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js index 791e8533..c8a4184c 100644 --- a/web/assets/js/model/xray.js +++ b/web/assets/js/model/xray.js @@ -468,6 +468,30 @@ class GrpcStreamSettings extends XrayCommonClass { } } +class HttpUpgradeStreamSettings extends XrayCommonClass { + constructor(acceptProxyProtocol=false, path='/', host='') { + super(); + this.acceptProxyProtocol = acceptProxyProtocol; + this.path = path; + this.host = host; + } + + static fromJson(json={}) { + return new HttpUpgradeStreamSettings( + json.acceptProxyProtocol, + json.path, + json.host, + ); + } + + toJson() { + return { + acceptProxyProtocol: this.acceptProxyProtocol, + path: this.path, + host: this.host, + }; + } +} class TlsStreamSettings extends XrayCommonClass { constructor(serverName='', @@ -833,6 +857,7 @@ class StreamSettings extends XrayCommonClass { httpSettings=new HttpStreamSettings(), quicSettings=new QuicStreamSettings(), grpcSettings=new GrpcStreamSettings(), + httpupgradeSettings=new HttpUpgradeStreamSettings(), sockopt = undefined, ) { super(); @@ -848,6 +873,7 @@ class StreamSettings extends XrayCommonClass { this.http = httpSettings; this.quic = quicSettings; this.grpc = grpcSettings; + this.httpupgrade = httpupgradeSettings; this.sockopt = sockopt; } @@ -910,6 +936,7 @@ class StreamSettings extends XrayCommonClass { HttpStreamSettings.fromJson(json.httpSettings), QuicStreamSettings.fromJson(json.quicSettings), GrpcStreamSettings.fromJson(json.grpcSettings), + HttpUpgradeStreamSettings.fromJson(json.httpupgradeSettings), SockoptStreamSettings.fromJson(json.sockopt), ); } @@ -929,6 +956,7 @@ class StreamSettings extends XrayCommonClass { httpSettings: network === 'http' ? this.http.toJson() : undefined, quicSettings: network === 'quic' ? this.quic.toJson() : undefined, grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined, + httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined, sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined, }; } @@ -1045,6 +1073,10 @@ class Inbound extends XrayCommonClass { return this.network === "http"; } + get isHttpupgrade() { + return this.network === "httpupgrade"; + } + // Shadowsocks get method() { switch (this.protocol) { @@ -1075,6 +1107,8 @@ class Inbound extends XrayCommonClass { return this.stream.ws.getHeader("Host"); } else if (this.isH2) { return this.stream.http.host[0]; + } else if (this.isHttpupgrade) { + return this.stream.httpupgrade.host; } return null; } @@ -1086,6 +1120,8 @@ class Inbound extends XrayCommonClass { return this.stream.ws.path; } else if (this.isH2) { return this.stream.http.path; + } else if (this.isHttpupgrade) { + return this.stream.httpupgrade.path; } return null; } @@ -1121,7 +1157,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"].includes(this.network); + return ["tcp", "ws", "http", "quic", "grpc", "httpupgrade"].includes(this.network); } //this is used for xtls-rprx-vision @@ -1207,6 +1243,10 @@ class Inbound extends XrayCommonClass { if (this.stream.grpc.multiMode){ obj.type = 'multi' } + } else if (network === 'httpupgrade') { + let httpupgrade = this.stream.httpupgrade; + obj.path = httpupgrade.path; + obj.host = httpupgrade.host; } if (security === 'tls') { @@ -1279,6 +1319,11 @@ class Inbound extends XrayCommonClass { params.set("mode", "multi"); } break; + case "httpupgrade": + const httpupgrade = this.stream.httpupgrade; + params.set("path", httpupgrade.path); + params.set("host", httpupgrade.host); + break; } if (security === 'tls') { @@ -1393,6 +1438,11 @@ class Inbound extends XrayCommonClass { params.set("mode", "multi"); } break; + case "httpupgrade": + const httpupgrade = this.stream.httpupgrade; + params.set("path", httpupgrade.path); + params.set("host", httpupgrade.host); + break; } if (security === 'tls') { @@ -1474,6 +1524,11 @@ class Inbound extends XrayCommonClass { params.set("mode", "multi"); } break; + case "httpupgrade": + const httpupgrade = this.stream.httpupgrade; + params.set("path", httpupgrade.path); + params.set("host", httpupgrade.host); + break; } if (security === 'tls') { diff --git a/web/html/xui/form/outbound.html b/web/html/xui/form/outbound.html index 469c42b9..b6874240 100644 --- a/web/html/xui/form/outbound.html +++ b/web/html/xui/form/outbound.html @@ -214,34 +214,34 @@ <!-- stream settings --> <template v-if="outbound.canEnableStream()"> - <a-form-item label='{{ i18n "transmission" }}'> - <a-select v-model="outbound.stream.network" @change="streamNetworkChange" - :dropdown-class-name="themeSwitcher.currentTheme"> - <a-select-option value="tcp">TCP</a-select-option> - <a-select-option value="kcp">mKCP</a-select-option> - <a-select-option value="ws">WS</a-select-option> - <a-select-option value="http">H2</a-select-option> - <a-select-option value="quic">QUIC</a-select-option> - <a-select-option value="grpc">gRPC</a-select-option> - </a-select> - </a-form-item> + <a-form-item label='{{ i18n "transmission" }}'> + <a-select v-model="outbound.stream.network" @change="streamNetworkChange" + :dropdown-class-name="themeSwitcher.currentTheme"> + <a-select-option value="tcp">TCP</a-select-option> + <a-select-option value="kcp">mKCP</a-select-option> + <a-select-option value="ws">WS</a-select-option> + <a-select-option value="http">H2</a-select-option> + <a-select-option value="quic">QUIC</a-select-option> + <a-select-option value="grpc">gRPC</a-select-option> + <a-select-option value="httpupgrade">HttpUpgrade</a-select-option> + </a-select> + </a-form-item> <template v-if="outbound.stream.network === 'tcp'"> <a-form-item label='HTTP {{ i18n "camouflage" }}'> - <a-switch - :checked="outbound.stream.tcp.type === 'http'" + <a-switch :checked="outbound.stream.tcp.type === 'http'" @change="checked => outbound.stream.tcp.type = checked ? 'http' : 'none'"> </a-switch> </a-form-item> <template v-if="outbound.stream.tcp.type == 'http'"> - <a-form-item label='{{ i18n "host" }}'> - <a-input v-model.trim="outbound.stream.tcp.host"></a-input> - </a-form-item> - <a-form-item label='{{ i18n "path" }}'> - <a-input v-model.trim="outbound.stream.tcp.path"></a-input> - </a-form-item> + <a-form-item label='{{ i18n "host" }}'> + <a-input v-model.trim="outbound.stream.tcp.host"></a-input> + </a-form-item> + <a-form-item label='{{ i18n "path" }}'> + <a-input v-model.trim="outbound.stream.tcp.path"></a-input> + </a-form-item> </template> </template> - + <!-- kcp --> <template v-if="outbound.stream.network === 'kcp'"> <a-form-item label='{{ i18n "camouflage" }}'> @@ -265,7 +265,7 @@ </a-form-item> <a-form-item label='Uplink (MB/s)'> <a-input-number v-model.number="outbound.stream.kcp.upCap"></a-input-number> - </a-form-item> + </a-form-item> <a-form-item label='Downlink (MB/s)'> <a-input-number v-model.number="outbound.stream.kcp.downCap"></a-input-number> </a-form-item> @@ -279,7 +279,7 @@ <a-input-number v-model.number="outbound.stream.kcp.writeBuffer"></a-input-number> </a-form-item> </template> - + <!-- ws --> <template v-if="outbound.stream.network === 'ws'"> <a-form-item label='{{ i18n "host" }}'> @@ -287,9 +287,9 @@ </a-form-item> <a-form-item label='{{ i18n "path" }}'> <a-form-item><a-input v-model.trim="outbound.stream.ws.path"></a-input> - </a-form-item> + </a-form-item> </template> - + <!-- http --> <template v-if="outbound.stream.network === 'http'"> <a-form-item label='{{ i18n "host" }}'> @@ -299,7 +299,7 @@ <a-input v-model.trim="outbound.stream.http.path"></a-input> </a-form-item> </template> - + <!-- quic --> <template v-if="outbound.stream.network === 'quic'"> <a-form-item label='{{ i18n "pages.inbounds.stream.quic.encryption" }}'> @@ -311,7 +311,7 @@ </a-form-item> <a-form-item label='{{ i18n "password" }}'> <a-input v-model.trim="outbound.stream.quic.key"></a-input> - </a-form-item> + </a-form-item> <a-form-item label='{{ i18n "camouflage" }}'> <a-select v-model="outbound.stream.quic.type" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select-option value="none">None</a-select-option> @@ -323,7 +323,7 @@ </a-select> </a-form-item> </template> - + <!-- grpc --> <template v-if="outbound.stream.network === 'grpc'"> <a-form-item label='Service Name'> @@ -333,6 +333,16 @@ <a-switch v-model="outbound.stream.grpc.multiMode"></a-switch> </a-form-item> </template> + + <!-- httpupgrade --> + <template v-if="outbound.stream.network === 'httpupgrade'"> + <a-form-item label='{{ i18n "host" }}'> + <a-input v-model="outbound.stream.httpupgrade.host"></a-input> + </a-form-item> + <a-form-item label='{{ i18n "path" }}'> + <a-form-item><a-input v-model.trim="outbound.stream.httpupgrade.path"></a-input> + </a-form-item> + </template> </template> <!-- tls settings --> diff --git a/web/html/xui/form/stream/stream_httpupgrade.html b/web/html/xui/form/stream/stream_httpupgrade.html new file mode 100644 index 00000000..73f10b07 --- /dev/null +++ b/web/html/xui/form/stream/stream_httpupgrade.html @@ -0,0 +1,13 @@ +{{define "form/streamHTTPUPGRADE"}} +<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }"> + <a-form-item label="PROXY Protocol"> + <a-switch v-model="inbound.stream.httpupgrade.acceptProxyProtocol"></a-switch> + </a-form-item> + <a-form-item label='{{ i18n "path" }}'> + <a-input v-model.trim="inbound.stream.httpupgrade.path"></a-input> + </a-form-item> + <a-form-item label='{{ i18n "host" }}'> + <a-input v-model.trim="inbound.stream.httpupgrade.host"></a-input> + </a-form-item> +</a-form> +{{end}} diff --git a/web/html/xui/form/stream/stream_settings.html b/web/html/xui/form/stream/stream_settings.html index af81651d..a3cb0362 100644 --- a/web/html/xui/form/stream/stream_settings.html +++ b/web/html/xui/form/stream/stream_settings.html @@ -2,7 +2,7 @@ <!-- select stream network --> <a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }"> <a-form-item label='{{ i18n "transmission" }}'> - <a-select v-model="inbound.stream.network" style="width: 50%" @change="streamNetworkChange" + <a-select v-model="inbound.stream.network" style="width: 75%" @change="streamNetworkChange" :dropdown-class-name="themeSwitcher.currentTheme"> <a-select-option value="tcp">TCP</a-select-option> <a-select-option value="kcp">mKCP</a-select-option> @@ -10,6 +10,7 @@ <a-select-option value="http">H2</a-select-option> <a-select-option value="quic">QUIC</a-select-option> <a-select-option value="grpc">gRPC</a-select-option> + <a-select-option value="httpupgrade">HttpUpgrade</a-select-option> </a-select> </a-form-item> </a-form> @@ -43,6 +44,12 @@ <template v-if="inbound.stream.network === 'grpc'"> {{template "form/streamGRPC"}} </template> + +<!-- httpupgrade --> +<template v-if="inbound.stream.network === 'httpupgrade'"> + {{template "form/streamHTTPUPGRADE"}} +</template> + <!-- sockopt --> <template> {{template "form/streamSockopt"}} diff --git a/web/html/xui/inbound_info_modal.html b/web/html/xui/inbound_info_modal.html index c8341651..e679bbd0 100644 --- a/web/html/xui/inbound_info_modal.html +++ b/web/html/xui/inbound_info_modal.html @@ -25,7 +25,7 @@ <tr> <td>{{ i18n "transmission" }}</td><td><a-tag color="green">[[ inbound.network ]]</a-tag></td> </tr> - <template v-if="inbound.isTcp || inbound.isWs || inbound.isH2"> + <template v-if="inbound.isTcp || inbound.isWs || inbound.isH2 || inbound.isHttpupgrade "> <tr> <td>{{ i18n "host" }}</td> <td v-if="inbound.host"> |
