diff --git a/common/urltest/urltest.go b/common/urltest/urltest.go index c60fa569..436c2a5e 100644 --- a/common/urltest/urltest.go +++ b/common/urltest/urltest.go @@ -50,6 +50,9 @@ func (s *HistoryStorage) StoreURLTestHistory(tag string, history *History) { } func URLTest(ctx context.Context, link string, detour N.Dialer) (t uint16, err error) { + if link == "" { + link = "https://www.gstatic.com/generate_204" + } linkURL, err := url.Parse(link) if err != nil { return diff --git a/docs/configuration/outbound/urltest.md b/docs/configuration/outbound/urltest.md index 83d174ba..cdfed7b9 100644 --- a/docs/configuration/outbound/urltest.md +++ b/docs/configuration/outbound/urltest.md @@ -10,7 +10,7 @@ "proxy-b", "proxy-c" ], - "url": "http://www.gstatic.com/generate_204", + "url": "https://www.gstatic.com/generate_204", "interval": "1m", "tolerance": 50 } @@ -26,7 +26,7 @@ List of outbound tags to test. #### url -The URL to test. `http://www.gstatic.com/generate_204` will be used if empty. +The URL to test. `https://www.gstatic.com/generate_204` will be used if empty. #### interval diff --git a/docs/configuration/outbound/urltest.zh.md b/docs/configuration/outbound/urltest.zh.md index 98a36ecc..210eadb5 100644 --- a/docs/configuration/outbound/urltest.zh.md +++ b/docs/configuration/outbound/urltest.zh.md @@ -10,7 +10,7 @@ "proxy-b", "proxy-c" ], - "url": "http://www.gstatic.com/generate_204", + "url": "https://www.gstatic.com/generate_204", "interval": "1m", "tolerance": 50 } @@ -26,7 +26,7 @@ #### url -用于测试的链接。默认使用 `http://www.gstatic.com/generate_204`。 +用于测试的链接。默认使用 `https://www.gstatic.com/generate_204`。 #### interval diff --git a/experimental/clashapi/api_meta_group.go b/experimental/clashapi/api_meta_group.go index 34cf26e2..e9c8f0f3 100644 --- a/experimental/clashapi/api_meta_group.go +++ b/experimental/clashapi/api_meta_group.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "strconv" + "strings" "sync" "time" @@ -67,6 +68,9 @@ func getGroupDelay(server *Server) func(w http.ResponseWriter, r *http.Request) query := r.URL.Query() url := query.Get("url") + if strings.HasPrefix(url, "http://") { + url = "" + } timeout, err := strconv.ParseInt(query.Get("timeout"), 10, 32) if err != nil { render.Status(r, http.StatusBadRequest) diff --git a/experimental/clashapi/proxies.go b/experimental/clashapi/proxies.go index bdc97436..be0f22a1 100644 --- a/experimental/clashapi/proxies.go +++ b/experimental/clashapi/proxies.go @@ -6,6 +6,7 @@ import ( "net/http" "sort" "strconv" + "strings" "time" "github.com/sagernet/sing-box/adapter" @@ -214,6 +215,9 @@ func getProxyDelay(server *Server) func(w http.ResponseWriter, r *http.Request) return func(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() url := query.Get("url") + if strings.HasPrefix(url, "http://") { + url = "" + } timeout, err := strconv.ParseInt(query.Get("timeout"), 10, 16) if err != nil { render.Status(r, http.StatusBadRequest) diff --git a/go.mod b/go.mod index eddd1344..48bebab4 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/sagernet/gomobile v0.0.0-20221130124640-349ebaa752ca github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 - github.com/sagernet/sing v0.2.3-0.20230412070623-d88db59703cd + github.com/sagernet/sing v0.2.3-0.20230413012039-2fb7e38ac4bf github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440 github.com/sagernet/sing-shadowsocks v0.2.1-0.20230412123110-1a7c32b4e2e7 github.com/sagernet/sing-shadowtls v0.1.1-0.20230409094821-9abef019436f diff --git a/go.sum b/go.sum index e05f2c7a..c8517d52 100644 --- a/go.sum +++ b/go.sum @@ -111,8 +111,8 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byL github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= -github.com/sagernet/sing v0.2.3-0.20230412070623-d88db59703cd h1:SVO7Lr04d8P6EMrBDgv2fkpxPBeJuz/OZukk7+ymTqw= -github.com/sagernet/sing v0.2.3-0.20230412070623-d88db59703cd/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= +github.com/sagernet/sing v0.2.3-0.20230413012039-2fb7e38ac4bf h1:vb0X9OLdWOzqDH5lsC7DHWEx6dw++p+nsKeYxxEvYUA= +github.com/sagernet/sing v0.2.3-0.20230413012039-2fb7e38ac4bf/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440 h1:VH8/BcOVuApHtS+vKP+khxlGRcXH7KKhgkTDtNynqSQ= github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440/go.mod h1:69PNSHyEmXdjf6C+bXBOdr2GQnPeEyWjIzo/MV8gmz8= github.com/sagernet/sing-shadowsocks v0.2.1-0.20230412123110-1a7c32b4e2e7 h1:3WDMIF1aE/twc5gJ+9PF2ZJqUxwZ80MPtNBKE3yBevU= diff --git a/outbound/builder.go b/outbound/builder.go index f032d83b..45d48425 100644 --- a/outbound/builder.go +++ b/outbound/builder.go @@ -54,7 +54,7 @@ func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, t case C.TypeSelector: return NewSelector(router, logger, tag, options.SelectorOptions) case C.TypeURLTest: - return NewURLTest(router, logger, tag, options.URLTestOptions) + return NewURLTest(ctx, router, logger, tag, options.URLTestOptions) default: return nil, E.New("unknown outbound type: ", options.Type) } diff --git a/outbound/urltest.go b/outbound/urltest.go index ac6badb4..02254df3 100644 --- a/outbound/urltest.go +++ b/outbound/urltest.go @@ -26,6 +26,7 @@ var ( type URLTest struct { myOutboundAdapter + ctx context.Context tags []string link string interval time.Duration @@ -33,7 +34,7 @@ type URLTest struct { group *URLTestGroup } -func NewURLTest(router adapter.Router, logger log.ContextLogger, tag string, options option.URLTestOutboundOptions) (*URLTest, error) { +func NewURLTest(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.URLTestOutboundOptions) (*URLTest, error) { outbound := &URLTest{ myOutboundAdapter: myOutboundAdapter{ protocol: C.TypeURLTest, @@ -41,6 +42,7 @@ func NewURLTest(router adapter.Router, logger log.ContextLogger, tag string, opt logger: logger, tag: tag, }, + ctx: ctx, tags: options.Outbounds, link: options.URL, interval: time.Duration(options.Interval), @@ -68,7 +70,7 @@ func (s *URLTest) Start() error { } outbounds = append(outbounds, detour) } - s.group = NewURLTestGroup(s.router, s.logger, outbounds, s.link, s.interval, s.tolerance) + s.group = NewURLTestGroup(s.ctx, s.router, s.logger, outbounds, s.link, s.interval, s.tolerance) return s.group.Start() } @@ -97,14 +99,7 @@ func (s *URLTest) DialContext(ctx context.Context, network string, destination M return conn, nil } s.logger.ErrorContext(ctx, err) - go s.group.checkOutbounds() - outbounds := s.group.Fallback(outbound) - for _, fallback := range outbounds { - conn, err = fallback.DialContext(ctx, network, destination) - if err == nil { - return conn, nil - } - } + s.group.history.DeleteURLTestHistory(outbound.Tag()) return nil, err } @@ -115,14 +110,7 @@ func (s *URLTest) ListenPacket(ctx context.Context, destination M.Socksaddr) (ne return conn, nil } s.logger.ErrorContext(ctx, err) - go s.group.checkOutbounds() - outbounds := s.group.Fallback(outbound) - for _, fallback := range outbounds { - conn, err = fallback.ListenPacket(ctx, destination) - if err == nil { - return conn, nil - } - } + s.group.history.DeleteURLTestHistory(outbound.Tag()) return nil, err } @@ -135,6 +123,7 @@ func (s *URLTest) NewPacketConnection(ctx context.Context, conn N.PacketConn, me } type URLTestGroup struct { + ctx context.Context router adapter.Router logger log.Logger outbounds []adapter.Outbound @@ -147,11 +136,7 @@ type URLTestGroup struct { close chan struct{} } -func NewURLTestGroup(router adapter.Router, logger log.Logger, outbounds []adapter.Outbound, link string, interval time.Duration, tolerance uint16) *URLTestGroup { - if link == "" { - //goland:noinspection HttpUrlsUsage - link = "http://www.gstatic.com/generate_204" - } +func NewURLTestGroup(ctx context.Context, router adapter.Router, logger log.Logger, outbounds []adapter.Outbound, link string, interval time.Duration, tolerance uint16) *URLTestGroup { if interval == 0 { interval = C.DefaultURLTestInterval } @@ -165,6 +150,7 @@ func NewURLTestGroup(router adapter.Router, logger log.Logger, outbounds []adapt history = urltest.NewHistoryStorage() } return &URLTestGroup{ + ctx: ctx, router: router, logger: logger, outbounds: outbounds, @@ -254,7 +240,7 @@ func (g *URLTestGroup) loopCheck() { } func (g *URLTestGroup) checkOutbounds() { - _, _ = g.URLTest(context.Background(), g.link) + _, _ = g.URLTest(g.ctx, g.link) } func (g *URLTestGroup) URLTest(ctx context.Context, link string) (map[string]uint16, error) {