Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 17:15 UTC
caddyhttp: {http.request.body_base64} placeholder (#7367)
Francis Lavoie committed
Dec 13, 2025 at 23:01 UTC
4037d0576094c5f9f570825601615b62cb8d85b1
2 files changed
+16
modules/caddyhttp/app.go
+1
@@ -51,6 +51,7 @@ func init() {
51
// Placeholder | Description
52
// ------------|---------------
53
// `{http.request.body}` | The request body (⚠️ inefficient; use only for debugging)
54
+// `{http.request.body_base64}` | The request body, base64-encoded (⚠️ for debugging)
55
// `{http.request.cookie.*}` | HTTP request cookie
56
// `{http.request.duration}` | Time up to now spent handling the request (after decoding headers from client)
57
// `{http.request.duration_ms}` | Same as 'duration', but in milliseconds.
modules/caddyhttp/replacer.go
+15
@@ -229,6 +229,21 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo
229
req.Body = io.NopCloser(buf) // replace real body with buffered data
230
return buf.String(), true
231
232
+ case "http.request.body_base64":
233
+ if req.Body == nil {
234
+ return "", true
235
+ }
236
+ // normally net/http will close the body for us, but since we
237
+ // are replacing it with a fake one, we have to ensure we close
238
+ // the real body ourselves when we're done
239
+ defer req.Body.Close()
240
+ // read the request body into a buffer (can't pool because we
241
+ // don't know its lifetime and would have to make a copy anyway)
242
+ buf := new(bytes.Buffer)
243
+ _, _ = io.Copy(buf, req.Body) // can't handle error, so just ignore it
244
+ req.Body = io.NopCloser(buf) // replace real body with buffered data
245
+ return base64.StdEncoding.EncodeToString(buf.Bytes()), true
246
+
247
// original request, before any internal changes
248
case "http.request.orig_method":
249
or, _ := req.Context().Value(OriginalRequestCtxKey).(http.Request)