mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-25 17:56:34 +08:00
httpserver: give each req context a Replacer that preserves custom values (#1937)
This allows custom replacements to be defined in a way that propagates throughout all plugins.
This commit is contained in:
parent
169ab3acda
commit
9a22cda15d
|
@ -214,6 +214,9 @@ func SameNext(next1, next2 Handler) bool {
|
|||
|
||||
// Context key constants.
|
||||
const (
|
||||
// ReplacerCtxKey is the context key for a per-request replacer.
|
||||
ReplacerCtxKey caddy.CtxKey = "replacer"
|
||||
|
||||
// RemoteUserCtxKey is the key for the remote user of the request, if any (basicauth).
|
||||
RemoteUserCtxKey caddy.CtxKey = "remote_user"
|
||||
|
||||
|
|
|
@ -102,20 +102,30 @@ func (lw *limitWriter) String() string {
|
|||
// emptyValue should be the string that is used in place
|
||||
// of empty string (can still be empty string).
|
||||
func NewReplacer(r *http.Request, rr *ResponseRecorder, emptyValue string) Replacer {
|
||||
rb := newLimitWriter(MaxLogBodySize)
|
||||
if r.Body != nil {
|
||||
r.Body = struct {
|
||||
io.Reader
|
||||
io.Closer
|
||||
}{io.TeeReader(r.Body, rb), io.Closer(r.Body)}
|
||||
repl := &replacer{
|
||||
request: r,
|
||||
responseRecorder: rr,
|
||||
emptyValue: emptyValue,
|
||||
}
|
||||
return &replacer{
|
||||
request: r,
|
||||
requestBody: rb,
|
||||
responseRecorder: rr,
|
||||
customReplacements: make(map[string]string),
|
||||
emptyValue: emptyValue,
|
||||
|
||||
// extract customReplacements from a request replacer when present.
|
||||
if existing, ok := r.Context().Value(ReplacerCtxKey).(*replacer); ok {
|
||||
repl.requestBody = existing.requestBody
|
||||
repl.customReplacements = existing.customReplacements
|
||||
} else {
|
||||
// if there is no existing replacer, build one from scratch.
|
||||
rb := newLimitWriter(MaxLogBodySize)
|
||||
if r.Body != nil {
|
||||
r.Body = struct {
|
||||
io.Reader
|
||||
io.Closer
|
||||
}{io.TeeReader(r.Body, rb), io.Closer(r.Body)}
|
||||
}
|
||||
repl.requestBody = rb
|
||||
repl.customReplacements = make(map[string]string)
|
||||
}
|
||||
|
||||
return repl
|
||||
}
|
||||
|
||||
func canLogRequest(r *http.Request) bool {
|
||||
|
|
|
@ -356,6 +356,12 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
c := context.WithValue(r.Context(), OriginalURLCtxKey, urlCopy)
|
||||
r = r.WithContext(c)
|
||||
|
||||
// Setup a replacer for the request that keeps track of placeholder
|
||||
// values across plugins.
|
||||
replacer := NewReplacer(r, nil, "")
|
||||
c = context.WithValue(r.Context(), ReplacerCtxKey, replacer)
|
||||
r = r.WithContext(c)
|
||||
|
||||
w.Header().Set("Server", caddy.AppName)
|
||||
|
||||
status, _ := s.serveHTTP(w, r)
|
||||
|
|
Loading…
Reference in New Issue
Block a user