From 37dbe075196d638d6bd417716deaf067247ee966 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Thu, 22 Oct 2015 10:55:23 -0400 Subject: [PATCH] Dump request when daemon is set to debug Uses a new middleware which calls httputils.DumpRequest which is output to `logrus.Debug`. This is implemented in a separate middleare so that we only have to check the logging level when the router is instantiated rather than at every request. If this was just `logrus.Debug(httputil.DumpRequest(...))`, the DumpRequest would be called on each request requardless of logging level set on the daemon. Signed-off-by: Brian Goff --- api/server/middleware.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/api/server/middleware.go b/api/server/middleware.go index 47e52ee5b2..7581adee58 100644 --- a/api/server/middleware.go +++ b/api/server/middleware.go @@ -1,6 +1,9 @@ package server import ( + "bytes" + "encoding/json" + "io/ioutil" "net/http" "runtime" "strings" @@ -28,6 +31,32 @@ func (s *Server) loggingMiddleware(handler httputils.APIFunc) httputils.APIFunc } } +// debugRequestMiddleware dumps the request to logger +// This is implemented separately from `loggingMiddleware` so that we don't have to +// check the logging level or have httputil.DumpRequest called on each request. +// Instead the middleware is only injected when the logging level is set to debug +func (s *Server) debugRequestMiddleware(handler httputils.APIFunc) httputils.APIFunc { + return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { + if s.cfg.Logging && r.Method == "POST" { + if err := httputils.CheckForJSON(r); err == nil { + var buf bytes.Buffer + if _, err := buf.ReadFrom(r.Body); err == nil { + r.Body.Close() + r.Body = ioutil.NopCloser(&buf) + var postForm map[string]interface{} + if err := json.Unmarshal(buf.Bytes(), &postForm); err == nil { + if _, exists := postForm["password"]; exists { + postForm["password"] = "*****" + } + logrus.Debugf("form data: %q", postForm) + } + } + } + } + return handler(ctx, w, r, vars) + } +} + // userAgentMiddleware checks the User-Agent header looking for a valid docker client spec. func (s *Server) userAgentMiddleware(handler httputils.APIFunc) httputils.APIFunc { return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { @@ -110,6 +139,13 @@ func (s *Server) handleWithGlobalMiddlewares(handler httputils.APIFunc) httputil s.loggingMiddleware, } + // Only want this on debug level + // this is separate from the logging middleware so that we can do this check here once, + // rather than for each request. + if logrus.GetLevel() == logrus.DebugLevel { + middlewares = append(middlewares, s.debugRequestMiddleware) + } + h := handler for _, m := range middlewares { h = m(h)