From 7a1c8f94192c6118eee4a566cc55a635feb47339 Mon Sep 17 00:00:00 2001 From: Diego Heras Date: Sun, 12 Jan 2020 19:14:36 +0100 Subject: [PATCH] core: add rss url decode in download controller. resolves #4617 #6589 #4760 #6397 #5752 (#6936) --- .../ActionFilters/DownloadActionFilter.cs | 34 +++++++++++++++++++ .../Controllers/DownloadController.cs | 2 ++ 2 files changed, 36 insertions(+) create mode 100644 src/Jackett.Server/ActionFilters/DownloadActionFilter.cs diff --git a/src/Jackett.Server/ActionFilters/DownloadActionFilter.cs b/src/Jackett.Server/ActionFilters/DownloadActionFilter.cs new file mode 100644 index 000000000..4734bbf24 --- /dev/null +++ b/src/Jackett.Server/ActionFilters/DownloadActionFilter.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.WebUtilities; + +namespace Jackett.Server.ActionFilters +{ + public class DownloadActionFilter: ActionFilterAttribute + { + public override void OnActionExecuting(ActionExecutingContext filterContext) + { + // in Torznab RSS feed the "link" and "enclosure url" attributes are encoded following the RSS specification + // replacing & with & + // valid link => http://127.0.0.1:9117/dl/1337x/?jackett_apikey=ygm5k29&path=Q2ZESjhBYnJEQUIxeGd&file=Little+Mons + // encoded => http://127.0.0.1:9117/dl/1337x/?jackett_apikey=ygm5k29&path=Q2ZESjhBYnJEQUIxeGd&file=Little+Mons + // all RSS readers are able to decode the url and show the user the valid link + // some Jackett users are not decoding the url properly and this causes a 404 error in Jackett download + // this ActionFilter tries to do the decoding as a fallback, the RSS feed we provide is valid! + if (filterContext.ActionArguments.ContainsKey("path") || !filterContext.HttpContext.Request.QueryString.HasValue) + return; + + // recover the original query string and parse it manually + var qs = filterContext.HttpContext.Request.QueryString.Value; + qs = qs.Replace("&", "&"); + var parsedQs = QueryHelpers.ParseQuery(qs); + if (parsedQs == null) + return; + + // inject the arguments in the controller + if (parsedQs.ContainsKey("path") && !filterContext.ActionArguments.ContainsKey("path")) + filterContext.ActionArguments.Add("path", parsedQs["path"].ToString()); + if (parsedQs.ContainsKey("file") && !filterContext.ActionArguments.ContainsKey("file")) + filterContext.ActionArguments.Add("file", parsedQs["file"].ToString()); + } + } +} diff --git a/src/Jackett.Server/Controllers/DownloadController.cs b/src/Jackett.Server/Controllers/DownloadController.cs index 73dfd0f76..00294c811 100644 --- a/src/Jackett.Server/Controllers/DownloadController.cs +++ b/src/Jackett.Server/Controllers/DownloadController.cs @@ -10,10 +10,12 @@ using NLog; using System; using System.Text; using System.Threading.Tasks; +using Jackett.Server.ActionFilters; namespace Jackett.Server.Controllers { [AllowAnonymous] + [DownloadActionFilter] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] [Route("dl/{indexerID}")] public class DownloadController : Controller