fixed api, fixed ListFiles function

This commit is contained in:
yusing 2024-10-02 17:34:35 +08:00
parent ed9d8aab6f
commit ef52ccb929
8 changed files with 62 additions and 51 deletions

View file

@ -30,9 +30,9 @@ func NewHandler(cfg *config.Config) http.Handler {
mux.HandleFunc("GET", "/v1/list", wrap(cfg, v1.List)) mux.HandleFunc("GET", "/v1/list", wrap(cfg, v1.List))
mux.HandleFunc("GET", "/v1/list/{what}", wrap(cfg, v1.List)) mux.HandleFunc("GET", "/v1/list/{what}", wrap(cfg, v1.List))
mux.HandleFunc("GET", "/v1/file", v1.GetFileContent) mux.HandleFunc("GET", "/v1/file", v1.GetFileContent)
mux.HandleFunc("GET", "/v1/file/{filename}", v1.GetFileContent) mux.HandleFunc("GET", "/v1/file/{filename...}", v1.GetFileContent)
mux.HandleFunc("POST", "/v1/file/{filename}", v1.SetFileContent) mux.HandleFunc("POST", "/v1/file/{filename...}", v1.SetFileContent)
mux.HandleFunc("PUT", "/v1/file/{filename}", v1.SetFileContent) mux.HandleFunc("PUT", "/v1/file/{filename...}", v1.SetFileContent)
mux.HandleFunc("GET", "/v1/stats", wrap(cfg, v1.Stats)) mux.HandleFunc("GET", "/v1/stats", wrap(cfg, v1.Stats))
mux.HandleFunc("GET", "/v1/error_page", error_page.GetHandleFunc()) mux.HandleFunc("GET", "/v1/error_page", error_page.GetHandleFunc())
return mux return mux

View file

@ -5,6 +5,7 @@ import (
"net/http" "net/http"
"os" "os"
"path" "path"
"strings"
U "github.com/yusing/go-proxy/internal/api/v1/utils" U "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common" "github.com/yusing/go-proxy/internal/common"
@ -41,7 +42,7 @@ func SetFileContent(w http.ResponseWriter, r *http.Request) {
var validateErr E.NestedError var validateErr E.NestedError
if filename == common.ConfigFileName { if filename == common.ConfigFileName {
validateErr = config.Validate(content) validateErr = config.Validate(content)
} else { } else if !strings.HasPrefix(filename, path.Base(common.MiddlewareComposeBasePath)) {
validateErr = provider.Validate(content) validateErr = provider.Validate(content)
} }

View file

@ -1,19 +1,20 @@
package v1 package v1
import ( import (
"encoding/json"
"net/http" "net/http"
"os" "strings"
U "github.com/yusing/go-proxy/internal/api/v1/utils" U "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common" "github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/config" "github.com/yusing/go-proxy/internal/config"
"github.com/yusing/go-proxy/internal/net/http/middleware" "github.com/yusing/go-proxy/internal/net/http/middleware"
"github.com/yusing/go-proxy/internal/utils"
) )
const ( const (
ListRoutes = "routes" ListRoutes = "routes"
ListConfigFiles = "config_files" ListConfigFiles = "config_files"
ListMiddlewares = "middlewares"
ListMiddlewareTrace = "middleware_trace" ListMiddlewareTrace = "middleware_trace"
) )
@ -28,6 +29,8 @@ func List(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
listRoutes(cfg, w, r) listRoutes(cfg, w, r)
case ListConfigFiles: case ListConfigFiles:
listConfigFiles(w, r) listConfigFiles(w, r)
case ListMiddlewares:
listMiddlewares(w, r)
case ListMiddlewareTrace: case ListMiddlewareTrace:
listMiddlewareTrace(w, r) listMiddlewareTrace(w, r)
default: default:
@ -46,34 +49,25 @@ func listRoutes(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
} }
} }
if err := U.RespondJson(w, routes); err != nil { U.HandleErr(w, r, U.RespondJson(w, routes))
U.HandleErr(w, r, err)
}
} }
func listConfigFiles(w http.ResponseWriter, r *http.Request) { func listConfigFiles(w http.ResponseWriter, r *http.Request) {
files, err := os.ReadDir(common.ConfigBasePath) files, err := utils.ListFiles(common.ConfigBasePath, 1)
if err != nil { if err != nil {
U.HandleErr(w, r, err) U.HandleErr(w, r, err)
return return
} }
filenames := make([]string, len(files)) for i := range files {
for i, f := range files { files[i] = strings.TrimPrefix(files[i], common.ConfigBasePath+"/")
filenames[i] = f.Name()
} }
resp, err := json.Marshal(filenames) U.HandleErr(w, r, U.RespondJson(w, files))
if err != nil {
U.HandleErr(w, r, err)
return
}
w.Write(resp)
} }
func listMiddlewareTrace(w http.ResponseWriter, r *http.Request) { func listMiddlewareTrace(w http.ResponseWriter, r *http.Request) {
resp, err := json.Marshal(middleware.GetAllTrace()) U.HandleErr(w, r, U.RespondJson(w, middleware.GetAllTrace()))
if err != nil {
U.HandleErr(w, r, err)
return
} }
w.Write(resp)
func listMiddlewares(w http.ResponseWriter, r *http.Request) {
U.HandleErr(w, r, U.RespondJson(w, middleware.All()))
} }

