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
+}