From 1c6c7714a38879f78c486fcb9c7c6e39fc39c6a5 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 14 Jul 2021 12:49:34 -0400 Subject: [PATCH] caddyhttp: Fix edgecase with auto HTTP->HTTPS logic (#4243) --- caddytest/integration/autohttps_test.go | 20 ++++++++++++++++++++ modules/caddyhttp/server.go | 11 +++++++++++ 2 files changed, 31 insertions(+) diff --git a/caddytest/integration/autohttps_test.go b/caddytest/integration/autohttps_test.go index 72968e95..a065b0df 100644 --- a/caddytest/integration/autohttps_test.go +++ b/caddytest/integration/autohttps_test.go @@ -103,3 +103,23 @@ func TestAutoHTTPRedirectsInsertedBeforeUserDefinedCatchAll(t *testing.T) { tester.AssertGetResponse("http://foo.localhost:9080/", 200, "Foo") tester.AssertGetResponse("http://baz.localhost:9080/", 200, "Baz") } + +func TestAutoHTTPRedirectsInsertedBeforeUserDefinedCatchAllWithNoExplicitHTTPSite(t *testing.T) { + tester := caddytest.NewTester(t) + tester.InitServer(` + { + http_port 9080 + https_port 9443 + local_certs + } + http://:9080 { + respond "Foo" + } + bar.localhost { + respond "Bar" + } + `, "caddyfile") + tester.AssertRedirect("http://bar.localhost:9080/", "https://bar.localhost/", http.StatusPermanentRedirect) + tester.AssertGetResponse("http://foo.localhost:9080/", 200, "Foo") + tester.AssertGetResponse("http://baz.localhost:9080/", 200, "Foo") +} diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index 294ee6af..9dc1028e 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -379,7 +379,9 @@ func (s *Server) hasTLSClientAuth() bool { // that it is after any other host matcher but before any "catch-all" // route without a host matcher. func (s *Server) findLastRouteWithHostMatcher() int { + foundHostMatcher := false lastIndex := len(s.Routes) + for i, route := range s.Routes { // since we want to break out of an inner loop, use a closure // to allow us to use 'return' when we found a host matcher @@ -388,6 +390,7 @@ func (s *Server) findLastRouteWithHostMatcher() int { for _, matcher := range sets { switch matcher.(type) { case *MatchHost: + foundHostMatcher = true return true } } @@ -401,6 +404,14 @@ func (s *Server) findLastRouteWithHostMatcher() int { lastIndex = i + 1 } } + + // If we didn't actually find a host matcher, return 0 + // because that means every defined route was a "catch-all". + // See https://caddy.community/t/how-to-set-priority-in-caddyfile/13002/8 + if !foundHostMatcher { + return 0 + } + return lastIndex }