mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-23 17:28:53 +02:00
Feat/fileserver (#60)
* cleanup code for URL type * fix makefile for trace mode * refactor, merge Entry, RawEntry and Route into one. * Implement fileserver. * refactor: rename HTTPRoute to ReverseProxyRoute to avoid confusion * refactor: move metrics logger to middleware package - fix prometheus metrics for load balanced routes - route will now fail when health monitor fail to start * fix extra output of ls-* commands by defer initializaing stuff, speed up start time * add test for path traversal attack, small fix on FileServer.Start method * rename rule.on.bypass to pass * refactor and fixed map-to-map deserialization * updated route loading logic * schemas: add "add_prefix" option to modify_request middleware * updated route JSONMarshalling --------- Co-authored-by: yusing <yusing@6uo.me>
This commit is contained in:
@@ -2,6 +2,8 @@ package health
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/common"
|
||||
)
|
||||
|
||||
type HealthCheckConfig struct {
|
||||
@@ -11,3 +13,8 @@ type HealthCheckConfig struct {
|
||||
Interval time.Duration `json:"interval" validate:"omitempty,min=1s"`
|
||||
Timeout time.Duration `json:"timeout" validate:"omitempty,min=1s"`
|
||||
}
|
||||
|
||||
var DefaultHealthConfig = &HealthCheckConfig{
|
||||
Interval: common.HealthCheckIntervalDefault,
|
||||
Timeout: common.HealthCheckTimeoutDefault,
|
||||
}
|
||||
|
||||
36
internal/watcher/health/monitor/fileserver.go
Normal file
36
internal/watcher/health/monitor/fileserver.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/watcher/health"
|
||||
)
|
||||
|
||||
type FileServerHealthMonitor struct {
|
||||
*monitor
|
||||
path string
|
||||
}
|
||||
|
||||
func NewFileServerHealthMonitor(alias string, config *health.HealthCheckConfig, path string) *FileServerHealthMonitor {
|
||||
mon := &FileServerHealthMonitor{path: path}
|
||||
mon.monitor = newMonitor(nil, config, mon.CheckHealth)
|
||||
mon.service = alias
|
||||
return mon
|
||||
}
|
||||
|
||||
func (s *FileServerHealthMonitor) CheckHealth() (*health.HealthCheckResult, error) {
|
||||
start := time.Now()
|
||||
_, err := os.Stat(s.path)
|
||||
|
||||
detail := ""
|
||||
if err != nil {
|
||||
detail = err.Error()
|
||||
}
|
||||
|
||||
return &health.HealthCheckResult{
|
||||
Healthy: err == nil,
|
||||
Latency: time.Since(start),
|
||||
Detail: detail,
|
||||
}, nil
|
||||
}
|
||||
@@ -26,7 +26,7 @@ var pinger = &http.Client{
|
||||
},
|
||||
}
|
||||
|
||||
func NewHTTPHealthMonitor(url types.URL, config *health.HealthCheckConfig) *HTTPHealthMonitor {
|
||||
func NewHTTPHealthMonitor(url *types.URL, config *health.HealthCheckConfig) *HTTPHealthMonitor {
|
||||
mon := new(HTTPHealthMonitor)
|
||||
mon.monitor = newMonitor(url, config, mon.CheckHealth)
|
||||
if config.UseGet {
|
||||
@@ -37,7 +37,7 @@ func NewHTTPHealthMonitor(url types.URL, config *health.HealthCheckConfig) *HTTP
|
||||
return mon
|
||||
}
|
||||
|
||||
func NewHTTPHealthChecker(url types.URL, config *health.HealthCheckConfig) health.HealthChecker {
|
||||
func NewHTTPHealthChecker(url *types.URL, config *health.HealthCheckConfig) health.HealthChecker {
|
||||
return NewHTTPHealthMonitor(url, config)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/net/types"
|
||||
net "github.com/yusing/go-proxy/internal/net/types"
|
||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||
"github.com/yusing/go-proxy/internal/watcher/health"
|
||||
)
|
||||
@@ -19,7 +19,7 @@ type JSONRepresentation struct {
|
||||
Latency time.Duration
|
||||
LastSeen time.Time
|
||||
Detail string
|
||||
URL types.URL
|
||||
URL *net.URL
|
||||
Extra map[string]any
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ type (
|
||||
monitor struct {
|
||||
service string
|
||||
config *health.HealthCheckConfig
|
||||
url atomic.Value[types.URL]
|
||||
url atomic.Value[*types.URL]
|
||||
|
||||
status atomic.Value[health.Status]
|
||||
lastResult *health.HealthCheckResult
|
||||
@@ -39,7 +39,7 @@ type (
|
||||
|
||||
var ErrNegativeInterval = errors.New("negative interval")
|
||||
|
||||
func newMonitor(url types.URL, config *health.HealthCheckConfig, healthCheckFunc HealthCheckFunc) *monitor {
|
||||
func newMonitor(url *types.URL, config *health.HealthCheckConfig, healthCheckFunc HealthCheckFunc) *monitor {
|
||||
mon := &monitor{
|
||||
config: config,
|
||||
checkHealth: healthCheckFunc,
|
||||
@@ -118,12 +118,12 @@ func (mon *monitor) Finish(reason any) {
|
||||
}
|
||||
|
||||
// UpdateURL implements HealthChecker.
|
||||
func (mon *monitor) UpdateURL(url types.URL) {
|
||||
func (mon *monitor) UpdateURL(url *types.URL) {
|
||||
mon.url.Store(url)
|
||||
}
|
||||
|
||||
// URL implements HealthChecker.
|
||||
func (mon *monitor) URL() types.URL {
|
||||
func (mon *monitor) URL() *types.URL {
|
||||
return mon.url.Load()
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ func (mon *monitor) checkUpdateHealth() error {
|
||||
if !result.Healthy {
|
||||
extras.Add("Last Seen", strutils.FormatLastSeen(GetLastSeen(mon.service)))
|
||||
}
|
||||
if !mon.url.Load().Nil() {
|
||||
if mon.url.Load() != nil {
|
||||
extras.Add("Service URL", mon.url.Load().String())
|
||||
}
|
||||
if result.Detail != "" {
|
||||
|
||||
@@ -15,7 +15,7 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func NewRawHealthMonitor(url types.URL, config *health.HealthCheckConfig) *RawHealthMonitor {
|
||||
func NewRawHealthMonitor(url *types.URL, config *health.HealthCheckConfig) *RawHealthMonitor {
|
||||
mon := new(RawHealthMonitor)
|
||||
mon.monitor = newMonitor(url, config, mon.CheckHealth)
|
||||
mon.dialer = &net.Dialer{
|
||||
@@ -25,7 +25,7 @@ func NewRawHealthMonitor(url types.URL, config *health.HealthCheckConfig) *RawHe
|
||||
return mon
|
||||
}
|
||||
|
||||
func NewRawHealthChecker(url types.URL, config *health.HealthCheckConfig) health.HealthChecker {
|
||||
func NewRawHealthChecker(url *types.URL, config *health.HealthCheckConfig) health.HealthChecker {
|
||||
return NewRawHealthMonitor(url, config)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ type (
|
||||
}
|
||||
HealthChecker interface {
|
||||
CheckHealth() (result *HealthCheckResult, err error)
|
||||
URL() types.URL
|
||||
URL() *types.URL
|
||||
Config() *HealthCheckConfig
|
||||
UpdateURL(url types.URL)
|
||||
UpdateURL(url *types.URL)
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user