package proxy import ( "fmt" "net/http" "strings" log "github.com/go-pkgz/lgr" "github.com/go-pkgz/rest" "github.com/umputun/reproxy/app/discovery" ) func (h *Http) healthMiddleware(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" && strings.EqualFold(r.URL.Path, "/health") { h.healthHandler(w, r) return } next.ServeHTTP(w, r) } return http.HandlerFunc(fn) } func (h *Http) healthHandler(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") mappers := h.Mappers() total := 0 for _, m := range mappers { if m.MatchType == discovery.MTProxy { total++ } } pingErrs := h.CheckHealth() var errs []string for _, pingErr := range pingErrs { if pingErr != nil { errs = append(errs, pingErr.Error()) } } if len(errs) > 0 { w.WriteHeader(http.StatusExpectationFailed) errResp := struct { Status string `json:"status,omitempty"` Services int `json:"services,omitempty"` Passed int `json:"passed,omitempty"` Failed int `json:"failed,omitempty"` Errors []string `json:"errors,omitempty"` }{Status: "failed", Services: total, Passed: len(pingErrs) - len(errs), Failed: len(errs), Errors: errs} rest.RenderJSON(w, errResp) return } w.WriteHeader(http.StatusOK) _, err := fmt.Fprintf(w, `{"status": "ok", "services": %d}`, total) if err != nil { log.Printf("[WARN] failed to send health, %v", err) } } // pingHandler middleware response with pong to /ping. Stops chain if ping request detected func (h *Http) pingHandler(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" && strings.EqualFold(r.URL.Path, "/ping") { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("pong")) return } next.ServeHTTP(w, r) } return http.HandlerFunc(fn) }