Skip to content

Commit 062de56

Browse files
authored
Merge branch 'master' into leaf-verifier-caddyfile
2 parents 5a9471f + 30743c3 commit 062de56

File tree

13 files changed

+185
-72
lines changed

13 files changed

+185
-72
lines changed

.goreleaser.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ archives:
111111
- id: default
112112
format_overrides:
113113
- goos: windows
114-
format: zip
114+
formats: zip
115115
name_template: >-
116116
{{ .ProjectName }}_
117117
{{- .Version }}_

caddytest/integration/caddyfile_adapt/header.caddyfiletest

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@
1212
@images path /images/*
1313
header @images {
1414
Cache-Control "public, max-age=3600, stale-while-revalidate=86400"
15+
match {
16+
status 200
17+
}
1518
}
1619
header {
1720
+Link "Foo"
1821
+Link "Bar"
22+
match status 200
1923
}
2024
header >Set Defer
2125
header >Replace Deferred Replacement
@@ -42,6 +46,11 @@
4246
{
4347
"handler": "headers",
4448
"response": {
49+
"require": {
50+
"status_code": [
51+
200
52+
]
53+
},
4554
"set": {
4655
"Cache-Control": [
4756
"public, max-age=3600, stale-while-revalidate=86400"
@@ -136,6 +145,11 @@
136145
"Foo",
137146
"Bar"
138147
]
148+
},
149+
"require": {
150+
"status_code": [
151+
200
152+
]
139153
}
140154
}
141155
},

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ require (
99
github.com/Masterminds/sprig/v3 v3.3.0
1010
github.com/alecthomas/chroma/v2 v2.14.0
1111
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
12-
github.com/caddyserver/certmagic v0.21.5
12+
github.com/caddyserver/certmagic v0.21.7
1313
github.com/caddyserver/zerossl v0.1.3
1414
github.com/dustin/go-humanize v1.0.1
1515
github.com/go-chi/chi/v5 v5.0.12
1616
github.com/google/cel-go v0.21.0
1717
github.com/google/uuid v1.6.0
1818
github.com/klauspost/compress v1.17.11
1919
github.com/klauspost/cpuid/v2 v2.2.9
20-
github.com/mholt/acmez/v3 v3.0.0
20+
github.com/mholt/acmez/v3 v3.0.1
2121
github.com/prometheus/client_golang v1.19.1
22-
github.com/quic-go/quic-go v0.48.2
22+
github.com/quic-go/quic-go v0.49.0
2323
github.com/smallstep/certificates v0.26.1
2424
github.com/smallstep/nosql v0.6.1
2525
github.com/smallstep/truststore v0.13.0
@@ -74,7 +74,7 @@ require (
7474
go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect
7575
go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect
7676
go.opentelemetry.io/contrib/propagators/ot v1.17.0 // indirect
77-
go.uber.org/mock v0.4.0 // indirect
77+
go.uber.org/mock v0.5.0 // indirect
7878
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
7979
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect
8080
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect

go.sum

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
8989
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
9090
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
9191
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
92-
github.com/caddyserver/certmagic v0.21.5 h1:iIga4nZRgd27EIEbX7RZmoRMul+EVBn/h7bAGL83dnY=
93-
github.com/caddyserver/certmagic v0.21.5/go.mod h1:n1sCo7zV1Ez2j+89wrzDxo4N/T1Ws/Vx8u5NvuBFabw=
92+
github.com/caddyserver/certmagic v0.21.7 h1:66KJioPFJwttL43KYSWk7ErSmE6LfaJgCQuhm8Sg6fg=
93+
github.com/caddyserver/certmagic v0.21.7/go.mod h1:LCPG3WLxcnjVKl/xpjzM0gqh0knrKKKiO5WVttX2eEI=
9494
github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA=
9595
github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
9696
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
@@ -344,8 +344,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
344344
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
345345
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
346346
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
347-
github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E=
348-
github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ=
347+
github.com/mholt/acmez/v3 v3.0.1 h1:4PcjKjaySlgXK857aTfDuRbmnM5gb3Ruz3tvoSJAUp8=
348+
github.com/mholt/acmez/v3 v3.0.1/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ=
349349
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
350350
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
351351
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
@@ -392,8 +392,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k
392392
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
393393
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
394394
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
395-
github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
396-
github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
395+
github.com/quic-go/quic-go v0.49.0 h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94=
396+
github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s=
397397
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
398398
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
399399
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
@@ -564,8 +564,8 @@ go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
564564
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
565565
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
566566
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
567-
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
568-
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
567+
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
568+
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
569569
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
570570
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
571571
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=

modules/caddyhttp/app.go

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -529,21 +529,6 @@ func (app *App) Start() error {
529529
// enable TLS if there is a policy and if this is not the HTTP port
530530
useTLS := len(srv.TLSConnPolicies) > 0 && int(listenAddr.StartPort+portOffset) != app.httpPort()
531531

532-
// enable HTTP/3 if configured
533-
if h3ok && useTLS {
534-
app.logger.Info("enabling HTTP/3 listener", zap.String("addr", hostport))
535-
if err := srv.serveHTTP3(listenAddr.At(portOffset), tlsCfg); err != nil {
536-
return err
537-
}
538-
}
539-
540-
if h3ok && !useTLS {
541-
// Can only serve h3 with TLS enabled
542-
app.logger.Warn("HTTP/3 skipped because it requires TLS",
543-
zap.String("network", listenAddr.Network),
544-
zap.String("addr", hostport))
545-
}
546-
547532
if h1ok || h2ok && useTLS || h2cok {
548533
// create the listener for this socket
549534
lnAny, err := listenAddr.Listen(app.ctx, portOffset, net.ListenConfig{KeepAlive: time.Duration(srv.KeepAliveInterval)})
@@ -614,6 +599,33 @@ func (app *App) Start() error {
614599
zap.String("network", listenAddr.Network),
615600
zap.String("addr", hostport))
616601
}
602+
603+
if h3ok {
604+
// Can't serve HTTP/3 on the same socket as HTTP/1 and 2 because it uses
605+
// a different transport mechanism... which is fine, but the OS doesn't
606+
// differentiate between a SOCK_STREAM file and a SOCK_DGRAM file; they
607+
// are still one file on the system. So even though "unixpacket" and
608+
// "unixgram" are different network types just as "tcp" and "udp" are,
609+
// the OS will not let us use the same file as both STREAM and DGRAM.
610+
if listenAddr.IsUnixNetwork() {
611+
app.logger.Warn("HTTP/3 disabled because Unix can't multiplex STREAM and DGRAM on same socket",
612+
zap.String("file", hostport))
613+
continue
614+
}
615+
616+
if useTLS {
617+
// enable HTTP/3 if configured
618+
app.logger.Info("enabling HTTP/3 listener", zap.String("addr", hostport))
619+
if err := srv.serveHTTP3(listenAddr.At(portOffset), tlsCfg); err != nil {
620+
return err
621+
}
622+
} else {
623+
// Can only serve h3 with TLS enabled
624+
app.logger.Warn("HTTP/3 skipped because it requires TLS",
625+
zap.String("network", listenAddr.Network),
626+
zap.String("addr", hostport))
627+
}
628+
}
617629
}
618630
}
619631

modules/caddyhttp/headers/caddyfile.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
9999
handler.Response.Deferred = true
100100
continue
101101
}
102+
if field == "match" {
103+
responseMatchers := make(map[string]caddyhttp.ResponseMatcher)
104+
err := caddyhttp.ParseNamedResponseMatcher(h.NewFromNextSegment(), responseMatchers)
105+
if err != nil {
106+
return nil, err
107+
}
108+
matcher := responseMatchers["match"]
109+
handler.Response.Require = &matcher
110+
continue
111+
}
102112
if hasArgs {
103113
return nil, h.Err("cannot specify headers in both arguments and block") // because it would be weird
104114
}

modules/caddyhttp/headers/headers_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,28 @@ func TestHandler(t *testing.T) {
143143
"Cache-Control": []string{"no-cache"},
144144
},
145145
},
146+
{ // same as above, but checks that response headers are left alone when "Require" conditions are unmet
147+
handler: Handler{
148+
Response: &RespHeaderOps{
149+
Require: &caddyhttp.ResponseMatcher{
150+
Headers: http.Header{
151+
"Cache-Control": nil,
152+
},
153+
},
154+
HeaderOps: &HeaderOps{
155+
Add: http.Header{
156+
"Cache-Control": []string{"no-cache"},
157+
},
158+
},
159+
},
160+
},
161+
respHeader: http.Header{
162+
"Cache-Control": []string{"something"},
163+
},
164+
expectedRespHeader: http.Header{
165+
"Cache-Control": []string{"something"},
166+
},
167+
},
146168
{
147169
handler: Handler{
148170
Response: &RespHeaderOps{

modules/caddyhttp/logging.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ func errLogValues(err error) (status int, msg string, fields func() []zapcore.Fi
211211
}
212212
return
213213
}
214+
fields = func() []zapcore.Field {
215+
return []zapcore.Field{
216+
zap.Error(err),
217+
}
218+
}
214219
status = http.StatusInternalServerError
215220
msg = err.Error()
216221
return

modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,18 @@ func (t *Transport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
131131
// is equivalent to a route consisting of:
132132
//
133133
// # Add trailing slash for directory requests
134+
// # This redirection is automatically disabled if "{http.request.uri.path}/index.php"
135+
// # doesn't appear in the try_files list
134136
// @canonicalPath {
135137
// file {path}/index.php
136138
// not path */
137139
// }
138140
// redir @canonicalPath {path}/ 308
139141
//
140-
// # If the requested file does not exist, try index files
142+
// # If the requested file does not exist, try index files and assume index.php always exists
141143
// @indexFiles file {
142144
// try_files {path} {path}/index.php index.php
145+
// try_policy first_exist_fallback
143146
// split_path .php
144147
// }
145148
// rewrite @indexFiles {http.matchers.file.relative}

