diff --git a/compose.yml b/compose.yml index cef7fee..6a8df24 100755 --- a/compose.yml +++ b/compose.yml @@ -45,6 +45,7 @@ services: restart: unless-stopped environment: LOG_LEVEL: ${FLARESOLVERR_LOG_LEVEL} + # FLARESOLVERR_SESSION: ${FLARESOLVERR_SESSION:-goyomi} ports: - "8191:8191" networks: diff --git a/internal/httpclient/client.go b/internal/httpclient/client.go index fafc938..9bb45d0 100755 --- a/internal/httpclient/client.go +++ b/internal/httpclient/client.go @@ -122,36 +122,29 @@ func (c *Client) Do(req *http.Request) (*http.Response, error) { req.Header.Set("User-Agent", c.userAgent) } - // Always route through FlareSolverr when configured. Go's TLS fingerprint - // doesn't match Chrome's, so Cloudflare clearance cookies from FS are - // rejected by Go's net/http — meaning every direct request gets challenged - // again. FS Chrome caches the clearance internally, so subsequent calls - // for the same domain are near-instant. - // - // When FS is not configured, fall back to direct HTTP. - if c.fsClient != nil { - return c.doFS(req, 0) + // Try direct first. Most sites don't have Cloudflare, so this is fast. + // For Cloudflare sites, Go's TLS fingerprint doesn't match Chrome's, so + // the direct request gets 403 — fall back to FlareSolverr. FS uses a + // persistent session (Chrome caches cf_clearance), so only the first + // FS request per domain solves the challenge; subsequent ones are fast. + resp, err := c.doDirect(req) + var directStatus int + if err == nil { + directStatus = resp.StatusCode + if resp.StatusCode != http.StatusForbidden && resp.StatusCode != http.StatusServiceUnavailable { + return resp, nil + } + resp.Body.Close() } - // --- direct-first path (commented out — see TLS fingerprint issue above) --- - // resp, err := c.doDirect(req) - // var directStatus int - // if err == nil { - // directStatus = resp.StatusCode - // if resp.StatusCode != http.StatusForbidden && resp.StatusCode != http.StatusServiceUnavailable { - // return resp, nil - // } - // resp.Body.Close() - // } - // if c.fsClient == nil { - // if err != nil { - // return nil, err - // } - // return nil, fmt.Errorf("HTTP %d (challenge detected but FlareSolverr not configured)", resp.StatusCode) - // } - // return c.doFS(req, directStatus) + if c.fsClient == nil { + if err != nil { + return nil, err + } + return nil, fmt.Errorf("HTTP %d (challenge detected but FlareSolverr not configured)", resp.StatusCode) + } - return c.doDirect(req) + return c.doFS(req, directStatus) } func (c *Client) doDirect(req *http.Request) (*http.Response, error) {