From 7960b4259d976810691f1085332d4761abab9928 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Mon, 11 May 2020 12:14:47 -0600 Subject: [PATCH] caddyhttp: Minor refactoring for preparing requests While building a layer4 app for Caddy, I discovered that we need the ability to fill a request's context just like the HTTP server does, hence this exported function PrepareRequest(). --- modules/caddyhttp/routes.go | 4 ++-- modules/caddyhttp/server.go | 32 ++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/modules/caddyhttp/routes.go b/modules/caddyhttp/routes.go index 27d49225..10e0c9de 100644 --- a/modules/caddyhttp/routes.go +++ b/modules/caddyhttp/routes.go @@ -113,7 +113,7 @@ func (r Route) Empty() bool { // create a middleware chain. type RouteList []Route -// Provision sets up both the matchers and handlers in the route. +// Provision sets up both the matchers and handlers in the routes. func (routes RouteList) Provision(ctx caddy.Context) error { err := routes.ProvisionMatchers(ctx) if err != nil { @@ -284,7 +284,7 @@ type RawMatcherSets []caddy.ModuleMap type MatcherSets []MatcherSet // AnyMatch returns true if req matches any of the -// matcher sets in mss or if there are no matchers, +// matcher sets in ms or if there are no matchers, // in which case the request always matches. func (ms MatcherSets) AnyMatch(req *http.Request) bool { for _, m := range ms { diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index a4fda28c..55da2530 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -145,19 +145,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } - // set up the context for the request repl := caddy.NewReplacer() - ctx := context.WithValue(r.Context(), caddy.ReplacerCtxKey, repl) - ctx = context.WithValue(ctx, ServerCtxKey, s) - ctx = context.WithValue(ctx, VarsCtxKey, make(map[string]interface{})) - ctx = context.WithValue(ctx, routeGroupCtxKey, make(map[string]struct{})) - var url2 url.URL // avoid letting this escape to the heap - ctx = context.WithValue(ctx, OriginalRequestCtxKey, originalRequest(r, &url2)) - r = r.WithContext(ctx) - - // once the pointer to the request won't change - // anymore, finish setting up the replacer - addHTTPVarsToReplacer(repl, r, w) + r = PrepareRequest(r, repl, w, s) // encode the request for logging purposes before // it enters any handler chain; this is necessary @@ -470,6 +459,25 @@ func (slc ServerLogConfig) getLoggerName(host string) string { return slc.DefaultLoggerName } +// PrepareRequest fills the request r for use in a Caddy HTTP handler chain. w and s can +// be nil, but the handlers will lose response placeholders and access to the server. +func PrepareRequest(r *http.Request, repl *caddy.Replacer, w http.ResponseWriter, s *Server) *http.Request { + // set up the context for the request + ctx := context.WithValue(r.Context(), caddy.ReplacerCtxKey, repl) + ctx = context.WithValue(ctx, ServerCtxKey, s) + ctx = context.WithValue(ctx, VarsCtxKey, make(map[string]interface{})) + ctx = context.WithValue(ctx, routeGroupCtxKey, make(map[string]struct{})) + var url2 url.URL // avoid letting this escape to the heap + ctx = context.WithValue(ctx, OriginalRequestCtxKey, originalRequest(r, &url2)) + r = r.WithContext(ctx) + + // once the pointer to the request won't change + // anymore, finish setting up the replacer + addHTTPVarsToReplacer(repl, r, w) + + return r +} + // errLogValues inspects err and returns the status code // to use, the error log message, and any extra fields. // If err is a HandlerError, the returned values will