diff --git a/adapter/adapter.go b/adapter/adapter.go index 8136827a0..3efc8166f 100644 --- a/adapter/adapter.go +++ b/adapter/adapter.go @@ -39,6 +39,11 @@ type Proxy struct { extra *xsync.MapOf[string, *internalProxyState] } +// Adapter implements C.Proxy +func (p *Proxy) Adapter() C.ProxyAdapter { + return p.ProxyAdapter +} + // AliveForTestUrl implements C.Proxy func (p *Proxy) AliveForTestUrl(url string) bool { if state, ok := p.extra.Load(url); ok { diff --git a/adapter/outboundgroup/util.go b/adapter/outboundgroup/util.go index 84216377b..66b2510c1 100644 --- a/adapter/outboundgroup/util.go +++ b/adapter/outboundgroup/util.go @@ -4,3 +4,7 @@ type SelectAble interface { Set(string) error ForceSet(name string) } + +var _ SelectAble = (*Fallback)(nil) +var _ SelectAble = (*URLTest)(nil) +var _ SelectAble = (*Selector)(nil) diff --git a/constant/adapters.go b/constant/adapters.go index cb47f8716..b303eb846 100644 --- a/constant/adapters.go +++ b/constant/adapters.go @@ -158,6 +158,7 @@ type DelayHistoryStoreType int type Proxy interface { ProxyAdapter + Adapter() ProxyAdapter AliveForTestUrl(url string) bool DelayHistory() []DelayHistory ExtraDelayHistories() map[string]ProxyState diff --git a/hub/executor/executor.go b/hub/executor/executor.go index 66514e39b..214407b47 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -445,12 +445,12 @@ func patchSelectGroup(proxies map[string]C.Proxy) { } for name, proxy := range proxies { - outbound, ok := proxy.(*adapter.Proxy) + outbound, ok := proxy.(C.Proxy) if !ok { continue } - selector, ok := outbound.ProxyAdapter.(outboundgroup.SelectAble) + selector, ok := outbound.Adapter().(outboundgroup.SelectAble) if !ok { continue } diff --git a/hub/route/groups.go b/hub/route/groups.go index c4e9501f2..68d1f3542 100644 --- a/hub/route/groups.go +++ b/hub/route/groups.go @@ -9,7 +9,6 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/render" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile/cachefile" @@ -32,7 +31,7 @@ func GroupRouter() http.Handler { func getGroups(w http.ResponseWriter, r *http.Request) { var gs []C.Proxy for _, p := range tunnel.Proxies() { - if _, ok := p.(*adapter.Proxy).ProxyAdapter.(C.Group); ok { + if _, ok := p.Adapter().(C.Group); ok { gs = append(gs, p) } } @@ -43,7 +42,7 @@ func getGroups(w http.ResponseWriter, r *http.Request) { func getGroup(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - if _, ok := proxy.(*adapter.Proxy).ProxyAdapter.(C.Group); ok { + if _, ok := proxy.Adapter().(C.Group); ok { render.JSON(w, r, proxy) return } @@ -53,25 +52,15 @@ func getGroup(w http.ResponseWriter, r *http.Request) { func getGroupDelay(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - group, ok := proxy.(*adapter.Proxy).ProxyAdapter.(C.Group) + group, ok := proxy.Adapter().(C.Group) if !ok { render.Status(r, http.StatusNotFound) render.JSON(w, r, ErrNotFound) return } - switch proxy.(*adapter.Proxy).Type() { - case C.URLTest: - if urlTestGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.URLTest); ok { - urlTestGroup.ForceSet("") - } - case C.Fallback: - if fallbackGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.Fallback); ok { - fallbackGroup.ForceSet("") - } - } - - if proxy.(*adapter.Proxy).Type() != C.Selector { + if selectAble, ok := proxy.Adapter().(outboundgroup.SelectAble); ok && proxy.Type() != C.Selector { + selectAble.ForceSet("") cachefile.Cache().SetSelected(proxy.Name(), "") } diff --git a/hub/route/proxies.go b/hub/route/proxies.go index 9ff27c2dd..ba4e03f90 100644 --- a/hub/route/proxies.go +++ b/hub/route/proxies.go @@ -7,7 +7,6 @@ import ( "strconv" "time" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile/cachefile" @@ -82,8 +81,8 @@ func updateProxy(w http.ResponseWriter, r *http.Request) { return } - proxy := r.Context().Value(CtxKeyProxy).(*adapter.Proxy) - selector, ok := proxy.ProxyAdapter.(outboundgroup.SelectAble) + proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) + selector, ok := proxy.Adapter().(outboundgroup.SelectAble) if !ok { render.Status(r, http.StatusBadRequest) render.JSON(w, r, newError("Must be a Selector")) @@ -150,24 +149,12 @@ func getProxyDelay(w http.ResponseWriter, r *http.Request) { func unfixedProxy(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - switch proxy.(*adapter.Proxy).Type() { - case C.URLTest: - if urlTestGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.URLTest); ok { - urlTestGroup.ForceSet("") - } - case C.Fallback: - if fallbackGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.Fallback); ok { - fallbackGroup.ForceSet("") - } - default: - render.Status(r, http.StatusBadRequest) - render.JSON(w, r, ErrBadRequest) - return - } - - if proxy.(*adapter.Proxy).Type() != C.Selector { + if selectAble, ok := proxy.Adapter().(outboundgroup.SelectAble); ok && proxy.Type() != C.Selector { + selectAble.ForceSet("") cachefile.Cache().SetSelected(proxy.Name(), "") + render.NoContent(w, r) + return } - - render.NoContent(w, r) + render.Status(r, http.StatusBadRequest) + render.JSON(w, r, ErrBadRequest) }