1515using FlareSolverrSharp . Solvers ;
1616using FlareSolverrSharp . Types ;
1717using 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 }
0 commit comments