Skip to content
Closed
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions modules/caddyhttp/reverseproxy/healthchecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ type ActiveHealthChecks struct {
// this value is ignored.
Port int `json:"port,omitempty"`


// Configures the method of transport for the active health checker.
// The default transport is the handler's transport
TransportRaw json.RawMessage `json:"transport,omitempty" caddy:"namespace=http.reverse_proxy.health_checks.active.transport inline_key=protocol"`
Comment thread
ab14-tech marked this conversation as resolved.
Outdated

// HTTP headers to set on health check requests.
Headers http.Header `json:"headers,omitempty"`

Expand Down Expand Up @@ -128,6 +133,7 @@ type ActiveHealthChecks struct {
// body of a healthy backend.
ExpectBody string `json:"expect_body,omitempty"`

transport http.RoundTripper `json:"transport,omitempty"`
Comment thread
ab14-tech marked this conversation as resolved.
Outdated
uri *url.URL
httpClient *http.Client
bodyRegexp *regexp.Regexp
Expand Down Expand Up @@ -174,10 +180,21 @@ func (a *ActiveHealthChecks) Provision(ctx caddy.Context, h *Handler) error {
}
a.uri = parsedURI
}

// Use handler's transport if no active one set
if a.TransportRaw != nil {
mod, err := ctx.LoadModule(a, "TransportRaw")
if err != nil {
return fmt.Errorf("loading transport: %v", err)
}
a.transport = mod.(http.RoundTripper)
} else {
a.transport = h.Transport
}

a.httpClient = &http.Client{
Timeout: timeout,
Transport: h.Transport,
Transport: a.transport,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
if !a.FollowRedirects {
return http.ErrUseLastResponse
Expand Down Expand Up @@ -393,12 +410,17 @@ func (h *Handler) doActiveHealthCheck(dialInfo DialInfo, hostAddr string, networ
u.Host = net.JoinHostPort(host, port)
}

// this is kind of a hacky way to know if we should use HTTPS, but whatever
if tt, ok := h.Transport.(TLSTransport); ok && tt.TLSEnabled() {
// this is kind of a hacky way to know if we should use HTTPS
transport := h.HealthChecks.Active.Transport
if transport == nil {
transport = h.Transport
}

if tt, ok := transport.(TLSTransport); ok && tt.TLSEnabled() {
u.Scheme = "https"

// if the port is in the except list, flip back to HTTP
if ht, ok := h.Transport.(*HTTPTransport); ok && slices.Contains(ht.TLS.ExceptPorts, port) {
if ht, ok := transport.(*HTTPTransport); ok && slices.Contains(ht.TLS.ExceptPorts, port) {
u.Scheme = "http"
}
}
Expand Down