From 1622f40942bfd59be9f22e1fbbbe3602f56d3502 Mon Sep 17 00:00:00 2001 From: KZ Date: Thu, 23 Jul 2015 21:36:23 +0100 Subject: [PATCH] Passwords inputs are now the correct type. Fix configure_indexer not returning errors. Fix build warning. Change AB, HDT, MTTV, PHD, ST to use generic web client. --- src/Jackett.Console/Program.cs | 6 +- src/Jackett/Content/custom.js | 13 +- src/Jackett/Content/index.html | 11 +- src/Jackett/Controllers/AdminController.cs | 21 +--- src/Jackett/Engine.cs | 22 +--- src/Jackett/Indexers/AnimeBytes.cs | 113 +++++++++--------- src/Jackett/Indexers/HDTorrents.cs | 1 - src/Jackett/Indexers/IPTorrents.cs | 3 +- src/Jackett/Indexers/MoreThanTV.cs | 112 +++++++++-------- src/Jackett/Indexers/PrivateHD.cs | 21 ++-- src/Jackett/Indexers/SceneTime.cs | 2 +- src/Jackett/JackettModule.cs | 2 +- src/Jackett/Services/ConfigurationService.cs | 14 ++- src/Jackett/Services/IndexerManagerService.cs | 2 +- src/Jackett/Startup.cs | 22 +++- src/Jackett/Utils/BrowserUtil.cs | 2 +- .../Utils/Clients/UnixLibCurlWebClient.cs | 15 ++- .../Utils/Clients/UnixSafeCurlWebClient.cs | 24 ++-- src/Jackett/Utils/Clients/WebByteResult.cs | 1 + src/Jackett/Utils/Clients/WebClientResult.cs | 1 + src/Jackett/Utils/Clients/WebRequest.cs | 1 - src/Jackett/Utils/Clients/WindowsWebClient.cs | 54 +++++++-- src/Jackett/Utils/WebAPIToNLogTracer.cs | 2 +- 23 files changed, 262 insertions(+), 203 deletions(-) diff --git a/src/Jackett.Console/Program.cs b/src/Jackett.Console/Program.cs index 35786546f..f948fab86 100644 --- a/src/Jackett.Console/Program.cs +++ b/src/Jackett.Console/Program.cs @@ -36,13 +36,13 @@ namespace JackettConsole Engine.ServiceConfig.Uninstall(); return; case "/l": // Logging - Engine.LogRequests = true; + Startup.LogRequests = true; break; case "/t": // Tracing - Engine.TracingEnabled = true; + Startup.TracingEnabled = true; break; case "/curlsafe": // Curl safe mode - Engine.CurlSafe = true; + Startup.CurlSafe = true; break; case "/start": // Start Service if (!Engine.ServiceConfig.ServiceRunning()) diff --git a/src/Jackett/Content/custom.js b/src/Jackett/Content/custom.js index c2b02e7c6..8c4017828 100644 --- a/src/Jackett/Content/custom.js +++ b/src/Jackett/Content/custom.js @@ -1,6 +1,4 @@ - - -reloadIndexers(); +reloadIndexers(); loadJackettSettings(); function loadJackettSettings() { @@ -162,6 +160,7 @@ function displayIndexerSetup(id) { doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert"); return; } + populateSetupForm(id, data.name, data.config); }).fail(function () { @@ -172,6 +171,10 @@ function displayIndexerSetup(id) { } function populateConfigItems(configForm, config) { + // Set flag so we show fields named password as a password input + for (var i = 0; i < config.length; i++) { + config[i].ispassword = config[i].id.toLowerCase() === 'password'; + } var $formItemContainer = configForm.find(".config-setup-form"); $formItemContainer.empty(); var setupItemTemplate = Handlebars.compile($("#templates > .setup-item")[0].outerHTML); @@ -204,7 +207,7 @@ function getConfigModalJson(configForm) { var id = $el.data("id"); switch (type) { case "inputstring": - configJson[id] = $el.find(".setup-item-inputstring").val(); + configJson[id] = $el.find(".setup-item-inputstring input").val(); break; case "inputbool": configJson[id] = $el.find(".setup-item-inputbool input").is(":checked"); @@ -215,9 +218,7 @@ function getConfigModalJson(configForm) { } function populateSetupForm(indexerId, name, config) { - var configForm = newConfigModal(name, config); - var $goButton = configForm.find(".setup-indexer-go"); $goButton.click(function () { var data = { indexer: indexerId, name: name }; diff --git a/src/Jackett/Content/index.html b/src/Jackett/Content/index.html index fd365a742..ef01513c4 100644 --- a/src/Jackett/Content/index.html +++ b/src/Jackett/Content/index.html @@ -143,8 +143,15 @@
{{name}}
{{{value_element}}}
- - +
+ {{#if ispassword}} + + {{else}} + + {{/if}} + +
+
{{#if value}} diff --git a/src/Jackett/Controllers/AdminController.cs b/src/Jackett/Controllers/AdminController.cs index 69b878634..5adbb205b 100644 --- a/src/Jackett/Controllers/AdminController.cs +++ b/src/Jackett/Controllers/AdminController.cs @@ -172,17 +172,15 @@ namespace Jackett.Controllers catch (Exception ex) { jsonReply["result"] = "error"; - //jsonReply["error"] = Newtonsoft.Json.JsonConvert.SerializeObject(ex); + jsonReply["error"] = ex.Message; if (ex is ExceptionWithConfigData) { jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson(); - } + } } return Json(jsonReply); } - - [Route("get_indexers")] [HttpGet] public IHttpActionResult Indexers() @@ -323,13 +321,10 @@ namespace Jackett.Controllers serverService.ReserveUrls(true); } - // This is giving a warning - is there a better way of doing this? - Task.Run(() => - { + (new Thread(() => { Thread.Sleep(500); serverService.Start(); - }); - + })).Start(); } jsonReply["result"] = "success"; @@ -342,14 +337,6 @@ namespace Jackett.Controllers } return Json(jsonReply); } - - - [Route("jackett_restart")] - [HttpPost] - public IHttpActionResult Restart() - { - return null; - } } } diff --git a/src/Jackett/Engine.cs b/src/Jackett/Engine.cs index d26250b0c..c1340871e 100644 --- a/src/Jackett/Engine.cs +++ b/src/Jackett/Engine.cs @@ -22,24 +22,6 @@ namespace Jackett Logger.Info("Starting Jackett " + ConfigService.GetVersion()); } - public static bool TracingEnabled - { - get; - set; - } - - public static bool LogRequests - { - get; - set; - } - - public static bool CurlSafe - { - get; - set; - } - public static void BuildContainer() { var builder = new ContainerBuilder(); @@ -136,13 +118,13 @@ namespace Jackett logFile.MaxArchiveFiles = 1; logFile.KeepFileOpen = false; logFile.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence; - var logFileRule = new LoggingRule("*", TracingEnabled?LogLevel.Debug: LogLevel.Info, logFile); + var logFileRule = new LoggingRule("*", LogLevel.Info, logFile); logConfig.LoggingRules.Add(logFileRule); var logConsole = new ConsoleTarget(); logConfig.AddTarget("console", logConsole); logConsole.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}"; - var logConsoleRule = new LoggingRule("*", TracingEnabled ? LogLevel.Debug : LogLevel.Info, logConsole); + var logConsoleRule = new LoggingRule("*", Startup.TracingEnabled ? LogLevel.Debug : LogLevel.Info, logConsole); logConfig.LoggingRules.Add(logConsoleRule); LogManager.Configuration = logConfig; diff --git a/src/Jackett/Indexers/AnimeBytes.cs b/src/Jackett/Indexers/AnimeBytes.cs index b65fe26c7..e692dc0ae 100644 --- a/src/Jackett/Indexers/AnimeBytes.cs +++ b/src/Jackett/Indexers/AnimeBytes.cs @@ -2,6 +2,7 @@ using Jackett.Models; using Jackett.Services; using Jackett.Utils; +using Jackett.Utils.Clients; using Newtonsoft.Json.Linq; using NLog; using System; @@ -39,16 +40,14 @@ namespace Jackett.Indexers } } - private readonly string LoginUrl = ""; private readonly string SearchUrl = ""; - public bool AllowRaws { get; private set; } - CookieContainer cookieContainer; - HttpClientHandler handler; - HttpClient client; - public AnimeBytes(IIndexerManagerService i, Logger l) + private IWebClient webclient; + private string cookieHeader = ""; + + public AnimeBytes(IIndexerManagerService i, IWebClient client, Logger l) : base(name: "AnimeBytes", description: "The web's best Chinese cartoons", link: new Uri("https://animebytes.tv"), @@ -60,16 +59,7 @@ namespace Jackett.Indexers TorznabCaps.Categories.Add(new TorznabCategory { ID = "5070", Name = "TV/Anime" }); LoginUrl = SiteLink + "/user/login"; SearchUrl = SiteLink + "/torrents.php?filter_cat[1]=1"; - - cookieContainer = new CookieContainer(); - handler = new HttpClientHandler - { - CookieContainer = cookieContainer, - AllowAutoRedirect = false, - UseCookies = true, - }; - client = new HttpClient(handler); - client.DefaultRequestHeaders.Add("User-Agent", BrowserUtil.ChromeUserAgent); + webclient = client; } public Task GetConfigurationForSetup() @@ -85,8 +75,12 @@ namespace Jackett.Indexers // Get the login form as we need the CSRF Token - var loginPage = await client.GetAsync(LoginUrl); - CQ loginPageDom = await loginPage.Content.ReadAsStringAsync(); + var loginPage = await webclient.GetString(new Utils.Clients.WebRequest() + { + Url = LoginUrl + }); + + CQ loginPageDom =loginPage.Content; var csrfToken = loginPageDom["input[name=\"csrf_token\"]"].Last(); // Build login form @@ -102,45 +96,39 @@ namespace Jackett.Indexers var content = new FormUrlEncodedContent(pairs); // Do the login - var response = await client.PostAsync(LoginUrl, content); - var responseContent = await response.Content.ReadAsStringAsync(); - - // Compatiblity issue between the cookie format and httpclient - // Pull it out manually ignoring the expiry date then set it manually - // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer - IEnumerable cookies; - if (response.Headers.TryGetValues("set-cookie", out cookies)) + var response = await webclient.GetString(new Utils.Clients.WebRequest() { - foreach (var c in cookies) + Cookies = loginPage.Cookies, + PostData = pairs, + Referer = LoginUrl, + Type = RequestType.POST, + Url = LoginUrl + }); + + // Follow the redirect + if (response.Status == HttpStatusCode.RedirectMethod) + { + cookieHeader = response.Cookies; + response = await webclient.GetString(new Utils.Clients.WebRequest() { - cookieContainer.SetCookies(SiteLink, c.Substring(0, c.LastIndexOf(';'))); - } + Url = SearchUrl, + PostData = pairs, + Referer = SiteLink.ToString(), + Cookies = cookieHeader + }); } - foreach (Cookie cookie in cookieContainer.GetCookies(SiteLink)) - { - if (cookie.Name == "session") - { - cookie.Expires = DateTime.Now.AddDays(360); - break; - } - } - - // Get the home page now we are logged in as AllowAutoRedirect is false as we needed to get the cookie manually. - response = await client.GetAsync(SiteLink); - responseContent = await response.Content.ReadAsStringAsync(); - - if (!responseContent.Contains("/user/logout")) + if (!response.Content.Contains("/user/logout")) { + // Their login page appears to be broken and just gives a 500 error. throw new ExceptionWithConfigData("Failed to login, 6 failed attempts will get you banned for 6 hours.", (ConfigurationData)config); } else { AllowRaws = config.IncludeRaw.Value; var configSaveData = new JObject(); - cookieContainer.DumpToJson(SiteLink, configSaveData); + configSaveData["cookies"] = cookieHeader; configSaveData["raws"] = AllowRaws; - SaveConfig(configSaveData); IsConfigured = true; } @@ -148,9 +136,13 @@ namespace Jackett.Indexers public void LoadFromSavedConfiguration(JToken jsonConfig) { - cookieContainer.FillFromJson(SiteLink, jsonConfig, logger); - IsConfigured = true; - AllowRaws = jsonConfig["raws"].Value(); + // The old config used an array - just fail to load it + if (!(jsonConfig["cookies"] is JArray)) + { + cookieHeader = (string)jsonConfig["cookies"]; + AllowRaws = jsonConfig["raws"].Value(); + IsConfigured = true; + } } @@ -170,9 +162,6 @@ namespace Jackett.Indexers return sb.ToString(); } - - - public async Task PerformQuery(TorznabQuery query) { // The result list @@ -218,9 +207,13 @@ namespace Jackett.Indexers } // Get the content from the tracker - var response = await client.GetAsync(queryUrl); - var responseContent = await response.Content.ReadAsStringAsync(); - CQ dom = responseContent; + var response = await webclient.GetString(new Utils.Clients.WebRequest() + { + Cookies = cookieHeader, + Url = queryUrl, + Type = RequestType.GET + }); + CQ dom = response.Content; // Parse try @@ -379,7 +372,7 @@ namespace Jackett.Indexers } catch (Exception ex) { - OnParseError(responseContent, ex); + OnParseError(response.Content, ex); } // Add to the cache @@ -391,9 +384,15 @@ namespace Jackett.Indexers return releases.Select(s => (ReleaseInfo)s.Clone()).ToArray(); } - public Task Download(Uri link) + public async Task Download(Uri link) { - return client.GetByteArrayAsync(link); + var response = await webclient.GetBytes(new Utils.Clients.WebRequest() + { + Url = link.ToString(), + Cookies = cookieHeader + }); + + return response.Content; } } } diff --git a/src/Jackett/Indexers/HDTorrents.cs b/src/Jackett/Indexers/HDTorrents.cs index 643c5385f..994937e72 100644 --- a/src/Jackett/Indexers/HDTorrents.cs +++ b/src/Jackett/Indexers/HDTorrents.cs @@ -137,7 +137,6 @@ namespace Jackett.Indexers } release = new ReleaseInfo(); - long? size; release.Title = qRow.Find("td.mainblockcontent b a").Text(); release.Description = release.Title; diff --git a/src/Jackett/Indexers/IPTorrents.cs b/src/Jackett/Indexers/IPTorrents.cs index 802e7c02e..13e3a0af1 100644 --- a/src/Jackett/Indexers/IPTorrents.cs +++ b/src/Jackett/Indexers/IPTorrents.cs @@ -58,8 +58,7 @@ namespace Jackett.Indexers Url = SiteLink.ToString(), PostData = pairs, Referer = SiteLink.ToString(), - Type = RequestType.POST, - AutoRedirect = true + Type = RequestType.POST }); cookieHeader = response.Cookies; diff --git a/src/Jackett/Indexers/MoreThanTV.cs b/src/Jackett/Indexers/MoreThanTV.cs index 98c38c00f..7f470faa7 100644 --- a/src/Jackett/Indexers/MoreThanTV.cs +++ b/src/Jackett/Indexers/MoreThanTV.cs @@ -2,6 +2,7 @@ using Jackett.Models; using Jackett.Services; using Jackett.Utils; +using Jackett.Utils.Clients; using Newtonsoft.Json.Linq; using NLog; using System; @@ -23,14 +24,10 @@ namespace Jackett.Indexers private readonly string DownloadUrl = ""; private readonly string GuidUrl = ""; - CookieContainer cookies; - HttpClientHandler handler; - HttpClient client; + private IWebClient client; + private string cookieHeader = ""; - string cookieHeader; - int retries = 3; - - public MoreThanTV(IIndexerManagerService i, Logger l) + public MoreThanTV(IIndexerManagerService i, IWebClient c, Logger l) : base(name: "MoreThanTV", description: "ROMANIAN Private Torrent Tracker for TV / MOVIES, and the internal tracker for the release group DRACULA.", link: new Uri("https://www.morethan.tv"), @@ -42,15 +39,7 @@ namespace Jackett.Indexers SearchUrl = SiteLink + "/ajax.php?action=browse&searchstr="; DownloadUrl = SiteLink + "/torrents.php?action=download&id="; GuidUrl = SiteLink + "/torrents.php?torrentid="; - - cookies = new CookieContainer(); - handler = new HttpClientHandler - { - CookieContainer = cookies, - AllowAutoRedirect = true, - UseCookies = true, - }; - client = new HttpClient(handler); + client = c; } public Task GetConfigurationForSetup() @@ -71,32 +60,26 @@ namespace Jackett.Indexers { "keeplogged", "1" } }; - var content = new FormUrlEncodedContent(pairs); - - string responseContent; - - var configSaveData = new JObject(); - - if (Engine.IsWindows) + var loginResponse = await client.GetString(new Utils.Clients.WebRequest() { - // If Windows use .net http - var response = await client.PostAsync(LoginUrl, content); - responseContent = await response.Content.ReadAsStringAsync(); - cookies.DumpToJson(SiteLink, configSaveData); + PostData = pairs, + Url = LoginUrl, + Type = RequestType.POST + }); - } - else + if (loginResponse.Status == HttpStatusCode.Found) { - // If UNIX system use curl - var response = await CurlHelper.PostAsync(LoginUrl, pairs); - responseContent = Encoding.UTF8.GetString(response.Content); - cookieHeader = response.CookieHeader; - configSaveData["cookie_header"] = cookieHeader; + cookieHeader = loginResponse.Cookies; + loginResponse = await client.GetString(new Utils.Clients.WebRequest() + { + Url = SiteLink.ToString(), + Cookies = cookieHeader + }); } - if (!responseContent.Contains("logout.php?")) + if (!loginResponse.Content.Contains("logout.php?")) { - CQ dom = responseContent; + CQ dom = loginResponse.Content; dom["#loginform > table"].Remove(); var errorMessage = dom["#loginform"].Text().Trim().Replace("\n\t", " "); throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config); @@ -104,6 +87,8 @@ namespace Jackett.Indexers } else { + var configSaveData = new JObject(); + configSaveData["cookies"] = cookieHeader; SaveConfig(configSaveData); IsConfigured = true; } @@ -111,9 +96,12 @@ namespace Jackett.Indexers public void LoadFromSavedConfiguration(JToken jsonConfig) { - cookies.FillFromJson(SiteLink, jsonConfig, logger); - cookieHeader = cookies.GetCookieHeader(SiteLink); - IsConfigured = true; + // The old config used an array - just fail to load it + if (!(jsonConfig["cookies"] is JArray)) + { + cookieHeader = (string)jsonConfig["cookies"]; + IsConfigured = true; + } } private void FillReleaseInfoFromJson(ReleaseInfo release, JObject r) @@ -133,21 +121,30 @@ namespace Jackett.Indexers var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString(); var episodeSearchUrl = SearchUrl + HttpUtility.UrlEncode(searchString); + WebClientStringResult response = null; - string results; - if (Engine.IsWindows) + // Their web server is fairly flakey - try up to three times. + for(int i = 0; i < 3; i++) { - results = await client.GetStringAsync(episodeSearchUrl, retries); - } - else - { - var response = await CurlHelper.GetAsync(episodeSearchUrl, cookieHeader); - results = Encoding.UTF8.GetString(response.Content); + try + { + response = await client.GetString(new Utils.Clients.WebRequest() + { + Url = episodeSearchUrl, + Type = RequestType.GET, + Cookies = cookieHeader + }); + + break; + } + catch (Exception e){ + logger.Error(e, "Error checking for results from MoreThanTv."); + } } + try { - - var json = JObject.Parse(results); + var json = JObject.Parse(response.Content); foreach (JObject r in json["response"]["results"]) { DateTime pubDate = DateTime.MinValue; @@ -186,7 +183,7 @@ namespace Jackett.Indexers } catch (Exception ex) { - OnParseError(results, ex); + OnParseError(response.Content, ex); } return releases.ToArray(); @@ -194,15 +191,14 @@ namespace Jackett.Indexers public async Task Download(Uri link) { - if (Engine.IsWindows) + var result = await client.GetBytes(new Utils.Clients.WebRequest() { - return await client.GetByteArrayAsync(link); - } - else - { - var response = await CurlHelper.GetAsync(link.ToString(), cookieHeader); - return response.Content; - } + Cookies = cookieHeader, + Url = link.ToString(), + Type = RequestType.GET + }); + + return result.Content; } } } diff --git a/src/Jackett/Indexers/PrivateHD.cs b/src/Jackett/Indexers/PrivateHD.cs index 6c41ada3d..9230f7888 100644 --- a/src/Jackett/Indexers/PrivateHD.cs +++ b/src/Jackett/Indexers/PrivateHD.cs @@ -46,8 +46,7 @@ namespace Jackett.Indexers var loginPage = await webclient.GetString(new Utils.Clients.WebRequest() { Url = LoginUrl, - Type = RequestType.GET, - AutoRedirect = true, + Type = RequestType.GET }); var token = new Regex("Avz.CSRF_TOKEN = '(.*?)';").Match(loginPage.Content).Groups[1].ToString(); @@ -58,26 +57,34 @@ namespace Jackett.Indexers { "remember", "on" } }; - var response = await webclient.GetString(new Utils.Clients.WebRequest() + // Send Post + var loginPost = await webclient.GetString(new Utils.Clients.WebRequest() { Url = LoginUrl, PostData = pairs, Referer = LoginUrl, Type = RequestType.POST, - AutoRedirect = true, Cookies = loginPage.Cookies }); - if (!response.Content.Contains("auth/logout")) + // Get result from redirect + var loginResult = await webclient.GetString(new Utils.Clients.WebRequest() { - CQ dom = response.Content; + Url = loginPost.RedirectingTo, + Type = RequestType.GET, + Cookies = loginPost.Cookies + }); + + if (!loginResult.Content.Contains("auth/logout")) + { + CQ dom = loginResult.Content; var messageEl = dom[".form-error"]; var errorMessage = messageEl.Text().Trim(); throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config); } else { - cookieHeader = response.Cookies; + cookieHeader = loginPost.Cookies; var configSaveData = new JObject(); configSaveData["cookies"] = cookieHeader; SaveConfig(configSaveData); diff --git a/src/Jackett/Indexers/SceneTime.cs b/src/Jackett/Indexers/SceneTime.cs index e72c64221..53e29af35 100644 --- a/src/Jackett/Indexers/SceneTime.cs +++ b/src/Jackett/Indexers/SceneTime.cs @@ -58,7 +58,7 @@ namespace Jackett.Indexers { var config = new ConfigurationDataBasicLogin(); config.LoadValuesFromJson(configJson); - + var pairs = new Dictionary { { "username", config.Username.Value }, { "password", config.Password.Value } diff --git a/src/Jackett/JackettModule.cs b/src/Jackett/JackettModule.cs index 0fb2d5966..23cfae951 100644 --- a/src/Jackett/JackettModule.cs +++ b/src/Jackett/JackettModule.cs @@ -21,7 +21,7 @@ namespace Jackett builder.RegisterApiControllers(thisAssembly).InstancePerRequest(); // Register the best web client for the platform or exec curl as a safe option - if (Engine.CurlSafe) + if (Startup.CurlSafe) { builder.RegisterType().As(); } diff --git a/src/Jackett/Services/ConfigurationService.cs b/src/Jackett/Services/ConfigurationService.cs index 3b9567bf2..45a901efc 100644 --- a/src/Jackett/Services/ConfigurationService.cs +++ b/src/Jackett/Services/ConfigurationService.cs @@ -125,12 +125,16 @@ namespace Jackett.Services public string GetContentFolder() { // If we are debugging we can use the non copied content. - var dir = Path.Combine(ApplicationFolder(), "Content"); - if (!Directory.Exists(dir)) - { - dir = Path.Combine(ApplicationFolder(), "..\\..\\..\\Jackett\\Content"); - } + string dir = Path.Combine(ApplicationFolder(), "Content"); ; +#if DEBUG + // When we are running in debug use the source files + var sourcePath = Path.GetFullPath(Path.Combine(ApplicationFolder(), "..\\..\\..\\Jackett\\Content")); + if (Directory.Exists(sourcePath)) + { + dir = sourcePath; + } +#endif return dir; } diff --git a/src/Jackett/Services/IndexerManagerService.cs b/src/Jackett/Services/IndexerManagerService.cs index b4ce1cf0a..47113a741 100644 --- a/src/Jackett/Services/IndexerManagerService.cs +++ b/src/Jackett/Services/IndexerManagerService.cs @@ -74,7 +74,7 @@ namespace Jackett.Services var indexer = GetIndexer(name); var browseQuery = new TorznabQuery(); var results = await indexer.PerformQuery(browseQuery); - logger.Debug(string.Format("Found {0} releases from {1}", results.Length, indexer.DisplayName)); + logger.Info(string.Format("Found {0} releases from {1}", results.Length, indexer.DisplayName)); if (results.Length == 0) throw new Exception("Found no results while trying to browse this tracker"); } diff --git a/src/Jackett/Startup.cs b/src/Jackett/Startup.cs index 01c1cf70a..779d49d51 100644 --- a/src/Jackett/Startup.cs +++ b/src/Jackett/Startup.cs @@ -22,6 +22,24 @@ namespace Jackett { public class Startup { + public static bool TracingEnabled + { + get; + set; + } + + public static bool LogRequests + { + get; + set; + } + + public static bool CurlSafe + { + get; + set; + } + public void Configuration(IAppBuilder appBuilder) { // Configure Web API for self-host. @@ -30,13 +48,13 @@ namespace Jackett appBuilder.Use(); // Setup tracing if enabled - if (Engine.TracingEnabled) + if (TracingEnabled) { config.EnableSystemDiagnosticsTracing(); config.Services.Replace(typeof(ITraceWriter), new WebAPIToNLogTracer()); } // Add request logging if enabled - if (Engine.LogRequests) + if (LogRequests) { config.MessageHandlers.Add(new WebAPIRequestLogger()); } diff --git a/src/Jackett/Utils/BrowserUtil.cs b/src/Jackett/Utils/BrowserUtil.cs index 669b1e346..cc23d2baa 100644 --- a/src/Jackett/Utils/BrowserUtil.cs +++ b/src/Jackett/Utils/BrowserUtil.cs @@ -10,7 +10,7 @@ namespace Jackett.Utils { public static string ChromeUserAgent { - get { return "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36"; } + get { return "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36"; } } } } diff --git a/src/Jackett/Utils/Clients/UnixLibCurlWebClient.cs b/src/Jackett/Utils/Clients/UnixLibCurlWebClient.cs index 3f1fe5221..2def39d6f 100644 --- a/src/Jackett/Utils/Clients/UnixLibCurlWebClient.cs +++ b/src/Jackett/Utils/Clients/UnixLibCurlWebClient.cs @@ -37,12 +37,25 @@ namespace Jackett.Utils.Clients response = await CurlHelper.PostAsync(request.Url, request.PostData, request.Cookies, request.Referer); } - return new WebClientByteResult() + var result = new WebClientByteResult() { Content = response.Content, Cookies = response.CookieHeader, Status = response.Status }; + + if (response.Headers != null) + { + foreach(var header in response.Headers) + { + if(string.Equals(header.Key, "location", StringComparison.InvariantCultureIgnoreCase) && header.Value !=null) + { + result.RedirectingTo = header.Value; + } + } + } + + return result; } public async Task GetString(WebRequest request) diff --git a/src/Jackett/Utils/Clients/UnixSafeCurlWebClient.cs b/src/Jackett/Utils/Clients/UnixSafeCurlWebClient.cs index 6737eb06e..1a2b6916e 100644 --- a/src/Jackett/Utils/Clients/UnixSafeCurlWebClient.cs +++ b/src/Jackett/Utils/Clients/UnixSafeCurlWebClient.cs @@ -37,7 +37,8 @@ namespace Jackett.Utils.Clients { Cookies = byteResult.Cookies, Status = byteResult.Status, - Content = Encoding.UTF8.GetString(byteResult.Content) + Content = Encoding.UTF8.GetString(byteResult.Content), + RedirectingTo = byteResult.RedirectingTo }; } @@ -71,7 +72,7 @@ namespace Jackett.Utils.Clients string stdout = null; await Task.Run(() => { - stdout = processService.StartProcessAndGetOutput("curl", args.ToString(), true); + stdout = processService.StartProcessAndGetOutput(@"C:\Apps\curl.exe", args.ToString(), true); }); var outputData = File.ReadAllBytes(tempFile); @@ -97,15 +98,20 @@ namespace Jackett.Utils.Clients var headerSplitIndex = header.IndexOf(':'); if (headerSplitIndex > 0) { - var name = header.Substring(0, headerSplitIndex); + var name = header.Substring(0, headerSplitIndex).ToLowerInvariant(); var value = header.Substring(headerSplitIndex + 1); - if (string.Equals(name, "set-cookie", StringComparison.InvariantCultureIgnoreCase)) + switch (name) { - var cookieDataSplit = value.IndexOf(';'); - if (cookieDataSplit > 0) - { - result.Cookies += value.Substring(0, cookieDataSplit + 1) + " "; - } + case "set-cookie": + var cookieDataSplit = value.IndexOf(';'); + if (cookieDataSplit > 0) + { + result.Cookies += value.Substring(0, cookieDataSplit + 1) + " "; + }//Location + break; + case "location": + result.RedirectingTo = value.Trim(); + break; } } } diff --git a/src/Jackett/Utils/Clients/WebByteResult.cs b/src/Jackett/Utils/Clients/WebByteResult.cs index 501a26fc5..b904ec070 100644 --- a/src/Jackett/Utils/Clients/WebByteResult.cs +++ b/src/Jackett/Utils/Clients/WebByteResult.cs @@ -12,5 +12,6 @@ namespace Jackett.Utils.Clients public HttpStatusCode Status { get; set; } public string Cookies { get; set; } public byte[] Content { get; set; } + public string RedirectingTo { get; set; } } } diff --git a/src/Jackett/Utils/Clients/WebClientResult.cs b/src/Jackett/Utils/Clients/WebClientResult.cs index 8d31e72bc..a801e8800 100644 --- a/src/Jackett/Utils/Clients/WebClientResult.cs +++ b/src/Jackett/Utils/Clients/WebClientResult.cs @@ -12,5 +12,6 @@ namespace Jackett.Utils.Clients public HttpStatusCode Status { get; set; } public string Cookies { get; set; } public string Content { get; set; } + public string RedirectingTo { get; set; } } } diff --git a/src/Jackett/Utils/Clients/WebRequest.cs b/src/Jackett/Utils/Clients/WebRequest.cs index 487b844e9..b18e6a860 100644 --- a/src/Jackett/Utils/Clients/WebRequest.cs +++ b/src/Jackett/Utils/Clients/WebRequest.cs @@ -19,7 +19,6 @@ namespace Jackett.Utils.Clients public string Cookies { get; set; } public string Referer { get; set; } public RequestType Type { get; set; } - public bool AutoRedirect { get; set; } } public enum RequestType diff --git a/src/Jackett/Utils/Clients/WindowsWebClient.cs b/src/Jackett/Utils/Clients/WindowsWebClient.cs index 7be704154..12048fe05 100644 --- a/src/Jackett/Utils/Clients/WindowsWebClient.cs +++ b/src/Jackett/Utils/Clients/WindowsWebClient.cs @@ -13,19 +13,19 @@ namespace Jackett.Utils.Clients class WindowsWebClient : IWebClient { private Logger logger; - CookieContainer cookies; + public WindowsWebClient(Logger l) { logger = l; - cookies = new CookieContainer(); + } public async Task GetBytes(WebRequest request) { logger.Debug(string.Format("WindowsWebClient:GetBytes(Url:{0})", request.Url)); - + var cookies = new CookieContainer(); if (!string.IsNullOrEmpty(request.Cookies)) { var uri = new Uri(request.Url); @@ -45,7 +45,7 @@ namespace Jackett.Utils.Clients var client = new HttpClient(new HttpClientHandler { CookieContainer = cookies, - AllowAutoRedirect = false, + AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more. UseCookies = true, }); @@ -64,8 +64,24 @@ namespace Jackett.Utils.Clients var result = new WebClientByteResult(); result.Content = await response.Content.ReadAsByteArrayAsync(); - result.Cookies = cookies.GetCookieHeader(new Uri(request.Url)); + result.Status = response.StatusCode; + + // Compatiblity issue between the cookie format and httpclient + // Pull it out manually ignoring the expiry date then set it manually + // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer + IEnumerable cookieHeaders; + if (response.Headers.TryGetValues("set-cookie", out cookieHeaders)) + { + var cookieBuilder = new StringBuilder(); + foreach (var c in cookieHeaders) + { + cookieBuilder.AppendFormat("{0} ", c.Substring(0, c.LastIndexOf(';'))); + } + + result.Cookies = cookieBuilder.ToString().TrimEnd(); + } + return result; } @@ -93,7 +109,7 @@ namespace Jackett.Utils.Clients var client = new HttpClient(new HttpClientHandler { CookieContainer = cookies, - AllowAutoRedirect = request.AutoRedirect, + AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more. UseCookies = true, }); @@ -111,8 +127,32 @@ namespace Jackett.Utils.Clients var result = new WebClientStringResult(); result.Content = await response.Content.ReadAsStringAsync(); - result.Cookies = cookies.GetCookieHeader(new Uri(request.Url)); + + // Compatiblity issue between the cookie format and httpclient + // Pull it out manually ignoring the expiry date then set it manually + // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer + IEnumerable cookieHeaders; + if (response.Headers.TryGetValues("set-cookie", out cookieHeaders)) + { + var cookieBuilder = new StringBuilder(); + foreach (var c in cookieHeaders) + { + if (cookieBuilder.Length > 0) + { + cookieBuilder.Append("; "); + } + + cookieBuilder.Append( c.Substring(0, c.IndexOf(';'))); + } + + result.Cookies = cookieBuilder.ToString(); + } + result.Status = response.StatusCode; + if (null != response.Headers.Location) + { + result.RedirectingTo = response.Headers.Location.ToString(); + } return result; } } diff --git a/src/Jackett/Utils/WebAPIToNLogTracer.cs b/src/Jackett/Utils/WebAPIToNLogTracer.cs index 810bc60ec..2db729117 100644 --- a/src/Jackett/Utils/WebAPIToNLogTracer.cs +++ b/src/Jackett/Utils/WebAPIToNLogTracer.cs @@ -13,7 +13,7 @@ namespace Jackett.Utils public void Trace(HttpRequestMessage request, string category, TraceLevel level, Action traceAction) { - if (Engine.TracingEnabled) + if (Startup.TracingEnabled) { TraceRecord rec = new TraceRecord(request, category, level); traceAction(rec);