package api import ( "bytes" "encoding/json" "math/rand" "net/http" "time" "github.com/stefanprodan/podinfo/pkg/version" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" "go.uber.org/zap" ) func randomErrorMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rand.Seed(time.Now().Unix()) if rand.Int31n(3) == 0 { errors := []int{http.StatusInternalServerError, http.StatusBadRequest, http.StatusConflict} w.WriteHeader(errors[rand.Intn(len(errors))]) return } next.ServeHTTP(w, r) }) } func versionMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { r.Header.Set("X-API-Version", version.VERSION) r.Header.Set("X-API-Revision", version.REVISION) next.ServeHTTP(w, r) }) } func (s *Server) JSONResponse(w http.ResponseWriter, r *http.Request, result interface{}) { body, err := json.Marshal(result) if err != nil { w.WriteHeader(http.StatusInternalServerError) s.logger.Error("JSON marshal failed", zap.Error(err)) return } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Header().Set("X-Content-Type-Options", "nosniff") w.WriteHeader(http.StatusOK) w.Write(prettyJSON(body)) } func (s *Server) JSONResponseCode(w http.ResponseWriter, r *http.Request, result interface{}, responseCode int) { body, err := json.Marshal(result) if err != nil { w.WriteHeader(http.StatusInternalServerError) s.logger.Error("JSON marshal failed", zap.Error(err)) return } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Header().Set("X-Content-Type-Options", "nosniff") w.WriteHeader(responseCode) w.Write(prettyJSON(body)) } func (s *Server) ErrorResponse(w http.ResponseWriter, r *http.Request, span trace.Span, error string, code int) { data := struct { Code int `json:"code"` Message string `json:"message"` }{ Code: code, Message: error, } span.SetStatus(codes.Error, error) body, err := json.Marshal(data) if err != nil { w.WriteHeader(http.StatusInternalServerError) s.logger.Error("JSON marshal failed", zap.Error(err)) return } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Header().Set("X-Content-Type-Options", "nosniff") w.WriteHeader(http.StatusOK) w.Write(prettyJSON(body)) } func prettyJSON(b []byte) []byte { var out bytes.Buffer json.Indent(&out, b, "", " ") return out.Bytes() }