From 1136e2cfeed5cc06a0811d39c2560c06f9dd74a2 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Sat, 4 May 2019 10:49:50 -0600 Subject: Add reverse proxy --- modules/caddyhttp/reverseproxy/healthchecker.go | 64 +++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 modules/caddyhttp/reverseproxy/healthchecker.go (limited to 'modules/caddyhttp/reverseproxy/healthchecker.go') diff --git a/modules/caddyhttp/reverseproxy/healthchecker.go b/modules/caddyhttp/reverseproxy/healthchecker.go new file mode 100755 index 0000000..add3aa0 --- /dev/null +++ b/modules/caddyhttp/reverseproxy/healthchecker.go @@ -0,0 +1,64 @@ +package reverseproxy + +import ( + "net/http" + "time" +) + +// Upstream represents the interface that must be satisfied to use the healthchecker. +type Upstream interface { + SetHealthiness(bool) +} + +// HealthChecker represents a worker that periodically evaluates if proxy upstream host is healthy. +type HealthChecker struct { + upstream Upstream + Ticker *time.Ticker + HTTPClient *http.Client +} + +// ScheduleChecks periodically runs health checks against an upstream host. +func (h *HealthChecker) ScheduleChecks(url string) { + // check if a host is healthy on start vs waiting for timer + h.upstream.SetHealthiness(h.IsHealthy(url)) + + for { + select { + case <-h.Ticker.C: + h.upstream.SetHealthiness(h.IsHealthy(url)) + } + } +} + +// Stop stops the healthchecker from makeing further requests. +func (h *HealthChecker) Stop() { + h.Ticker.Stop() +} + +// IsHealthy attempts to check if a upstream host is healthy. +func (h *HealthChecker) IsHealthy(url string) bool { + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return false + } + + resp, err := h.HTTPClient.Do(req) + if err != nil { + return false + } + + if resp.StatusCode < 200 || resp.StatusCode >= 400 { + return false + } + + return true +} + +// NewHealthCheckWorker returns a new instance of a HealthChecker. +func NewHealthCheckWorker(u Upstream, interval time.Duration, client *http.Client) *HealthChecker { + return &HealthChecker{ + upstream: u, + Ticker: time.NewTicker(interval), + HTTPClient: client, + } +} -- cgit v1.2.3