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().
This commit is contained in:
Matthew Holt 2020-05-11 12:14:47 -06:00
parent 2c91688f39
commit 7960b4259d
No known key found for this signature in database
GPG key ID: 2A349DD577D586A5
2 changed files with 22 additions and 14 deletions

View file

@ -113,7 +113,7 @@ func (r Route) Empty() bool {
// create a middleware chain. // create a middleware chain.
type RouteList []Route 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 { func (routes RouteList) Provision(ctx caddy.Context) error {
err := routes.ProvisionMatchers(ctx) err := routes.ProvisionMatchers(ctx)
if err != nil { if err != nil {
@ -284,7 +284,7 @@ type RawMatcherSets []caddy.ModuleMap
type MatcherSets []MatcherSet type MatcherSets []MatcherSet
// AnyMatch returns true if req matches any of the // 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. // in which case the request always matches.
func (ms MatcherSets) AnyMatch(req *http.Request) bool { func (ms MatcherSets) AnyMatch(req *http.Request) bool {
for _, m := range ms { for _, m := range ms {

View file

@ -145,19 +145,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
} }
// set up the context for the request
repl := caddy.NewReplacer() repl := caddy.NewReplacer()
ctx := context.WithValue(r.Context(), caddy.ReplacerCtxKey, repl) r = PrepareRequest(r, repl, w, s)
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)
// encode the request for logging purposes before // encode the request for logging purposes before
// it enters any handler chain; this is necessary // it enters any handler chain; this is necessary
@ -470,6 +459,25 @@ func (slc ServerLogConfig) getLoggerName(host string) string {
return slc.DefaultLoggerName 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 // errLogValues inspects err and returns the status code
// to use, the error log message, and any extra fields. // to use, the error log message, and any extra fields.
// If err is a HandlerError, the returned values will // If err is a HandlerError, the returned values will