diff --git a/experimental/clashapi/api_meta.go b/experimental/clashapi/api_meta.go index 77dad7979..8b31d8a42 100644 --- a/experimental/clashapi/api_meta.go +++ b/experimental/clashapi/api_meta.go @@ -2,6 +2,7 @@ package clashapi import ( "bytes" + "context" "net" "net/http" "runtime/debug" @@ -27,7 +28,7 @@ func (s *Server) setupMetaAPI(r chi.Router) { }) r.Mount("/", middleware.Profiler()) } - r.Get("/memory", memory(s.trafficManager)) + r.Get("/memory", memory(s.ctx, s.trafficManager)) r.Mount("/group", groupRouter(s)) r.Mount("/upgrade", upgradeRouter(s)) } @@ -37,7 +38,7 @@ type Memory struct { OSLimit uint64 `json:"oslimit"` // maybe we need it in the future } -func memory(trafficManager *trafficontrol.Manager) func(w http.ResponseWriter, r *http.Request) { +func memory(ctx context.Context, trafficManager *trafficontrol.Manager) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { var conn net.Conn if r.Header.Get("Upgrade") == "websocket" { @@ -46,6 +47,7 @@ func memory(trafficManager *trafficontrol.Manager) func(w http.ResponseWriter, r if err != nil { return } + defer conn.Close() } if conn == nil { @@ -58,7 +60,12 @@ func memory(trafficManager *trafficontrol.Manager) func(w http.ResponseWriter, r buf := &bytes.Buffer{} var err error first := true - for range tick.C { + for { + select { + case <-ctx.Done(): + return + case <-tick.C: + } buf.Reset() inuse := trafficManager.Snapshot().Memory diff --git a/experimental/clashapi/connections.go b/experimental/clashapi/connections.go index 5074adf78..14274b311 100644 --- a/experimental/clashapi/connections.go +++ b/experimental/clashapi/connections.go @@ -38,6 +38,7 @@ func getConnections(ctx context.Context, trafficManager *trafficontrol.Manager) if err != nil { return } + defer conn.Close() intervalStr := r.URL.Query().Get("interval") interval := 1000 diff --git a/experimental/clashapi/server.go b/experimental/clashapi/server.go index 5118766e4..33094d34a 100644 --- a/experimental/clashapi/server.go +++ b/experimental/clashapi/server.go @@ -114,7 +114,7 @@ func NewServer(ctx context.Context, logFactory log.ObservableFactory, options op chiRouter.Group(func(r chi.Router) { r.Use(authentication(options.Secret)) r.Get("/", hello(options.ExternalUI != "")) - r.Get("/logs", getLogs(logFactory)) + r.Get("/logs", getLogs(s.ctx, logFactory)) r.Get("/traffic", traffic(s.ctx, trafficManager)) r.Get("/version", version) r.Mount("/configs", configRouter(s, logFactory)) @@ -362,7 +362,7 @@ type Log struct { Payload string `json:"payload"` } -func getLogs(logFactory log.ObservableFactory) func(w http.ResponseWriter, r *http.Request) { +func getLogs(ctx context.Context, logFactory log.ObservableFactory) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { levelText := r.URL.Query().Get("level") if levelText == "" { @@ -401,6 +401,8 @@ func getLogs(logFactory log.ObservableFactory) func(w http.ResponseWriter, r *ht var logEntry log.Entry for { select { + case <-ctx.Done(): + return case <-done: return case logEntry = <-subscription: