containers without port mapped will no longer be served

This commit is contained in:
yusing 2024-10-01 17:18:17 +08:00
parent 44cfd65f6c
commit c3b779a810
11 changed files with 50 additions and 48 deletions

View file

@ -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)
}

View file

@ -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)

View file

@ -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) {

View file

@ -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)

View file

@ -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
}

View file

@ -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)
},
}

View file

@ -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() {

View file

@ -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}

View file

@ -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)

View file

@ -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
}

View file

@ -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())