diff options
Diffstat (limited to 'modules/caddyhttp/reverseproxy')
| -rw-r--r-- | modules/caddyhttp/reverseproxy/caddyfile.go | 12 | ||||
| -rw-r--r-- | modules/caddyhttp/reverseproxy/circuitbreaker.go | 4 | ||||
| -rw-r--r-- | modules/caddyhttp/reverseproxy/command.go | 6 | ||||
| -rw-r--r-- | modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go | 17 | ||||
| -rw-r--r-- | modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go | 4 | ||||
| -rw-r--r-- | modules/caddyhttp/reverseproxy/httptransport.go | 5 | ||||
| -rw-r--r-- | modules/caddyhttp/reverseproxy/ntlm.go | 8 | ||||
| -rw-r--r-- | modules/caddyhttp/reverseproxy/reverseproxy.go | 50 | ||||
| -rw-r--r-- | modules/caddyhttp/reverseproxy/selectionpolicies.go | 32 | 
9 files changed, 69 insertions, 69 deletions
diff --git a/modules/caddyhttp/reverseproxy/caddyfile.go b/modules/caddyhttp/reverseproxy/caddyfile.go index c8cf26e..9dba769 100644 --- a/modules/caddyhttp/reverseproxy/caddyfile.go +++ b/modules/caddyhttp/reverseproxy/caddyfile.go @@ -108,11 +108,11 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {  				name := d.Val()  				mod, err := caddy.GetModule("http.handlers.reverse_proxy.selection_policies." + name)  				if err != nil { -					return d.Errf("getting load balancing policy module '%s': %v", mod.Name, err) +					return d.Errf("getting load balancing policy module '%s': %v", mod, err)  				}  				unm, ok := mod.New().(caddyfile.Unmarshaler)  				if !ok { -					return d.Errf("load balancing policy module '%s' is not a Caddyfile unmarshaler", mod.Name) +					return d.Errf("load balancing policy module '%s' is not a Caddyfile unmarshaler", mod)  				}  				err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())  				if err != nil { @@ -120,7 +120,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {  				}  				sel, ok := unm.(Selector)  				if !ok { -					return d.Errf("module %s is not a Selector", mod.Name) +					return d.Errf("module %s is not a Selector", mod)  				}  				if h.LoadBalancing == nil {  					h.LoadBalancing = new(LoadBalancing) @@ -391,11 +391,11 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {  				name := d.Val()  				mod, err := caddy.GetModule("http.handlers.reverse_proxy.transport." + name)  				if err != nil { -					return d.Errf("getting transport module '%s': %v", mod.Name, err) +					return d.Errf("getting transport module '%s': %v", mod, err)  				}  				unm, ok := mod.New().(caddyfile.Unmarshaler)  				if !ok { -					return d.Errf("transport module '%s' is not a Caddyfile unmarshaler", mod.Name) +					return d.Errf("transport module '%s' is not a Caddyfile unmarshaler", mod)  				}  				err = unm.UnmarshalCaddyfile(d.NewFromNextTokens())  				if err != nil { @@ -403,7 +403,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {  				}  				rt, ok := unm.(http.RoundTripper)  				if !ok { -					return d.Errf("module %s is not a RoundTripper", mod.Name) +					return d.Errf("module %s is not a RoundTripper", mod)  				}  				h.TransportRaw = caddyconfig.JSONModuleObject(rt, "protocol", name, nil) diff --git a/modules/caddyhttp/reverseproxy/circuitbreaker.go b/modules/caddyhttp/reverseproxy/circuitbreaker.go index de2a6f9..474f1c6 100644 --- a/modules/caddyhttp/reverseproxy/circuitbreaker.go +++ b/modules/caddyhttp/reverseproxy/circuitbreaker.go @@ -41,8 +41,8 @@ type localCircuitBreaker struct {  // CaddyModule returns the Caddy module information.  func (localCircuitBreaker) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.circuit_breakers.local", -		New:  func() caddy.Module { return new(localCircuitBreaker) }, +		ID:  "http.reverse_proxy.circuit_breakers.local", +		New: func() caddy.Module { return new(localCircuitBreaker) },  	}  } diff --git a/modules/caddyhttp/reverseproxy/command.go b/modules/caddyhttp/reverseproxy/command.go index 0ddb8f2..e16c4f5 100644 --- a/modules/caddyhttp/reverseproxy/command.go +++ b/modules/caddyhttp/reverseproxy/command.go @@ -113,8 +113,8 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {  	}  	urlHost := fromURL.Hostname()  	if urlHost != "" { -		route.MatcherSetsRaw = []map[string]json.RawMessage{ -			map[string]json.RawMessage{ +		route.MatcherSetsRaw = []caddy.ModuleMap{ +			caddy.ModuleMap{  				"host": caddyconfig.JSON(caddyhttp.MatchHost{urlHost}, nil),  			},  		} @@ -138,7 +138,7 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {  	cfg := &caddy.Config{  		Admin: &caddy.AdminConfig{Disabled: true}, -		AppsRaw: map[string]json.RawMessage{ +		AppsRaw: caddy.ModuleMap{  			"http": caddyconfig.JSON(httpApp, nil),  		},  	} diff --git a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go index ed97342..8e723b2 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go @@ -18,6 +18,7 @@ import (  	"encoding/json"  	"net/http" +	"github.com/caddyserver/caddy/v2"  	"github.com/caddyserver/caddy/v2/caddyconfig"  	"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"  	"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" @@ -121,12 +122,12 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error  	}  	// route to redirect to canonical path if index PHP file -	redirMatcherSet := map[string]json.RawMessage{ +	redirMatcherSet := caddy.ModuleMap{  		"file": h.JSON(fileserver.MatchFile{  			TryFiles: []string{"{http.request.uri.path}/index.php"},  		}, nil),  		"not": h.JSON(caddyhttp.MatchNegate{ -			MatchersRaw: map[string]json.RawMessage{ +			MatchersRaw: caddy.ModuleMap{  				"path": h.JSON(caddyhttp.MatchPath{"*/"}, nil),  			},  		}, nil), @@ -136,12 +137,12 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error  		Headers:    http.Header{"Location": []string{"{http.request.uri.path}/"}},  	}  	redirRoute := caddyhttp.Route{ -		MatcherSetsRaw: []map[string]json.RawMessage{redirMatcherSet}, +		MatcherSetsRaw: []caddy.ModuleMap{redirMatcherSet},  		HandlersRaw:    []json.RawMessage{caddyconfig.JSONModuleObject(redirHandler, "handler", "static_response", nil)},  	}  	// route to rewrite to PHP index file -	rewriteMatcherSet := map[string]json.RawMessage{ +	rewriteMatcherSet := caddy.ModuleMap{  		"file": h.JSON(fileserver.MatchFile{  			TryFiles: []string{"{http.request.uri.path}", "{http.request.uri.path}/index.php", "index.php"},  		}, nil), @@ -151,13 +152,13 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error  		Rehandle: true,  	}  	rewriteRoute := caddyhttp.Route{ -		MatcherSetsRaw: []map[string]json.RawMessage{rewriteMatcherSet}, +		MatcherSetsRaw: []caddy.ModuleMap{rewriteMatcherSet},  		HandlersRaw:    []json.RawMessage{caddyconfig.JSONModuleObject(rewriteHandler, "handler", "rewrite", nil)},  	}  	// route to actually reverse proxy requests to PHP files;  	// match only requests that are for PHP files -	rpMatcherSet := map[string]json.RawMessage{ +	rpMatcherSet := caddy.ModuleMap{  		"path": h.JSON([]string{"*.php"}, nil),  	} @@ -193,7 +194,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error  	// create the final reverse proxy route which is  	// conditional on matching PHP files  	rpRoute := caddyhttp.Route{ -		MatcherSetsRaw: []map[string]json.RawMessage{rpMatcherSet}, +		MatcherSetsRaw: []caddy.ModuleMap{rpMatcherSet},  		HandlersRaw:    []json.RawMessage{caddyconfig.JSONModuleObject(rpHandler, "handler", "reverse_proxy", nil)},  	} @@ -207,7 +208,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error  			{  				Class: "route",  				Value: caddyhttp.Route{ -					MatcherSetsRaw: []map[string]json.RawMessage{userMatcherSet}, +					MatcherSetsRaw: []caddy.ModuleMap{userMatcherSet},  					HandlersRaw:    []json.RawMessage{caddyconfig.JSONModuleObject(subroute, "handler", "subroute", nil)},  				},  			}, diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go index 21aeb17..aff9a6e 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go @@ -73,8 +73,8 @@ type Transport struct {  // CaddyModule returns the Caddy module information.  func (Transport) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.transport.fastcgi", -		New:  func() caddy.Module { return new(Transport) }, +		ID:  "http.reverse_proxy.transport.fastcgi", +		New: func() caddy.Module { return new(Transport) },  	}  } diff --git a/modules/caddyhttp/reverseproxy/httptransport.go b/modules/caddyhttp/reverseproxy/httptransport.go index 38a904e..1dd1d14 100644 --- a/modules/caddyhttp/reverseproxy/httptransport.go +++ b/modules/caddyhttp/reverseproxy/httptransport.go @@ -40,6 +40,7 @@ type HTTPTransport struct {  	// TODO: It's possible that other transports (like fastcgi) might be  	// able to borrow/use at least some of these config fields; if so,  	// maybe move them into a type called CommonTransport and embed it? +  	TLS                   *TLSConfig     `json:"tls,omitempty"`  	KeepAlive             *KeepAlive     `json:"keep_alive,omitempty"`  	Compression           *bool          `json:"compression,omitempty"` @@ -59,8 +60,8 @@ type HTTPTransport struct {  // CaddyModule returns the Caddy module information.  func (HTTPTransport) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.transport.http", -		New:  func() caddy.Module { return new(HTTPTransport) }, +		ID:  "http.reverse_proxy.transport.http", +		New: func() caddy.Module { return new(HTTPTransport) },  	}  } diff --git a/modules/caddyhttp/reverseproxy/ntlm.go b/modules/caddyhttp/reverseproxy/ntlm.go index e2d46b4..ea2bb85 100644 --- a/modules/caddyhttp/reverseproxy/ntlm.go +++ b/modules/caddyhttp/reverseproxy/ntlm.go @@ -30,12 +30,12 @@ func init() {  	caddy.RegisterModule(NTLMTransport{})  } -// NTLMTransport proxies HTTP+NTLM authentication is being used. +// NTLMTransport proxies HTTP with NTLM authentication.  // It basically wraps HTTPTransport so that it is compatible with  // NTLM's HTTP-hostile requirements. Specifically, it will use  // HTTPTransport's single, default *http.Transport for all requests  // (unless the client's connection is already mapped to a different -// transport) until a request comes in with Authorization header +// transport) until a request comes in with an Authorization header  // that has "NTLM" or "Negotiate"; when that happens, NTLMTransport  // maps the client's connection (by its address, req.RemoteAddr)  // to a new transport that is used only by that downstream conn. @@ -56,8 +56,8 @@ type NTLMTransport struct {  // CaddyModule returns the Caddy module information.  func (NTLMTransport) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.transport.http_ntlm", -		New:  func() caddy.Module { return new(NTLMTransport) }, +		ID:  "http.reverse_proxy.transport.http_ntlm", +		New: func() caddy.Module { return new(NTLMTransport) },  	}  } diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go index 87895e2..132f222 100644 --- a/modules/caddyhttp/reverseproxy/reverseproxy.go +++ b/modules/caddyhttp/reverseproxy/reverseproxy.go @@ -42,8 +42,8 @@ func init() {  // Handler implements a highly configurable and production-ready reverse proxy.  type Handler struct { -	TransportRaw   json.RawMessage  `json:"transport,omitempty"` -	CBRaw          json.RawMessage  `json:"circuit_breaker,omitempty"` +	TransportRaw   json.RawMessage  `json:"transport,omitempty" caddy:"namespace=http.reverse_proxy.transport inline_key=protocol"` +	CBRaw          json.RawMessage  `json:"circuit_breaker,omitempty" caddy:"namespace=http.reverse_proxy.circuit_breakers inline_key=type"`  	LoadBalancing  *LoadBalancing   `json:"load_balancing,omitempty"`  	HealthChecks   *HealthChecks    `json:"health_checks,omitempty"`  	Upstreams      UpstreamPool     `json:"upstreams,omitempty"` @@ -60,8 +60,8 @@ type Handler struct {  // CaddyModule returns the Caddy module information.  func (Handler) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy", -		New:  func() caddy.Module { return new(Handler) }, +		ID:  "http.handlers.reverse_proxy", +		New: func() caddy.Module { return new(Handler) },  	}  } @@ -71,30 +71,25 @@ func (h *Handler) Provision(ctx caddy.Context) error {  	// start by loading modules  	if h.TransportRaw != nil { -		val, err := ctx.LoadModuleInline("protocol", "http.handlers.reverse_proxy.transport", h.TransportRaw) +		mod, err := ctx.LoadModule(h, "TransportRaw")  		if err != nil { -			return fmt.Errorf("loading transport module: %s", err) +			return fmt.Errorf("loading transport: %v", err)  		} -		h.Transport = val.(http.RoundTripper) -		h.TransportRaw = nil // allow GC to deallocate +		h.Transport = mod.(http.RoundTripper)  	}  	if h.LoadBalancing != nil && h.LoadBalancing.SelectionPolicyRaw != nil { -		val, err := ctx.LoadModuleInline("policy", -			"http.handlers.reverse_proxy.selection_policies", -			h.LoadBalancing.SelectionPolicyRaw) +		mod, err := ctx.LoadModule(h.LoadBalancing, "SelectionPolicyRaw")  		if err != nil { -			return fmt.Errorf("loading load balancing selection module: %s", err) +			return fmt.Errorf("loading load balancing selection policy: %s", err)  		} -		h.LoadBalancing.SelectionPolicy = val.(Selector) -		h.LoadBalancing.SelectionPolicyRaw = nil // allow GC to deallocate +		h.LoadBalancing.SelectionPolicy = mod.(Selector)  	}  	if h.CBRaw != nil { -		val, err := ctx.LoadModuleInline("type", "http.handlers.reverse_proxy.circuit_breakers", h.CBRaw) +		mod, err := ctx.LoadModule(h, "CBRaw")  		if err != nil { -			return fmt.Errorf("loading circuit breaker module: %s", err) +			return fmt.Errorf("loading circuit breaker: %s", err)  		} -		h.CB = val.(CircuitBreaker) -		h.CBRaw = nil // allow GC to deallocate +		h.CB = mod.(CircuitBreaker)  	}  	// set up transport @@ -128,12 +123,14 @@ func (h *Handler) Provision(ctx caddy.Context) error {  		// defaulting to a sane wait period between attempts  		h.LoadBalancing.TryInterval = caddy.Duration(250 * time.Millisecond)  	} -	lbMatcherSets, err := h.LoadBalancing.RetryMatchRaw.Setup(ctx) +	lbMatcherSets, err := ctx.LoadModule(h.LoadBalancing, "RetryMatchRaw") +	if err != nil { +		return err +	} +	err = h.LoadBalancing.RetryMatch.FromInterface(lbMatcherSets)  	if err != nil {  		return err  	} -	h.LoadBalancing.RetryMatch = lbMatcherSets -	h.LoadBalancing.RetryMatchRaw = nil // allow GC to deallocate  	// if active health checks are enabled, configure them and start a worker  	if h.HealthChecks != nil && @@ -407,7 +404,7 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, di Dia  	// do the round-trip  	start := time.Now()  	res, err := h.Transport.RoundTrip(req) -	latency := time.Since(start) +	duration := time.Since(start)  	if err != nil {  		return err  	} @@ -415,12 +412,13 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, di Dia  	h.logger.Debug("upstream roundtrip",  		zap.Object("request", caddyhttp.LoggableHTTPRequest{Request: req}),  		zap.Object("headers", caddyhttp.LoggableHTTPHeader(res.Header)), +		zap.Duration("duration", duration),  		zap.Int("status", res.StatusCode),  	)  	// update circuit breaker on current conditions  	if di.Upstream.cb != nil { -		di.Upstream.cb.RecordMetric(res.StatusCode, latency) +		di.Upstream.cb.RecordMetric(res.StatusCode, duration)  	}  	// perform passive health checks (if enabled) @@ -434,7 +432,7 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, di Dia  		// strike if the roundtrip took too long  		if h.HealthChecks.Passive.UnhealthyLatency > 0 && -			latency >= time.Duration(h.HealthChecks.Passive.UnhealthyLatency) { +			duration >= time.Duration(h.HealthChecks.Passive.UnhealthyLatency) {  			h.countFailure(di.Upstream)  		}  	} @@ -651,10 +649,10 @@ func removeConnectionHeaders(h http.Header) {  // LoadBalancing has parameters related to load balancing.  type LoadBalancing struct { -	SelectionPolicyRaw json.RawMessage          `json:"selection_policy,omitempty"` +	SelectionPolicyRaw json.RawMessage          `json:"selection_policy,omitempty" caddy:"namespace=http.reverse_proxy.selection_policies inline_key=policy"`  	TryDuration        caddy.Duration           `json:"try_duration,omitempty"`  	TryInterval        caddy.Duration           `json:"try_interval,omitempty"` -	RetryMatchRaw      caddyhttp.RawMatcherSets `json:"retry_match,omitempty"` +	RetryMatchRaw      caddyhttp.RawMatcherSets `json:"retry_match,omitempty" caddy:"namespace=http.matchers"`  	SelectionPolicy Selector              `json:"-"`  	RetryMatch      caddyhttp.MatcherSets `json:"-"` diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies.go b/modules/caddyhttp/reverseproxy/selectionpolicies.go index a21e44c..937ae37 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies.go @@ -48,8 +48,8 @@ type RandomSelection struct{}  // CaddyModule returns the Caddy module information.  func (RandomSelection) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.selection_policies.random", -		New:  func() caddy.Module { return new(RandomSelection) }, +		ID:  "http.reverse_proxy.selection_policies.random", +		New: func() caddy.Module { return new(RandomSelection) },  	}  } @@ -84,8 +84,8 @@ type RandomChoiceSelection struct {  // CaddyModule returns the Caddy module information.  func (RandomChoiceSelection) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.selection_policies.random_choose", -		New:  func() caddy.Module { return new(RandomChoiceSelection) }, +		ID:  "http.reverse_proxy.selection_policies.random_choose", +		New: func() caddy.Module { return new(RandomChoiceSelection) },  	}  } @@ -154,8 +154,8 @@ type LeastConnSelection struct{}  // CaddyModule returns the Caddy module information.  func (LeastConnSelection) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.selection_policies.least_conn", -		New:  func() caddy.Module { return new(LeastConnSelection) }, +		ID:  "http.reverse_proxy.selection_policies.least_conn", +		New: func() caddy.Module { return new(LeastConnSelection) },  	}  } @@ -199,8 +199,8 @@ type RoundRobinSelection struct {  // CaddyModule returns the Caddy module information.  func (RoundRobinSelection) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.selection_policies.round_robin", -		New:  func() caddy.Module { return new(RoundRobinSelection) }, +		ID:  "http.reverse_proxy.selection_policies.round_robin", +		New: func() caddy.Module { return new(RoundRobinSelection) },  	}  } @@ -227,8 +227,8 @@ type FirstSelection struct{}  // CaddyModule returns the Caddy module information.  func (FirstSelection) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.selection_policies.first", -		New:  func() caddy.Module { return new(FirstSelection) }, +		ID:  "http.reverse_proxy.selection_policies.first", +		New: func() caddy.Module { return new(FirstSelection) },  	}  } @@ -249,8 +249,8 @@ type IPHashSelection struct{}  // CaddyModule returns the Caddy module information.  func (IPHashSelection) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.selection_policies.ip_hash", -		New:  func() caddy.Module { return new(IPHashSelection) }, +		ID:  "http.reverse_proxy.selection_policies.ip_hash", +		New: func() caddy.Module { return new(IPHashSelection) },  	}  } @@ -270,8 +270,8 @@ type URIHashSelection struct{}  // CaddyModule returns the Caddy module information.  func (URIHashSelection) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.selection_policies.uri_hash", -		New:  func() caddy.Module { return new(URIHashSelection) }, +		ID:  "http.reverse_proxy.selection_policies.uri_hash", +		New: func() caddy.Module { return new(URIHashSelection) },  	}  } @@ -289,8 +289,8 @@ type HeaderHashSelection struct {  // CaddyModule returns the Caddy module information.  func (HeaderHashSelection) CaddyModule() caddy.ModuleInfo {  	return caddy.ModuleInfo{ -		Name: "http.handlers.reverse_proxy.selection_policies.header", -		New:  func() caddy.Module { return new(HeaderHashSelection) }, +		ID:  "http.reverse_proxy.selection_policies.header", +		New: func() caddy.Module { return new(HeaderHashSelection) },  	}  }  | 
