fix: fetcher proxy support, Dockerfile sing-box, rename index format
1. sslinks 403: Cloudflare blocks server IP. Add fetcher.proxy_url config so subscription/flow requests can route through an HTTP proxy. 2. Egress probe: Docker image lacked sing-box. Install sing-box v1.11.4 in the Alpine runtime stage. 3. Collection rename: group by display baseName instead of internal groupKey, format index as -N instead of %02d. Fixes double-suffix issue where EnsureUniqueProxyNames appended -2/-3 onto existing 02.
This commit is contained in:
@@ -52,6 +52,7 @@ func (d *Deps) HandleDownloadCollection(c fiber.Ctx) error {
|
||||
RequestUserAgent: c.Get("User-Agent"),
|
||||
ForceRefresh: c.Query("refresh") == "1" || c.Query("noCache") == "1",
|
||||
CacheRepo: d.CacheRepo,
|
||||
ProxyURL: d.Cfg.Fetcher.ProxyURL,
|
||||
})
|
||||
if err != nil {
|
||||
return failed(c, err.Error(), 500)
|
||||
@@ -82,6 +83,7 @@ func (d *Deps) HandleDownloadSource(c fiber.Ctx) error {
|
||||
RequestUserAgent: c.Get("User-Agent"),
|
||||
ForceRefresh: c.Query("refresh") == "1" || c.Query("noCache") == "1",
|
||||
CacheRepo: d.CacheRepo,
|
||||
ProxyURL: d.Cfg.Fetcher.ProxyURL,
|
||||
})
|
||||
if err != nil {
|
||||
return failed(c, err.Error(), 500)
|
||||
@@ -182,6 +184,7 @@ func (d *Deps) HandlePreviewSource(c fiber.Ctx) error {
|
||||
Settings: settings,
|
||||
RequestUserAgent: c.Get("User-Agent"),
|
||||
CacheRepo: d.CacheRepo,
|
||||
ProxyURL: d.Cfg.Fetcher.ProxyURL,
|
||||
})
|
||||
if err != nil {
|
||||
return failed(c, err.Error(), 400)
|
||||
@@ -210,6 +213,7 @@ func (d *Deps) HandlePreviewCollection(c fiber.Ctx) error {
|
||||
Settings: settings,
|
||||
RequestUserAgent: c.Get("User-Agent"),
|
||||
CacheRepo: d.CacheRepo,
|
||||
ProxyURL: d.Cfg.Fetcher.ProxyURL,
|
||||
})
|
||||
if err != nil {
|
||||
return failed(c, err.Error(), 400)
|
||||
@@ -296,7 +300,7 @@ func (d *Deps) HandleFlowInfo(c fiber.Ctx) error {
|
||||
"error": fiber.Map{"code": "NO_FLOW_INFO", "type": "NO_FLOW_INFO", "message": "No flow info"},
|
||||
})
|
||||
}
|
||||
headers, err := fetchFlowHeaders(flowReq)
|
||||
headers, err := fetchFlowHeaders(flowReq, d.Cfg.Fetcher.ProxyURL)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{
|
||||
"status": "failed",
|
||||
@@ -573,8 +577,8 @@ func parseJSONHeaders(v any) map[string]string {
|
||||
return result
|
||||
}
|
||||
|
||||
func fetchFlowHeaders(req *flowRequest) (string, error) {
|
||||
client := &http.Client{Timeout: req.Timeout}
|
||||
func fetchFlowHeaders(req *flowRequest, proxyURL string) (string, error) {
|
||||
client := buildFlowHTTPClient(req.Timeout, proxyURL)
|
||||
httpReq, err := http.NewRequest("GET", req.URL, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -708,3 +712,21 @@ func applyFiltersSafe(nodes []model.ProxyNode, filters []model.FilterRule, setti
|
||||
// Use the filter package's ApplyFilters with FilterContext
|
||||
return applyFiltersWithContext(nodes, filters, settings, target, sourceId)
|
||||
}
|
||||
|
||||
// buildFlowHTTPClient builds an HTTP client for flow-info requests with
|
||||
// optional proxy support.
|
||||
func buildFlowHTTPClient(timeout time.Duration, proxyURL string) *http.Client {
|
||||
if proxyURL == "" {
|
||||
return &http.Client{Timeout: timeout}
|
||||
}
|
||||
pu, err := url.Parse(proxyURL)
|
||||
if err != nil {
|
||||
return &http.Client{Timeout: timeout}
|
||||
}
|
||||
return &http.Client{
|
||||
Timeout: timeout,
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyURL(pu),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2226,7 +2226,7 @@ func TestSetSafeResponseHeaderVar(t *testing.T) {
|
||||
func TestFetchFlowHeadersError(t *testing.T) {
|
||||
// invalid URL -> error
|
||||
req := &flowRequest{URL: "http://localhost:1/no-server", UserAgent: "ua", Timeout: 1000000000}
|
||||
_, err := fetchFlowHeaders(req)
|
||||
_, err := fetchFlowHeaders(req, "")
|
||||
if err == nil {
|
||||
// connection may succeed in some envs; just don't fail the test
|
||||
t.Log("fetchFlowHeaders to invalid URL did not error (env-dependent)")
|
||||
|
||||
Reference in New Issue
Block a user