github.com/igoogolx/clash@v1.19.8/hub/route/connections.go (about) 1 package route 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "strconv" 7 "time" 8 9 "github.com/igoogolx/clash/tunnel/statistic" 10 11 "github.com/Dreamacro/protobytes" 12 "github.com/go-chi/chi/v5" 13 "github.com/go-chi/render" 14 "github.com/gorilla/websocket" 15 ) 16 17 func connectionRouter() http.Handler { 18 r := chi.NewRouter() 19 r.Get("/", getConnections) 20 r.Delete("/", closeAllConnections) 21 r.Delete("/{id}", closeConnection) 22 return r 23 } 24 25 func getConnections(w http.ResponseWriter, r *http.Request) { 26 if !websocket.IsWebSocketUpgrade(r) { 27 snapshot := statistic.DefaultManager.Snapshot() 28 render.JSON(w, r, snapshot) 29 return 30 } 31 32 conn, err := upgrader.Upgrade(w, r, nil) 33 if err != nil { 34 return 35 } 36 37 intervalStr := r.URL.Query().Get("interval") 38 interval := 1000 39 if intervalStr != "" { 40 t, err := strconv.Atoi(intervalStr) 41 if err != nil { 42 render.Status(r, http.StatusBadRequest) 43 render.JSON(w, r, ErrBadRequest) 44 return 45 } 46 47 interval = t 48 } 49 50 buf := protobytes.BytesWriter{} 51 sendSnapshot := func() error { 52 buf.Reset() 53 snapshot := statistic.DefaultManager.Snapshot() 54 if err := json.NewEncoder(&buf).Encode(snapshot); err != nil { 55 return err 56 } 57 58 return conn.WriteMessage(websocket.TextMessage, buf.Bytes()) 59 } 60 61 if err := sendSnapshot(); err != nil { 62 return 63 } 64 65 tick := time.NewTicker(time.Millisecond * time.Duration(interval)) 66 defer tick.Stop() 67 for range tick.C { 68 if err := sendSnapshot(); err != nil { 69 break 70 } 71 } 72 } 73 74 func closeConnection(w http.ResponseWriter, r *http.Request) { 75 id := chi.URLParam(r, "id") 76 snapshot := statistic.DefaultManager.Snapshot() 77 for _, c := range snapshot.Connections { 78 if id == c.ID() { 79 c.Close() 80 break 81 } 82 } 83 render.NoContent(w, r) 84 } 85 86 func closeAllConnections(w http.ResponseWriter, r *http.Request) { 87 snapshot := statistic.DefaultManager.Snapshot() 88 for _, c := range snapshot.Connections { 89 c.Close() 90 } 91 render.NoContent(w, r) 92 }