diff --git a/internal/api/v1/list_route.go b/internal/api/v1/list_route.go index 56f3238e..e861a4ef 100644 --- a/internal/api/v1/list_route.go +++ b/internal/api/v1/list_route.go @@ -10,12 +10,8 @@ import ( func ListRouteHandler(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) { which := r.PathValue("which") - if which == "" || which == "all" { - gphttp.RespondJSON(w, r, routes.ByAlias()) - return - } - routesMap := routes.ByAlias() - if route, ok := routesMap[which]; ok { + route, ok := routes.Get(which) + if ok { gphttp.RespondJSON(w, r, route) } else { gphttp.RespondJSON(w, r, nil) diff --git a/internal/api/v1/list_route_providers.go b/internal/api/v1/list_route_providers.go index 85f7048f..2b373e9e 100644 --- a/internal/api/v1/list_route_providers.go +++ b/internal/api/v1/list_route_providers.go @@ -2,11 +2,22 @@ package v1 import ( "net/http" + "time" + "github.com/coder/websocket" + "github.com/coder/websocket/wsjson" config "github.com/yusing/go-proxy/internal/config/types" "github.com/yusing/go-proxy/internal/net/gphttp" + "github.com/yusing/go-proxy/internal/net/gphttp/gpwebsocket" + "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders" ) -func ListRouteProvidersHandler(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) { - gphttp.RespondJSON(w, r, cfg.RouteProviderList()) +func ListRouteProvidersHandler(cfgInstance config.ConfigInstance, w http.ResponseWriter, r *http.Request) { + if httpheaders.IsWebsocket(r.Header) { + gpwebsocket.Periodic(w, r, 5*time.Second, func(conn *websocket.Conn) error { + return wsjson.Write(r.Context(), conn, cfgInstance.RouteProviderList()) + }) + } else { + gphttp.RespondJSON(w, r, cfgInstance.RouteProviderList()) + } } diff --git a/internal/api/v1/list_routes.go b/internal/api/v1/list_routes.go index d74e83b4..80ab5e09 100644 --- a/internal/api/v1/list_routes.go +++ b/internal/api/v1/list_routes.go @@ -2,13 +2,24 @@ package v1 import ( "net/http" + "slices" config "github.com/yusing/go-proxy/internal/config/types" "github.com/yusing/go-proxy/internal/net/gphttp" "github.com/yusing/go-proxy/internal/route/routes" - route "github.com/yusing/go-proxy/internal/route/types" ) func ListRoutesHandler(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) { - gphttp.RespondJSON(w, r, routes.ByAlias(route.RouteType(r.FormValue("type")))) + rts := make([]routes.Route, 0) + provider := r.FormValue("provider") + if provider == "" { + gphttp.RespondJSON(w, r, slices.Collect(routes.Iter)) + return + } + for r := range routes.Iter { + if r.ProviderName() == provider { + rts = append(rts, r) + } + } + gphttp.RespondJSON(w, r, rts) } diff --git a/internal/config/config.go b/internal/config/config.go index 8422748c..044ee104 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -301,7 +301,7 @@ func (cfg *Config) initAutoCert(autocertCfg *autocert.Config) gperr.Error { func (cfg *Config) initProxmox(proxmoxCfg []proxmox.Config) gperr.Error { proxmox.Clients.Clear() - var errs = gperr.NewBuilder() + errs := gperr.NewBuilder() for _, cfg := range proxmoxCfg { if err := cfg.Init(); err != nil { errs.Add(err.Subject(cfg.URL)) diff --git a/internal/config/query.go b/internal/config/query.go index 70b101bd..1960a70c 100644 --- a/internal/config/query.go +++ b/internal/config/query.go @@ -1,6 +1,7 @@ package config import ( + config "github.com/yusing/go-proxy/internal/config/types" "github.com/yusing/go-proxy/internal/route" "github.com/yusing/go-proxy/internal/route/provider" ) @@ -23,10 +24,13 @@ func (cfg *Config) DumpRouteProviders() map[string]*provider.Provider { return entries } -func (cfg *Config) RouteProviderList() []string { - var list []string +func (cfg *Config) RouteProviderList() []config.RouteProviderListResponse { + var list []config.RouteProviderListResponse cfg.providers.RangeAll(func(_ string, p *provider.Provider) { - list = append(list, p.ShortName()) + list = append(list, config.RouteProviderListResponse{ + ShortName: p.ShortName(), + FullName: p.String(), + }) }) return list } diff --git a/internal/config/types/config.go b/internal/config/types/config.go index 7db60366..4460025e 100644 --- a/internal/config/types/config.go +++ b/internal/config/types/config.go @@ -42,12 +42,15 @@ type ( HomepageConfig struct { UseDefaultCategories bool `json:"use_default_categories"` } - + RouteProviderListResponse struct { + ShortName string `json:"short_name"` + FullName string `json:"full_name"` + } ConfigInstance interface { Value() *Config Reload() gperr.Error Statistics() map[string]any - RouteProviderList() []string + RouteProviderList() []RouteProviderListResponse Context() context.Context GetAgent(agentAddrOrDockerHost string) (*agent.AgentConfig, bool) VerifyNewAgent(host string, ca agent.PEMPair, client agent.PEMPair) (int, gperr.Error) diff --git a/internal/route/routes/query.go b/internal/route/routes/query.go index ae3d773b..869d54cd 100644 --- a/internal/route/routes/query.go +++ b/internal/route/routes/query.go @@ -5,7 +5,6 @@ import ( "time" "github.com/yusing/go-proxy/internal/homepage" - route "github.com/yusing/go-proxy/internal/route/types" "github.com/yusing/go-proxy/internal/watcher/health" ) @@ -69,16 +68,16 @@ func getHealthInfoRaw(r Route) *HealthInfoRaw { func HealthMap() map[string]map[string]string { healthMap := make(map[string]map[string]string, NumRoutes()) - for alias, r := range Iter { - healthMap[alias] = getHealthInfo(r) + for r := range Iter { + healthMap[r.Name()] = getHealthInfo(r) } return healthMap } func HealthInfo() map[string]*HealthInfoRaw { healthMap := make(map[string]*HealthInfoRaw, NumRoutes()) - for alias, r := range Iter { - healthMap[alias] = getHealthInfoRaw(r) + for r := range Iter { + healthMap[r.Name()] = getHealthInfoRaw(r) } return healthMap } @@ -116,29 +115,9 @@ func HomepageConfig(categoryFilter, providerFilter string) homepage.Homepage { return hp } -func ByAlias(typeFilter ...route.RouteType) map[string]Route { - rts := make(map[string]Route) - if len(typeFilter) == 0 || typeFilter[0] == "" { - typeFilter = []route.RouteType{route.RouteTypeHTTP, route.RouteTypeStream} - } - for _, t := range typeFilter { - switch t { - case route.RouteTypeHTTP: - for alias, r := range HTTP.Iter { - rts[alias] = r - } - case route.RouteTypeStream: - for alias, r := range Stream.Iter { - rts[alias] = r - } - } - } - return rts -} - func ByProvider() map[string][]Route { rts := make(map[string][]Route) - for _, r := range HTTP.Iter { + for r := range Iter { rts[r.ProviderName()] = append(rts[r.ProviderName()], r) } return rts diff --git a/internal/route/routes/routes.go b/internal/route/routes/routes.go index 1797025b..bc85b43d 100644 --- a/internal/route/routes/routes.go +++ b/internal/route/routes/routes.go @@ -9,13 +9,16 @@ var ( Stream = pool.New[StreamRoute]("stream_routes") ) -func Iter(yield func(alias string, r Route) bool) { - for k, r := range HTTP.Iter { - if !yield(k, r) { +func Iter(yield func(r Route) bool) { + for _, r := range HTTP.Iter { + if !yield(r) { break } } - for k, r := range Stream.Iter { +} + +func IterKV(yield func(alias string, r Route) bool) { + for k, r := range HTTP.Iter { if !yield(k, r) { break }