Skip to content

Commit 2033709

Browse files
committed
More fixes
1 parent 4f79593 commit 2033709

File tree

10 files changed

+192
-56
lines changed

10 files changed

+192
-56
lines changed
+36-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,42 @@
1-

1+
using System;
2+
using System.Collections.Generic;
3+
using FlareSolverrSharp.Exceptions;
4+
using System.Net.Http;
5+
using System.Threading.Tasks;
6+
27
namespace FlareSolverrSharp.Sample;
38

4-
static class Program
9+
public static class Program
510
{
6-
static void Main()
11+
12+
public static async Task Main()
713
{
8-
ClearanceHandlerSample.SampleGet().Wait();
9-
ClearanceHandlerSample.SamplePostUrlEncoded().Wait();
14+
/*ClearanceHandlerSample.SampleGet().Wait();
15+
ClearanceHandlerSample.SamplePostUrlEncoded().Wait();*/
16+
17+
var handler = new ClearanceHandler(Settings.FlareSolverrApiUrl)
18+
{
19+
EnsureResponseIntegrity = false,
20+
Solverr =
21+
{
22+
MaxTimeout = 60000
23+
}
24+
};
25+
26+
var client = new HttpClient(handler);
27+
28+
var x = await client.GetAsync(Settings.ProtectedUri);
29+
30+
Console.WriteLine(x);
31+
Console.WriteLine( ChallengeDetector.IsClearanceRequiredAsync(x));
32+
/*foreach (KeyValuePair<string, IEnumerable<string>> pair in x.Headers) {
33+
Console.WriteLine(pair);
34+
}*/
35+
foreach (var y in x.Headers.Server) {
36+
37+
Console.WriteLine(y.Product.Name);
38+
}
39+
// Assert.IsTrue(c.Message.Contains("Error connecting to FlareSolverr server"));
1040
}
41+
1142
}

test/FlareSolverrSharp.Tests/Settings.cs renamed to sample/FlareSolverrSharp.Sample/Settings.cs

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
using System;
2+
using System.Runtime.CompilerServices;
23

3-
namespace FlareSolverrSharp.Tests;
4+
[assembly: InternalsVisibleTo("FlareSolverrSharp.Tests")]
5+
6+
namespace FlareSolverrSharp.Sample;
47

58
internal static class Settings
69
{
7-
internal const string FlareSolverrApiUrl = "http://localhost:8191/";
8-
internal const string ProxyUrl = "http://127.0.0.1:8888/";
9-
internal static readonly Uri ProtectedUri = new Uri("https://nowsecure.nl");
10-
internal static readonly Uri ProtectedPostUri = new Uri("https://badasstorrents.com/torrents/search/720p/date/desc");
10+
11+
internal const string FlareSolverrApiUrl = "http://localhost:8191/";
12+
internal const string ProxyUrl = "http://127.0.0.1:8888/";
13+
internal static readonly Uri ProtectedUri = new Uri("https://nowsecure.nl");
14+
15+
internal static readonly Uri ProtectedPostUri =
16+
new Uri("https://badasstorrents.com/torrents/search/720p/date/desc");
17+
1118
internal static readonly Uri ProtectedDdgUri = new Uri("https://anidex.info/?q=text");
1219
internal static readonly Uri ProtectedCcfUri = new Uri("https://www.muziekfabriek.org");
1320

@@ -23,4 +30,5 @@ internal static class Settings
2330
* sudo tinyproxy -d
2431
* sudo tail -f /tmp/tinyproxy.log
2532
*/
33+
2634
}

src/FlareSolverrSharp/ChallengeDetector.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ public static bool IsClearanceRequiredAsync(HttpResponseMessage response)
2727
private static bool IsCloudflareProtectedAsync(HttpResponseMessage response)
2828
{
2929
// check response headers
30-
if (!response.Headers.Server.Any(i =>
30+
if (response.Headers.Server.Any(i =>
3131
i.Product != null
3232
&& CloudflareValues.CloudflareServerNames.Contains(
33-
i.Product.Name.ToLower())))
34-
return false;
33+
i.Product.Name.ToLower()))) {
34+
return true;
35+
}
3536

