diff options
author | Francis Lavoie <lavofr@gmail.com> | 2023-03-27 18:40:15 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-27 22:40:15 +0000 |
commit | 2b3046de36bad70bd7e48478c99a8a030fb35b98 (patch) | |
tree | e9052b2c53ecfcffa0530248bc4337f33d6bfea5 | |
parent | 1aef807c71b1ea8e70e664765e0010734aee468c (diff) |
caddyhttp: Log request body bytes read (#5461)
-rw-r--r-- | modules/caddyhttp/server.go | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index eb61806..82fdbe5 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -19,6 +19,7 @@ import ( "crypto/tls" "encoding/json" "fmt" + "io" "net" "net/http" "net/netip" @@ -259,6 +260,14 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { wrec := NewResponseRecorder(w, nil, nil) w = wrec + // wrap the request body in a LengthReader + // so we can track the number of bytes read from it + var bodyReader *lengthReader + if r.Body != nil { + bodyReader = &lengthReader{Source: r.Body} + r.Body = bodyReader + } + // capture the original version of the request accLog := s.accessLogger.With(loggableReq) @@ -285,7 +294,13 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { userID, _ := repl.GetString("http.auth.user.id") + reqBodyLength := 0 + if bodyReader != nil { + reqBodyLength = bodyReader.Length + } + log("handled request", + zap.Int("bytes_read", reqBodyLength), zap.String("user_id", userID), zap.Duration("duration", duration), zap.Int("size", wrec.Size()), @@ -826,6 +841,23 @@ func cloneURL(from, to *url.URL) { } } +// lengthReader is an io.ReadCloser that keeps track of the +// number of bytes read from the request body. +type lengthReader struct { + Source io.ReadCloser + Length int +} + +func (r *lengthReader) Read(b []byte) (int, error) { + n, err := r.Source.Read(b) + r.Length += n + return n, err +} + +func (r *lengthReader) Close() error { + return r.Source.Close() +} + // Context keys for HTTP request context values. const ( // For referencing the server instance |