mirror of
https://github.com/Jackett/Jackett
synced 2025-02-25 07:32:38 +00:00
automatically decode CloudFlare protected emails
This commit is contained in:
parent
e34ffcbaa6
commit
3f629ba7d2
3 changed files with 61 additions and 5 deletions
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Jackett.Utils
|
namespace Jackett.Utils
|
||||||
|
@ -21,5 +22,37 @@ namespace Jackett.Utils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This can be used to decode e-mail addresses protected by cloudflare
|
||||||
|
public static string DecodeCloudFlareProtectedEmail(string input)
|
||||||
|
{
|
||||||
|
var key = Convert.ToInt32(input.Substring(0, 2), 16);
|
||||||
|
string result = "";
|
||||||
|
for (var i = 2; i < input.Length - 1; i += 2)
|
||||||
|
{
|
||||||
|
var hexChar = input.Substring(i, 2);
|
||||||
|
var intChar = Convert.ToInt32(hexChar, 16) ^ key;
|
||||||
|
var strChar = Convert.ToChar(intChar);
|
||||||
|
result += strChar;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode cloudflare protected emails in a HTML document
|
||||||
|
public static string DecodeCloudFlareProtectedEmailFromHTML(string html)
|
||||||
|
{
|
||||||
|
Regex CFEMailRegex = new Regex("<span class=\"__cf_email__\" data-cfemail=\"(\\w+)\">\\[email protected\\]<\\/span><script data-cfhash='[\\w]+' type=\"text\\/javascript\">.*?<\\/script>", RegexOptions.Compiled);
|
||||||
|
var CFEMailRegexMatches = CFEMailRegex.Match(html);
|
||||||
|
|
||||||
|
while (CFEMailRegexMatches.Success)
|
||||||
|
{
|
||||||
|
string all = CFEMailRegexMatches.Groups[0].Value;
|
||||||
|
string cfemail = CFEMailRegexMatches.Groups[1].Value;
|
||||||
|
var decoded = DecodeCloudFlareProtectedEmail(cfemail);
|
||||||
|
html = html.Replace(all, decoded);
|
||||||
|
CFEMailRegexMatches = CFEMailRegexMatches.NextMatch();
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,14 @@ namespace Jackett.Utils.Clients
|
||||||
logger.Debug(string.Format("WindowsWebClient:GetString(Url:{0})", request.Url));
|
logger.Debug(string.Format("WindowsWebClient:GetString(Url:{0})", request.Url));
|
||||||
var result = await Run(request);
|
var result = await Run(request);
|
||||||
logger.Debug(string.Format("WindowsWebClient: Returning {0} => {1}", result.Status, (result.Content == null ? "<NULL>" : Encoding.UTF8.GetString(result.Content))));
|
logger.Debug(string.Format("WindowsWebClient: Returning {0} => {1}", result.Status, (result.Content == null ? "<NULL>" : Encoding.UTF8.GetString(result.Content))));
|
||||||
return Mapper.Map<WebClientStringResult>(result);
|
WebClientStringResult stringResult = Mapper.Map<WebClientStringResult>(result);
|
||||||
|
string[] server;
|
||||||
|
if (stringResult.Headers.TryGetValue("server", out server))
|
||||||
|
{
|
||||||
|
if (server[0] == "cloudflare-nginx")
|
||||||
|
stringResult.Content = BrowserUtil.DecodeCloudFlareProtectedEmailFromHTML(stringResult.Content);
|
||||||
|
}
|
||||||
|
return stringResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<WebClientByteResult> Run(WebRequest webRequest)
|
private async Task<WebClientByteResult> Run(WebRequest webRequest)
|
||||||
|
@ -141,6 +148,12 @@ namespace Jackett.Utils.Clients
|
||||||
var result = new WebClientByteResult();
|
var result = new WebClientByteResult();
|
||||||
result.Content = await response.Content.ReadAsByteArrayAsync();
|
result.Content = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
|
||||||
|
foreach (var header in response.Headers)
|
||||||
|
{
|
||||||
|
IEnumerable<string> value = header.Value;
|
||||||
|
result.Headers[header.Key.ToLowerInvariant()] = value.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
// some cloudflare clients are using a refresh header
|
// some cloudflare clients are using a refresh header
|
||||||
// Pull it out manually
|
// Pull it out manually
|
||||||
if (response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && response.Headers.Contains("Refresh"))
|
if (response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && response.Headers.Contains("Refresh"))
|
||||||
|
@ -199,7 +212,6 @@ namespace Jackett.Utils.Clients
|
||||||
}
|
}
|
||||||
result.Cookies = cookieBuilder.ToString().Trim();
|
result.Cookies = cookieBuilder.ToString().Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerUtil.ResureRedirectIsFullyQualified(webRequest, result);
|
ServerUtil.ResureRedirectIsFullyQualified(webRequest, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,15 @@ namespace Jackett.Utils.Clients
|
||||||
{
|
{
|
||||||
logger.Debug(string.Format("UnixLibCurlWebClient:GetString(Url:{0})", request.Url));
|
logger.Debug(string.Format("UnixLibCurlWebClient:GetString(Url:{0})", request.Url));
|
||||||
var result = await RunCloudFlare(request);
|
var result = await RunCloudFlare(request);
|
||||||
logger.Debug(string.Format("UnixLibCurlWebClient:GetString Returning {0} => {1}", result.Status, (result.Content == null ? "<NULL>" : Encoding.UTF8.GetString(result.Content))));
|
logger.Debug(string.Format("UnixLibCurlWebClient:GetString Returning {0} => {1}", result.Status, (result.Content == null ? "<NULL>" : Encoding.UTF8.GetString(result.Content))));
|
||||||
return Mapper.Map<WebClientStringResult>(result);
|
WebClientStringResult stringResult = Mapper.Map<WebClientStringResult>(result);
|
||||||
|
string[] server;
|
||||||
|
if (stringResult.Headers.TryGetValue("server", out server))
|
||||||
|
{
|
||||||
|
if (server[0] == "cloudflare-nginx")
|
||||||
|
stringResult.Content = BrowserUtil.DecodeCloudFlareProtectedEmailFromHTML(stringResult.Content);
|
||||||
|
}
|
||||||
|
return stringResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CloudFlareChallengeSolverSolve(string challengePageContent, Uri uri)
|
private string CloudFlareChallengeSolverSolve(string challengePageContent, Uri uri)
|
||||||
|
@ -142,7 +149,11 @@ namespace Jackett.Utils.Clients
|
||||||
{
|
{
|
||||||
foreach (var header in response.HeaderList)
|
foreach (var header in response.HeaderList)
|
||||||
{
|
{
|
||||||
switch (header[0].ToLowerInvariant())
|
var key = header[0].ToLowerInvariant();
|
||||||
|
|
||||||
|
result.Headers[key] = new string[] { header[1] }; // doesn't support multiple identical headers?
|
||||||
|
|
||||||
|
switch (key)
|
||||||
{
|
{
|
||||||
case "location":
|
case "location":
|
||||||
result.RedirectingTo = header[1];
|
result.RedirectingTo = header[1];
|
||||||
|
|
Loading…
Reference in a new issue