mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-12-21 14:57:00 +01:00
Add DisableAutoFallback option for proxy endpoints #896
- Added new behavior in upstream random selector (ignore offline check for upstream if there is only one upstream for this proxy rule) - Added config file only DisableAutoFallback option
This commit is contained in:
@@ -47,23 +47,24 @@ func GetDefaultProxyEndpoint() ProxyEndpoint {
|
||||
randomPrefix := uuid.New().String()
|
||||
return ProxyEndpoint{
|
||||
ProxyType: ProxyTypeHost,
|
||||
RootOrMatchingDomain: randomPrefix + ".internal",
|
||||
MatchingDomainAlias: []string{},
|
||||
ActiveOrigins: []*loadbalance.Upstream{},
|
||||
InactiveOrigins: []*loadbalance.Upstream{},
|
||||
UseStickySession: false,
|
||||
UseActiveLoadBalance: false,
|
||||
Disabled: false,
|
||||
BypassGlobalTLS: false,
|
||||
VirtualDirectories: []*VirtualDirectoryEndpoint{},
|
||||
HeaderRewriteRules: GetDefaultHeaderRewriteRules(),
|
||||
EnableWebsocketCustomHeaders: false,
|
||||
AuthenticationProvider: GetDefaultAuthenticationProvider(),
|
||||
RequireRateLimit: false,
|
||||
RateLimit: 0,
|
||||
DisableUptimeMonitor: false,
|
||||
AccessFilterUUID: "default",
|
||||
DefaultSiteOption: DefaultSite_InternalStaticWebServer,
|
||||
DefaultSiteValue: "",
|
||||
}
|
||||
RootOrMatchingDomain: randomPrefix + ".internal",
|
||||
MatchingDomainAlias: []string{},
|
||||
ActiveOrigins: []*loadbalance.Upstream{},
|
||||
InactiveOrigins: []*loadbalance.Upstream{},
|
||||
UseStickySession: false,
|
||||
UseActiveLoadBalance: false,
|
||||
Disabled: false,
|
||||
BypassGlobalTLS: false,
|
||||
VirtualDirectories: []*VirtualDirectoryEndpoint{},
|
||||
HeaderRewriteRules: GetDefaultHeaderRewriteRules(),
|
||||
EnableWebsocketCustomHeaders: false,
|
||||
AuthenticationProvider: GetDefaultAuthenticationProvider(),
|
||||
RequireRateLimit: false,
|
||||
RateLimit: 0,
|
||||
DisableUptimeMonitor: false,
|
||||
DisableAutoFallback: false,
|
||||
AccessFilterUUID: "default",
|
||||
DefaultSiteOption: DefaultSite_InternalStaticWebServer,
|
||||
DefaultSiteValue: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ func (router *Router) StartProxyService() error {
|
||||
}
|
||||
}
|
||||
|
||||
selectedUpstream, err := router.loadBalancer.GetRequestUpstreamTarget(w, r, sep.ActiveOrigins, sep.UseStickySession)
|
||||
selectedUpstream, err := router.loadBalancer.GetRequestUpstreamTarget(w, r, sep.ActiveOrigins, sep.UseStickySession, sep.DisableAutoFallback)
|
||||
if err != nil {
|
||||
http.ServeFile(w, r, "./web/hosterror.html")
|
||||
router.Option.Logger.PrintAndLog("dprouter", "failed to get upstream for hostname", err)
|
||||
|
||||
@@ -61,7 +61,20 @@ func (m *RouteManager) NotifyHostUnreachableWithTimeout(upstreamIp string, timeo
|
||||
*/
|
||||
|
||||
// FilterOfflineOrigins return only online origins from a list of origins
|
||||
func (m *RouteManager) FilterOfflineOrigins(origins []*Upstream) []*Upstream {
|
||||
// If originalUpstreamCount is 1 (only one upstream), or disableAutoFallback is true, return all origins unchanged
|
||||
func (m *RouteManager) FilterOfflineOrigins(origins []*Upstream, originalUpstreamCount int, disableAutoFallback bool) []*Upstream {
|
||||
// If there's only one upstream, don't filter it out even if it's offline
|
||||
// This prevents the 521 error when upgrading/restarting the only upstream server
|
||||
if originalUpstreamCount == 1 {
|
||||
return origins
|
||||
}
|
||||
|
||||
// If auto-fallback is disabled, don't filter offline origins
|
||||
// This allows uptime monitoring to continue without automatically disabling upstreams
|
||||
if disableAutoFallback {
|
||||
return origins
|
||||
}
|
||||
|
||||
var onlineOrigins []*Upstream
|
||||
for _, origin := range origins {
|
||||
if m.IsTargetOnline(origin.OriginIpOrDomain) {
|
||||
|
||||
@@ -19,7 +19,7 @@ const (
|
||||
|
||||
// GetRequestUpstreamTarget return the upstream target where this
|
||||
// request should be routed
|
||||
func (m *RouteManager) GetRequestUpstreamTarget(w http.ResponseWriter, r *http.Request, origins []*Upstream, useStickySession bool) (*Upstream, error) {
|
||||
func (m *RouteManager) GetRequestUpstreamTarget(w http.ResponseWriter, r *http.Request, origins []*Upstream, useStickySession bool, disableAutoFallback bool) (*Upstream, error) {
|
||||
if len(origins) == 0 {
|
||||
return nil, errors.New("no upstream is defined for this host")
|
||||
}
|
||||
@@ -30,8 +30,9 @@ func (m *RouteManager) GetRequestUpstreamTarget(w http.ResponseWriter, r *http.R
|
||||
targetOriginId, err := m.getSessionHandler(r, origins)
|
||||
if err != nil {
|
||||
// No valid session found or origin is offline
|
||||
// Filter the offline origins
|
||||
origins = m.FilterOfflineOrigins(origins)
|
||||
// Filter the offline origins (but only if there's more than 1 upstream and auto-fallback is not disabled)
|
||||
originalUpstreamCount := len(origins)
|
||||
origins = m.FilterOfflineOrigins(origins, originalUpstreamCount, disableAutoFallback)
|
||||
if len(origins) == 0 {
|
||||
return nil, errors.New("no online upstream is available for origin: " + r.Host)
|
||||
}
|
||||
@@ -55,8 +56,9 @@ func (m *RouteManager) GetRequestUpstreamTarget(w http.ResponseWriter, r *http.R
|
||||
}
|
||||
|
||||
//No sticky session, get a random origin
|
||||
//Filter the offline origins
|
||||
origins = m.FilterOfflineOrigins(origins)
|
||||
//Filter the offline origins (but only if there's more than 1 upstream and auto-fallback is not disabled)
|
||||
originalUpstreamCount := len(origins)
|
||||
origins = m.FilterOfflineOrigins(origins, originalUpstreamCount, disableAutoFallback)
|
||||
if len(origins) == 0 {
|
||||
return nil, errors.New("no online upstream is available for origin: " + r.Host)
|
||||
}
|
||||
@@ -73,8 +75,9 @@ func (m *RouteManager) GetRequestUpstreamTarget(w http.ResponseWriter, r *http.R
|
||||
}
|
||||
|
||||
// GetUsableUpstreamCounts return the number of usable upstreams
|
||||
func (m *RouteManager) GetUsableUpstreamCounts(origins []*Upstream) int {
|
||||
origins = m.FilterOfflineOrigins(origins)
|
||||
func (m *RouteManager) GetUsableUpstreamCounts(origins []*Upstream, disableAutoFallback bool) int {
|
||||
originalUpstreamCount := len(origins)
|
||||
origins = m.FilterOfflineOrigins(origins, originalUpstreamCount, disableAutoFallback)
|
||||
return len(origins)
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, targe
|
||||
reqHostname := r.Host
|
||||
|
||||
/* Load balancing */
|
||||
selectedUpstream, err := h.Parent.loadBalancer.GetRequestUpstreamTarget(w, r, target.ActiveOrigins, target.UseStickySession)
|
||||
selectedUpstream, err := h.Parent.loadBalancer.GetRequestUpstreamTarget(w, r, target.ActiveOrigins, target.UseStickySession, target.DisableAutoFallback)
|
||||
if err != nil {
|
||||
http.ServeFile(w, r, "./web/rperror.html")
|
||||
h.Parent.Option.Logger.PrintAndLog("proxy", "Failed to assign an upstream for this request", err)
|
||||
|
||||
@@ -210,6 +210,7 @@ type ProxyEndpoint struct {
|
||||
|
||||
//Uptime Monitor
|
||||
DisableUptimeMonitor bool //Disable uptime monitor for this endpoint
|
||||
DisableAutoFallback bool //Disable automatic fallback when uptime monitor detects an upstream is down (continue monitoring but don't auto-disable upstream)
|
||||
DisableLogging bool //Disable logging of reverse proxy requests
|
||||
DisableStatisticCollection bool //Disable statistic collection for this endpoint
|
||||
|
||||
|
||||
@@ -428,6 +428,7 @@ func ReverseProxyHandleAddEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Tags: tags,
|
||||
DisableUptimeMonitor: !enableUtm,
|
||||
DisableAutoFallback: false, // Default to false for new endpoints
|
||||
DisableLogging: disableLog,
|
||||
BlockCommonExploits: blockCommonExploits,
|
||||
BlockAICrawlers: blockAICrawlers,
|
||||
@@ -627,20 +628,24 @@ func ReverseProxyHandleEditEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
BasicAuthExceptionRules: []*dynamicproxy.BasicAuthExceptionRule{},
|
||||
}
|
||||
}
|
||||
if authProviderType == 1 {
|
||||
switch authProviderType {
|
||||
case 1:
|
||||
newProxyEndpoint.AuthenticationProvider.AuthMethod = dynamicproxy.AuthMethodBasic
|
||||
} else if authProviderType == 2 {
|
||||
case 2:
|
||||
newProxyEndpoint.AuthenticationProvider.AuthMethod = dynamicproxy.AuthMethodForward
|
||||
} else if authProviderType == 3 {
|
||||
case 3:
|
||||
newProxyEndpoint.AuthenticationProvider.AuthMethod = dynamicproxy.AuthMethodOauth2
|
||||
} else {
|
||||
default:
|
||||
newProxyEndpoint.AuthenticationProvider.AuthMethod = dynamicproxy.AuthMethodNone
|
||||
}
|
||||
|
||||
disableAutoFallback, _ := utils.PostBool(r, "dAutoFallback")
|
||||
|
||||
newProxyEndpoint.RequireRateLimit = requireRateLimit
|
||||
newProxyEndpoint.RateLimit = proxyRateLimit
|
||||
newProxyEndpoint.UseStickySession = useStickySession
|
||||
newProxyEndpoint.DisableUptimeMonitor = disbleUtm
|
||||
newProxyEndpoint.DisableAutoFallback = disableAutoFallback
|
||||
newProxyEndpoint.DisableChunkedTransferEncoding = disableChunkedEncoding
|
||||
newProxyEndpoint.DisableLogging = disableLogging
|
||||
newProxyEndpoint.DisableStatisticCollection = disableStatisticCollection
|
||||
|
||||
@@ -316,6 +316,12 @@
|
||||
<small>Enable active uptime monitor and auto disable upstreams that are offline</small></label>
|
||||
</div>
|
||||
<br>
|
||||
<!-- <div class="ui checkbox" style="margin-top: 0.4em; margin-left: 2em;">
|
||||
<input type="checkbox" class="DisableAutoFallback">
|
||||
<label>Disable Auto Fallback<br>
|
||||
<small>Continue monitoring but don't automatically disable upstreams when offline</small></label>
|
||||
</div>
|
||||
<br> -->
|
||||
<div class="ui checkbox" style="margin-top: 0.4em;">
|
||||
<input type="checkbox" class="UseStickySession">
|
||||
<label>Use Sticky Session<br>
|
||||
@@ -924,6 +930,7 @@
|
||||
let epttype = "host";
|
||||
let useStickySession = $(editor).find(".UseStickySession")[0].checked;
|
||||
let DisableUptimeMonitor = !$(editor).find(".EnableUptimeMonitor")[0].checked;
|
||||
let disableAutoFallback = false; //$(editor).find(".DisableAutoFallback")[0].checked;
|
||||
let authProviderType = $(editor).find(".authProviderPicker input[type='radio']:checked").val();
|
||||
let requireRateLimit = $(editor).find(".RequireRateLimit")[0].checked;
|
||||
let rateLimit = $(editor).find(".RateLimit").val();
|
||||
@@ -946,6 +953,7 @@
|
||||
"rootname": uuid,
|
||||
"ss":useStickySession,
|
||||
"dutm": DisableUptimeMonitor,
|
||||
"dAutoFallback": disableAutoFallback,
|
||||
"bpgtls": bypassGlobalTLS,
|
||||
"authprovider" :authProviderType,
|
||||
"rate" :requireRateLimit,
|
||||
@@ -1408,6 +1416,19 @@
|
||||
editor.find(".EnableUptimeMonitor").off("change");
|
||||
editor.find(".EnableUptimeMonitor").prop("checked", !subd.DisableUptimeMonitor);
|
||||
editor.find(".EnableUptimeMonitor").on("change", function() {
|
||||
// Enable/disable the auto fallback option based on uptime monitor state
|
||||
var isUptimeMonitorEnabled = $(this).is(":checked");
|
||||
editor.find(".DisableAutoFallback").prop("disabled", !isUptimeMonitorEnabled);
|
||||
if (!isUptimeMonitorEnabled) {
|
||||
editor.find(".DisableAutoFallback").prop("checked", false);
|
||||
}
|
||||
saveProxyInlineEdit(uuid);
|
||||
});
|
||||
|
||||
editor.find(".DisableAutoFallback").off("change");
|
||||
editor.find(".DisableAutoFallback").prop("checked", subd.DisableAutoFallback);
|
||||
editor.find(".DisableAutoFallback").prop("disabled", subd.DisableUptimeMonitor);
|
||||
editor.find(".DisableAutoFallback").on("change", function() {
|
||||
saveProxyInlineEdit(uuid);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user