summaryrefslogtreecommitdiff
path: root/pkg/api/server/handler_api.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api/server/handler_api.go')
-rw-r--r--pkg/api/server/handler_api.go52
1 files changed, 36 insertions, 16 deletions
diff --git a/pkg/api/server/handler_api.go b/pkg/api/server/handler_api.go
index 4b93998ee..30a1680c9 100644
--- a/pkg/api/server/handler_api.go
+++ b/pkg/api/server/handler_api.go
@@ -2,32 +2,52 @@ package server
import (
"context"
+ "fmt"
"net/http"
+ "runtime"
+ "github.com/containers/libpod/pkg/api/handlers/utils"
log "github.com/sirupsen/logrus"
)
// APIHandler is a wrapper to enhance HandlerFunc's and remove redundant code
-func APIHandler(ctx context.Context, h http.HandlerFunc) http.HandlerFunc {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- log.Debugf("APIHandler -- Method: %s URL: %s", r.Method, r.URL.String())
- if err := r.ParseForm(); err != nil {
- log.Infof("Failed Request: unable to parse form: %q", err)
- }
+func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ // http.Server hides panics, we want to see them and fix the cause.
+ defer func() {
+ err := recover()
+ if err != nil {
+ buf := make([]byte, 1<<20)
+ n := runtime.Stack(buf, true)
+ log.Warnf("Recovering from podman handler panic: %v, %s", err, buf[:n])
+ // Try to inform client things went south... won't work if handler already started writing response body
+ utils.InternalServerError(w, fmt.Errorf("%v", err))
+ }
+ }()
+
+ // Wrapper to hide some boiler plate
+ fn := func(w http.ResponseWriter, r *http.Request) {
+ // Connection counting, ugh. Needed to support the sliding window for idle checking.
+ s.ConnectionCh <- EnterHandler
+ defer func() { s.ConnectionCh <- ExitHandler }()
+
+ log.Debugf("APIHandler -- Method: %s URL: %s (conn %d/%d)",
+ r.Method, r.URL.String(), s.ActiveConnections, s.TotalConnections)
- // TODO: Use ConnContext when ported to go 1.13
- c := context.WithValue(r.Context(), "decoder", ctx.Value("decoder"))
- c = context.WithValue(c, "runtime", ctx.Value("runtime"))
- c = context.WithValue(c, "shutdownFunc", ctx.Value("shutdownFunc"))
- r = r.WithContext(c)
+ if err := r.ParseForm(); err != nil {
+ log.Infof("Failed Request: unable to parse form: %q", err)
+ }
- h(w, r)
+ // TODO: Use r.ConnContext when ported to go 1.13
+ c := context.WithValue(r.Context(), "decoder", s.Decoder)
+ c = context.WithValue(c, "runtime", s.Runtime)
+ c = context.WithValue(c, "shutdownFunc", s.Shutdown)
+ r = r.WithContext(c)
- shutdownFunc := r.Context().Value("shutdownFunc").(func() error)
- if err := shutdownFunc(); err != nil {
- log.Errorf("Failed to shutdown Server in APIHandler(): %s", err.Error())
+ h(w, r)
}
- })
+ fn(w, r)
+ }
}
// VersionedPath prepends the version parsing code