caddyhttp: Add {http.request.body} placeholder

This commit is contained in:
Matthew Holt 2020-07-16 19:25:37 -06:00
parent 6eafd4e82f
commit 6f0f159ba5
No known key found for this signature in database
GPG key ID: 2A349DD577D586A5
2 changed files with 22 additions and 0 deletions

View file

@ -47,6 +47,7 @@ func init() {
//
// Placeholder | Description
// ------------|---------------
// `{http.request.body}` | The request body (⚠️ inefficient; use only for debugging)
// `{http.request.cookie.*}` | HTTP request cookie
// `{http.request.header.*}` | Specific request header field
// `{http.request.host.labels.*}` | Request host labels (0-based from right); e.g. for foo.example.com: 0=com, 1=example, 2=foo

View file

@ -15,6 +15,7 @@
package caddyhttp
import (
"bytes"
"context"
"crypto/ecdsa"
"crypto/ed25519"
@ -25,6 +26,8 @@ import (
"crypto/x509"
"encoding/asn1"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/textproto"
@ -136,6 +139,24 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo
return dir, true
case "http.request.uri.query":
return req.URL.RawQuery, true
case "http.request.body":
if req.Body == nil {
return "", true
}
// normally net/http will close the body for us, but since we
// are replacing it with a fake one, we have to ensure we close
// the real body ourselves when we're done
defer req.Body.Close()
// read the request body into a buffer (can't pool because we
// don't know its lifetime and would have to make a copy anyway)
buf := new(bytes.Buffer)
_, err := io.Copy(buf, req.Body)
if err != nil {
return "", true
}
// replace real body with buffered data
req.Body = ioutil.NopCloser(buf)
return buf.String(), true
// original request, before any internal changes
case "http.request.orig_method":