View file

@ -12,6 +12,9 @@ import (
var Logger = logrus.WithField("module", "api") var Logger = logrus.WithField("module", "api")
func HandleErr(w http.ResponseWriter, r *http.Request, origErr error, code ...int) { func HandleErr(w http.ResponseWriter, r *http.Request, origErr error, code ...int) {
if origErr == nil {
return
}
err := E.From(origErr).Subjectf("%s %s", r.Method, r.URL) err := E.From(origErr).Subjectf("%s %s", r.Method, r.URL)
Logger.Error(err) Logger.Error(err)
if len(code) > 0 { if len(code) > 0 {

View file

@ -38,6 +38,7 @@ func (cfg *Config) RoutesByAlias() map[string]U.SerializedObject {
obj["provider"] = p.GetName() obj["provider"] = p.GetName()
obj["type"] = string(r.Type()) obj["type"] = string(r.Type())
obj["started"] = r.Started() obj["started"] = r.Started()
obj["raw"] = r.Entry()
routes[alias] = obj routes[alias] = obj
}) })
return routes return routes
@ -46,30 +47,17 @@ func (cfg *Config) RoutesByAlias() map[string]U.SerializedObject {
func (cfg *Config) Statistics() map[string]any { func (cfg *Config) Statistics() map[string]any {
nTotalStreams := 0 nTotalStreams := 0
nTotalRPs := 0 nTotalRPs := 0
providerStats := make(map[string]any) providerStats := make(map[string]PR.ProviderStats)
cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) { cfg.proxyProviders.RangeAll(func(name string, p *PR.Provider) {
if !r.Started() { providerStats[name] = p.Statistics()
return
}
s, ok := providerStats[p.GetName()]
if !ok {
s = make(map[string]int)
}
stats := s.(map[string]int)
switch r.Type() {
case R.RouteTypeStream:
stats["num_streams"]++
nTotalStreams++
case R.RouteTypeReverseProxy:
stats["num_reverse_proxies"]++
nTotalRPs++
default:
panic("bug: should not reach here")
}
}) })
for _, stats := range providerStats {
nTotalRPs += stats.NumRPs
nTotalStreams += stats.NumStreams
}
return map[string]any{ return map[string]any{
"num_total_streams": nTotalStreams, "num_total_streams": nTotalStreams,
"num_total_reverse_proxies": nTotalRPs, "num_total_reverse_proxies": nTotalRPs,

View file

@ -20,6 +20,10 @@ func Get(name string) (middleware *Middleware, ok bool) {
return return
} }
func All() map[string]*Middleware {
return middlewares
}
// initialize middleware names and label parsers // initialize middleware names and label parsers
func init() { func init() {
middlewares = map[string]*Middleware{ middlewares = map[string]*Middleware{

View file

@ -32,6 +32,11 @@ type (
String() string String() string
} }
ProviderType string ProviderType string
ProviderStats struct {
NumRPs int `json:"num_reverse_proxies"`
NumStreams int `json:"num_streams"`
Type ProviderType `json:"type"`
}
EventResult struct { EventResult struct {
nRemoved int nRemoved int
nAdded int nAdded int
@ -164,6 +169,24 @@ func (p *Provider) LoadRoutes() E.NestedError {
return E.FailWith("loading routes", err) return E.FailWith("loading routes", err)
} }
func (p *Provider) Statistics() ProviderStats {
numRPs := 0
numStreams := 0
p.routes.RangeAll(func(_ string, r R.Route) {
switch r.Type() {
case R.RouteTypeReverseProxy:
numRPs++
case R.RouteTypeStream:
numStreams++
}
})
return ProviderStats{
NumRPs: numRPs,
NumStreams: numStreams,
Type: p.t,
}
}
func (p *Provider) watchEvents() { func (p *Provider) watchEvents() {
p.watcherCtx, p.watcherCancel = context.WithCancel(context.Background()) p.watcherCtx, p.watcherCancel = context.WithCancel(context.Background())
events, errs := p.watcher.Events(p.watcherCtx) events, errs := p.watcher.Events(p.watcherCtx)

View file

@ -23,9 +23,7 @@ func ListFiles(dir string, maxDepth int) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, subEntry := range subEntries { files = append(files, subEntries...)
files = append(files, path.Join(dir, entry.Name(), subEntry))
}
} else { } else {
files = append(files, path.Join(dir, entry.Name())) files = append(files, path.Join(dir, entry.Name()))
} }