mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
improve torznab error handling
This commit is contained in:
@@ -34,7 +34,7 @@ namespace Jackett.Controllers
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
if (queryApiKey != validApiKey)
|
if (queryApiKey != validApiKey)
|
||||||
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
|
actionContext.Response = ResultsController.GetErrorHttpResponseMessage(actionContext, HttpStatusCode.Unauthorized, 100, $"Invalid API Key");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ namespace Jackett.Controllers
|
|||||||
if (!parameters.ContainsKey("indexerId"))
|
if (!parameters.ContainsKey("indexerId"))
|
||||||
{
|
{
|
||||||
indexerController.CurrentIndexer = null;
|
indexerController.CurrentIndexer = null;
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
actionContext.Response = ResultsController.GetErrorHttpResponseMessage(actionContext, HttpStatusCode.NotFound, 200, $"indexer is not specified");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ namespace Jackett.Controllers
|
|||||||
if (indexerId.IsNullOrEmptyOrWhitespace())
|
if (indexerId.IsNullOrEmptyOrWhitespace())
|
||||||
{
|
{
|
||||||
indexerController.CurrentIndexer = null;
|
indexerController.CurrentIndexer = null;
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
actionContext.Response = ResultsController.GetErrorHttpResponseMessage(actionContext, HttpStatusCode.NotFound, 201, $"Indexer is not specified (empty value)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,14 +71,14 @@ namespace Jackett.Controllers
|
|||||||
if (indexer == null)
|
if (indexer == null)
|
||||||
{
|
{
|
||||||
indexerController.CurrentIndexer = null;
|
indexerController.CurrentIndexer = null;
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid parameter");
|
actionContext.Response = ResultsController.GetErrorHttpResponseMessage(actionContext, HttpStatusCode.NotFound, 201, $"Indexer is not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!indexer.IsConfigured)
|
if (!indexer.IsConfigured)
|
||||||
{
|
{
|
||||||
indexerController.CurrentIndexer = null;
|
indexerController.CurrentIndexer = null;
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Indexer is not configured");
|
actionContext.Response = ResultsController.GetErrorHttpResponseMessage(actionContext, HttpStatusCode.NotFound, 201, $"Indexer is not configured");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ namespace Jackett.Controllers
|
|||||||
var queryType = query.GetType();
|
var queryType = query.GetType();
|
||||||
var converter = queryType.GetMethod("ToTorznabQuery", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
var converter = queryType.GetMethod("ToTorznabQuery", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
||||||
if (converter == null)
|
if (converter == null)
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "");
|
actionContext.Response = ResultsController.GetErrorHttpResponseMessage(actionContext, HttpStatusCode.BadRequest, 900, $"ToTorznabQuery() not found");
|
||||||
var converted = converter.Invoke(null, new object[] { query });
|
var converted = converter.Invoke(null, new object[] { query });
|
||||||
var torznabQuery = converted as TorznabQuery;
|
var torznabQuery = converted as TorznabQuery;
|
||||||
resultController.CurrentQuery = torznabQuery;
|
resultController.CurrentQuery = torznabQuery;
|
||||||
@@ -113,7 +113,7 @@ namespace Jackett.Controllers
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery))
|
if (!resultController.CurrentIndexer.CanHandleQuery(resultController.CurrentQuery))
|
||||||
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, $"{resultController.CurrentIndexer.ID} does not support the requested query. Please check the capabilities (t=caps) and make sure the search mode and categories are supported.");
|
actionContext.Response = ResultsController.GetErrorHttpResponseMessage(actionContext, HttpStatusCode.NotImplemented, 201, $"{resultController.CurrentIndexer.ID} does not support the requested query. Please check the capabilities (t=caps) and make sure the search mode and categories are supported.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,65 +309,88 @@ namespace Jackett.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await CurrentIndexer.ResultsForQuery(CurrentQuery);
|
try
|
||||||
|
|
||||||
// Some trackers do not support multiple category filtering so filter the releases that match manually.
|
|
||||||
int? newItemCount = null;
|
|
||||||
|
|
||||||
// Cache non query results
|
|
||||||
if (string.IsNullOrEmpty(CurrentQuery.SanitizedSearchTerm))
|
|
||||||
{
|
{
|
||||||
newItemCount = cacheService.GetNewItemCount(CurrentIndexer, result.Releases);
|
var result = await CurrentIndexer.ResultsForQuery(CurrentQuery);
|
||||||
cacheService.CacheRssResults(CurrentIndexer, result.Releases);
|
|
||||||
|
// Some trackers do not support multiple category filtering so filter the releases that match manually.
|
||||||
|
int? newItemCount = null;
|
||||||
|
|
||||||
|
// Cache non query results
|
||||||
|
if (string.IsNullOrEmpty(CurrentQuery.SanitizedSearchTerm))
|
||||||
|
{
|
||||||
|
newItemCount = cacheService.GetNewItemCount(CurrentIndexer, result.Releases);
|
||||||
|
cacheService.CacheRssResults(CurrentIndexer, result.Releases);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log info
|
||||||
|
var logBuilder = new StringBuilder();
|
||||||
|
if (newItemCount != null)
|
||||||
|
{
|
||||||
|
logBuilder.AppendFormat("Found {0} ({1} new) releases from {2}", result.Releases.Count(), newItemCount, CurrentIndexer.DisplayName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logBuilder.AppendFormat("Found {0} releases from {1}", result.Releases.Count(), CurrentIndexer.DisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm))
|
||||||
|
{
|
||||||
|
logBuilder.AppendFormat(" for: {0}", CurrentQuery.GetQueryString());
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info(logBuilder.ToString());
|
||||||
|
|
||||||
|
var serverUrl = serverService.GetServerUrl(Request);
|
||||||
|
var resultPage = new ResultPage(new ChannelInfo
|
||||||
|
{
|
||||||
|
Title = CurrentIndexer.DisplayName,
|
||||||
|
Description = CurrentIndexer.DisplayDescription,
|
||||||
|
Link = new Uri(CurrentIndexer.SiteLink),
|
||||||
|
ImageUrl = new Uri(serverUrl + "logos/" + CurrentIndexer.ID + ".png"),
|
||||||
|
ImageTitle = CurrentIndexer.DisplayName,
|
||||||
|
ImageLink = new Uri(CurrentIndexer.SiteLink),
|
||||||
|
ImageDescription = CurrentIndexer.DisplayName
|
||||||
|
});
|
||||||
|
|
||||||
|
var proxiedReleases = result.Releases.Select(r => AutoMapper.Mapper.Map<ReleaseInfo>(r)).Select(r =>
|
||||||
|
{
|
||||||
|
r.Link = serverService.ConvertToProxyLink(r.Link, serverUrl, r.Origin.ID, "dl", r.Title);
|
||||||
|
return r;
|
||||||
|
});
|
||||||
|
|
||||||
|
resultPage.Releases = proxiedReleases.ToList();
|
||||||
|
|
||||||
|
var xml = resultPage.ToXml(new Uri(serverUrl));
|
||||||
|
// Force the return as XML
|
||||||
|
return ResponseMessage(new HttpResponseMessage()
|
||||||
|
{
|
||||||
|
Content = new StringContent(xml, Encoding.UTF8, "application/rss+xml")
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
// Log info
|
|
||||||
var logBuilder = new StringBuilder();
|
|
||||||
if (newItemCount != null)
|
|
||||||
{
|
{
|
||||||
logBuilder.AppendFormat("Found {0} ({1} new) releases from {2}", result.Releases.Count(), newItemCount, CurrentIndexer.DisplayName);
|
Engine.Logger.Error(e);
|
||||||
|
return GetErrorXML(900, e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static public HttpResponseMessage GetErrorHttpResponseMessage(HttpActionContext actionContext, HttpStatusCode status, int torznabCode, string description)
|
||||||
|
{
|
||||||
|
var parameters = actionContext.RequestContext.RouteData.Values;
|
||||||
|
var action = parameters["action"] as string;
|
||||||
|
|
||||||
|
if (action == "torznab")
|
||||||
|
{
|
||||||
|
return GetErrorXMLHttpResponseMessage(torznabCode, description);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logBuilder.AppendFormat("Found {0} releases from {1}", result.Releases.Count(), CurrentIndexer.DisplayName);
|
return actionContext.Request.CreateErrorResponse(status, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(CurrentQuery.SanitizedSearchTerm))
|
|
||||||
{
|
|
||||||
logBuilder.AppendFormat(" for: {0}", CurrentQuery.GetQueryString());
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Info(logBuilder.ToString());
|
|
||||||
|
|
||||||
var serverUrl = serverService.GetServerUrl(Request);
|
|
||||||
var resultPage = new ResultPage(new ChannelInfo
|
|
||||||
{
|
|
||||||
Title = CurrentIndexer.DisplayName,
|
|
||||||
Description = CurrentIndexer.DisplayDescription,
|
|
||||||
Link = new Uri(CurrentIndexer.SiteLink),
|
|
||||||
ImageUrl = new Uri(serverUrl + "logos/" + CurrentIndexer.ID + ".png"),
|
|
||||||
ImageTitle = CurrentIndexer.DisplayName,
|
|
||||||
ImageLink = new Uri(CurrentIndexer.SiteLink),
|
|
||||||
ImageDescription = CurrentIndexer.DisplayName
|
|
||||||
});
|
|
||||||
|
|
||||||
var proxiedReleases = result.Releases.Select(r => AutoMapper.Mapper.Map<ReleaseInfo>(r)).Select(r =>
|
|
||||||
{
|
|
||||||
r.Link = serverService.ConvertToProxyLink(r.Link, serverUrl, r.Origin.ID, "dl", r.Title);
|
|
||||||
return r;
|
|
||||||
});
|
|
||||||
|
|
||||||
resultPage.Releases = proxiedReleases.ToList();
|
|
||||||
|
|
||||||
var xml = resultPage.ToXml(new Uri(serverUrl));
|
|
||||||
// Force the return as XML
|
|
||||||
return ResponseMessage(new HttpResponseMessage()
|
|
||||||
{
|
|
||||||
Content = new StringContent(xml, Encoding.UTF8, "application/rss+xml")
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHttpActionResult GetErrorXML(int code, string description)
|
static public HttpResponseMessage GetErrorXMLHttpResponseMessage(int code, string description)
|
||||||
{
|
{
|
||||||
var xdoc = new XDocument(
|
var xdoc = new XDocument(
|
||||||
new XDeclaration("1.0", "UTF-8", null),
|
new XDeclaration("1.0", "UTF-8", null),
|
||||||
@@ -379,10 +402,15 @@ namespace Jackett.Controllers
|
|||||||
|
|
||||||
var xml = xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString();
|
var xml = xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString();
|
||||||
|
|
||||||
return ResponseMessage(new HttpResponseMessage()
|
return new HttpResponseMessage()
|
||||||
{
|
{
|
||||||
Content = new StringContent(xml, Encoding.UTF8, "application/xml")
|
Content = new StringContent(xml, Encoding.UTF8, "application/xml")
|
||||||
});
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public IHttpActionResult GetErrorXML(int code, string description)
|
||||||
|
{
|
||||||
|
return ResponseMessage(GetErrorXMLHttpResponseMessage(code, description));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
Reference in New Issue
Block a user