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:
2026-07-28 17:38:57 +08:00
parent edae8235a6
commit 040e3ebab1
8 changed files with 110 additions and 64 deletions
+22 -1
View File
@@ -6,6 +6,7 @@ import (
"io"
"math"
"net/http"
"net/url"
"strings"
"sync"
"time"
@@ -31,6 +32,7 @@ type BuildOptions struct {
RequestUserAgent string
ForceRefresh bool
CacheRepo *database.CacheRepo
ProxyURL string
}
// BuildResult holds the output of a subscription build.
@@ -249,7 +251,7 @@ func fetchSubscriptionUrl(ctx context.Context, url string, sub model.SourceRecor
}
timeout := getTimeout(opts.Settings)
httpClient := &http.Client{Timeout: timeout}
httpClient := buildHTTPClient(timeout, opts.ProxyURL)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
@@ -612,3 +614,22 @@ func (aw *AsyncWriter) WaitWithTimeout(timeout time.Duration) {
// Prevent unused import
var _ = math.MaxInt32
// buildHTTPClient creates an *http.Client with optional proxy support.
// If proxyURL is empty, a standard client is returned.
func buildHTTPClient(timeout time.Duration, proxyURL string) *http.Client {
if proxyURL == "" {
return &http.Client{Timeout: timeout}
}
pu, err := url.Parse(proxyURL)
if err != nil {
logrus.WithError(err).Warn("Invalid proxy_url, falling back to direct")
return &http.Client{Timeout: timeout}
}
return &http.Client{
Timeout: timeout,
Transport: &http.Transport{
Proxy: http.ProxyURL(pu),
},
}
}