live-sfu-demo/internal/server/runtime_config.go

97 lines
2.8 KiB
Go

package server
import (
"encoding/json"
"net/http"
)
func (s *Server) handleManageRuntimeConfig(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
raw := r.URL.Query().Get("raw") == "1"
view := s.cfg.ViewRuntime(!raw)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(view)
case http.MethodPut, http.MethodPost, http.MethodPatch:
// read raw bytes first to allow both shapes
bodyBytes := make([]byte, 0, 4096)
buf := make([]byte, 4096)
for {
n, err := r.Body.Read(buf)
if n > 0 {
bodyBytes = append(bodyBytes, buf[:n]...)
}
if err != nil {
break
}
}
var patch map[string]string
var wrapped struct {
Values map[string]string `json:"values"`
}
if err := json.Unmarshal(bodyBytes, &wrapped); err == nil && wrapped.Values != nil && len(wrapped.Values) > 0 {
patch = wrapped.Values
} else {
// flat map fallback
_ = json.Unmarshal(bodyBytes, &patch)
}
if len(patch) == 0 {
http.Error(w, "values required (send {values: {KEY: value}} or flat {KEY: value})", http.StatusBadRequest)
return
}
changed, err := s.cfg.ApplyRuntimePatch(patch)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := s.cfg.SaveRuntime(); err != nil {
http.Error(w, "save: "+err.Error(), http.StatusInternalServerError)
return
}
s.ApplyRuntimeConfig()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]any{"ok": true, "changed": changed, "values": s.cfg.ViewRuntime(false).Values})
default:
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
}
}
func (s *Server) handleManageRuntimeConfigReset(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost && r.Method != http.MethodDelete {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
var body struct {
Keys []string `json:"keys"`
}
_ = json.NewDecoder(r.Body).Decode(&body)
if len(body.Keys) == 0 {
// reset all: clear overrides via ApplyRuntimePatch for each key to trigger revert
all := s.cfg.ViewRuntime(false).Values
patch := map[string]string{}
for k := range all {
patch[k] = ""
}
if _, err := s.cfg.ApplyRuntimePatch(patch); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
} else {
patch := map[string]string{}
for _, k := range body.Keys {
patch[k] = ""
}
if _, err := s.cfg.ApplyRuntimePatch(patch); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
if err := s.cfg.SaveRuntime(); err != nil {
http.Error(w, "save: "+err.Error(), http.StatusInternalServerError)
return
}
s.ApplyRuntimeConfig()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]any{"ok": true})
}