@marcel91200 / caddy Mirror · read-only / commits / 6c38ae73
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 12, 00:45 UTC

reverseproxy: Add valid Upstream to DialInfo in active health checks (#6949)

Currently if we extract the DialInfo from a Request Context during an active health check, then the Upstream in the DialInfo is nil. This PR attempts to set the Upstream to a sensible value, based on wether or not the Upstream has been overriden in the active health check's config.

Jesper Brix Rosenkilde committed Apr 15, 2025 at 16:44 UTC 6c38ae7381b3338b173c59706673d11783091dee
3 files changed +17 -7
modules/caddyhttp/reverseproxy/healthchecks.go
+15 -3
@@ -309,7 +309,9 @@ func (h *Handler) doActiveHealthCheckForAllHosts() {
309 }
310 }()
311
312 - networkAddr, err := caddy.NewReplacer().ReplaceOrErr(upstream.Dial, true, true)
312 + repl := caddy.NewReplacer()
313 +
314 + networkAddr, err := repl.ReplaceOrErr(upstream.Dial, true, true)
315 if err != nil {
316 if c := h.HealthChecks.Active.logger.Check(zapcore.ErrorLevel, "invalid use of placeholders in dial address for active health checks"); c != nil {
317 c.Write(
@@ -344,14 +346,24 @@ func (h *Handler) doActiveHealthCheckForAllHosts() {
346 return
347 }
348 hostAddr := addr.JoinHostPort(0)
347 - dialAddr := hostAddr
349 if addr.IsUnixNetwork() || addr.IsFdNetwork() {
350 // this will be used as the Host portion of a http.Request URL, and
351 // paths to socket files would produce an error when creating URL,
352 // so use a fake Host value instead; unix sockets are usually local
353 hostAddr = "localhost"
354 }
354 - err = h.doActiveHealthCheck(DialInfo{Network: addr.Network, Address: dialAddr}, hostAddr, networkAddr, upstream)
355 +
356 + // Fill in the dial info for the upstream
357 + // If the upstream is set, use that instead
358 + dialInfoUpstream := upstream
359 + if h.HealthChecks.Active.Upstream != "" {
360 + dialInfoUpstream = &Upstream{
361 + Dial: h.HealthChecks.Active.Upstream,
362 + }
363 + }
364 + dialInfo, _ := dialInfoUpstream.fillDialInfo(repl)
365 +
366 + err = h.doActiveHealthCheck(dialInfo, hostAddr, networkAddr, upstream)
367 if err != nil {
368 if c := h.HealthChecks.Active.logger.Check(zapcore.ErrorLevel, "active health check failed"); c != nil {
369 c.Write(
modules/caddyhttp/reverseproxy/hosts.go
+1 -3
@@ -17,7 +17,6 @@ package reverseproxy
17 import (
18 "context"
19 "fmt"
20 - "net/http"
20 "net/netip"
21 "strconv"
22 "sync/atomic"
@@ -100,8 +99,7 @@ func (u *Upstream) Full() bool {
99
100 // fillDialInfo returns a filled DialInfo for upstream u, using the request
101 // context. Note that the returned value is not a pointer.
103 -func (u *Upstream) fillDialInfo(r *http.Request) (DialInfo, error) {
104 - repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
102 +func (u *Upstream) fillDialInfo(repl *caddy.Replacer) (DialInfo, error) {
103 var addr caddy.NetworkAddress
104
105 // use provided dial address
modules/caddyhttp/reverseproxy/reverseproxy.go
+1 -1
@@ -532,7 +532,7 @@ func (h *Handler) proxyLoopIteration(r *http.Request, origReq *http.Request, w h
532 // the dial address may vary per-request if placeholders are
533 // used, so perform those replacements here; the resulting
534 // DialInfo struct should have valid network address syntax
535 - dialInfo, err := upstream.fillDialInfo(r)
535 + dialInfo, err := upstream.fillDialInfo(repl)
536 if err != nil {
537 return true, fmt.Errorf("making dial info: %v", err)
538 }