Skip to content

Commit e806042

Browse files
committed
1 parent 2033709 commit e806042

13 files changed

+313
-106
lines changed

src/FlareSolverrSharp/ChallengeDetector.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ private static bool IsCloudflareProtectedAsync(HttpResponseMessage response)
3131
i.Product != null
3232
&& CloudflareValues.CloudflareServerNames.Contains(
3333
i.Product.Name.ToLower()))) {
34+
// return false;
3435
return true;
3536
}
3637

3738
// detect CloudFlare and DDoS-GUARD
3839
if (response.StatusCode is HttpStatusCode.ServiceUnavailable or HttpStatusCode.Forbidden
39-
or (HttpStatusCode) 523) {
40+
or (HttpStatusCode) CloudflareValues.CloudflareStatusCodes.OriginUnreachable) {
4041
var responseHtml = response.Content.ReadAsStringAsync().Result;
4142

4243

src/FlareSolverrSharp/ClearanceHandler.cs

+65-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using FlareSolverrSharp.Solvers;
1616
using FlareSolverrSharp.Types;
1717
using Cookie = System.Net.Cookie;
18+
1819
// ReSharper disable InconsistentNaming
1920

2021
// ReSharper disable InvalidXmlDocComment
@@ -43,16 +44,18 @@ public class ClearanceHandler : DelegatingHandler
4344

4445
public bool CookieCapacity { get; set; }
4546

47+
private readonly IFlaresolverrResponseStorage _responseStorage;
48+
4649
/// <summary>
4750
/// Creates a new instance of the <see cref="ClearanceHandler"/>.
4851
/// </summary>
4952
/// <param name="flareSolverrApiUrl">FlareSolverr API URL. If null or empty it will detect the challenges, but
5053
/// they will not be solved. Example: "http://localhost:8191/"</param>
51-
public ClearanceHandler(string api)
52-
: this(new FlareSolverr(api)) { }
54+
public ClearanceHandler(string api)
55+
: this(new FlareSolverr(api), new DefaultFlaresolverrResponseStorage()) { }
5356

54-
55-
public ClearanceHandler(FlareSolverr solverr)
57+
58+
public ClearanceHandler(FlareSolverr solverr, IFlaresolverrResponseStorage storage)
5659
: base(new HttpClientHandler())
5760
{
5861
m_client = new HttpClient(new HttpClientHandler
@@ -63,7 +66,8 @@ public ClearanceHandler(FlareSolverr solverr)
6366
});
6467

6568

66-
Solverr = solverr;
69+
Solverr = solverr;
70+
_responseStorage = storage;
6771
}
6872

6973
/// <summary>
@@ -87,6 +91,7 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
8791
var response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
8892

8993
// Detect if there is a challenge in the response
94+
/*
9095
if (ChallengeDetector.IsClearanceRequiredAsync(response)) {
9196
9297
// Resolve the challenge using FlareSolverr API
@@ -111,13 +116,67 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
111116
if (EnsureResponseIntegrity) {
112117
113118
if (ChallengeDetector.IsClearanceRequiredAsync(response)) {
114-
// throw new FlareSolverrException("The cookies provided by FlareSolverr are not valid");
119+
throw new FlareSolverrException("The cookies provided by FlareSolverr are not valid");
115120
}
116121
}
117122
118123
// Add the "Set-Cookie" header in the response with the cookies provided by FlareSolverr
119124
InjectSetCookieHeader(response, flareSolverrResponse);
120125
}
126+
*/
127+
if (!ChallengeDetector.IsClearanceRequiredAsync(response)) {
128+
129+
return response;
130+
}
131+
132+
var flareSolverrResponse = await _responseStorage.LoadAsync();
133+
134+
if (flareSolverrResponse != null) {
135+
// Set user agent
136+
if (flareSolverrResponse.Solution.UserAgent != null
137+
&& flareSolverrResponse.Solution.UserAgent !=(request.Headers.UserAgent.ToString())) {
138+
// Set the User-Agent if required
139+
m_userAgent = flareSolverrResponse.Solution.UserAgent;
140+
SetUserAgentHeader(request);
141+
}
142+
143+
// Retry request with saved response
144+
InjectCookies(request, flareSolverrResponse);
145+
response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
146+
147+
if (!ChallengeDetector.IsClearanceRequiredAsync(response)) {
148+
// Success with saved response
149+
InjectSetCookieHeader(response, flareSolverrResponse);
150+
return response;
151+
}
152+
}
153+
154+
// Resolve the challenge using FlareSolverr API
155+
flareSolverrResponse = await Solverr.SolveAsync(request);
156+
157+
// Save the FlareSolverr User-Agent for the following requests
158+
var flareSolverUserAgent = flareSolverrResponse.Solution.UserAgent;
159+
160+
if (flareSolverUserAgent != null && !flareSolverUserAgent.Equals(request.Headers.UserAgent.ToString()))
161+
{
162+
m_userAgent = flareSolverUserAgent;
163+
164+
// Set the User-Agent if required
165+
SetUserAgentHeader(request);
166+
}
167+
168+
// Change the cookies in the original request with the cookies provided by FlareSolverr
169+
InjectCookies(request, flareSolverrResponse);
170+
response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
171+
172+
// Detect if there is a challenge in the response
173+
if (EnsureResponseIntegrity && ChallengeDetector.IsClearanceRequiredAsync(response)) {
174+
throw new FlareSolverrException("The cookies provided by FlareSolverr are not valid");
175+
}
176+
177+
// Add the "Set-Cookie" header in the response with the cookies provided by FlareSolverr
178+
InjectSetCookieHeader(response, flareSolverrResponse);
179+
await _responseStorage.SaveAsync(flareSolverrResponse);
121180

122181
return response;
123182
}

src/FlareSolverrSharp/Exceptions/FlareSolverrException.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace FlareSolverrSharp.Exceptions;
77
/// </summary>
88
public class FlareSolverrException : HttpRequestException
99
{
10-
public FlareSolverrException(string message) : base(message)
11-
{
12-
}
10+
11+
public FlareSolverrException(string message) : base(message) { }
12+
1313
}

src/FlareSolverrSharp/FlareSolverrSharp.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<TargetFramework>net8.0</TargetFramework>
55
<PackageId>FlareSolverrSharp</PackageId>
66
<RootNamespace>FlareSolverrSharp</RootNamespace>
7+
<LangVersion>latest</LangVersion>
78
<Version>3.0.7</Version>
89
<Authors>Diego Heras (ngosang)</Authors>
910
<Description>FlareSolverr .Net / Proxy server to bypass Cloudflare protection.</Description>
@@ -25,6 +26,7 @@
2526

2627
<ItemGroup>
2728
<PackageReference Include="Flurl.Http" Version="4.0.2" />
29+
<PackageReference Include="System.Text.Json" Version="8.0.5" />
2830
</ItemGroup>
2931

3032
</Project>

0 commit comments

Comments
 (0)