| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- package api
- import (
- "encoding/json"
- "fmt"
- "net/http"
- "time"
- "proxmox-router/internal/bwtest"
- )
- // handleGetBwTestServer returns status and metrics for the local BwTest server
- func (s *Server) handleGetBwTestServer(w http.ResponseWriter, r *http.Request) {
- status := s.bwtestMgr.GetServerStatus()
- writeJSON(w, http.StatusOK, status)
- }
- // handleUpdateBwTestServer updates the server configuration
- func (s *Server) handleUpdateBwTestServer(w http.ResponseWriter, r *http.Request) {
- var cfg bwtest.ServerConfig
- if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
- return
- }
- if err := s.bwtestMgr.SetServerConfig(cfg); err != nil {
- writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, s.bwtestMgr.GetServerStatus())
- }
- // handleStartBwTest initiates a bandwidth test
- func (s *Server) handleStartBwTest(w http.ResponseWriter, r *http.Request) {
- var req bwtest.SessionRequest
- if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
- return
- }
- if req.Target == "" {
- req.Target = "127.0.0.1"
- }
- if req.Port <= 0 {
- req.Port = 2000
- }
- if err := s.bwtestMgr.StartTest(r.Context(), req); err != nil {
- writeJSON(w, http.StatusConflict, map[string]string{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, s.bwtestMgr.GetTestStatus())
- }
- // handleStopBwTest terminates any running test
- func (s *Server) handleStopBwTest(w http.ResponseWriter, r *http.Request) {
- s.bwtestMgr.StopTest()
- writeJSON(w, http.StatusOK, map[string]bool{"stopped": true})
- }
- // handleGetBwTestStatus retrieves current status, telemetry, and metrics
- func (s *Server) handleGetBwTestStatus(w http.ResponseWriter, r *http.Request) {
- status := s.bwtestMgr.GetTestStatus()
- writeJSON(w, http.StatusOK, status)
- }
- // handleStreamBwTest streams real-time telemetry samples over Server-Sent Events (SSE)
- func (s *Server) handleStreamBwTest(w http.ResponseWriter, r *http.Request) {
- flusher, ok := w.(http.Flusher)
- if !ok {
- http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
- return
- }
- w.Header().Set("Content-Type", "text/event-stream")
- w.Header().Set("Cache-Control", "no-cache")
- w.Header().Set("Connection", "keep-alive")
- w.Header().Set("X-Accel-Buffering", "no")
- subCh, unsubscribe := s.bwtestMgr.SubscribeClient()
- defer unsubscribe()
- ticker := time.NewTicker(500 * time.Millisecond)
- defer ticker.Stop()
- for {
- select {
- case <-r.Context().Done():
- return
- case sample, ok := <-subCh:
- if !ok {
- return
- }
- data, err := json.Marshal(sample)
- if err == nil {
- fmt.Fprintf(w, "data: %s\n\n", data)
- flusher.Flush()
- }
- case <-ticker.C:
- // Send heartbeat/current status snapshot if no sample arrives
- status := s.bwtestMgr.GetTestStatus()
- if !status.Running {
- summaryData, _ := json.Marshal(map[string]interface{}{
- "type": "status",
- "running": false,
- "summary": status.Summary,
- "error": status.Error,
- })
- fmt.Fprintf(w, "data: %s\n\n", summaryData)
- flusher.Flush()
- return
- }
- }
- }
- }
- // handleGetBwTestHistory returns historical test records
- func (s *Server) handleGetBwTestHistory(w http.ResponseWriter, r *http.Request) {
- history := s.bwtestMgr.GetHistory()
- writeJSON(w, http.StatusOK, history)
- }
|