bwtest_handlers.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package api
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "time"
  7. "proxmox-router/internal/bwtest"
  8. )
  9. // handleGetBwTestServer returns status and metrics for the local BwTest server
  10. func (s *Server) handleGetBwTestServer(w http.ResponseWriter, r *http.Request) {
  11. status := s.bwtestMgr.GetServerStatus()
  12. writeJSON(w, http.StatusOK, status)
  13. }
  14. // handleUpdateBwTestServer updates the server configuration
  15. func (s *Server) handleUpdateBwTestServer(w http.ResponseWriter, r *http.Request) {
  16. var cfg bwtest.ServerConfig
  17. if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil {
  18. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  19. return
  20. }
  21. if err := s.bwtestMgr.SetServerConfig(cfg); err != nil {
  22. writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
  23. return
  24. }
  25. writeJSON(w, http.StatusOK, s.bwtestMgr.GetServerStatus())
  26. }
  27. // handleStartBwTest initiates a bandwidth test
  28. func (s *Server) handleStartBwTest(w http.ResponseWriter, r *http.Request) {
  29. var req bwtest.SessionRequest
  30. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  31. writeJSON(w, http.StatusBadRequest, map[string]string{"error": "Invalid JSON: " + err.Error()})
  32. return
  33. }
  34. if req.Target == "" {
  35. req.Target = "127.0.0.1"
  36. }
  37. if req.Port <= 0 {
  38. req.Port = 2000
  39. }
  40. if err := s.bwtestMgr.StartTest(r.Context(), req); err != nil {
  41. writeJSON(w, http.StatusConflict, map[string]string{"error": err.Error()})
  42. return
  43. }
  44. writeJSON(w, http.StatusOK, s.bwtestMgr.GetTestStatus())
  45. }
  46. // handleStopBwTest terminates any running test
  47. func (s *Server) handleStopBwTest(w http.ResponseWriter, r *http.Request) {
  48. s.bwtestMgr.StopTest()
  49. writeJSON(w, http.StatusOK, map[string]bool{"stopped": true})
  50. }
  51. // handleGetBwTestStatus retrieves current status, telemetry, and metrics
  52. func (s *Server) handleGetBwTestStatus(w http.ResponseWriter, r *http.Request) {
  53. status := s.bwtestMgr.GetTestStatus()
  54. writeJSON(w, http.StatusOK, status)
  55. }
  56. // handleStreamBwTest streams real-time telemetry samples over Server-Sent Events (SSE)
  57. func (s *Server) handleStreamBwTest(w http.ResponseWriter, r *http.Request) {
  58. flusher, ok := w.(http.Flusher)
  59. if !ok {
  60. http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
  61. return
  62. }
  63. w.Header().Set("Content-Type", "text/event-stream")
  64. w.Header().Set("Cache-Control", "no-cache")
  65. w.Header().Set("Connection", "keep-alive")
  66. w.Header().Set("X-Accel-Buffering", "no")
  67. subCh, unsubscribe := s.bwtestMgr.SubscribeClient()
  68. defer unsubscribe()
  69. ticker := time.NewTicker(500 * time.Millisecond)
  70. defer ticker.Stop()
  71. for {
  72. select {
  73. case <-r.Context().Done():
  74. return
  75. case sample, ok := <-subCh:
  76. if !ok {
  77. return
  78. }
  79. data, err := json.Marshal(sample)
  80. if err == nil {
  81. fmt.Fprintf(w, "data: %s\n\n", data)
  82. flusher.Flush()
  83. }
  84. case <-ticker.C:
  85. // Send heartbeat/current status snapshot if no sample arrives
  86. status := s.bwtestMgr.GetTestStatus()
  87. if !status.Running {
  88. summaryData, _ := json.Marshal(map[string]interface{}{
  89. "type": "status",
  90. "running": false,
  91. "summary": status.Summary,
  92. "error": status.Error,
  93. })
  94. fmt.Fprintf(w, "data: %s\n\n", summaryData)
  95. flusher.Flush()
  96. return
  97. }
  98. }
  99. }
  100. }
  101. // handleGetBwTestHistory returns historical test records
  102. func (s *Server) handleGetBwTestHistory(w http.ResponseWriter, r *http.Request) {
  103. history := s.bwtestMgr.GetHistory()
  104. writeJSON(w, http.StatusOK, history)
  105. }