@marcel91200 / caddy Mirror · read-only / commits / acf8d6a1
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 11, 13:30 UTC

caddytls: Consolidate empty APs more smartly (#7567)

* caddytls: Consoldate empty APs more smartly (fix #7559) * Revise consolidation logic

Matt Holt committed Mar 26, 2026 at 14:41 UTC acf8d6a1ae933df6ae8cda037050a51041c1d67e
3 files changed +116 -8
caddyconfig/httpcaddyfile/tlsapp.go
+20 -3
@@ -698,14 +698,31 @@ func consolidateAutomationPolicies(aps []*caddytls.AutomationPolicy) []*caddytls
698 emptyAPCount := 0
699 origLenAPs := len(aps)
700 // compute the number of empty policies (disregarding subjects) - see #4128
701 + // while we're at it,
702 emptyAP := new(caddytls.AutomationPolicy)
703 for i := 0; i < len(aps); i++ {
704 emptyAP.SubjectsRaw = aps[i].SubjectsRaw
705 + emptyAP.ManagersRaw = nil
706 if reflect.DeepEqual(aps[i], emptyAP) {
707 + // AP is empty
708 emptyAPCount++
706 - if !automationPolicyHasAllPublicNames(aps[i]) {
707 - // if this automation policy has internal names, we might as well remove it
708 - // so auto-https can implicitly use the internal issuer
709 +
710 + // see if this AP shadows something later
711 + shadowIdx := automationPolicyShadows(i, aps)
712 + emptyAP.SubjectsRaw = nil
713 + if shadowIdx >= 0 {
714 + emptyAP.SubjectsRaw = aps[shadowIdx].SubjectsRaw
715 + // allow the later policy, which is likely for a wildcard, to have cert
716 + // managers ("get_certificate"), since wildcards now cover specific
717 + // subdomains by default, when configured (see discussion in #7559)
718 + emptyAP.ManagersRaw = aps[shadowIdx].ManagersRaw
719 + }
720 +
721 + // if this is the last AP, we can delete it, since auto-https should
722 + // pick it up; if it shadows something later that is also empty, we
723 + // can similarly delete this; but if it shadows something that is NOT
724 + // empty, we must not delete it since the shadowing has a purpose
725 + if i == len(aps)-1 || (shadowIdx >= 0 && reflect.DeepEqual(aps[shadowIdx], emptyAP)) {
726 aps = slices.Delete(aps, i, i+1)
727 i--
728 }
caddytest/integration/caddyfile_adapt/tls_automation_policies_11.caddyfiletest
-5
@@ -54,11 +54,6 @@ b.com {
54 "via": "http"
55 }
56 ]
57 - },
58 - {
59 - "subjects": [
60 - "b.com"
61 - ]
57 }
58 ]
59 }
caddytest/integration/caddyfile_adapt/tls_automation_policies_12.caddyfiletest new
+96
@@ -0,0 +1,96 @@
1 +# example from https://github.com/caddyserver/caddy/issues/7559
2 +*.test.local {
3 + tls {
4 + get_certificate http http://cert-server:9000/certs
5 + }
6 + respond "wildcard"
7 +}
8 +
9 +# certificate for this subdomain is covered by wildcard above
10 +subdomain.test.local {
11 + respond "subdomain"
12 +}
13 +
14 +----------
15 +{
16 + "apps": {
17 + "http": {
18 + "servers": {
19 + "srv0": {
20 + "listen": [
21 + ":443"
22 + ],
23 + "routes": [
24 + {
25 + "match": [
26 + {
27 + "host": [
28 + "subdomain.test.local"
29 + ]
30 + }
31 + ],
32 + "handle": [
33 + {
34 + "handler": "subroute",
35 + "routes": [
36 + {
37 + "handle": [
38 + {
39 + "body": "subdomain",
40 + "handler": "static_response"
41 + }
42 + ]
43 + }
44 + ]
45 + }
46 + ],
47 + "terminal": true
48 + },
49 + {
50 + "match": [
51 + {
52 + "host": [
53 + "*.test.local"
54 + ]
55 + }
56 + ],
57 + "handle": [
58 + {
59 + "handler": "subroute",
60 + "routes": [
61 + {
62 + "handle": [
63 + {
64 + "body": "wildcard",
65 + "handler": "static_response"
66 + }
67 + ]
68 + }
69 + ]
70 + }
71 + ],
72 + "terminal": true
73 + }
74 + ]
75 + }
76 + }
77 + },
78 + "tls": {
79 + "automation": {
80 + "policies": [
81 + {
82 + "subjects": [
83 + "*.test.local"
84 + ],
85 + "get_certificate": [
86 + {
87 + "url": "http://cert-server:9000/certs",
88 + "via": "http"
89 + }
90 + ]
91 + }
92 + ]
93 + }
94 + }
95 + }
96 +}
\ No newline at end of file