github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/api/server/handler_api.go (about) 1 package server 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "runtime" 8 9 "github.com/containers/libpod/pkg/api/handlers/utils" 10 log "github.com/sirupsen/logrus" 11 ) 12 13 // APIHandler is a wrapper to enhance HandlerFunc's and remove redundant code 14 func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc { 15 return func(w http.ResponseWriter, r *http.Request) { 16 // http.Server hides panics, we want to see them and fix the cause. 17 defer func() { 18 err := recover() 19 if err != nil { 20 buf := make([]byte, 1<<20) 21 n := runtime.Stack(buf, true) 22 log.Warnf("Recovering from API handler panic: %v, %s", err, buf[:n]) 23 // Try to inform client things went south... won't work if handler already started writing response body 24 utils.InternalServerError(w, fmt.Errorf("%v", err)) 25 } 26 }() 27 28 // Wrapper to hide some boiler plate 29 fn := func(w http.ResponseWriter, r *http.Request) { 30 log.Debugf("APIHandler -- Method: %s URL: %s", r.Method, r.URL.String()) 31 32 if err := r.ParseForm(); err != nil { 33 log.Infof("Failed Request: unable to parse form: %q", err) 34 } 35 36 // TODO: Use r.ConnContext when ported to go 1.13 37 c := context.WithValue(r.Context(), "decoder", s.Decoder) 38 c = context.WithValue(c, "runtime", s.Runtime) 39 c = context.WithValue(c, "shutdownFunc", s.Shutdown) 40 r = r.WithContext(c) 41 42 h(w, r) 43 } 44 fn(w, r) 45 } 46 } 47 48 // VersionedPath prepends the version parsing code 49 // any handler may override this default when registering URL(s) 50 func VersionedPath(p string) string { 51 return "/v{version:[0-9][0-9.]*}" + p 52 }