From 65905566dd6a191c2ae1a991823e6c20f3896f72 Mon Sep 17 00:00:00 2001 From: Etheirystech Date: Fri, 3 Apr 2026 14:08:55 +0200 Subject: [PATCH] Fixed: Use FlareSolverr response body instead of re-requesting The second HTTP request after FlareSolverr solves a Cloudflare challenge fails because cf_clearance is validated against the solver's TLS fingerprint, which .NET HttpClient cannot replicate. Use the solved response body directly and fall back to cookie retry only when FlareSolverr returns no body. Also fix error message to report flaresolverrResponse.StatusCode instead of the original response.StatusCode. Closes #2561 --- .../FlareSolverr/FlareSolverr.cs | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/IndexerProxies/FlareSolverr/FlareSolverr.cs b/src/NzbDrone.Core/IndexerProxies/FlareSolverr/FlareSolverr.cs index 5107bf151..2a186f45e 100644 --- a/src/NzbDrone.Core/IndexerProxies/FlareSolverr/FlareSolverr.cs +++ b/src/NzbDrone.Core/IndexerProxies/FlareSolverr/FlareSolverr.cs @@ -58,7 +58,7 @@ public override HttpResponse PostResponse(HttpResponse response) if (flaresolverrResponse.StatusCode != HttpStatusCode.OK && flaresolverrResponse.StatusCode != HttpStatusCode.InternalServerError) { - throw new FlareSolverrException("HTTP StatusCode not 200 or 500. Status is :" + response.StatusCode); + throw new FlareSolverrException("HTTP StatusCode not 200 or 500. Status is :" + flaresolverrResponse.StatusCode); } var result = JsonConvert.DeserializeObject(flaresolverrResponse.Content); @@ -71,7 +71,32 @@ public override HttpResponse PostResponse(HttpResponse response) InjectCookies(newRequest, result); - //Request again with User-Agent and Cookies from Flaresolverr + // Use FlareSolverr's response body directly when available. + // A second HTTP request with the extracted cookies would get rejected + // because cf_clearance is validated against the TLS fingerprint of the + // client that solved the challenge (FlareSolverr's headless browser), + // which differs from .NET HttpClient's fingerprint. + if (result.Solution.Response.IsNotNullOrWhiteSpace()) + { + var headers = new HttpHeader(); + + // Preserve the Content-Type from FlareSolverr's solution so downstream + // parsers (e.g. JSON indexers) interpret the body correctly. + if (result.Solution.Headers?.ContentType.IsNotNullOrWhiteSpace() == true) + { + headers.ContentType = result.Solution.Headers.ContentType; + } + + return new HttpResponse( + response.Request, + headers, + response.Cookies, + result.Solution.Response, + response.ElapsedTime, + HttpStatusCode.OK); + } + + // Fallback: if FlareSolverr returned no body, retry with cookies (original behavior) var finalResponse = _httpClient.Execute(newRequest); return finalResponse;