service: parse json job requests once

This commit is contained in:
Brad Stein 2026-03-31 20:53:59 -03:00
parent 1c9edb95f8
commit ecd31ffa1c
2 changed files with 36 additions and 10 deletions

View File

@ -95,7 +95,8 @@ func (a *App) handleBuild(w http.ResponseWriter, r *http.Request) {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
node := requestValue(r, "node")
values := requestValues(r)
node := values["node"]
job, err := a.Build(node)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@ -109,9 +110,10 @@ func (a *App) handleReplace(w http.ResponseWriter, r *http.Request) {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
node := requestValue(r, "node")
host := requestValue(r, "host")
device := requestValue(r, "device")
values := requestValues(r)
node := values["node"]
host := values["host"]
device := values["device"]
job, err := a.Replace(node, host, device)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@ -204,19 +206,27 @@ func normalizeGroupValue(raw string) string {
return strings.TrimPrefix(value, "/")
}
func requestValue(r *http.Request, key string) string {
func requestValues(r *http.Request) map[string]string {
values := map[string]string{}
if err := r.ParseForm(); err == nil {
if value := strings.TrimSpace(r.Form.Get(key)); value != "" {
return value
for key, rawValues := range r.Form {
for _, raw := range rawValues {
if value := strings.TrimSpace(raw); value != "" {
values[key] = value
break
}
}
}
}
var payload map[string]any
if err := json.NewDecoder(r.Body).Decode(&payload); err == nil {
if value, ok := payload[key].(string); ok {
return strings.TrimSpace(value)
for key, raw := range payload {
if value, ok := raw.(string); ok && strings.TrimSpace(value) != "" {
values[key] = strings.TrimSpace(value)
}
}
}
return ""
return values
}
func writeJSON(w http.ResponseWriter, status int, payload any) {

View File

@ -121,6 +121,22 @@ func TestInternalSnapshotAndWatch(t *testing.T) {
}
}
func TestRequestValuesJSONBody(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/api/jobs/replace", strings.NewReader(`{"node":"titan-13","host":"titan-20","device":"hosttmp:///tmp"}`))
req.Header.Set("Content-Type", "application/json")
values := requestValues(req)
if values["node"] != "titan-13" {
t.Fatalf("expected node titan-13, got %q", values["node"])
}
if values["host"] != "titan-20" {
t.Fatalf("expected host titan-20, got %q", values["host"])
}
if values["device"] != "hosttmp:///tmp" {
t.Fatalf("expected device hosttmp:///tmp, got %q", values["device"])
}
}
func newTestApp(t *testing.T) *App {
t.Helper()
dir := t.TempDir()