Fixed: (Rarbg) Check for rate limits before parsing token errors

pull/1463/head
Bogdan 2 years ago
parent 5bb3dbfbf5
commit 71775b97a3

@ -23,14 +23,14 @@ namespace NzbDrone.Core.Test.IndexerTests.RarbgTests
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
Subject.Definition = new IndexerDefinition() Subject.Definition = new IndexerDefinition
{ {
Name = "Rarbg", Name = "Rarbg",
Settings = new RarbgSettings() Settings = new RarbgSettings()
}; };
Mocker.GetMock<IRarbgTokenProvider>() Mocker.GetMock<IRarbgTokenProvider>()
.Setup(v => v.GetToken(It.IsAny<RarbgSettings>())) .Setup(v => v.GetToken(It.IsAny<RarbgSettings>(), Subject.RateLimit))
.Returns("validtoken"); .Returns("validtoken");
} }

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
using NLog; using NLog;
@ -9,6 +10,7 @@ using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Exceptions; using NzbDrone.Core.Exceptions;
using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser; using NzbDrone.Core.Parser;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -24,7 +26,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
public override IndexerPrivacy Privacy => IndexerPrivacy.Public; public override IndexerPrivacy Privacy => IndexerPrivacy.Public;
public override IndexerCapabilities Capabilities => SetCapabilities(); public override IndexerCapabilities Capabilities => SetCapabilities();
public override TimeSpan RateLimit => TimeSpan.FromSeconds(5); public override TimeSpan RateLimit => TimeSpan.FromSeconds(7);
private readonly IRarbgTokenProvider _tokenProvider; private readonly IRarbgTokenProvider _tokenProvider;
public Rarbg(IRarbgTokenProvider tokenProvider, IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger) public Rarbg(IRarbgTokenProvider tokenProvider, IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
@ -35,7 +37,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
public override IIndexerRequestGenerator GetRequestGenerator() public override IIndexerRequestGenerator GetRequestGenerator()
{ {
return new RarbgRequestGenerator(_tokenProvider) { Settings = Settings, Categories = Capabilities.Categories }; return new RarbgRequestGenerator(_tokenProvider, RateLimit) { Settings = Settings, Categories = Capabilities.Categories };
} }
public override IParseIndexerResponse GetParser() public override IParseIndexerResponse GetParser()
@ -43,6 +45,23 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
return new RarbgParser(Capabilities, _logger); return new RarbgParser(Capabilities, _logger);
} }
public static void CheckResponseByStatusCode(IndexerResponse response)
{
var responseCode = (int)response.HttpResponse.StatusCode;
switch (responseCode)
{
case (int)HttpStatusCode.TooManyRequests:
throw new TooManyRequestsException(response.HttpRequest, response.HttpResponse, TimeSpan.FromMinutes(2));
case 520:
throw new TooManyRequestsException(response.HttpRequest, response.HttpResponse, TimeSpan.FromMinutes(3));
case (int)HttpStatusCode.OK:
break;
default:
throw new IndexerException(response, "Indexer API call returned an unexpected StatusCode [{0}]", responseCode);
}
}
private IndexerCapabilities SetCapabilities() private IndexerCapabilities SetCapabilities()
{ {
var caps = new IndexerCapabilities var caps = new IndexerCapabilities
@ -97,6 +116,8 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
{ {
var response = await FetchIndexerResponse(request); var response = await FetchIndexerResponse(request);
CheckResponseByStatusCode(response);
// try and recover from token errors // try and recover from token errors
var jsonResponse = new HttpResponse<RarbgResponse>(response.HttpResponse); var jsonResponse = new HttpResponse<RarbgResponse>(response.HttpResponse);
@ -106,7 +127,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
{ {
_logger.Debug("Invalid or expired token, refreshing token from Rarbg"); _logger.Debug("Invalid or expired token, refreshing token from Rarbg");
_tokenProvider.ExpireToken(Settings); _tokenProvider.ExpireToken(Settings);
var newToken = _tokenProvider.GetToken(Settings); var newToken = _tokenProvider.GetToken(Settings, RateLimit);
var qs = HttpUtility.ParseQueryString(request.HttpRequest.Url.Query); var qs = HttpUtility.ParseQueryString(request.HttpRequest.Url.Query);
qs.Set("token", newToken); qs.Set("token", newToken);

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using NLog; using NLog;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
@ -28,19 +27,8 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse) public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
{ {
var results = new List<ReleaseInfo>(); var results = new List<ReleaseInfo>();
var responseCode = (int)indexerResponse.HttpResponse.StatusCode;
switch (responseCode) Rarbg.CheckResponseByStatusCode(indexerResponse);
{
case (int)HttpStatusCode.TooManyRequests:
throw new TooManyRequestsException(indexerResponse.HttpRequest, indexerResponse.HttpResponse, TimeSpan.FromMinutes(2));
case 520:
throw new TooManyRequestsException(indexerResponse.HttpRequest, indexerResponse.HttpResponse, TimeSpan.FromMinutes(3));
case (int)HttpStatusCode.OK:
break;
default:
throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", responseCode);
}
var jsonResponse = new HttpResponse<RarbgResponse>(indexerResponse.HttpResponse); var jsonResponse = new HttpResponse<RarbgResponse>(indexerResponse.HttpResponse);

@ -11,13 +11,15 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
public class RarbgRequestGenerator : IIndexerRequestGenerator public class RarbgRequestGenerator : IIndexerRequestGenerator
{ {
private readonly IRarbgTokenProvider _tokenProvider; private readonly IRarbgTokenProvider _tokenProvider;
private readonly TimeSpan _rateLimit;
public RarbgSettings Settings { get; set; } public RarbgSettings Settings { get; set; }
public IndexerCapabilitiesCategories Categories { get; set; } public IndexerCapabilitiesCategories Categories { get; set; }
public RarbgRequestGenerator(IRarbgTokenProvider tokenProvider) public RarbgRequestGenerator(IRarbgTokenProvider tokenProvider, TimeSpan rateLimit)
{ {
_tokenProvider = tokenProvider; _tokenProvider = tokenProvider;
_rateLimit = rateLimit;
} }
private IEnumerable<IndexerRequest> GetRequest(string term, int[] categories, string imdbId = null, int? tmdbId = null, int? tvdbId = null) private IEnumerable<IndexerRequest> GetRequest(string term, int[] categories, string imdbId = null, int? tmdbId = null, int? tvdbId = null)
@ -59,7 +61,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
} }
requestBuilder.AddQueryParam("limit", "100"); requestBuilder.AddQueryParam("limit", "100");
requestBuilder.AddQueryParam("token", _tokenProvider.GetToken(Settings)); requestBuilder.AddQueryParam("token", _tokenProvider.GetToken(Settings, _rateLimit));
requestBuilder.AddQueryParam("format", "json_extended"); requestBuilder.AddQueryParam("format", "json_extended");
requestBuilder.AddQueryParam("app_id", $"rralworP_{BuildInfo.Version}"); requestBuilder.AddQueryParam("app_id", $"rralworP_{BuildInfo.Version}");

@ -9,7 +9,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
{ {
public interface IRarbgTokenProvider public interface IRarbgTokenProvider
{ {
string GetToken(RarbgSettings settings); string GetToken(RarbgSettings settings, TimeSpan rateLimit);
void ExpireToken(RarbgSettings settings); void ExpireToken(RarbgSettings settings);
} }
@ -31,16 +31,18 @@ namespace NzbDrone.Core.Indexers.Definitions.Rarbg
_tokenCache.Remove(settings.BaseUrl); _tokenCache.Remove(settings.BaseUrl);
} }
public string GetToken(RarbgSettings settings) public string GetToken(RarbgSettings settings, TimeSpan rateLimit)
{ {
return _tokenCache.Get(settings.BaseUrl, return _tokenCache.Get(settings.BaseUrl,
() => () =>
{ {
var requestBuilder = new HttpRequestBuilder(settings.BaseUrl.Trim('/')) var requestBuilder = new HttpRequestBuilder(settings.BaseUrl.Trim('/'))
.WithRateLimit(5.0) .WithRateLimit(rateLimit.TotalSeconds)
.Resource($"/pubapi_v2.php?get_token=get_token&app_id=rralworP_{BuildInfo.Version}") .Resource($"/pubapi_v2.php?get_token=get_token&app_id=rralworP_{BuildInfo.Version}")
.Accept(HttpAccept.Json); .Accept(HttpAccept.Json);
requestBuilder.LogResponseContent = true;
var response = _httpClient.Get<JObject>(requestBuilder.Build()); var response = _httpClient.Get<JObject>(requestBuilder.Build());
return response.Resource["token"].ToString(); return response.Resource["token"].ToString();

Loading…
Cancel
Save