github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/experimental/clashapi/api_meta.go (about) 1 package clashapi 2 3 import ( 4 "bytes" 5 "net/http" 6 "time" 7 8 "github.com/inazumav/sing-box/common/json" 9 "github.com/inazumav/sing-box/experimental/clashapi/trafficontrol" 10 "github.com/sagernet/websocket" 11 12 "github.com/go-chi/chi/v5" 13 "github.com/go-chi/render" 14 ) 15 16 // API created by Clash.Meta 17 18 func (s *Server) setupMetaAPI(r chi.Router) { 19 r.Get("/memory", memory(s.trafficManager)) 20 r.Mount("/group", groupRouter(s)) 21 } 22 23 type Memory struct { 24 Inuse uint64 `json:"inuse"` 25 OSLimit uint64 `json:"oslimit"` // maybe we need it in the future 26 } 27 28 func memory(trafficManager *trafficontrol.Manager) func(w http.ResponseWriter, r *http.Request) { 29 return func(w http.ResponseWriter, r *http.Request) { 30 var wsConn *websocket.Conn 31 if websocket.IsWebSocketUpgrade(r) { 32 var err error 33 wsConn, err = upgrader.Upgrade(w, r, nil) 34 if err != nil { 35 return 36 } 37 } 38 39 if wsConn == nil { 40 w.Header().Set("Content-Type", "application/json") 41 render.Status(r, http.StatusOK) 42 } 43 44 tick := time.NewTicker(time.Second) 45 defer tick.Stop() 46 buf := &bytes.Buffer{} 47 var err error 48 first := true 49 for range tick.C { 50 buf.Reset() 51 52 inuse := trafficManager.Snapshot().Memory 53 54 // make chat.js begin with zero 55 // this is shit var,but we need output 0 for first time 56 if first { 57 first = false 58 inuse = 0 59 } 60 if err := json.NewEncoder(buf).Encode(Memory{ 61 Inuse: inuse, 62 OSLimit: 0, 63 }); err != nil { 64 break 65 } 66 if wsConn == nil { 67 _, err = w.Write(buf.Bytes()) 68 w.(http.Flusher).Flush() 69 } else { 70 err = wsConn.WriteMessage(websocket.TextMessage, buf.Bytes()) 71 } 72 73 if err != nil { 74 break 75 } 76 } 77 } 78 }