Skip to content

Commit

Permalink
caddyhttp: Implement http.request.uuid placeholder (#4285)
Browse files Browse the repository at this point in the history
  • Loading branch information
rainerborene authored Dec 15, 2021
1 parent a1c4121 commit 180ae0c
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 0 deletions.
1 change: 1 addition & 0 deletions modules/caddyhttp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func init() {
// `{http.request.body}` | The request body (⚠️ inefficient; use only for debugging)
// `{http.request.cookie.*}` | HTTP request cookie
// `{http.request.duration}` | Time up to now spent handling the request (after decoding headers from client)
// `{http.request.uuid}` | The request unique identifier
// `{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
// `{http.request.host}` | The host part of the request's Host header
Expand Down
19 changes: 19 additions & 0 deletions modules/caddyhttp/replacer.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (

"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/modules/caddytls"
"github.com/google/uuid"
)

// NewTestReplacer creates a replacer for an http.Request
Expand All @@ -54,6 +55,7 @@ func NewTestReplacer(req *http.Request) *caddy.Replacer {

func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.ResponseWriter) {
SetVar(req.Context(), "start_time", time.Now())
SetVar(req.Context(), "uuid", new(requestID))

httpVars := func(key string) (interface{}, bool) {
if req != nil {
Expand Down Expand Up @@ -146,6 +148,9 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo
case "http.request.duration":
start := GetVar(req.Context(), "start_time").(time.Time)
return time.Since(start), true
case "http.request.uuid":
id := GetVar(req.Context(), "uuid").(*requestID)
return id.String(), true
case "http.request.body":
if req.Body == nil {
return "", true
Expand Down Expand Up @@ -400,6 +405,20 @@ func getTLSPeerCert(cs *tls.ConnectionState) *x509.Certificate {
return cs.PeerCertificates[0]
}

type requestID struct {
value string
}

// Lazy generates UUID string or return cached value if present
func (rid *requestID) String() string {
if rid.value == "" {
if id, err := uuid.NewRandom(); err == nil {
rid.value = id.String()
}
}
return rid.value
}

const (
reqCookieReplPrefix = "http.request.cookie."
reqHeaderReplPrefix = "http.request.header."
Expand Down

0 comments on commit 180ae0c

Please sign in to comment.