package processapi import ( "context" "encoding/json" "errors" "net/http" "strconv" "time" "github.com/itworx/pulse/internal/auth" "github.com/itworx/pulse/internal/problem" "github.com/itworx/pulse/internal/process" ) type Handler struct { Provider interface { Snapshot(context.Context) (process.Snapshot, error) } Limits process.Limits } func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet || r.URL.Path != "/api/v1/processes" { http.NotFound(w, r) return } if _, ok := auth.PrincipalFromContext(r.Context()); !ok { problem.Write(w, r, http.StatusUnauthorized, "UNAUTHORIZED", "Authentication required", "Authentication is required to read processes.", nil) return } limit := 50 if value := r.URL.Query().Get("limit"); value != "" { parsed, err := strconv.Atoi(value) if err != nil { problem.Write(w, r, http.StatusBadRequest, "PROCESS_LIMIT_INVALID", "Invalid process limit", "The process page limit is invalid.", nil) return } limit = parsed } mode := process.SortMode(r.URL.Query().Get("sort")) if mode == "" { mode = process.SortCPU } var snapshot process.Snapshot var err error if h.Provider == nil { snapshot = process.UnknownSnapshot(time.Now().UTC(), "process", "agent", "source_unavailable") } else { snapshot, err = h.Provider.Snapshot(r.Context()) } if err != nil { if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { return } problem.Write(w, r, http.StatusServiceUnavailable, "PROCESS_UNAVAILABLE", "Processgegevens niet beschikbaar", "De procesgegevens konden niet worden gelezen.", nil) return } page, err := process.FilteredPage(snapshot, mode, limit, r.URL.Query().Get("after"), h.Limits, r.URL.Query().Get("q"), r.URL.Query().Get("container")) if err != nil { problem.Write(w, r, http.StatusBadRequest, "PROCESS_QUERY_INVALID", "Invalid process query", "The process sort, cursor or limit is invalid.", nil) return } w.Header().Set("Content-Type", "application/json") w.Header().Set("Cache-Control", "private, max-age=5") _ = json.NewEncoder(w).Encode(page) }