3637
// detect CloudFlare and DDoS-GUARD
3738
if (response.StatusCode is HttpStatusCode.ServiceUnavailable or HttpStatusCode.Forbidden

src/FlareSolverrSharp/ClearanceHandler.cs

+15-11
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+
// ReSharper disable InconsistentNaming
1819

1920
// ReSharper disable InvalidXmlDocComment
2021

@@ -26,9 +27,9 @@ namespace FlareSolverrSharp;
2627
public class ClearanceHandler : DelegatingHandler
2728
{
2829

29-
private readonly HttpClient _client;
30+
private readonly HttpClient m_client;
3031

31-
private string _userAgent;
32+
private string m_userAgent;
3233

3334
public FlareSolverr Solverr { get; }
3435

@@ -40,6 +41,8 @@ public class ClearanceHandler : DelegatingHandler
4041

4142
public bool EnsureResponseIntegrity { get; set; }
4243

44+
public bool CookieCapacity { get; set; }
45+
4346
/// <summary>
4447
/// Creates a new instance of the <see cref="ClearanceHandler"/>.
4548
/// </summary>
@@ -52,7 +55,7 @@ public ClearanceHandler(string api)
5255
public ClearanceHandler(FlareSolverr solverr)
5356
: base(new HttpClientHandler())
5457
{
55-
_client = new HttpClient(new HttpClientHandler
58+
m_client = new HttpClient(new HttpClientHandler
5659
{
5760
AllowAutoRedirect = false,
5861
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
@@ -94,7 +97,7 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
9497

9598
if (flareSolverUserAgent != null
9699
&& flareSolverUserAgent != (request.Headers.UserAgent.ToString())) {
97-
_userAgent = flareSolverUserAgent;
100+
m_userAgent = flareSolverUserAgent;
98101

99102
// Set the User-Agent if required
100103
SetUserAgentHeader(request);
@@ -105,8 +108,11 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
105108
response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
106109

107110
// Detect if there is a challenge in the response
108-
if (EnsureResponseIntegrity && ChallengeDetector.IsClearanceRequiredAsync(response)) {
109-
throw new FlareSolverrException("The cookies provided by FlareSolverr are not valid");
111+
if (EnsureResponseIntegrity) {
112+
113+
if (ChallengeDetector.IsClearanceRequiredAsync(response)) {
114+
// throw new FlareSolverrException("The cookies provided by FlareSolverr are not valid");
115+
}
110116
}
111117

112118
// Add the "Set-Cookie" header in the response with the cookies provided by FlareSolverr
@@ -118,15 +124,13 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
118124

119125
private void SetUserAgentHeader(HttpRequestMessage request)
120126
{
121-
if (_userAgent != null) {
127+
if (m_userAgent != null) {
122128
// Overwrite the header
123129
request.Headers.Remove(FlareSolverrValues.UserAgent);
124-
request.Headers.Add(FlareSolverrValues.UserAgent, _userAgent);
130+
request.Headers.Add(FlareSolverrValues.UserAgent, m_userAgent);
125131
}
126132
}
127133

128-
public bool CookieCapacity { get; set; }
129-
130134
private void InjectCookies(HttpRequestMessage request, FlareSolverrResponse flareSolverrResponse)
131135
{
132136
// use only Cloudflare and DDoS-GUARD cookies
@@ -206,7 +210,7 @@ private static bool IsCloudflareCookie(string cookieName)
206210
protected override void Dispose(bool disposing)
207211
{
208212
if (disposing)
209-
_client.Dispose();
213+
m_client.Dispose();
210214

211215
base.Dispose(disposing);
212216
}

src/FlareSolverrSharp/Constants/CloudflareValues.cs

+40
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,44 @@ public static class CloudflareValues
2929
"<title>Attention Required! | Cloudflare</title>" // Cloudflare Blocked
3030
];
3131

32+
/*
33+
*Cloudflare
34+
35+
Cloudflare's reverse proxy service expands the 5xx series of errors space to signal issues with the origin server.[51]
36+
37+
520 Web Server Returned an Unknown Error
38+
The origin server returned an empty, unknown, or unexpected response to Cloudflare.[52]
39+
521 Web Server Is Down
40+
The origin server refused connections from Cloudflare. Security solutions at the origin may be blocking legitimate connections from certain Cloudflare IP addresses.
41+
522 Connection Timed Out
42+
Cloudflare timed out contacting the origin server.
43+
523 Origin Is Unreachable
44+
Cloudflare could not reach the origin server; for example, if the DNS records for the origin server are incorrect or missing.
45+
524 A Timeout Occurred
46+
Cloudflare was able to complete a TCP connection to the origin server, but did not receive a timely HTTP response.
47+
525 SSL Handshake Failed
48+
Cloudflare could not negotiate a SSL/TLS handshake with the origin server.
49+
526 Invalid SSL Certificate
50+
Cloudflare could not validate the SSL certificate on the origin web server. Also used by Cloud Foundry's gorouter.
51+
527 Railgun Error (obsolete)
52+
Error 527 indicated an interrupted connection between Cloudflare and the origin server's Railgun server.[53] This error is obsolete as Cloudflare has deprecated Railgun.
53+
530
54+
Error 530 is returned along with a 1xxx error.[54]
55+
*/
56+
57+
58+
public enum CloudflareStatusCodes : int
59+
{
60+
61+
WebServerUnknown = 520,
62+
WebServerDown = 521,
63+
ConnectionTimedOut = 522,
64+
OriginUnreachable = 523,
65+
TimeoutOccurred = 524,
66+
SslHandshakeFailed = 525,
67+
InvalidSslCertificate = 526,
68+
RailgunError = 527,
69+
70+
}
71+
3272
}

src/FlareSolverrSharp/Solvers/FlareSolverr.cs

+36-8
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class FlareSolverr : INotifyPropertyChanged
4141

4242
private static readonly SemaphoreLocker s_locker = new SemaphoreLocker();
4343

44-
private readonly HttpClient m_httpClient;
44+
private /*readonly*/ HttpClient m_httpClient;
4545

4646
public Uri FlareSolverrApi { get; }
4747

@@ -53,7 +53,7 @@ public int MaxTimeout
5353
set
5454
{
5555
SetField(ref m_maxTimeout, value);
56-
m_httpClient.Timeout = AdjustHttpClientTimeout();
56+
// m_httpClient.Timeout = AdjustHttpClientTimeout();
5757
}
5858
}
5959

@@ -76,10 +76,10 @@ public FlareSolverr(string flareSolverrApiUrl)
7676

7777
FlareSolverrApi = new Uri($"{apiUrl}v1");
7878

79-
m_httpClient = new HttpClient()
79+
/*m_httpClient = new HttpClient()
8080
{
8181
// Timeout = AdjustHttpClientTimeout()
82-
};
82+
};*/
8383

8484
MaxTimeout = FlareSolverrValues.MAX_TIMEOUT_DEFAULT;
8585
Proxy = new FlareSolverrRequestProxy();
@@ -143,13 +143,13 @@ private async Task<FlareSolverrResponse> SendFlareSolverrRequestAsync(HttpConten
143143
//todo: what is this "semaphore locker" for
144144

145145
// await s_locker.LockAsync(() => SendRequestAsync(flareSolverrRequest));
146-
HttpResponseMessage response;
146+
HttpResponseMessage response;
147147

148148
try {
149-
// m_httpClient = new HttpClient();
149+
m_httpClient = new HttpClient();
150150

151151
// wait 5 more seconds to make sure we return the FlareSolverr timeout message
152-
// m_httpClient.Timeout = TimeSpan.FromMilliseconds(MaxTimeout + 5000);
152+
m_httpClient.Timeout = TimeSpan.FromMilliseconds(MaxTimeout + 5000);
153153
response = await m_httpClient.PostAsync(FlareSolverrApi, flareSolverrRequest);
154154
}
155155
catch (HttpRequestException e) {
@@ -159,7 +159,7 @@ private async Task<FlareSolverrResponse> SendFlareSolverrRequestAsync(HttpConten
159159
throw new FlareSolverrException($"Exception: {e}");
160160
}
161161
finally {
162-
// m_httpClient.Dispose();
162+
m_httpClient.Dispose();
163163
}
164164

165165
// Don't try parsing if FlareSolverr hasn't returned 200 or 500
@@ -270,6 +270,34 @@ private HttpContent GenerateFlareSolverrRequest(HttpRequestMessage request, stri
270270
Session = sessionId
271271
};
272272
}
273+
/*else if (request.Method == HttpMethod.Post) {
274+
// request.Content.GetType() doesn't work well when encoding != utf-8
275+
var contentMediaType = request.Content.Headers.ContentType?.MediaType.ToLower() ?? "<null>";
276+
277+
if (contentMediaType.Contains("application/x-www-form-urlencoded")) {
278+
req = new FlareSolverrRequestPost
279+
{
280+
Command = FlareSolverrValues.CMD_REQUEST_POST,
281+
Url = url,
282+
PostData = request.Content.ReadAsStringAsync().Result,
283+
MaxTimeout = MaxTimeout,
284+
Proxy = Proxy,
285+
Session = sessionId
286+
};
287+
}
288+
else if (contentMediaType.Contains("multipart/form-data")
289+
|| contentMediaType.Contains("text/html")) {
290+
//TODO Implement - check if we just need to pass the content-type with the relevant headers
291+
throw new FlareSolverrException("Unimplemented POST Content-Type: " + contentMediaType);
292+
}
293+
else {
294+
throw new FlareSolverrException("Unsupported POST Content-Type: " + contentMediaType);
295+
}
296+
}
297+
else {
298+
throw new FlareSolverrException("Unsupported HttpMethod: " + request.Method);
299+
}*/
300+
273301
else if (request.Method == HttpMethod.Post) {
274302
// request.Content.GetType() doesn't work well when encoding != utf-8
275303
var contentType = request.Content.Headers.ContentType;

src/FlareSolverrSharp/Types/FlareSolverrResponse.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public class FlareSolverrSolution
6969
public string Url;
7070

7171
[JsonPropertyName("status")]
72-
public string Status;
72+
public int Status;
7373

7474
[JsonPropertyName("headers")]
7575
public FlareSolverrHeaders Headers;

test/FlareSolverrSharp.Tests/ClearanceHandlerTests.cs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Threading.Tasks;
99
using System.Web;
1010
using FlareSolverrSharp.Exceptions;
11+
using FlareSolverrSharp.Sample;
1112
using FlareSolverrSharp.Solvers;
1213
using Microsoft.VisualStudio.TestTools.UnitTesting;
1314

test/FlareSolverrSharp.Tests/FlareSolverrSharp.Tests.csproj

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<AssemblyName>FlareSolverrSharp.Tests</AssemblyName>
77
<RootNamespace>FlareSolverrSharp.Tests</RootNamespace>
88
<Version>3.0.7</Version>
9-
<!-- <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> -->
9+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
1010
</PropertyGroup>
1111

1212
<ItemGroup>
@@ -15,6 +15,7 @@
1515
</ItemGroup>
1616

1717
<ItemGroup>
18+
<ProjectReference Include="..\..\sample\FlareSolverrSharp.Sample\FlareSolverrSharp.Sample.csproj" />
1819
<ProjectReference Include="..\..\src\FlareSolverrSharp\FlareSolverrSharp.csproj" />
1920
</ItemGroup>
2021

0 commit comments

Comments
 (0)