mirror of https://github.com/Jackett/Jackett
parent
dd8556d21d
commit
8d8622479d
|
@ -4,6 +4,7 @@ using System.Collections.Specialized;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AngleSharp.Dom;
|
using AngleSharp.Dom;
|
||||||
|
@ -21,15 +22,15 @@ namespace Jackett.Common.Indexers
|
||||||
public class Anidex : BaseWebIndexer
|
public class Anidex : BaseWebIndexer
|
||||||
{
|
{
|
||||||
public Anidex(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps)
|
public Anidex(IIndexerConfigurationService configService, Utils.Clients.WebClient wc, Logger l, IProtectionService ps)
|
||||||
: base(name: "Anidex",
|
: base("Anidex",
|
||||||
description: "Anidex is a Public torrent tracker and indexer, primarily for English fansub groups of anime",
|
description: "Anidex is a Public torrent tracker and indexer, primarily for English fansub groups of anime",
|
||||||
link: "https://anidex.info/",
|
link: "https://anidex.info/",
|
||||||
caps: new TorznabCapabilities(),
|
caps: new TorznabCapabilities(),
|
||||||
configService: configService,
|
configService: configService,
|
||||||
client: wc,
|
client: wc,
|
||||||
logger: l,
|
logger: l,
|
||||||
p: ps,
|
p: ps,
|
||||||
configData: new ConfigurationData())
|
configData: new ConfigurationData())
|
||||||
{
|
{
|
||||||
Encoding = Encoding.UTF8;
|
Encoding = Encoding.UTF8;
|
||||||
Language = "en-us";
|
Language = "en-us";
|
||||||
|
@ -130,15 +131,6 @@ namespace Jackett.Common.Indexers
|
||||||
|
|
||||||
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
await ConfigureDDoSGuardCookie();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.Log(LogLevel.Warn, ex, $"Exception while configuring DDoS Guard cookie. Attempting search without. (Exception: {ex})");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get specified categories. If none were specified, use all available.
|
// Get specified categories. If none were specified, use all available.
|
||||||
var searchCategories = MapTorznabCapsToTrackers(query);
|
var searchCategories = MapTorznabCapsToTrackers(query);
|
||||||
if (searchCategories.Count == 0)
|
if (searchCategories.Count == 0)
|
||||||
|
@ -159,12 +151,15 @@ namespace Jackett.Common.Indexers
|
||||||
var searchUri = GetAbsoluteUrl("?" + queryParameters.GetQueryString());
|
var searchUri = GetAbsoluteUrl("?" + queryParameters.GetQueryString());
|
||||||
var response = await RequestStringWithCookiesAndRetry(searchUri.AbsoluteUri);
|
var response = await RequestStringWithCookiesAndRetry(searchUri.AbsoluteUri);
|
||||||
|
|
||||||
// Check for DDOS Guard or other error
|
// Check for DDOS Guard
|
||||||
if (response.Status == System.Net.HttpStatusCode.Forbidden)
|
if (response.Status == System.Net.HttpStatusCode.Forbidden)
|
||||||
throw new IOException("Anidex search was forbidden. This was likely caused by DDOS protection.");
|
{
|
||||||
|
await ConfigureDDoSGuardCookie();
|
||||||
|
response = await RequestStringWithCookiesAndRetry(searchUri.AbsoluteUri);
|
||||||
|
}
|
||||||
|
|
||||||
if (response.Status != System.Net.HttpStatusCode.OK)
|
if (response.Status != System.Net.HttpStatusCode.OK)
|
||||||
throw new IOException($"Anidex search returned unexpected result. Expected 200 OK but got {response.Status.ToString()}.");
|
throw new WebException($"Anidex search returned unexpected result. Expected 200 OK but got {response.Status}.", WebExceptionStatus.ProtocolError);
|
||||||
|
|
||||||
// Search seems to have been a success so parse it
|
// Search seems to have been a success so parse it
|
||||||
return ParseResult(response.Content);
|
return ParseResult(response.Content);
|
||||||
|
@ -219,55 +214,14 @@ namespace Jackett.Common.Indexers
|
||||||
|
|
||||||
private async Task ConfigureDDoSGuardCookie()
|
private async Task ConfigureDDoSGuardCookie()
|
||||||
{
|
{
|
||||||
const string pathAndQueryBase64Encoded = "Lw=="; // "/"
|
const string ddosPostUrl = "https://check.ddos-guard.net/check.js";
|
||||||
const string baseUriBase64Encoded = "aHR0cHM6Ly9hbmlkZXguaW5mbw=="; // "http://anidex.info"
|
var response = await RequestStringWithCookies(ddosPostUrl, string.Empty);
|
||||||
const string ddosPostUrl = "https://ddgu.ddos-guard.net/ddgu/";
|
if (response.Status != System.Net.HttpStatusCode.OK)
|
||||||
|
throw new WebException($"Unexpected DDOS Guard response: Status: {response.Status}", WebExceptionStatus.ProtocolError);
|
||||||
try
|
if (response.IsRedirect)
|
||||||
{
|
throw new WebException($"Unexpected DDOS Guard response: Redirect: {response.RedirectingTo}", WebExceptionStatus.UnknownError);
|
||||||
// Check if the cookie already exists, if so exit without doing anything
|
if (string.IsNullOrWhiteSpace(response.Cookies))
|
||||||
if (IsCookiePresent("__ddgu") && IsCookiePresent("__ddg1"))
|
throw new WebException("Unexpected DDOS Guard response: Empty cookie", WebExceptionStatus.ReceiveFailure);
|
||||||
{
|
|
||||||
logger.Debug("DDOS Guard cookies are already present. Skipping bypass.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a request to DDoS Guard to get the redirect URL
|
|
||||||
var ddosPostData = new List<KeyValuePair<string, string>>
|
|
||||||
{
|
|
||||||
{ "u", pathAndQueryBase64Encoded },
|
|
||||||
{ "h", baseUriBase64Encoded },
|
|
||||||
{ "p", string.Empty }
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = await PostDataWithCookiesAndRetry(ddosPostUrl, ddosPostData);
|
|
||||||
|
|
||||||
if (!result.IsRedirect)
|
|
||||||
// Success returns a redirect. For anything else, assume a failure.
|
|
||||||
throw new IOException($"Unexpected result from DDOS Guard while attempting to bypass: {result.Content}");
|
|
||||||
|
|
||||||
// Call the redirect URL to retrieve the cookie
|
|
||||||
result = await RequestStringWithCookiesAndRetry(result.RedirectingTo);
|
|
||||||
if (!result.IsRedirect)
|
|
||||||
// Success is another redirect. For anything else, assume a failure.
|
|
||||||
throw new IOException($"Unexpected result when returning from DDOS Guard bypass: {result.Content}");
|
|
||||||
|
|
||||||
// If we got to this point, the bypass should have succeeded and we have stored the necessary cookies to access the site normally.
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new IOException($"Error while configuring DDoS Guard cookie: {ex}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsCookiePresent(string name)
|
|
||||||
{
|
|
||||||
var rawCookies = CookieHeader.Split(';');
|
|
||||||
IDictionary<string, string> cookies = rawCookies
|
|
||||||
.Where(e => e.Contains('='))
|
|
||||||
.ToDictionary((e) => e.Split('=')[0].Trim(), (e) => e.Split('=')[1].Trim());
|
|
||||||
|
|
||||||
return cookies.ContainsKey(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TResult ParseValueFromRow<TResult>(IElement row, string propertyName, string selector,
|
private static TResult ParseValueFromRow<TResult>(IElement row, string propertyName, string selector,
|
||||||
|
|
Loading…
Reference in New Issue