diff --git a/src/Jackett.Server/Middleware/CustomExceptionHandler.cs b/src/Jackett.Server/Middleware/CustomExceptionHandler.cs new file mode 100644 index 000000000..1081985a1 --- /dev/null +++ b/src/Jackett.Server/Middleware/CustomExceptionHandler.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Jackett.Common; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NLog; + +namespace Jackett.Server.Middleware +{ + public class CustomExceptionHandler + { + private readonly RequestDelegate _next; + private Logger logger; + + public CustomExceptionHandler(RequestDelegate next, Logger l) + { + _next = next; + logger = l; + } + + public async Task Invoke(HttpContext httpContext) + { + try + { + await _next(httpContext); + } + catch (Exception ex) + { + try + { + string msg = ""; + var json = new JObject(); + + logger.Error(ex); + + var message = ex.Message; + if (ex.InnerException != null) + { + message += ": " + ex.InnerException.Message; + } + + msg = message; + + if (ex is ExceptionWithConfigData) + { + json["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson(null, false); + } + + json["result"] = "error"; + json["error"] = msg; + json["stacktrace"] = ex.StackTrace; + if (ex.InnerException != null) + { + json["innerstacktrace"] = ex.InnerException.StackTrace; + } + + httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; + httpContext.Response.ContentType = "application/json"; + await httpContext.Response.WriteAsync(json.ToString()); + return; + } + catch (Exception ex2) + { + logger.Error(ex2, "An exception was thrown attempting to execute the custom exception error handler."); + } + + await _next(httpContext); + } + } + } + + // Extension method used to add the middleware to the HTTP request pipeline. + public static class CustomExceptionHandlerExtensions + { + public static IApplicationBuilder UseCustomExceptionHandler(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} diff --git a/src/Jackett.Server/Middleware/RedirectRules.cs b/src/Jackett.Server/Middleware/RedirectRules.cs new file mode 100644 index 000000000..dc90e0a77 --- /dev/null +++ b/src/Jackett.Server/Middleware/RedirectRules.cs @@ -0,0 +1,24 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Rewrite; +using Microsoft.Net.Http.Headers; + +namespace Jackett.Server.Middleware +{ + public class RedirectRules + { + public static void RedirectToDashboard(RewriteContext context) + { + var request = context.HttpContext.Request; + + if (request.Path == null || string.IsNullOrWhiteSpace(request.Path.ToString()) || request.Path.ToString() == "/") + { + // 301 is the status code of permanent redirect + var redir = Initialisation.ServerService.BasePath() + "/UI/Dashboard"; + var response = context.HttpContext.Response; + response.StatusCode = StatusCodes.Status301MovedPermanently; + context.Result = RuleResult.EndResponse; + response.Headers[HeaderNames.Location] = redir; + } + } + } +} diff --git a/src/Jackett.Server/Middleware/RewriteRules.cs b/src/Jackett.Server/Middleware/RewriteRules.cs new file mode 100644 index 000000000..8d87f7797 --- /dev/null +++ b/src/Jackett.Server/Middleware/RewriteRules.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Rewrite; +using System; + +namespace Jackett.Server.Middleware +{ + public class RewriteRules + { + public static void RewriteBasePath(RewriteContext context) + { + var request = context.HttpContext.Request; + + string serverBasePath = Initialisation.ServerService.BasePath() ?? string.Empty; + + if (request.Path != null && request.Path.HasValue && serverBasePath.Length > 0 && request.Path.Value.StartsWith(serverBasePath, StringComparison.Ordinal)) + { + request.Path = new PathString(request.Path.Value.Substring(serverBasePath.Length)); + } + } + } +} diff --git a/src/Jackett.Server/Startup.cs b/src/Jackett.Server/Startup.cs index 14bb4823b..0a82f8467 100644 --- a/src/Jackett.Server/Startup.cs +++ b/src/Jackett.Server/Startup.cs @@ -3,9 +3,11 @@ using Autofac.Extensions.DependencyInjection; using Jackett.Common.Models.Config; using Jackett.Common.Plumbing; using Jackett.Common.Services.Interfaces; +using Jackett.Server.Middleware; using Jackett.Server.Services; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Rewrite; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; @@ -59,6 +61,14 @@ namespace Jackett.Server app.UseDeveloperExceptionPage(); + app.UseCustomExceptionHandler(); + + var rewriteOptions = new RewriteOptions() + .Add(RewriteRules.RewriteBasePath) + .Add(RedirectRules.RedirectToDashboard); + + app.UseRewriter(rewriteOptions); + app.UseFileServer(new FileServerOptions { FileProvider = new PhysicalFileProvider(Initialisation.ConfigService.GetContentFolder()),