diff --git a/internal/autocert/provider_test/ovh_test.go b/internal/autocert/provider_test/ovh_test.go index 9463f1d8..e9d778f7 100644 --- a/internal/autocert/provider_test/ovh_test.go +++ b/internal/autocert/provider_test/ovh_test.go @@ -45,6 +45,6 @@ oauth2_config: testYaml = testYaml[1:] // remove first \n opt := make(map[string]any) ExpectNoError(t, yaml.Unmarshal([]byte(testYaml), opt)) - ExpectTrue(t, U.Deserialize(opt, cfg).NoError()) + ExpectNoError(t, U.Deserialize(opt, cfg).Error()) ExpectDeepEqual(t, cfg, cfgExpected) } diff --git a/internal/config/query.go b/internal/config/query.go index 7d70b6cc..0337699a 100644 --- a/internal/config/query.go +++ b/internal/config/query.go @@ -27,6 +27,9 @@ func (cfg *Config) DumpProviders() map[string]*PR.Provider { func (cfg *Config) RoutesByAlias() map[string]U.SerializedObject { routes := make(map[string]U.SerializedObject) cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) { + if !r.Started() { + return + } obj, err := U.Serialize(r) if err.HasError() { cfg.l.Error(err) @@ -46,6 +49,9 @@ func (cfg *Config) Statistics() map[string]any { providerStats := make(map[string]any) cfg.forEachRoute(func(alias string, r R.Route, p *PR.Provider) { + if !r.Started() { + return + } s, ok := providerStats[p.GetName()] if !ok { s = make(map[string]int) diff --git a/internal/models/raw_entry.go b/internal/models/raw_entry.go index 8cfc0e95..34020d19 100644 --- a/internal/models/raw_entry.go +++ b/internal/models/raw_entry.go @@ -5,7 +5,6 @@ import ( "strconv" "strings" - "github.com/sirupsen/logrus" . "github.com/yusing/go-proxy/internal/common" D "github.com/yusing/go-proxy/internal/docker" F "github.com/yusing/go-proxy/internal/utils/functional" @@ -32,7 +31,7 @@ type ( var NewProxyEntries = F.NewMapOf[string, *RawEntry] -func (e *RawEntry) FillMissingFields() bool { +func (e *RawEntry) FillMissingFields() { isDocker := e.ProxyProperties != nil if !isDocker { e.ProxyProperties = &D.ProxyProperties{} @@ -59,7 +58,7 @@ func (e *RawEntry) FillMissingFields() bool { } else if pp == "" { if p, ok := F.FirstValueOf(e.PrivatePortMapping); ok { pp = fmt.Sprint(p.PrivatePort) - } else { + } else if !isDocker { pp = "80" } } @@ -73,12 +72,6 @@ func (e *RawEntry) FillMissingFields() bool { // try to fallback to first public port if p, ok := F.FirstValueOf(e.PublicPortMapping); ok { pp = fmt.Sprint(p.PublicPort) - } else if e.Running { - // ignore only if it is NOT RUNNING - // because stopped containers - // will have empty port mapping got from docker - logrus.Debugf("ignored port %s for %s", pp, e.ContainerName) - return false } } } @@ -120,7 +113,9 @@ func (e *RawEntry) FillMissingFields() bool { e.Port = joinPorts(lp, pp, extra) - return true + if e.Port == "" { + e.Port = "0" + } } func (e *RawEntry) splitPorts() (lp string, pp string, extra string) { diff --git a/internal/net/http/middleware/forward_auth.go b/internal/net/http/middleware/forward_auth.go index ba5b8bc7..6853e578 100644 --- a/internal/net/http/middleware/forward_auth.go +++ b/internal/net/http/middleware/forward_auth.go @@ -34,15 +34,6 @@ type ( } ) -const ( - xForwardedFor = "X-Forwarded-For" - xForwardedMethod = "X-Forwarded-Method" - xForwardedHost = "X-Forwarded-Host" - xForwardedProto = "X-Forwarded-Proto" - xForwardedURI = "X-Forwarded-Uri" - xForwardedPort = "X-Forwarded-Port" -) - var ForwardAuth = func() *forwardAuth { fa := new(forwardAuth) fa.m = new(Middleware) diff --git a/internal/net/http/middleware/middlewares.go b/internal/net/http/middleware/middlewares.go index 9f71279f..f86a8ca9 100644 --- a/internal/net/http/middleware/middlewares.go +++ b/internal/net/http/middleware/middlewares.go @@ -16,7 +16,7 @@ import ( var middlewares map[string]*Middleware func Get(name string) (middleware *Middleware, ok bool) { - middleware, ok = middlewares[strings.ToLower(name)] + middleware, ok = middlewares[U.ToLowerNoSnake(name)] return } diff --git a/internal/net/http/middleware/x_forwarded.go b/internal/net/http/middleware/x_forwarded.go index 9a2f4d3b..1bd59032 100644 --- a/internal/net/http/middleware/x_forwarded.go +++ b/internal/net/http/middleware/x_forwarded.go @@ -4,23 +4,32 @@ import ( "net" ) +const ( + xForwardedFor = "X-Forwarded-For" + xForwardedMethod = "X-Forwarded-Method" + xForwardedHost = "X-Forwarded-Host" + xForwardedProto = "X-Forwarded-Proto" + xForwardedURI = "X-Forwarded-Uri" + xForwardedPort = "X-Forwarded-Port" +) + var SetXForwarded = &Middleware{ rewrite: func(req *Request) { req.Header.Del("Forwarded") - req.Header.Del("X-Forwarded-For") - req.Header.Del("X-Forwarded-Host") - req.Header.Del("X-Forwarded-Proto") + req.Header.Del(xForwardedFor) + req.Header.Del(xForwardedHost) + req.Header.Del(xForwardedProto) clientIP, _, err := net.SplitHostPort(req.RemoteAddr) if err == nil { - req.Header.Set("X-Forwarded-For", clientIP) + req.Header.Set(xForwardedFor, clientIP) } else { - req.Header.Del("X-Forwarded-For") + req.Header.Del(xForwardedFor) } - req.Header.Set("X-Forwarded-Host", req.Host) + req.Header.Set(xForwardedHost, req.Host) if req.TLS == nil { - req.Header.Set("X-Forwarded-Proto", "http") + req.Header.Set(xForwardedProto, "http") } else { - req.Header.Set("X-Forwarded-Proto", "https") + req.Header.Set(xForwardedProto, "https") } }, } @@ -28,8 +37,8 @@ var SetXForwarded = &Middleware{ var HideXForwarded = &Middleware{ rewrite: func(req *Request) { req.Header.Del("Forwarded") - req.Header.Del("X-Forwarded-For") - req.Header.Del("X-Forwarded-Host") - req.Header.Del("X-Forwarded-Proto") + req.Header.Del(xForwardedFor) + req.Header.Del(xForwardedHost) + req.Header.Del(xForwardedProto) }, } diff --git a/internal/proxy/entry.go b/internal/proxy/entry.go index 4f7b0243..51ea2528 100644 --- a/internal/proxy/entry.go +++ b/internal/proxy/entry.go @@ -48,9 +48,7 @@ func (rp *ReverseProxyEntry) IsDocker() bool { } func ValidateEntry(m *M.RawEntry) (any, E.NestedError) { - if !m.FillMissingFields() { - return nil, E.Missing("fields") - } + m.FillMissingFields() scheme, err := T.NewScheme(m.Scheme) if err.HasError() { diff --git a/internal/proxy/fields/stream_port.go b/internal/proxy/fields/stream_port.go index 881d18e7..75824f82 100644 --- a/internal/proxy/fields/stream_port.go +++ b/internal/proxy/fields/stream_port.go @@ -12,7 +12,7 @@ type StreamPort struct { ProxyPort Port `json:"proxy"` } -func ValidateStreamPort(p string) (StreamPort, E.NestedError) { +func ValidateStreamPort(p string) (_ StreamPort, err E.NestedError) { split := strings.Split(p, ":") switch len(split) { @@ -21,24 +21,26 @@ func ValidateStreamPort(p string) (StreamPort, E.NestedError) { case 2: break default: - return ErrStreamPort, E.Invalid("stream port", p).With("too many colons") + err = E.Invalid("stream port", p).With("too many colons") + return } listeningPort, err := ValidatePort(split[0]) if err != nil { - return ErrStreamPort, err.Subject("listening port") + err = err.Subject("listening port") + return } proxyPort, err := ValidatePort(split[1]) if err.Is(E.ErrOutOfRange) { - return ErrStreamPort, err.Subject("proxy port") - } else if proxyPort == 0 { - return ErrStreamPort, E.Invalid("proxy port", p) + err = err.Subject("proxy port") + return } else if err != nil { proxyPort, err = parseNameToPort(split[1]) if err != nil { - return ErrStreamPort, E.Invalid("proxy port", proxyPort) + err = E.Invalid("proxy port", proxyPort) + return } } @@ -52,5 +54,3 @@ func parseNameToPort(name string) (Port, E.NestedError) { } return Port(port), nil } - -var ErrStreamPort = StreamPort{ErrPort, ErrPort} diff --git a/internal/proxy/provider/docker.go b/internal/proxy/provider/docker.go index 46fd4080..d6a89505 100755 --- a/internal/proxy/provider/docker.go +++ b/internal/proxy/provider/docker.go @@ -163,8 +163,8 @@ func (p *DockerProvider) entriesFromContainerLabels(container D.Container) (entr } // remove all entries that failed to fill in missing fields - entries.RemoveAll(func(re *M.RawEntry) bool { - return !re.FillMissingFields() + entries.RangeAll(func(_ string, re *M.RawEntry) { + re.FillMissingFields() }) return entries, errors.Build().Subject(container.ContainerName) diff --git a/internal/route/http.go b/internal/route/http.go index 6e39c496..50d0cec4 100755 --- a/internal/route/http.go +++ b/internal/route/http.go @@ -133,7 +133,9 @@ func (r *HTTPRoute) Start() E.NestedError { } } - if r.entry.IsDocker() && !r.entry.ContainerRunning { + if r.entry.URL.Port() == "0" || + r.entry.IsDocker() && !r.entry.ContainerRunning { + // TODO: if it use idlewatcher, set mux to dummy mux return nil } diff --git a/internal/route/stream.go b/internal/route/stream.go index 29319998..1cef5ec2 100755 --- a/internal/route/stream.go +++ b/internal/route/stream.go @@ -11,6 +11,7 @@ import ( "github.com/sirupsen/logrus" E "github.com/yusing/go-proxy/internal/error" P "github.com/yusing/go-proxy/internal/proxy" + PT "github.com/yusing/go-proxy/internal/proxy/fields" ) type StreamRoute struct { @@ -57,7 +58,7 @@ func (r *StreamRoute) String() string { } func (r *StreamRoute) Start() E.NestedError { - if r.started.Load() { + if r.Port.ListeningPort == PT.NoPort || r.started.Load() { return nil } r.ctx, r.cancel = context.WithCancel(context.Background())