Pulse/internal/api/router_routes_debug.go
2026-03-18 16:06:30 +00:00

50 lines
2.3 KiB
Go

package api
import (
"net/http"
"net/http/pprof"
"os"
"strings"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rs/zerolog/log"
)
// registerDebugRoutes registers /debug/pprof endpoints gated behind admin auth
// and settings:read scope. These endpoints expose Go runtime profiling data and
// must only be accessible to authenticated admin users.
func (r *Router) registerDebugRoutes() {
// Register exact /debug/pprof (no trailing slash) to prevent ServeMux's
// automatic 301 redirect which would leak endpoint existence without auth.
r.mux.HandleFunc("/debug/pprof", RequireAdmin(r.config, RequireScope(config.ScopeSettingsRead, func(w http.ResponseWriter, req *http.Request) {
// Redirect to trailing-slash version inside the auth boundary.
http.Redirect(w, req, "/debug/pprof/", http.StatusMovedPermanently)
})))
r.mux.HandleFunc("/debug/pprof/", RequireAdmin(r.config, RequireScope(config.ScopeSettingsRead, func(w http.ResponseWriter, req *http.Request) {
log.Debug().Str("path", req.URL.Path).Str("ip", req.RemoteAddr).Msg("pprof index request")
pprof.Index(w, req)
})))
r.mux.HandleFunc("/debug/pprof/cmdline", RequireAdmin(r.config, RequireScope(config.ScopeSettingsRead, func(w http.ResponseWriter, req *http.Request) {
log.Debug().Str("ip", req.RemoteAddr).Msg("pprof cmdline request")
pprof.Cmdline(w, req)
})))
r.mux.HandleFunc("/debug/pprof/profile", RequireAdmin(r.config, RequireScope(config.ScopeSettingsRead, func(w http.ResponseWriter, req *http.Request) {
log.Debug().Str("ip", req.RemoteAddr).Msg("pprof profile request")
pprof.Profile(w, req)
})))
r.mux.HandleFunc("/debug/pprof/symbol", RequireAdmin(r.config, RequireScope(config.ScopeSettingsRead, func(w http.ResponseWriter, req *http.Request) {
log.Debug().Str("ip", req.RemoteAddr).Msg("pprof symbol request")
pprof.Symbol(w, req)
})))
r.mux.HandleFunc("/debug/pprof/trace", RequireAdmin(r.config, RequireScope(config.ScopeSettingsRead, func(w http.ResponseWriter, req *http.Request) {
log.Debug().Str("ip", req.RemoteAddr).Msg("pprof trace request")
pprof.Trace(w, req)
})))
}
// pprofEnabled reports whether pprof endpoints should be registered.
// Returns true unless PULSE_PPROF_DISABLED is set to a truthy value.
func pprofEnabled() bool {
v := strings.ToLower(strings.TrimSpace(os.Getenv("PULSE_PPROF_DISABLED")))
return v != "true" && v != "1"
}