@@ -24,6 +24,7 @@ import (
2424 "regexp"
2525 "runtime/debug"
2626 "strconv"
27+ "strings"
2728 "time"
2829
2930 "go.uber.org/zap"
@@ -93,6 +94,9 @@ type ActiveHealthChecks struct {
9394 // The HTTP method to use for health checks (default "GET").
9495 Method string `json:"method,omitempty"`
9596
97+ // The body to send with the health check request.
98+ Body string `json:"body,omitempty"`
99+
96100 // Whether to follow HTTP redirects in response to active health checks (default off).
97101 FollowRedirects bool `json:"follow_redirects,omitempty"`
98102
@@ -396,22 +400,31 @@ func (h *Handler) doActiveHealthCheck(dialInfo DialInfo, hostAddr string, networ
396400 u .Path = h .HealthChecks .Active .Path
397401 }
398402
403+ // replacer used for both body and headers. Only globals (env vars, system info, etc.) are available
404+ repl := caddy .NewReplacer ()
405+
406+ // if body is provided, create a reader for it, otherwise nil
407+ var requestBody io.Reader
408+ if h .HealthChecks .Active .Body != "" {
409+ // set body, using replacer
410+ requestBody = strings .NewReader (repl .ReplaceAll (h .HealthChecks .Active .Body , "" ))
411+ }
412+
399413 // attach dialing information to this request, as well as context values that
400414 // may be expected by handlers of this request
401415 ctx := h .ctx .Context
402416 ctx = context .WithValue (ctx , caddy .ReplacerCtxKey , caddy .NewReplacer ())
403417 ctx = context .WithValue (ctx , caddyhttp .VarsCtxKey , map [string ]any {
404418 dialInfoVarKey : dialInfo ,
405419 })
406- req , err := http .NewRequestWithContext (ctx , h .HealthChecks .Active .Method , u .String (), nil )
420+ req , err := http .NewRequestWithContext (ctx , h .HealthChecks .Active .Method , u .String (), requestBody )
407421 if err != nil {
408422 return fmt .Errorf ("making request: %v" , err )
409423 }
410424 ctx = context .WithValue (ctx , caddyhttp .OriginalRequestCtxKey , * req )
411425 req = req .WithContext (ctx )
412426
413- // set headers, using a replacer with only globals (env vars, system info, etc.)
414- repl := caddy .NewReplacer ()
427+ // set headers, using replacer
415428 repl .Set ("http.reverse_proxy.active.target_upstream" , networkAddr )
416429 for key , vals := range h .HealthChecks .Active .Headers {
417430 key = repl .ReplaceAll (key , "" )
0 commit comments