reverseproxy: Caddyfile health check headers, host header support (#3948)

* reverse_proxy: 1.health check headers can be set through Caddyfile using health_headers directive; 2.health check header host can be set properly

* reverse_proxy:
replace example with syntax definition
inline health_headers directive parse function

* bugfix: change caddyfile_adapt testcase file from space to tab

* reverseproxy: modify health_header value document as optional and add more test cases
This commit is contained in:
yaxin 2021-01-05 02:26:18 +08:00 committed by GitHub
parent 7846bc1e06
commit 3c9256a1be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 1 deletions

View file

@ -0,0 +1,57 @@
:8884
reverse_proxy 127.0.0.1:65535 {
health_headers {
Host example.com
X-Header-Key 95ca39e3cbe7
X-Header-Keys VbG4NZwWnipo 335Q9/MhqcNU3s2TO
X-Empty-Value
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":8884"
],
"routes": [
{
"handle": [
{
"handler": "reverse_proxy",
"health_checks": {
"active": {
"headers": {
"Host": [
"example.com"
],
"X-Empty-Value": [
""
],
"X-Header-Key": [
"95ca39e3cbe7"
],
"X-Header-Keys": [
"VbG4NZwWnipo",
"335Q9/MhqcNU3s2TO"
]
}
}
},
"upstreams": [
{
"dial": "127.0.0.1:65535"
}
]
}
]
}
]
}
}
}
}
}

View file

@ -63,6 +63,9 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
// health_timeout <duration>
// health_status <status>
// health_body <regexp>
// health_headers {
// <field> [<values...>]
// }
//
// # passive health checking
// max_fails <num>
@ -313,6 +316,26 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
h.HealthChecks.Active.Port = portNum
case "health_headers":
healthHeaders := make(http.Header)
for d.Next() {
for d.NextBlock(0) {
key := d.Val()
values := d.RemainingArgs()
if len(values) == 0 {
values = append(values, "")
}
healthHeaders[key] = values
}
}
if h.HealthChecks == nil {
h.HealthChecks = new(HealthChecks)
}
if h.HealthChecks.Active == nil {
h.HealthChecks.Active = new(ActiveHealthChecks)
}
h.HealthChecks.Active.Headers = healthHeaders
case "health_interval":
if !d.NextArg() {
return d.ArgErr()

View file

@ -26,6 +26,7 @@ import (
"regexp"
"runtime/debug"
"strconv"
"strings"
"time"
"github.com/caddyserver/caddy/v2"
@ -241,7 +242,11 @@ func (h *Handler) doActiveHealthCheck(dialInfo DialInfo, hostAddr string, host H
return fmt.Errorf("making request: %v", err)
}
for key, hdrs := range h.HealthChecks.Active.Headers {
req.Header[key] = hdrs
if strings.ToLower(key) == "host" {
req.Host = h.HealthChecks.Active.Headers.Get(key)
} else {
req.Header[key] = hdrs
}
}
// do the request, being careful to tame the response body