package httpapi import ( "encoding/json" "log" "net/http" ) const ( internalErrorDetail = "an internal error occurred" badGatewayDetail = "upstream request failed" notFoundDetail = "resource not found" invalidInputDetail = "invalid request data" cdnExtractDetail = "could not extract prefixes from source" csvInvalidRowDetail = "invalid row in csv file" ) // Problem is RFC 9457 application/problem+json. type Problem struct { Type string `json:"type,omitempty"` Title string `json:"title"` Status int `json:"status"` Detail string `json:"detail,omitempty"` Instance string `json:"instance,omitempty"` } func writeProblem(w http.ResponseWriter, status int, title, detail string) { w.Header().Set("Content-Type", "application/problem+json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(Problem{ Type: "about:blank", Title: title, Status: status, Detail: detail, }) } func writeJSON(w http.ResponseWriter, status int, v any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(v) } func writeNoContent(w http.ResponseWriter) { w.WriteHeader(http.StatusNoContent) } // writeInternalError logs err server-side and returns a generic 500 problem (ERR-01). func writeInternalError(w http.ResponseWriter, operation string, err error) { if err != nil { log.Printf("httpapi: %s: %v", operation, err) } writeProblem(w, http.StatusInternalServerError, "Internal Error", internalErrorDetail) } // writeBadGateway logs err server-side and returns a generic 502 problem (ERR-01). func writeBadGateway(w http.ResponseWriter, operation string, err error) { if err != nil { log.Printf("httpapi: %s: %v", operation, err) } writeProblem(w, http.StatusBadGateway, "Bad Gateway", badGatewayDetail) }