GoDoxy/internal/route/routes/routequery/query.go
Yuzerion 1a5f3735cf
Feat/fileserver (#60)
* cleanup code for URL type

* fix makefile for trace mode

* refactor, merge Entry, RawEntry and Route into one. 

* Implement fileserver.

* refactor: rename HTTPRoute to ReverseProxyRoute to avoid confusion

* refactor: move metrics logger to middleware package

- fix prometheus metrics for load balanced routes
  - route will now fail when health monitor fail to start

* fix extra output of ls-* commands by defer initializaing stuff, speed up start time

* add test for path traversal attack, small fix on FileServer.Start method

* rename rule.on.bypass to pass

* refactor and fixed map-to-map  deserialization

* updated route loading logic

* schemas: add "add_prefix" option to modify_request middleware


* updated route JSONMarshalling

---------

Co-authored-by: yusing <yusing@6uo.me>
2025-02-06 18:23:10 +08:00

165 lines
4.1 KiB
Go

package routequery
import (
"strings"
"time"
"github.com/yusing/go-proxy/internal"
"github.com/yusing/go-proxy/internal/homepage"
provider "github.com/yusing/go-proxy/internal/route/provider/types"
"github.com/yusing/go-proxy/internal/route/routes"
route "github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
func getHealthInfo(r route.Route) map[string]string {
mon := r.HealthMonitor()
if mon == nil {
return map[string]string{
"status": "unknown",
"uptime": "n/a",
"latency": "n/a",
}
}
return map[string]string{
"status": mon.Status().String(),
"uptime": mon.Uptime().Round(time.Second).String(),
"latency": mon.Latency().Round(time.Microsecond).String(),
}
}
func HealthMap() map[string]map[string]string {
healthMap := make(map[string]map[string]string)
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
healthMap[alias] = getHealthInfo(r)
})
routes.GetStreamRoutes().RangeAll(func(alias string, r route.StreamRoute) {
healthMap[alias] = getHealthInfo(r)
})
return healthMap
}
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 == "" {
return
}
if _, ok := check[homepage.Category]; ok {
return
}
check[homepage.Category] = struct{}{}
categories = append(categories, homepage.Category)
})
return categories
}
func HomepageConfig(useDefaultCategories bool, categoryFilter, providerFilter string) homepage.Categories {
hpCfg := homepage.NewHomePageConfig()
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
item := r.HomepageConfig()
if item.IsEmpty() {
item = homepage.NewItem(alias)
}
if override := item.GetOverride(); override != item {
if providerFilter != "" && override.Provider != providerFilter ||
categoryFilter != "" && override.Category != categoryFilter {
return
}
hpCfg.Add(override)
return
}
item.Alias = alias
item.Provider = r.ProviderName()
if providerFilter != "" && item.Provider != providerFilter {
return
}
if item.Name == "" {
reference := r.TargetName()
cont := r.ContainerInfo()
if cont != nil {
reference = cont.ImageName
}
name, ok := internal.GetDisplayName(reference)
if ok {
item.Name = name
} else {
item.Name = strutils.Title(
strings.ReplaceAll(
strings.ReplaceAll(alias, "-", " "),
"_", " ",
),
)
}
}
if useDefaultCategories {
container := r.ContainerInfo()
if container != nil && item.Category == "" {
if category, ok := homepage.PredefinedCategories[container.ImageName]; ok {
item.Category = category
}
}
if item.Category == "" {
if category, ok := homepage.PredefinedCategories[strings.ToLower(alias)]; ok {
item.Category = category
}
}
}
if categoryFilter != "" && item.Category != categoryFilter {
return
}
switch {
case r.IsDocker():
if item.Category == "" {
item.Category = "Docker"
}
item.SourceType = string(provider.ProviderTypeDocker)
case r.UseLoadBalance():
if item.Category == "" {
item.Category = "Load-balanced"
}
item.SourceType = "loadbalancer"
default:
if item.Category == "" {
item.Category = "Others"
}
item.SourceType = string(provider.ProviderTypeFile)
}
item.AltURL = r.TargetURL().String()
hpCfg.Add(item)
})
return hpCfg
}
func RoutesByAlias(typeFilter ...route.RouteType) map[string]route.Route {
rts := make(map[string]route.Route)
if len(typeFilter) == 0 || typeFilter[0] == "" {
typeFilter = []route.RouteType{route.RouteTypeHTTP, route.RouteTypeStream}
}
for _, t := range typeFilter {
switch t {
case route.RouteTypeHTTP:
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
rts[alias] = r
})
case route.RouteTypeStream:
routes.GetStreamRoutes().RangeAll(func(alias string, r route.StreamRoute) {
rts[alias] = r
})
}
}
return rts
}