From b2b29dcd4956c9fa722daf6d31fc22aea74ed4fb Mon Sep 17 00:00:00 2001 From: Ali Asgar Date: Tue, 7 May 2024 20:10:15 +0530 Subject: [PATCH] reverseproxy: Implement health_follow_redirects (#6302) * added health_follow_redirect in active health checks * chore: code format * chore: refactore reversproxy healthcheck redirect variable name and description of the same * chore: formatting * changed reverse proxy health check status code range to be between 200-299 * chore: formatting --------- Co-authored-by: aliasgar --- modules/caddyhttp/reverseproxy/caddyfile.go | 13 +++++++++++++ modules/caddyhttp/reverseproxy/healthchecks.go | 11 ++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/modules/caddyhttp/reverseproxy/caddyfile.go b/modules/caddyhttp/reverseproxy/caddyfile.go index 3bc4de01..9de7aedd 100644 --- a/modules/caddyhttp/reverseproxy/caddyfile.go +++ b/modules/caddyhttp/reverseproxy/caddyfile.go @@ -75,6 +75,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) // health_timeout // health_status // health_body +// health_follow_redirects // health_headers { // [] // } @@ -450,6 +451,18 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { } h.HealthChecks.Active.ExpectBody = d.Val() + case "health_follow_redirects": + if d.NextArg() { + return d.ArgErr() + } + if h.HealthChecks == nil { + h.HealthChecks = new(HealthChecks) + } + if h.HealthChecks.Active == nil { + h.HealthChecks.Active = new(ActiveHealthChecks) + } + h.HealthChecks.Active.FollowRedirects = true + case "health_passes": if !d.NextArg() { return d.ArgErr() diff --git a/modules/caddyhttp/reverseproxy/healthchecks.go b/modules/caddyhttp/reverseproxy/healthchecks.go index 507e67c8..90db9b34 100644 --- a/modules/caddyhttp/reverseproxy/healthchecks.go +++ b/modules/caddyhttp/reverseproxy/healthchecks.go @@ -82,6 +82,9 @@ type ActiveHealthChecks struct { // HTTP headers to set on health check requests. Headers http.Header `json:"headers,omitempty"` + // Whether to follow HTTP redirects in response to active health checks (default off). + FollowRedirects bool `json:"follow_redirects,omitempty"` + // How frequently to perform active health checks (default 30s). Interval caddy.Duration `json:"interval,omitempty"` @@ -153,6 +156,12 @@ func (a *ActiveHealthChecks) Provision(ctx caddy.Context, h *Handler) error { a.httpClient = &http.Client{ Timeout: timeout, Transport: h.Transport, + CheckRedirect: func(req *http.Request, via []*http.Request) error { + if !a.FollowRedirects { + return http.ErrUseLastResponse + } + return nil + }, } for _, upstream := range h.Upstreams { @@ -453,7 +462,7 @@ func (h *Handler) doActiveHealthCheck(dialInfo DialInfo, hostAddr string, upstre markUnhealthy() return nil } - } else if resp.StatusCode < 200 || resp.StatusCode >= 400 { + } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { h.HealthChecks.Active.logger.Info("status code out of tolerances", zap.Int("status_code", resp.StatusCode), zap.String("host", hostAddr),