github.com/cookieai-jar/moby@v17.12.1-ce-rc2+incompatible/api/server/middleware/debug.go (about) 1 package middleware 2 3 import ( 4 "bufio" 5 "encoding/json" 6 "io" 7 "net/http" 8 "strings" 9 10 "github.com/docker/docker/api/server/httputils" 11 "github.com/docker/docker/pkg/ioutils" 12 "github.com/sirupsen/logrus" 13 "golang.org/x/net/context" 14 ) 15 16 // DebugRequestMiddleware dumps the request to logger 17 func DebugRequestMiddleware(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 18 return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 19 logrus.Debugf("Calling %s %s", r.Method, r.RequestURI) 20 21 if r.Method != "POST" { 22 return handler(ctx, w, r, vars) 23 } 24 if err := httputils.CheckForJSON(r); err != nil { 25 return handler(ctx, w, r, vars) 26 } 27 maxBodySize := 4096 // 4KB 28 if r.ContentLength > int64(maxBodySize) { 29 return handler(ctx, w, r, vars) 30 } 31 32 body := r.Body 33 bufReader := bufio.NewReaderSize(body, maxBodySize) 34 r.Body = ioutils.NewReadCloserWrapper(bufReader, func() error { return body.Close() }) 35 36 b, err := bufReader.Peek(maxBodySize) 37 if err != io.EOF { 38 // either there was an error reading, or the buffer is full (in which case the request is too large) 39 return handler(ctx, w, r, vars) 40 } 41 42 var postForm map[string]interface{} 43 if err := json.Unmarshal(b, &postForm); err == nil { 44 maskSecretKeys(postForm, r.RequestURI) 45 formStr, errMarshal := json.Marshal(postForm) 46 if errMarshal == nil { 47 logrus.Debugf("form data: %s", string(formStr)) 48 } else { 49 logrus.Debugf("form data: %q", postForm) 50 } 51 } 52 53 return handler(ctx, w, r, vars) 54 } 55 } 56 57 func maskSecretKeys(inp interface{}, path string) { 58 // Remove any query string from the path 59 idx := strings.Index(path, "?") 60 if idx != -1 { 61 path = path[:idx] 62 } 63 // Remove trailing / characters 64 path = strings.TrimRight(path, "/") 65 66 if arr, ok := inp.([]interface{}); ok { 67 for _, f := range arr { 68 maskSecretKeys(f, path) 69 } 70 return 71 } 72 73 if form, ok := inp.(map[string]interface{}); ok { 74 loop0: 75 for k, v := range form { 76 for _, m := range []string{"password", "secret", "jointoken", "unlockkey", "signingcakey"} { 77 if strings.EqualFold(m, k) { 78 form[k] = "*****" 79 continue loop0 80 } 81 } 82 maskSecretKeys(v, path) 83 } 84 85 // Route-specific redactions 86 if strings.HasSuffix(path, "/secrets/create") { 87 for k := range form { 88 if k == "Data" { 89 form[k] = "*****" 90 } 91 } 92 } 93 } 94 }