using Autofac; using System; using System.Reflection; using System.IO; using Newtonsoft.Json.Linq; using Jackett.Common.Indexers; using Jackett.Common.Indexers.Meta; using Jackett.Common.Models.Config; using Jackett.Common.Services; using Jackett.Common.Services.Interfaces; using Jackett.Common.Utils; using Jackett.Common.Utils.Clients; namespace Jackett.Common.Plumbing { public class JackettModule : Autofac.Module { private RuntimeSettings _runtimeSettings; public JackettModule (RuntimeSettings runtimeSettings) { _runtimeSettings = runtimeSettings; } protected override void Load(ContainerBuilder builder) { // Just register everything! TODO: Something better and more explicit than scanning everything. builder.RegisterAssemblyTypes(typeof(JackettModule).Assembly) .Except() .Except() .Except() .Except() .Except() .Except() .Except() .Except() .Except() .Except() .Except() .Except() .Except() .Except() .AsImplementedInterfaces().SingleInstance(); builder.RegisterInstance(_runtimeSettings); builder.Register(ctx => { return BuildServerConfig(ctx); }).As().SingleInstance(); builder.RegisterType(); // Register the best web client for the platform or the override switch (_runtimeSettings.ClientOverride) { case "httpclientnetcore": // do nothing, registered by the netcore app break; case "httpclient": RegisterWebClient(builder); break; case "httpclient2": RegisterWebClient(builder); break; case "safecurl": RegisterWebClient(builder); break; case "libcurl": RegisterWebClient(builder); break; case "automatic": default: if (System.Environment.OSVersion.Platform != PlatformID.Unix) { RegisterWebClient(builder); break; } var usehttpclient = DetectMonoCompatabilityWithHttpClient(); if (usehttpclient) RegisterWebClient(builder); else RegisterWebClient(builder); break; } } private void RegisterWebClient(ContainerBuilder builder) { //TODO: Remove once off Owin if (EnvironmentUtil.IsRunningLegacyOwin) { Engine.WebClientType = typeof(WebClientType); } builder.RegisterType().As(); } private ServerConfig BuildServerConfig(IComponentContext ctx) { var configService = ctx.Resolve(); return configService.BuildServerConfig(_runtimeSettings); } private static bool DetectMonoCompatabilityWithHttpClient() { bool usehttpclient = false; try { Type monotype = Type.GetType("Mono.Runtime"); if (monotype != null) { MethodInfo displayName = monotype.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static); if (displayName != null) { var monoVersion = displayName.Invoke(null, null).ToString(); var monoVersionO = new Version(monoVersion.Split(' ')[0]); if ((monoVersionO.Major >= 4 && monoVersionO.Minor >= 8) || monoVersionO.Major >= 5) { // check if btls is supported var monoSecurity = Assembly.Load("Mono.Security"); Type monoTlsProviderFactory = monoSecurity.GetType("Mono.Security.Interface.MonoTlsProviderFactory"); if (monoTlsProviderFactory != null) { MethodInfo isProviderSupported = monoTlsProviderFactory.GetMethod("IsProviderSupported"); if (isProviderSupported != null) { var btlsSupported = (bool)isProviderSupported.Invoke(null, new string[] { "btls" }); if (btlsSupported) { // initialize btls MethodInfo initialize = monoTlsProviderFactory.GetMethod("Initialize", new[] { typeof(string) }); if (initialize != null) { initialize.Invoke(null, new string[] { "btls" }); usehttpclient = true; } } } } } } } } catch (Exception e) { Console.Out.WriteLine("Error while deciding which HttpWebClient to use: " + e); } return usehttpclient; } } }