Files
godoxy-yusing/internal/watcher/health/monitor/http.go

85 lines
2.1 KiB
Go

package monitor
import (
"crypto/tls"
"errors"
"net/url"
"time"
"github.com/valyala/fasthttp"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/goutils/version"
)
type HTTPHealthMonitor struct {
*monitor
method string
}
var pinger = &fasthttp.Client{
ReadTimeout: 5 * time.Second,
WriteTimeout: 3 * time.Second,
MaxConnDuration: 0,
DisableHeaderNamesNormalizing: true,
DisablePathNormalizing: true,
TLSConfig: &tls.Config{
InsecureSkipVerify: true,
},
MaxConnsPerHost: 1,
NoDefaultUserAgentHeader: true,
}
func NewHTTPHealthMonitor(url *url.URL, config *types.HealthCheckConfig) *HTTPHealthMonitor {
mon := new(HTTPHealthMonitor)
mon.monitor = newMonitor(url, config, mon.CheckHealth)
if config.UseGet {
mon.method = fasthttp.MethodGet
} else {
mon.method = fasthttp.MethodHead
}
return mon
}
func (mon *HTTPHealthMonitor) CheckHealth() (types.HealthCheckResult, error) {
req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req)
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp)
req.SetRequestURI(mon.url.Load().JoinPath(mon.config.Path).String())
req.Header.SetMethod(mon.method)
req.Header.Set("User-Agent", "GoDoxy/"+version.Get().String())
req.Header.Set("Accept", "text/plain,text/html,*/*;q=0.8")
req.Header.Set("Accept-Encoding", "identity")
req.Header.Set("Cache-Control", "no-cache")
req.Header.Set("Pragma", "no-cache")
req.SetConnectionClose()
start := time.Now()
respErr := pinger.DoTimeout(req, resp, mon.config.Timeout)
lat := time.Since(start)
switch {
case respErr != nil:
// treat TLS error as healthy
var tlsErr *tls.CertificateVerificationError
if ok := errors.As(respErr, &tlsErr); !ok {
return types.HealthCheckResult{
Latency: lat,
Detail: respErr.Error(),
}, nil
}
case resp.StatusCode() == fasthttp.StatusServiceUnavailable:
return types.HealthCheckResult{
Latency: lat,
Detail: fasthttp.StatusMessage(resp.StatusCode()),
}, nil
}
return types.HealthCheckResult{
Latency: lat,
Healthy: true,
}, nil
}