From ac72f77a74cd30906cb00e39037fb1270f1666e8 Mon Sep 17 00:00:00 2001 From: yusing Date: Tue, 25 Feb 2025 11:31:06 +0800 Subject: [PATCH] homepage: refactor and fix overrides not being applied --- internal/api/v1/favicon/favicon.go | 4 +- internal/homepage/homepage.go | 64 +++++++++++------------ internal/homepage/homepage_test.go | 8 +-- internal/homepage/override_config.go | 13 ++--- internal/route/reverse_proxy.go | 2 +- internal/route/route.go | 26 +++++---- internal/route/routes/routequery/query.go | 22 ++++---- internal/route/types/route.go | 3 +- 8 files changed, 75 insertions(+), 67 deletions(-) diff --git a/internal/api/v1/favicon/favicon.go b/internal/api/v1/favicon/favicon.go index c4e0ffdb..cdd8455c 100644 --- a/internal/api/v1/favicon/favicon.go +++ b/internal/api/v1/favicon/favicon.go @@ -86,8 +86,8 @@ func GetFavIcon(w http.ResponseWriter, req *http.Request) { } var result *fetchResult - hp := r.HomepageConfig() - if !hp.IsEmpty() && hp.Icon != nil { + hp := r.HomepageItem() + if hp.Icon != nil { if hp.Icon.IconSource == homepage.IconSourceRelative { result = findIcon(r, req, hp.Icon.Value) } else { diff --git a/internal/homepage/homepage.go b/internal/homepage/homepage.go index b816f09b..481c87af 100644 --- a/internal/homepage/homepage.go +++ b/internal/homepage/homepage.go @@ -1,13 +1,15 @@ package homepage import ( + "encoding/json" + + config "github.com/yusing/go-proxy/internal/config/types" "github.com/yusing/go-proxy/internal/utils" ) type ( - //nolint:recvcheck - Categories map[string]Category - Category []*Item + Homepage map[string]Category + Category []*Item ItemConfig struct { Show bool `json:"show"` @@ -22,11 +24,8 @@ type ( Item struct { *ItemConfig - Alias string `json:"alias"` // proxy alias - Provider string `json:"provider"` - URL string `json:"url"` // alias + domain - - IsUnset bool `json:"-"` + Alias string + Provider string } ) @@ -38,33 +37,34 @@ func init() { }) } -func NewItem(alias string) *Item { - return &Item{ - ItemConfig: &ItemConfig{ - Show: true, - }, - Alias: alias, - IsUnset: true, +func (cfg *ItemConfig) GetOverride(alias string) *ItemConfig { + return overrideConfigInstance.GetOverride(alias, cfg) +} + +func (item *Item) MarshalJSON() ([]byte, error) { + godoxyCfg := config.GetInstance().Value() + // use first domain as base domain + domains := godoxyCfg.MatchDomains + var url *string + if len(domains) > 0 { + url = new(string) + *url = item.Alias + domains[0] } + return json.Marshal(map[string]any{ + "show": item.Show, + "alias": item.Alias, + "provider": item.Provider, + "url": url, + "name": item.Name, + "icon": item.Icon, + "category": item.Category, + "description": item.Description, + "sort_order": item.SortOrder, + "widget_config": item.WidgetConfig, + }) } -func NewHomePageConfig() Categories { - return Categories(make(map[string]Category)) -} - -func (item *Item) IsEmpty() bool { - return item == nil || item.IsUnset || item.ItemConfig == nil -} - -func (item *Item) ApplyOverride() *Item { - return overrideConfigInstance.ApplyOverride(item) -} - -func (c *Categories) Clear() { - *c = make(Categories) -} - -func (c Categories) Add(item *Item) { +func (c Homepage) Add(item *Item) { if c[item.Category] == nil { c[item.Category] = make(Category, 0) } diff --git a/internal/homepage/homepage_test.go b/internal/homepage/homepage_test.go index 6428ba72..0a29d142 100644 --- a/internal/homepage/homepage_test.go +++ b/internal/homepage/homepage_test.go @@ -20,7 +20,7 @@ func TestOverrideItem(t *testing.T) { Category: "App", }, } - override := &ItemConfig{ + want := &ItemConfig{ Show: true, Name: "Bar", Category: "Test", @@ -30,7 +30,7 @@ func TestOverrideItem(t *testing.T) { }, } overrides := GetOverrideConfig() - overrides.OverrideItem(a.Alias, override) - overridden := a.ApplyOverride() - ExpectDeepEqual(t, overridden.ItemConfig, override) + overrides.OverrideItem(a.Alias, want) + got := a.GetOverride(a.Alias) + ExpectDeepEqual(t, got, want) } diff --git a/internal/homepage/override_config.go b/internal/homepage/override_config.go index 040b5315..a6289c25 100644 --- a/internal/homepage/override_config.go +++ b/internal/homepage/override_config.go @@ -64,16 +64,17 @@ func (c *OverrideConfig) OverrideItems(items map[string]*ItemConfig) { } } -func (c *OverrideConfig) ApplyOverride(item *Item) *Item { +func (c *OverrideConfig) GetOverride(alias string, item *ItemConfig) *ItemConfig { c.mu.RLock() defer c.mu.RUnlock() - itemOverride, hasOverride := c.ItemOverrides[item.Alias] + itemOverride, hasOverride := c.ItemOverrides[alias] if hasOverride { - item.ItemConfig = itemOverride - item.IsUnset = false + return itemOverride } - if show, ok := c.ItemVisibility[item.Alias]; ok { - item.Show = show + if show, ok := c.ItemVisibility[alias]; ok { + clone := *item + clone.Show = show + return &clone } return item } diff --git a/internal/route/reverse_proxy.go b/internal/route/reverse_proxy.go index cd01b51f..ee1e1ae5 100755 --- a/internal/route/reverse_proxy.go +++ b/internal/route/reverse_proxy.go @@ -225,7 +225,7 @@ func (r *ReveseProxyRoute) addToLoadBalancer(parent task.Parent) { linked = l.(*ReveseProxyRoute) lb = linked.loadBalancer lb.UpdateConfigIfNeeded(cfg) - if linked.Homepage.IsEmpty() && !r.Homepage.IsEmpty() { + if linked.Homepage == nil { linked.Homepage = r.Homepage } } else { diff --git a/internal/route/route.go b/internal/route/route.go index 0666b565..7a446794 100644 --- a/internal/route/route.go +++ b/internal/route/route.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/docker/docker/api/types/container" "github.com/yusing/go-proxy/agent/pkg/agent" "github.com/yusing/go-proxy/internal" "github.com/yusing/go-proxy/internal/docker" @@ -15,7 +16,6 @@ import ( "github.com/yusing/go-proxy/internal/utils/strutils" "github.com/yusing/go-proxy/internal/watcher/health" - dockertypes "github.com/docker/docker/api/types" "github.com/yusing/go-proxy/internal/common" config "github.com/yusing/go-proxy/internal/config/types" "github.com/yusing/go-proxy/internal/net/gphttp/accesslog" @@ -41,7 +41,7 @@ type ( HealthCheck *health.HealthCheckConfig `json:"healthcheck,omitempty"` LoadBalance *loadbalance.Config `json:"load_balance,omitempty"` Middlewares map[string]docker.LabelMap `json:"middlewares,omitempty"` - Homepage *homepage.Item `json:"homepage,omitempty"` + Homepage *homepage.ItemConfig `json:"homepage,omitempty"` AccessLog *accesslog.Config `json:"access_log,omitempty"` Metadata `deserialize:"-"` @@ -190,8 +190,16 @@ func (r *Route) LoadBalanceConfig() *loadbalance.Config { return r.LoadBalance } -func (r *Route) HomepageConfig() *homepage.Item { - return r.Homepage +func (r *Route) HomepageConfig() *homepage.ItemConfig { + return r.Homepage.GetOverride(r.Alias) +} + +func (r *Route) HomepageItem() *homepage.Item { + return &homepage.Item{ + Alias: r.Alias, + Provider: r.Provider, + ItemConfig: r.HomepageConfig(), + } } func (r *Route) ContainerInfo() *docker.Container { @@ -370,14 +378,12 @@ func (r *Route) FinalizeHomepageConfig() { isDocker := r.Container != nil - if r.Homepage.IsEmpty() { - r.Homepage = homepage.NewItem(r.Alias) + if r.Homepage == nil { + r.Homepage = &homepage.ItemConfig{Show: true} } + r.Homepage = r.Homepage.GetOverride(r.Alias) hp := r.Homepage - hp.Alias = r.Alias - hp.Provider = r.Provider - hp = hp.ApplyOverride() var key string if hp.Name == "" { @@ -424,7 +430,7 @@ func (r *Route) FinalizeHomepageConfig() { } } -func lowestPort(ports map[int]dockertypes.Port) (res int) { +func lowestPort(ports map[int]container.Port) (res int) { cmp := (uint16)(65535) for port, v := range ports { if v.PrivatePort < cmp { diff --git a/internal/route/routes/routequery/query.go b/internal/route/routes/routequery/query.go index 227d7223..f1b30374 100644 --- a/internal/route/routes/routequery/query.go +++ b/internal/route/routes/routequery/query.go @@ -64,33 +64,33 @@ func HomepageCategories() []string { check := make(map[string]struct{}) categories := make([]string, 0) routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) { - homepage := r.HomepageConfig() - if homepage.IsEmpty() || homepage.Category == "" { + item := r.HomepageConfig() + if item == nil || item.Category == "" { return } - if _, ok := check[homepage.Category]; ok { + if _, ok := check[item.Category]; ok { return } - check[homepage.Category] = struct{}{} - categories = append(categories, homepage.Category) + check[item.Category] = struct{}{} + categories = append(categories, item.Category) }) return categories } -func HomepageConfig(categoryFilter, providerFilter string) homepage.Categories { - hpCfg := homepage.NewHomePageConfig() +func HomepageConfig(categoryFilter, providerFilter string) homepage.Homepage { + hp := make(homepage.Homepage) routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) { - item := r.HomepageConfig() - if providerFilter != "" && item.Provider != providerFilter { + if providerFilter != "" && r.ProviderName() != providerFilter { return } + item := r.HomepageItem() if categoryFilter != "" && item.Category != categoryFilter { return } - hpCfg.Add(item) + hp.Add(item) }) - return hpCfg + return hp } func RoutesByAlias(typeFilter ...route.RouteType) map[string]route.Route { diff --git a/internal/route/types/route.go b/internal/route/types/route.go index 2fe2ed3d..3011e03a 100644 --- a/internal/route/types/route.go +++ b/internal/route/types/route.go @@ -29,7 +29,8 @@ type ( IdlewatcherConfig() *idlewatcher.Config HealthCheckConfig() *health.HealthCheckConfig LoadBalanceConfig() *loadbalance.Config - HomepageConfig() *homepage.Item + HomepageConfig() *homepage.ItemConfig + HomepageItem() *homepage.Item ContainerInfo() *docker.Container Agent() *agent.AgentConfig