mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00

- Incorrect name being shown on dashboard "Proxies page" - Apps being shown when homepage.show is false - Load balanced routes are shown on homepage instead of the load balancer - Route with idlewatcher will now be removed on container destroy - Idlewatcher panic - Performance improvement - Idlewatcher infinitely loading - Reload stucked / not working properly - Streams stuck on shutdown / reload - etc... Added: - support idlewatcher for loadbalanced routes - partial implementation for stream type idlewatcher Issues: - graceful shutdown
69 lines
1.5 KiB
Go
69 lines
1.5 KiB
Go
package health
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/yusing/go-proxy/internal/net/types"
|
|
)
|
|
|
|
type HTTPHealthMonitor struct {
|
|
*monitor
|
|
method string
|
|
pinger *http.Client
|
|
}
|
|
|
|
func NewHTTPHealthMonitor(url types.URL, config *HealthCheckConfig, transport http.RoundTripper) *HTTPHealthMonitor {
|
|
mon := new(HTTPHealthMonitor)
|
|
mon.monitor = newMonitor(url, config, mon.CheckHealth)
|
|
mon.pinger = &http.Client{Timeout: config.Timeout, Transport: transport}
|
|
if config.UseGet {
|
|
mon.method = http.MethodGet
|
|
} else {
|
|
mon.method = http.MethodHead
|
|
}
|
|
return mon
|
|
}
|
|
|
|
func NewHTTPHealthChecker(url types.URL, config *HealthCheckConfig, transport http.RoundTripper) HealthChecker {
|
|
return NewHTTPHealthMonitor(url, config, transport)
|
|
}
|
|
|
|
func (mon *HTTPHealthMonitor) CheckHealth() (healthy bool, detail string, err error) {
|
|
ctx, cancel := mon.ContextWithTimeout("ping request timed out")
|
|
defer cancel()
|
|
|
|
req, reqErr := http.NewRequestWithContext(
|
|
ctx,
|
|
mon.method,
|
|
mon.url.Load().JoinPath(mon.config.Path).String(),
|
|
nil,
|
|
)
|
|
if reqErr != nil {
|
|
err = reqErr
|
|
return
|
|
}
|
|
|
|
req.Header.Set("Connection", "close")
|
|
resp, respErr := mon.pinger.Do(req)
|
|
if respErr == nil {
|
|
resp.Body.Close()
|
|
}
|
|
|
|
switch {
|
|
case respErr != nil:
|
|
// treat tls error as healthy
|
|
var tlsErr *tls.CertificateVerificationError
|
|
if ok := errors.As(respErr, &tlsErr); !ok {
|
|
detail = respErr.Error()
|
|
return
|
|
}
|
|
case resp.StatusCode == http.StatusServiceUnavailable:
|
|
detail = resp.Status
|
|
return
|
|
}
|
|
|
|
healthy = true
|
|
return
|
|
}
|