This commit is contained in:
yusing
2026-02-16 08:59:01 +08:00
parent 15b9635ee1
commit e4e6f6b3e8
242 changed files with 3953 additions and 3502 deletions

View File

@@ -1,12 +1,14 @@
package route
import (
"errors"
"net/http"
"sync"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/agent/pkg/agentproxy"
config "github.com/yusing/godoxy/internal/config/types"
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
"github.com/yusing/godoxy/internal/health/monitor"
"github.com/yusing/godoxy/internal/idlewatcher"
"github.com/yusing/godoxy/internal/logging/accesslog"
@@ -14,16 +16,14 @@ import (
"github.com/yusing/godoxy/internal/net/gphttp/loadbalancer"
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
nettypes "github.com/yusing/godoxy/internal/net/types"
"github.com/yusing/godoxy/internal/route/routes"
route "github.com/yusing/godoxy/internal/route/types"
"github.com/yusing/godoxy/internal/types"
gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/reverseproxy"
"github.com/yusing/goutils/task"
"github.com/yusing/goutils/version"
)
type ReveseProxyRoute struct {
type ReverseProxyRoute struct {
*Route
loadBalancer *loadbalancer.LoadBalancer
@@ -31,11 +31,11 @@ type ReveseProxyRoute struct {
rp *reverseproxy.ReverseProxy
}
var _ types.ReverseProxyRoute = (*ReveseProxyRoute)(nil)
var _ types.ReverseProxyRoute = (*ReverseProxyRoute)(nil)
// var globalMux = http.NewServeMux() // TODO: support regex subdomain matching.
func NewReverseProxyRoute(base *Route) (*ReveseProxyRoute, gperr.Error) {
func NewReverseProxyRoute(base *Route) (*ReverseProxyRoute, error) {
httpConfig := base.HTTPConfig
proxyURL := base.ProxyURL
@@ -111,7 +111,7 @@ func NewReverseProxyRoute(base *Route) (*ReveseProxyRoute, gperr.Error) {
}
}
r := &ReveseProxyRoute{
r := &ReverseProxyRoute{
Route: base,
rp: rp,
}
@@ -119,20 +119,21 @@ func NewReverseProxyRoute(base *Route) (*ReveseProxyRoute, gperr.Error) {
}
// ReverseProxy implements routes.ReverseProxyRoute.
func (r *ReveseProxyRoute) ReverseProxy() *reverseproxy.ReverseProxy {
func (r *ReverseProxyRoute) ReverseProxy() *reverseproxy.ReverseProxy {
return r.rp
}
// Start implements task.TaskStarter.
func (r *ReveseProxyRoute) Start(parent task.Parent) gperr.Error {
func (r *ReverseProxyRoute) Start(parent task.Parent) error {
r.task = parent.Subtask("http."+r.Name(), false)
r.task.SetValue(monitor.DisplayNameKey{}, r.DisplayName())
switch {
case r.UseIdleWatcher():
waker, err := idlewatcher.NewWatcher(parent, r, r.IdlewatcherConfig())
if err != nil {
r.task.Finish(err)
return gperr.Wrap(err)
return err
}
r.handler = waker
r.HealthMon = waker
@@ -149,7 +150,7 @@ func (r *ReveseProxyRoute) Start(parent task.Parent) gperr.Error {
r.rp.AccessLogger, err = accesslog.NewAccessLogger(r.task, r.AccessLog)
if err != nil {
r.task.Finish(err)
return gperr.Wrap(err)
return err
}
}
@@ -159,44 +160,50 @@ func (r *ReveseProxyRoute) Start(parent task.Parent) gperr.Error {
if r.HealthMon != nil {
if err := r.HealthMon.Start(r.task); err != nil {
return err
// TODO: add to event history
log.Warn().Err(err).Msg("health monitor error")
r.HealthMon = nil
}
}
ep := entrypoint.FromCtx(parent.Context())
if ep == nil {
err := errors.New("entrypoint not initialized")
r.task.Finish(err)
return err
}
if r.UseLoadBalance() {
r.addToLoadBalancer(parent)
} else {
routes.HTTP.Add(r)
if state := config.WorkingState.Load(); state != nil {
state.ShortLinkMatcher().AddRoute(r.Alias)
if err := r.addToLoadBalancer(parent, ep); err != nil {
r.task.Finish(err)
return err
}
} else {
if err := ep.StartAddRoute(r); err != nil {
r.task.Finish(err)
return err
}
r.task.OnCancel("remove_route", func() {
routes.HTTP.Del(r)
if state := config.WorkingState.Load(); state != nil {
state.ShortLinkMatcher().DelRoute(r.Alias)
}
})
}
return nil
}
func (r *ReveseProxyRoute) ServeHTTP(w http.ResponseWriter, req *http.Request) {
func (r *ReverseProxyRoute) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// req.Header.Set("Accept-Encoding", "identity")
r.handler.ServeHTTP(w, req)
}
var lbLock sync.Mutex
func (r *ReveseProxyRoute) addToLoadBalancer(parent task.Parent) {
func (r *ReverseProxyRoute) addToLoadBalancer(parent task.Parent, ep entrypoint.Entrypoint) error {
var lb *loadbalancer.LoadBalancer
cfg := r.LoadBalance
lbLock.Lock()
defer lbLock.Unlock()
l, ok := routes.HTTP.Get(cfg.Link)
var linked *ReveseProxyRoute
l, ok := ep.HTTPRoutes().Get(cfg.Link)
var linked *ReverseProxyRoute
if ok {
lbLock.Unlock()
linked = l.(*ReveseProxyRoute)
linked = l.(*ReverseProxyRoute) // it must be a reverse proxy route
lb = linked.loadBalancer
lb.UpdateConfigIfNeeded(cfg)
if linked.Homepage.Name == "" {
@@ -205,26 +212,24 @@ func (r *ReveseProxyRoute) addToLoadBalancer(parent task.Parent) {
} else {
lb = loadbalancer.New(cfg)
_ = lb.Start(parent) // always return nil
linked = &ReveseProxyRoute{
linked = &ReverseProxyRoute{
Route: &Route{
Alias: cfg.Link,
Homepage: r.Homepage,
Bind: r.Bind,
Metadata: Metadata{
LisURL: r.ListenURL(),
task: lb.Task(),
},
},
loadBalancer: lb,
handler: lb,
}
linked.SetHealthMonitor(lb)
routes.HTTP.AddKey(cfg.Link, linked)
if state := config.WorkingState.Load(); state != nil {
state.ShortLinkMatcher().AddRoute(cfg.Link)
if err := ep.StartAddRoute(linked); err != nil {
lb.Finish(err)
return err
}
r.task.OnFinished("remove_loadbalancer_route", func() {
routes.HTTP.DelKey(cfg.Link)
if state := config.WorkingState.Load(); state != nil {
state.ShortLinkMatcher().DelRoute(cfg.Link)
}
})
lbLock.Unlock()
}
r.loadBalancer = lb
@@ -233,4 +238,5 @@ func (r *ReveseProxyRoute) addToLoadBalancer(parent task.Parent) {
r.task.OnCancel("lb_remove_server", func() {
lb.RemoveServer(server)
})
return nil
}