Add middleware: Exception handling and rewrite/redirect

This commit is contained in:
flightlevel
2018-05-05 17:08:46 +10:00
parent f162902b36
commit 5eed9d7038
4 changed files with 139 additions and 0 deletions

View File

@@ -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<CustomExceptionHandler>();
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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));
}
}
}
}

View File

@@ -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()),