modules/caddyhttp/reverseproxy/reverseproxy.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ func (h Handler) prepareRequest(req *http.Request, repl *caddy.Replacer) (*http.
683683
req.Header.Set("Early-Data", "1")
684684
}
685685

686-
reqUpType := upgradeType(req.Header)
686+
reqUpgradeType := upgradeType(req.Header)
687687
removeConnectionHeaders(req.Header)
688688

689689
// Remove hop-by-hop headers to the backend. Especially
@@ -704,9 +704,9 @@ func (h Handler) prepareRequest(req *http.Request, repl *caddy.Replacer) (*http.
704704

705705
// After stripping all the hop-by-hop connection headers above, add back any
706706
// necessary for protocol upgrades, such as for websockets.
707-
if reqUpType != "" {
707+
if reqUpgradeType != "" {
708708
req.Header.Set("Connection", "Upgrade")
709-
req.Header.Set("Upgrade", reqUpType)
709+
req.Header.Set("Upgrade", reqUpgradeType)
710710
normalizeWebsocketHeaders(req.Header)
711711
}
712712

@@ -732,6 +732,9 @@ func (h Handler) prepareRequest(req *http.Request, repl *caddy.Replacer) (*http.
732732
return nil, err
733733
}
734734

735+
// Via header(s)
736+
req.Header.Add("Via", fmt.Sprintf("%d.%d Caddy", req.ProtoMajor, req.ProtoMinor))
737+
735738
return req, nil
736739
}
737740

@@ -882,13 +885,15 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, origRe
882885
}),
883886
)
884887

