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
}