bwtest_handlers.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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 := s.bwtestMgr.SubscribeClient()
  68. ticker := time.NewTicker(500 * time.Millisecond)
  69. defer ticker.Stop()
  70. for {
  71. select {
  72. case <-r.Context().Done():
  73. return
  74. case sample, ok := <-subCh:
  75. if !ok {
  76. return
  77. }
  78. data, err := json.Marshal(sample)
  79. if err == nil {
  80. fmt.Fprintf(w, "data: %s\n\n", data)
  81. flusher.Flush()
  82. }
  83. case <-ticker.C:
  84. // Send heartbeat/current status snapshot if no sample arrives
  85. status := s.bwtestMgr.GetTestStatus()
  86. if !status.Running {
  87. summaryData, _ := json.Marshal(map[string]interface{}{
  88. "type": "status",
  89. "running": false,
  90. "summary": status.Summary,
  91. "error": status.Error,
  92. })
  93. fmt.Fprintf(w, "data: %s\n\n", summaryData)
  94. flusher.Flush()
  95. return
  96. }
  97. }
  98. }
  99. }
  100. // handleGetBwTestHistory returns historical test records
  101. func (s *Server) handleGetBwTestHistory(w http.ResponseWriter, r *http.Request) {
  102. history := s.bwtestMgr.GetHistory()
  103. writeJSON(w, http.StatusOK, history)
  104. }