888+
const logMessage = "upstream roundtrip"
889+
885890
if err != nil {
886-
if c := logger.Check(zapcore.DebugLevel, "upstream roundtrip"); c != nil {
891+
if c := logger.Check(zapcore.DebugLevel, logMessage); c != nil {
887892
c.Write(zap.Error(err))
888893
}
889894
return err
890895
}
891-
if c := logger.Check(zapcore.DebugLevel, "upstream roundtrip"); c != nil {
896+
if c := logger.Check(zapcore.DebugLevel, logMessage); c != nil {
892897
c.Write(
893898
zap.Object("headers", caddyhttp.LoggableHTTPHeader{
894899
Header: res.Header,
@@ -1024,6 +1029,14 @@ func (h *Handler) finalizeResponse(
10241029
res.Header.Del(h)
10251030
}
10261031

1032+
// delete our Server header and use Via instead (see #6275)
1033+
rw.Header().Del("Server")
1034+
var protoPrefix string
1035+
if !strings.HasPrefix(strings.ToUpper(res.Proto), "HTTP/") {
1036+
protoPrefix = res.Proto[:strings.Index(res.Proto, "/")+1]
1037+
}
1038+
rw.Header().Add("Via", fmt.Sprintf("%s%d.%d Caddy", protoPrefix, res.ProtoMajor, res.ProtoMinor))
1039+
10271040
// apply any response header operations
10281041
if h.Headers != nil && h.Headers.Response != nil {
10291042
if h.Headers.Response.Require == nil ||

modules/caddytls/acmeissuer.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ type ACMEIssuer struct {
6060
// other than ACME transactions.
6161
Email string `json:"email,omitempty"`
6262

63+
// Optionally select an ACME profile to use for certificate
64+
// orders. Must be a profile name offered by the ACME server,
65+
// which are listed at its directory endpoint.
66+
//
67+
// EXPERIMENTAL: Subject to change.
68+
// See https://datatracker.ietf.org/doc/draft-aaron-acme-profiles/
69+
Profile string `json:"profile,omitempty"`
70+
6371
// If you have an existing account with the ACME server, put
6472
// the private key here in PEM format. The ACME client will
6573
// look up your account information with this key first before
@@ -184,6 +192,7 @@ func (iss *ACMEIssuer) makeIssuerTemplate() (certmagic.ACMEIssuer, error) {
184192
CA: iss.CA,
185193
TestCA: iss.TestCA,
186194
Email: iss.Email,
195+
Profile: iss.Profile,
187196
AccountKeyPEM: iss.AccountKey,
188197
CertObtainTimeout: time.Duration(iss.ACMETimeout),
189198
TrustedRoots: iss.rootPool,
@@ -338,6 +347,7 @@ func (iss *ACMEIssuer) generateZeroSSLEABCredentials(ctx context.Context, acct a
338347
// dir <directory_url>
339348
// test_dir <test_directory_url>
340349
// email <email>
350+
// profile <profile_name>
341351
// timeout <duration>
342352
// disable_http_challenge
343353
// disable_tlsalpn_challenge
@@ -400,6 +410,11 @@ func (iss *ACMEIssuer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
400410
return d.ArgErr()
401411
}
402412

413+
case "profile":
414+
if !d.AllArgs(&iss.Profile) {
415+
return d.ArgErr()
416+
}
417+
403418
case "timeout":
404419
var timeoutStr string
405420
if !d.AllArgs(&timeoutStr) {

0 commit comments

Comments
 (0)