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