@marcel91200 / caddy Mirror · read-only / commits / bc738991
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

caddyhttp: Support placeholders in MatchHost (#2810)

* Replace global placeholders in host matcher * caddyhttp: Fix panic on MatchHost tests

Pascal committed Oct 14, 2019 at 19:29 UTC bc738991b6234bf334855e1396919e79ef9791b8
3 files changed +58
modules/caddyhttp/caddyhttp.go
+3
@@ -273,6 +273,8 @@ func (app *App) automaticHTTPS() error {
273 // addresses to the routes that do HTTP->HTTPS redirects
274 lnAddrRedirRoutes := make(map[string]Route)
275
276 + repl := caddy.NewReplacer()
277 +
278 for srvName, srv := range app.Servers {
279 srv.tlsApp = tlsApp
280
@@ -294,6 +296,7 @@ func (app *App) automaticHTTPS() error {
296 for _, m := range matcherSet {
297 if hm, ok := m.(*MatchHost); ok {
298 for _, d := range *hm {
299 + d = repl.ReplaceAll(d, "")
300 if certmagic.HostQualifies(d) &&
301 !srv.AutoHTTPS.Skipped(d, srv.AutoHTTPS.Skip) {
302 domainSet[d] = struct{}{}
modules/caddyhttp/matchers.go
+3
@@ -118,8 +118,11 @@ func (m MatchHost) Match(r *http.Request) bool {
118 reqHost = strings.TrimSuffix(reqHost, "]")
119 }
120
121 + repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
122 +
123 outer:
124 for _, host := range m {
125 + host = repl.ReplaceAll(host, "")
126 if strings.Contains(host, "*") {
127 patternParts := strings.Split(host, ".")
128 incomingParts := strings.Split(reqHost, ".")
modules/caddyhttp/matchers_test.go
+52
@@ -20,12 +20,18 @@ import (
20 "net/http"
21 "net/http/httptest"
22 "net/url"
23 + "os"
24 "testing"
25
26 "github.com/caddyserver/caddy/v2"
27 )
28
29 func TestHostMatcher(t *testing.T) {
30 + err := os.Setenv("GO_BENCHMARK_DOMAIN", "localhost")
31 + if err != nil {
32 + t.Errorf("error while setting up environment: %v", err)
33 + }
34 +
35 for i, tc := range []struct {
36 match MatchHost
37 input string
@@ -106,8 +112,22 @@ func TestHostMatcher(t *testing.T) {
112 input: "example.com:5555",
113 expect: true,
114 },
115 + {
116 + match: MatchHost{"{env.GO_BENCHMARK_DOMAIN}"},
117 + input: "localhost",
118 + expect: true,
119 + },
120 + {
121 + match: MatchHost{"{env.GO_NONEXISTENT}"},
122 + input: "localhost",
123 + expect: false,
124 + },
125 } {
126 req := &http.Request{Host: tc.input}
127 + repl := caddy.NewReplacer()
128 + ctx := context.WithValue(req.Context(), caddy.ReplacerCtxKey, repl)
129 + req = req.WithContext(ctx)
130 +
131 actual := tc.match.Match(req)
132 if actual != tc.expect {
133 t.Errorf("Test %d %v: Expected %t, got %t for '%s'", i, tc.match, tc.expect, actual, tc.input)
@@ -518,3 +538,35 @@ func TestResponseMatcher(t *testing.T) {
538 }
539 }
540 }
541 +
542 +func BenchmarkHostMatcherWithoutPlaceholder(b *testing.B) {
543 + req := &http.Request{Host: "localhost"}
544 + repl := caddy.NewReplacer()
545 + ctx := context.WithValue(req.Context(), caddy.ReplacerCtxKey, repl)
546 + req = req.WithContext(ctx)
547 +
548 + match := MatchHost{"localhost"}
549 +
550 + b.ResetTimer()
551 + for i := 0; i < b.N; i++ {
552 + match.Match(req)
553 + }
554 +}
555 +
556 +func BenchmarkHostMatcherWithPlaceholder(b *testing.B) {
557 + err := os.Setenv("GO_BENCHMARK_DOMAIN", "localhost")
558 + if err != nil {
559 + b.Errorf("error while setting up environment: %v", err)
560 + }
561 +
562 + req := &http.Request{Host: "localhost"}
563 + repl := caddy.NewReplacer()
564 + ctx := context.WithValue(req.Context(), caddy.ReplacerCtxKey, repl)
565 + req = req.WithContext(ctx)
566 + match := MatchHost{"{env.GO_BENCHMARK_DOMAIN}"}
567 +
568 + b.ResetTimer()
569 + for i := 0; i < b.N; i++ {
570 + match.Match(req)
571 + }
572 +}