From 30dfb9cb6551497ca107f778dd2d0448dc18d919 Mon Sep 17 00:00:00 2001 From: Toby Chui Date: Mon, 30 Dec 2024 21:41:15 +0800 Subject: [PATCH] Added new UI feature - Added toggle for uptime monitor - Added toggle for enable custom header passthrough to websocket --- src/api.go | 1 + src/def.go | 2 +- src/reverseproxy.go | 43 +++++++++++++++++++++++++++ src/web/components/httprp.html | 15 +++++++++- src/web/snippet/customHeaders.html | 47 ++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src/api.go b/src/api.go index 2ea57fd..4e266eb 100644 --- a/src/api.go +++ b/src/api.go @@ -59,6 +59,7 @@ func RegisterHTTPProxyAPIs(authRouter *auth.RouterDef) { authRouter.HandleFunc("/api/proxy/header/handleHopByHop", HandleHopByHop) authRouter.HandleFunc("/api/proxy/header/handleHostOverwrite", HandleHostOverwrite) authRouter.HandleFunc("/api/proxy/header/handlePermissionPolicy", HandlePermissionPolicy) + authRouter.HandleFunc("/api/proxy/header/handleWsHeaderBehavior", HandleWsHeaderBehavior) /* Reverse proxy auth related */ authRouter.HandleFunc("/api/proxy/auth/exceptions/list", ListProxyBasicAuthExceptionPaths) authRouter.HandleFunc("/api/proxy/auth/exceptions/add", AddProxyBasicAuthExceptionPaths) diff --git a/src/def.go b/src/def.go index acb7bdd..b484945 100644 --- a/src/def.go +++ b/src/def.go @@ -42,7 +42,7 @@ import ( const ( /* Build Constants */ SYSTEM_NAME = "Zoraxy" - SYSTEM_VERSION = "3.1.5" + SYSTEM_VERSION = "3.1.6" DEVELOPMENT_BUILD = false /* Development: Set to false to use embedded web fs */ /* System Constants */ diff --git a/src/reverseproxy.go b/src/reverseproxy.go index cde2328..159d38f 100644 --- a/src/reverseproxy.go +++ b/src/reverseproxy.go @@ -467,6 +467,12 @@ func ReverseProxyHandleEditEndpoint(w http.ResponseWriter, r *http.Request) { } bypassGlobalTLS := (bpgtls == "true") + //Disable uptime monitor + disbleUtm, err := utils.PostBool(r, "dutm") + if err != nil { + disbleUtm = false + } + // Auth Provider authProviderTypeStr, _ := utils.PostPara(r, "authprovider") if authProviderTypeStr == "" { @@ -532,6 +538,7 @@ func ReverseProxyHandleEditEndpoint(w http.ResponseWriter, r *http.Request) { newProxyEndpoint.RequireRateLimit = requireRateLimit newProxyEndpoint.RateLimit = proxyRateLimit newProxyEndpoint.UseStickySession = useStickySession + newProxyEndpoint.DisableUptimeMonitor = disbleUtm //Prepare to replace the current routing rule readyRoutingRule, err := dynamicProxyRouter.PrepareProxyRoute(newProxyEndpoint) @@ -1553,3 +1560,39 @@ func HandlePermissionPolicy(w http.ResponseWriter, r *http.Request) { http.Error(w, "405 - Method not allowed", http.StatusMethodNotAllowed) } + +func HandleWsHeaderBehavior(w http.ResponseWriter, r *http.Request) { + domain, err := utils.PostPara(r, "domain") + if err != nil { + domain, err = utils.GetPara(r, "domain") + if err != nil { + utils.SendErrorResponse(w, "domain or matching rule not defined") + return + } + } + + targetProxyEndpoint, err := dynamicProxyRouter.LoadProxy(domain) + if err != nil { + utils.SendErrorResponse(w, "target endpoint not exists") + return + } + + if r.Method == http.MethodGet { + js, _ := json.Marshal(targetProxyEndpoint.EnableWebsocketCustomHeaders) + utils.SendJSONResponse(w, string(js)) + } else if r.Method == http.MethodPost { + enableWsHeader, err := utils.PostBool(r, "enable") + if err != nil { + utils.SendErrorResponse(w, "invalid enable state given") + return + } + + targetProxyEndpoint.EnableWebsocketCustomHeaders = enableWsHeader + SaveReverseProxyConfig(targetProxyEndpoint) + targetProxyEndpoint.UpdateToRuntime() + utils.SendOK(w) + + } else { + http.Error(w, "405 - Method not allowed", http.StatusMethodNotAllowed) + } +} diff --git a/src/web/components/httprp.html b/src/web/components/httprp.html index 1c61b37..8ecd402 100644 --- a/src/web/components/httprp.html +++ b/src/web/components/httprp.html @@ -258,6 +258,13 @@ if (payload.UseStickySession){ useStickySessionChecked = "checked"; } + + let enableUptimeMonitor = ""; + //Note the config file store the uptime monitor as disable, so we need to reverse the logic + if (!payload.DisableUptimeMonitor){ + enableUptimeMonitor = "checked"; + } + input = `
@@ -265,7 +272,11 @@
- +
+ + +
`; column.append(input); $(column).find(".upstreamList").addClass("editing"); @@ -441,6 +452,7 @@ var epttype = "host"; let useStickySession = $(row).find(".UseStickySession")[0].checked; + let DisableUptimeMonitor = !$(row).find(".EnableUptimeMonitor")[0].checked; let authProviderType = $(row).find(".authProviderPicker input[type='radio']:checked").val(); let requireRateLimit = $(row).find(".RequireRateLimit")[0].checked; let rateLimit = $(row).find(".RateLimit").val(); @@ -453,6 +465,7 @@ "type": epttype, "rootname": uuid, "ss":useStickySession, + "dutm": DisableUptimeMonitor, "bpgtls": bypassGlobalTLS, "authprovider" :authProviderType, "rate" :requireRateLimit, diff --git a/src/web/snippet/customHeaders.html b/src/web/snippet/customHeaders.html index b285ea5..e7fcd4b 100644 --- a/src/web/snippet/customHeaders.html +++ b/src/web/snippet/customHeaders.html @@ -117,6 +117,16 @@ + +
+

WebSocket Custom Headers

+

Copy custom headers from HTTP requests to WebSocket connections. + Might be required by some projects like MeshCentral.

+
+ + +

Settings in this section are for advanced users. Invalid settings might cause werid, unexpected behavior.

@@ -597,6 +607,7 @@ }) } + /* Manual Hostname overwrite */ function initManualHostOverwriteValue(){ $.get("/api/proxy/header/handleHostOverwrite?domain=" + editingEndpoint.ep, function(data){ if (data.error != undefined){ @@ -643,6 +654,42 @@ }) } initHopByHopRemoverState(); + + /* WebSocket Custom Headers */ + function initWebSocketCustomHeaderState(){ + $.get("/api/proxy/header/handleWsHeaderBehavior?domain=" + editingEndpoint.ep, function(data){ + if (data.error != undefined){ + parent.msgbox(data.error); + }else{ + if (data == true){ + $("#copyCustomHeadersWS").parent().checkbox("set checked"); + }else{ + $("#copyCustomHeadersWS").parent().checkbox("set unchecked"); + } + + //Bind event to the checkbox + $("#copyCustomHeadersWS").on("change", function(evt){ + let isChecked = $(this)[0].checked; + $.cjax({ + url: "/api/proxy/header/handleWsHeaderBehavior", + method: "POST", + data: { + "domain": editingEndpoint.ep, + "enable": isChecked, + }, + success: function(data){ + if (data.error != undefined){ + parent.msgbox(data.error, false); + }else{ + parent.msgbox("WebSocket Custom Header rule updated"); + } + } + }) + }) + } + }) + } + initWebSocketCustomHeaderState(); \ No newline at end of file