Do not follow redirects for the health check URLs
This commit is contained in:
parent
8c271cf40c
commit
18d90ecd96
16 changed files with 145 additions and 27 deletions
|
@ -47,19 +47,20 @@ type metricsRegistry interface {
|
|||
|
||||
// Options are the public health check options.
|
||||
type Options struct {
|
||||
Headers map[string]string
|
||||
Hostname string
|
||||
Scheme string
|
||||
Path string
|
||||
Port int
|
||||
Transport http.RoundTripper
|
||||
Interval time.Duration
|
||||
Timeout time.Duration
|
||||
LB Balancer
|
||||
Headers map[string]string
|
||||
Hostname string
|
||||
Scheme string
|
||||
Path string
|
||||
Port int
|
||||
FollowRedirects bool
|
||||
Transport http.RoundTripper
|
||||
Interval time.Duration
|
||||
Timeout time.Duration
|
||||
LB Balancer
|
||||
}
|
||||
|
||||
func (opt Options) String() string {
|
||||
return fmt.Sprintf("[Hostname: %s Headers: %v Path: %s Port: %d Interval: %s Timeout: %s]", opt.Hostname, opt.Headers, opt.Path, opt.Port, opt.Interval, opt.Timeout)
|
||||
return fmt.Sprintf("[Hostname: %s Headers: %v Path: %s Port: %d Interval: %s Timeout: %s FollowRedirects: %v]", opt.Hostname, opt.Headers, opt.Path, opt.Port, opt.Interval, opt.Timeout, opt.FollowRedirects)
|
||||
}
|
||||
|
||||
type backendURL struct {
|
||||
|
@ -239,6 +240,12 @@ func checkHealth(serverURL *url.URL, backend *BackendConfig) error {
|
|||
Transport: backend.Options.Transport,
|
||||
}
|
||||
|
||||
if !backend.FollowRedirects {
|
||||
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("HTTP request failed: %s", err)
|
||||
|
|
|
@ -469,3 +469,57 @@ func TestLBStatusUpdater(t *testing.T) {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotFollowingRedirects(t *testing.T) {
|
||||
redirectServerCalled := false
|
||||
redirectTestServer := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
redirectServerCalled = true
|
||||
}))
|
||||
defer redirectTestServer.Close()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Add("location", redirectTestServer.URL)
|
||||
rw.WriteHeader(http.StatusSeeOther)
|
||||
cancel()
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
lb := &testLoadBalancer{
|
||||
RWMutex: &sync.RWMutex{},
|
||||
servers: []*url.URL{testhelpers.MustParseURL(server.URL)},
|
||||
}
|
||||
|
||||
backend := NewBackendConfig(Options{
|
||||
Path: "/path",
|
||||
Interval: healthCheckInterval,
|
||||
Timeout: healthCheckTimeout,
|
||||
LB: lb,
|
||||
FollowRedirects: false,
|
||||
}, "backendName")
|
||||
|
||||
check := HealthCheck{
|
||||
Backends: make(map[string]*BackendConfig),
|
||||
metrics: testhelpers.NewCollectingHealthCheckMetrics(),
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
check.execute(ctx, backend)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
timeout := time.Duration(int(healthCheckInterval) + 500)
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
t.Fatal("test did not complete in time")
|
||||
case <-ctx.Done():
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
assert.False(t, redirectServerCalled, "HTTP redirect must not be followed")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue