From 276684f0764704148cc9538f51703578227def1d Mon Sep 17 00:00:00 2001 From: yusing Date: Wed, 18 Dec 2024 00:33:48 +0800 Subject: [PATCH] remove unnecessary encapsulation, setup branch updated to v0.8 --- internal/route/entry/reverse_proxy.go | 37 +++++------------- internal/route/entry/stream.go | 22 +++++------ internal/route/http.go | 52 +++++++++++++------------- internal/route/provider/docker_test.go | 4 +- internal/route/stream.go | 15 ++++---- internal/route/stream_impl.go | 8 ++-- internal/route/types/alias.go | 3 -- internal/route/types/host.go | 10 ----- internal/route/types/raw_entry.go | 1 + internal/setup.go | 2 +- 10 files changed, 60 insertions(+), 94 deletions(-) delete mode 100644 internal/route/types/alias.go delete mode 100644 internal/route/types/host.go diff --git a/internal/route/entry/reverse_proxy.go b/internal/route/entry/reverse_proxy.go index 67caaaf..115db85 100644 --- a/internal/route/entry/reverse_proxy.go +++ b/internal/route/entry/reverse_proxy.go @@ -15,22 +15,14 @@ import ( type ReverseProxyEntry struct { // real model after validation Raw *route.RawEntry `json:"raw"` - - Alias route.Alias `json:"alias"` - Scheme route.Scheme `json:"scheme"` - URL net.URL `json:"url"` - NoTLSVerify bool `json:"no_tls_verify,omitempty"` - PathPatterns []string `json:"path_patterns,omitempty"` - HealthCheck *health.HealthCheckConfig `json:"healthcheck,omitempty"` - LoadBalance *loadbalance.Config `json:"load_balance,omitempty"` - Middlewares map[string]docker.LabelMap `json:"middlewares,omitempty"` + URL net.URL `json:"url"` /* Docker only */ Idlewatcher *idlewatcher.Config `json:"idlewatcher,omitempty"` } func (rp *ReverseProxyEntry) TargetName() string { - return string(rp.Alias) + return rp.Raw.Alias } func (rp *ReverseProxyEntry) TargetURL() net.URL { @@ -42,11 +34,11 @@ func (rp *ReverseProxyEntry) RawEntry() *route.RawEntry { } func (rp *ReverseProxyEntry) LoadBalanceConfig() *loadbalance.Config { - return rp.LoadBalance + return rp.Raw.LoadBalance } func (rp *ReverseProxyEntry) HealthCheckConfig() *health.HealthCheckConfig { - return rp.HealthCheck + return rp.Raw.HealthCheck } func (rp *ReverseProxyEntry) IdlewatcherConfig() *idlewatcher.Config { @@ -59,14 +51,12 @@ func validateRPEntry(m *route.RawEntry, s route.Scheme, errs *E.Builder) *Revers cont = docker.DummyContainer } - lb := m.LoadBalance - if lb != nil && lb.Link == "" { - lb = nil + if m.LoadBalance != nil && m.LoadBalance.Link == "" { + m.LoadBalance = nil } - host := E.Collect(errs, route.ValidateHost, m.Host) port := E.Collect(errs, route.ValidatePort, m.Port) - url := E.Collect(errs, url.Parse, fmt.Sprintf("%s://%s:%d", s, host, port)) + url := E.Collect(errs, url.Parse, fmt.Sprintf("%s://%s:%d", s, m.Host, port)) iwCfg := E.Collect(errs, idlewatcher.ValidateConfig, cont) if errs.HasError() { @@ -74,15 +64,8 @@ func validateRPEntry(m *route.RawEntry, s route.Scheme, errs *E.Builder) *Revers } return &ReverseProxyEntry{ - Raw: m, - Alias: route.Alias(m.Alias), - Scheme: s, - URL: net.NewURL(url), - NoTLSVerify: m.NoTLSVerify, - PathPatterns: m.PathPatterns, - HealthCheck: m.HealthCheck, - LoadBalance: lb, - Middlewares: m.Middlewares, - Idlewatcher: iwCfg, + Raw: m, + URL: net.NewURL(url), + Idlewatcher: iwCfg, } } diff --git a/internal/route/entry/stream.go b/internal/route/entry/stream.go index 936dd42..4c5962c 100644 --- a/internal/route/entry/stream.go +++ b/internal/route/entry/stream.go @@ -15,19 +15,17 @@ import ( type StreamEntry struct { Raw *route.RawEntry `json:"raw"` - Alias route.Alias `json:"alias"` - Scheme route.StreamScheme `json:"scheme"` - URL net.URL `json:"url"` - Host route.Host `json:"host,omitempty"` - Port route.StreamPort `json:"port,omitempty"` - HealthCheck *health.HealthCheckConfig `json:"healthcheck,omitempty"` + Scheme route.StreamScheme `json:"scheme"` + URL net.URL `json:"url"` + ListenURL net.URL `json:"listening_url"` + Port route.StreamPort `json:"port,omitempty"` /* Docker only */ Idlewatcher *idlewatcher.Config `json:"idlewatcher,omitempty"` } func (s *StreamEntry) TargetName() string { - return string(s.Alias) + return s.Raw.Alias } func (s *StreamEntry) TargetURL() net.URL { @@ -44,7 +42,7 @@ func (s *StreamEntry) LoadBalanceConfig() *loadbalance.Config { } func (s *StreamEntry) HealthCheckConfig() *health.HealthCheckConfig { - return s.HealthCheck + return s.Raw.HealthCheck } func (s *StreamEntry) IdlewatcherConfig() *idlewatcher.Config { @@ -57,10 +55,10 @@ func validateStreamEntry(m *route.RawEntry, errs *E.Builder) *StreamEntry { cont = docker.DummyContainer } - host := E.Collect(errs, route.ValidateHost, m.Host) port := E.Collect(errs, route.ValidateStreamPort, m.Port) scheme := E.Collect(errs, route.ValidateStreamScheme, m.Scheme) - url := E.Collect(errs, net.ParseURL, fmt.Sprintf("%s://%s:%d", scheme.ListeningScheme, host, port.ProxyPort)) + url := E.Collect(errs, net.ParseURL, fmt.Sprintf("%s://%s:%d", scheme.ProxyScheme, m.Host, port.ProxyPort)) + listenURL := E.Collect(errs, net.ParseURL, fmt.Sprintf("%s://:%d", scheme.ListeningScheme, port.ListeningPort)) idleWatcherCfg := E.Collect(errs, idlewatcher.ValidateConfig, cont) if errs.HasError() { @@ -69,12 +67,10 @@ func validateStreamEntry(m *route.RawEntry, errs *E.Builder) *StreamEntry { return &StreamEntry{ Raw: m, - Alias: route.Alias(m.Alias), Scheme: *scheme, URL: url, - Host: host, + ListenURL: listenURL, Port: port, - HealthCheck: m.HealthCheck, Idlewatcher: idleWatcherCfg, } } diff --git a/internal/route/http.go b/internal/route/http.go index a4fb33b..4e32e42 100755 --- a/internal/route/http.go +++ b/internal/route/http.go @@ -35,25 +35,23 @@ type ( l zerolog.Logger } - - SubdomainKey = route.Alias ) // var globalMux = http.NewServeMux() // TODO: support regex subdomain matching. func NewHTTPRoute(entry *entry.ReverseProxyEntry) (impl, E.Error) { var trans *http.Transport - if entry.NoTLSVerify { + if entry.Raw.NoTLSVerify { trans = gphttp.DefaultTransportNoTLS } else { trans = gphttp.DefaultTransport } - service := string(entry.Alias) + service := entry.TargetName() rp := gphttp.NewReverseProxy(service, entry.URL, trans) - if len(entry.Middlewares) > 0 { - err := middleware.PatchReverseProxy(rp, entry.Middlewares) + if len(entry.Raw.Middlewares) > 0 { + err := middleware.PatchReverseProxy(rp, entry.Raw.Middlewares) if err != nil { return nil, err } @@ -63,15 +61,15 @@ func NewHTTPRoute(entry *entry.ReverseProxyEntry) (impl, E.Error) { ReverseProxyEntry: entry, rp: rp, l: logger.With(). - Str("type", string(entry.Scheme)). - Str("name", string(entry.Alias)). + Str("type", entry.URL.Scheme). + Str("name", service). Logger(), } return r, nil } func (r *HTTPRoute) String() string { - return string(r.Alias) + return r.TargetName() } // Start implements*task.TaskStarter. @@ -85,7 +83,7 @@ func (r *HTTPRoute) Start(providerSubtask *task.Task) E.Error { switch { case entry.UseIdleWatcher(r): - wakerTask := providerSubtask.Parent().Subtask("waker for " + string(r.Alias)) + wakerTask := providerSubtask.Parent().Subtask("waker for " + r.TargetName()) waker, err := idlewatcher.NewHTTPWaker(wakerTask, r.ReverseProxyEntry, r.rp) if err != nil { return err @@ -96,26 +94,27 @@ func (r *HTTPRoute) Start(providerSubtask *task.Task) E.Error { if entry.IsDocker(r) { client, err := docker.ConnectClient(r.Idlewatcher.DockerHost) if err == nil { - fallback := monitor.NewHTTPHealthChecker(r.rp.TargetURL, r.HealthCheck) - r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Idlewatcher.ContainerID, r.HealthCheck, fallback) + fallback := monitor.NewHTTPHealthChecker(r.rp.TargetURL, r.Raw.HealthCheck) + r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Idlewatcher.ContainerID, r.Raw.HealthCheck, fallback) r.task.OnCancel("close docker client", client.Close) } } if r.HealthMon == nil { - r.HealthMon = monitor.NewHTTPHealthMonitor(r.rp.TargetURL, r.HealthCheck) + r.HealthMon = monitor.NewHTTPHealthMonitor(r.rp.TargetURL, r.Raw.HealthCheck) } } if r.handler == nil { + pathPatterns := r.Raw.PathPatterns switch { - case len(r.PathPatterns) == 0: + case len(pathPatterns) == 0: r.handler = r.rp - case len(r.PathPatterns) == 1 && r.PathPatterns[0] == "/": + case len(pathPatterns) == 1 && pathPatterns[0] == "/": r.handler = r.rp default: mux := gphttp.NewServeMux() patErrs := E.NewBuilder("invalid path pattern(s)") - for _, p := range r.PathPatterns { + for _, p := range pathPatterns { patErrs.Add(mux.HandleFunc(p, r.rp.HandlerFunc)) } if err := patErrs.Error(); err != nil { @@ -136,9 +135,9 @@ func (r *HTTPRoute) Start(providerSubtask *task.Task) E.Error { if entry.UseLoadBalance(r) { r.addToLoadBalancer() } else { - routes.SetHTTPRoute(string(r.Alias), r) + routes.SetHTTPRoute(r.TargetName(), r) r.task.OnFinished("remove from route table", func() { - routes.DeleteHTTPRoute(string(r.Alias)) + routes.DeleteHTTPRoute(r.TargetName()) }) } @@ -159,20 +158,21 @@ func (r *HTTPRoute) ServeHTTP(w http.ResponseWriter, req *http.Request) { func (r *HTTPRoute) addToLoadBalancer() { var lb *loadbalancer.LoadBalancer - l, ok := routes.GetHTTPRoute(r.LoadBalance.Link) + cfg := r.Raw.LoadBalance + l, ok := routes.GetHTTPRoute(cfg.Link) var linked *HTTPRoute if ok { linked = l.(*HTTPRoute) lb = linked.loadBalancer - lb.UpdateConfigIfNeeded(r.LoadBalance) + lb.UpdateConfigIfNeeded(cfg) if linked.Raw.Homepage == nil && r.Raw.Homepage != nil { linked.Raw.Homepage = r.Raw.Homepage } } else { - lb = loadbalancer.New(r.LoadBalance) - lbTask := r.task.Parent().Subtask("loadbalancer " + r.LoadBalance.Link) + lb = loadbalancer.New(cfg) + lbTask := r.task.Parent().Subtask("loadbalancer " + cfg.Link) lbTask.OnCancel("remove lb from routes", func() { - routes.DeleteHTTPRoute(r.LoadBalance.Link) + routes.DeleteHTTPRoute(cfg.Link) }) if err := lb.Start(lbTask); err != nil { panic(err) // should always return nil @@ -180,18 +180,18 @@ func (r *HTTPRoute) addToLoadBalancer() { linked = &HTTPRoute{ ReverseProxyEntry: &entry.ReverseProxyEntry{ Raw: &route.RawEntry{ + Alias: cfg.Link, Homepage: r.Raw.Homepage, }, - Alias: route.Alias(lb.Link), }, HealthMon: lb, loadBalancer: lb, handler: lb, } - routes.SetHTTPRoute(r.LoadBalance.Link, linked) + routes.SetHTTPRoute(cfg.Link, linked) } r.loadBalancer = lb - r.server = loadbalance.NewServer(r.task.String(), r.rp.TargetURL, r.LoadBalance.Weight, r.handler, r.HealthMon) + r.server = loadbalance.NewServer(r.task.String(), r.rp.TargetURL, r.Raw.LoadBalance.Weight, r.handler, r.HealthMon) lb.AddServer(r.server) r.task.OnCancel("remove server from lb", func() { lb.RemoveServer(r.server) diff --git a/internal/route/provider/docker_test.go b/internal/route/provider/docker_test.go index d9af3bb..592927c 100644 --- a/internal/route/provider/docker_test.go +++ b/internal/route/provider/docker_test.go @@ -325,7 +325,7 @@ func TestStreamDefaultValues(t *testing.T) { a := ExpectType[*entry.StreamEntry](t, en) ExpectEqual(t, a.Scheme.ListeningScheme, T.Scheme("udp")) ExpectEqual(t, a.Scheme.ProxyScheme, T.Scheme("udp")) - ExpectEqual(t, a.Host, T.Host(privIP)) + ExpectEqual(t, a.URL.Hostname(), privIP) ExpectEqual(t, a.Port.ListeningPort, 0) ExpectEqual(t, a.Port.ProxyPort, T.Port(privPort)) }) @@ -337,7 +337,7 @@ func TestStreamDefaultValues(t *testing.T) { a := ExpectType[*entry.StreamEntry](t, en) ExpectEqual(t, a.Scheme.ListeningScheme, T.Scheme("udp")) ExpectEqual(t, a.Scheme.ProxyScheme, T.Scheme("udp")) - ExpectEqual(t, a.Host, testIP) + ExpectEqual(t, a.URL.Hostname(), testIP) ExpectEqual(t, a.Port.ListeningPort, 0) ExpectEqual(t, a.Port.ProxyPort, T.Port(pubPort)) }) diff --git a/internal/route/stream.go b/internal/route/stream.go index 6b7b88f..1a94630 100755 --- a/internal/route/stream.go +++ b/internal/route/stream.go @@ -3,7 +3,6 @@ package route import ( "context" "errors" - "fmt" "github.com/rs/zerolog" "github.com/yusing/go-proxy/internal/docker" @@ -44,7 +43,7 @@ func NewStreamRoute(entry *entry.StreamEntry) (impl, E.Error) { } func (r *StreamRoute) String() string { - return fmt.Sprintf("stream %s", r.Alias) + return "stream " + r.TargetName() } // Start implements*task.TaskStarter. @@ -59,7 +58,7 @@ func (r *StreamRoute) Start(providerSubtask *task.Task) E.Error { switch { case entry.UseIdleWatcher(r): - wakerTask := providerSubtask.Parent().Subtask("waker for " + string(r.Alias)) + wakerTask := providerSubtask.Parent().Subtask("waker for " + r.TargetName()) waker, err := idlewatcher.NewStreamWaker(wakerTask, r.StreamEntry, r.Stream) if err != nil { r.task.Finish(err) @@ -71,13 +70,13 @@ func (r *StreamRoute) Start(providerSubtask *task.Task) E.Error { if entry.IsDocker(r) { client, err := docker.ConnectClient(r.Idlewatcher.DockerHost) if err == nil { - fallback := monitor.NewRawHealthChecker(r.TargetURL(), r.HealthCheck) - r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Idlewatcher.ContainerID, r.HealthCheck, fallback) + fallback := monitor.NewRawHealthChecker(r.TargetURL(), r.Raw.HealthCheck) + r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Idlewatcher.ContainerID, r.Raw.HealthCheck, fallback) r.task.OnCancel("close docker client", client.Close) } } if r.HealthMon == nil { - r.HealthMon = monitor.NewRawHealthMonitor(r.TargetURL(), r.HealthCheck) + r.HealthMon = monitor.NewRawHealthMonitor(r.TargetURL(), r.Raw.HealthCheck) } } @@ -106,9 +105,9 @@ func (r *StreamRoute) Start(providerSubtask *task.Task) E.Error { go r.acceptConnections() - routes.SetStreamRoute(string(r.Alias), r) + routes.SetStreamRoute(r.TargetName(), r) r.task.OnFinished("remove from route table", func() { - routes.DeleteStreamRoute(string(r.Alias)) + routes.DeleteStreamRoute(r.TargetName()) }) return nil } diff --git a/internal/route/stream_impl.go b/internal/route/stream_impl.go index 68df2f5..e5ebeae 100644 --- a/internal/route/stream_impl.go +++ b/internal/route/stream_impl.go @@ -45,22 +45,22 @@ func (stream *Stream) Setup() error { switch stream.Scheme.ListeningScheme { case "tcp": - stream.targetAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%v", stream.Host, stream.Port.ProxyPort)) + stream.targetAddr, err = net.ResolveTCPAddr("tcp", stream.URL.Host) if err != nil { return err } - tcpListener, err := lcfg.Listen(stream.task.Context(), "tcp", fmt.Sprintf(":%v", stream.Port.ListeningPort)) + tcpListener, err := lcfg.Listen(stream.task.Context(), "tcp", stream.ListenURL.Host) if err != nil { return err } stream.Port.ListeningPort = T.Port(tcpListener.Addr().(*net.TCPAddr).Port) stream.listener = types.NetListener(tcpListener) case "udp": - stream.targetAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%v", stream.Host, stream.Port.ProxyPort)) + stream.targetAddr, err = net.ResolveUDPAddr("udp", stream.URL.Host) if err != nil { return err } - udpListener, err := lcfg.ListenPacket(stream.task.Context(), "udp", fmt.Sprintf(":%v", stream.Port.ListeningPort)) + udpListener, err := lcfg.ListenPacket(stream.task.Context(), "udp", stream.ListenURL.Host) if err != nil { return err } diff --git a/internal/route/types/alias.go b/internal/route/types/alias.go deleted file mode 100644 index 9201ee3..0000000 --- a/internal/route/types/alias.go +++ /dev/null @@ -1,3 +0,0 @@ -package types - -type Alias string diff --git a/internal/route/types/host.go b/internal/route/types/host.go deleted file mode 100644 index c1647bc..0000000 --- a/internal/route/types/host.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -type ( - Host string - Subdomain = Alias -) - -func ValidateHost[String ~string](s String) (Host, error) { - return Host(s), nil -} diff --git a/internal/route/types/raw_entry.go b/internal/route/types/raw_entry.go index e9e0168..e46226b 100644 --- a/internal/route/types/raw_entry.go +++ b/internal/route/types/raw_entry.go @@ -33,6 +33,7 @@ type ( LoadBalance *loadbalance.Config `json:"load_balance,omitempty" yaml:"load_balance"` Middlewares map[string]docker.LabelMap `json:"middlewares,omitempty" yaml:"middlewares"` Homepage *homepage.Item `json:"homepage,omitempty" yaml:"homepage"` + // AccessLog *accesslog.Config `json:"access_log,omitempty" yaml:"access_log"` /* Docker only */ Container *docker.Container `json:"container,omitempty" yaml:"-"` diff --git a/internal/setup.go b/internal/setup.go index d8611db..ee2063f 100644 --- a/internal/setup.go +++ b/internal/setup.go @@ -12,7 +12,7 @@ import ( ) var ( - branch = common.GetEnvString("BRANCH", "v0.7") + branch = common.GetEnvString("BRANCH", "v0.8") baseURL = "https://github.com/yusing/go-proxy/raw/" + branch requiredConfigs = []Config{ {common.ConfigBasePath, true, false, ""},