Better reverse proxy support

Added "base path override" config option that makes all links and
redirects work with your reverse proxy.
Fixed post config update reload to work properly.
Make redirects and ajax calls use relative pathing.
This commit is contained in:
Michael Robinson
2016-01-08 15:45:08 -07:00
parent 71c583d359
commit 42ec634cd3
10 changed files with 100 additions and 62 deletions

View File

@@ -1,15 +1,17 @@
$(document).ready(function () { var basePath = "";
$(document).ready(function () {
$.ajaxSetup({ cache: false }); $.ajaxSetup({ cache: false });
window.jackettIsLocal = window.location.hostname === 'localhost' || window.jackettIsLocal = window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1'; window.location.hostname === '127.0.0.1';
bindUIButtons(); bindUIButtons();
reloadIndexers();
loadJackettSettings(); loadJackettSettings();
reloadIndexers();
}); });
function getJackettConfig(callback) { function getJackettConfig(callback) {
var jqxhr = $.get("/admin/get_jackett_config", function (data) { var jqxhr = $.get("get_jackett_config", function (data) {
callback(data); callback(data);
}).fail(function () { }).fail(function () {
@@ -22,6 +24,8 @@ function loadJackettSettings() {
$("#api-key-input").val(data.config.api_key); $("#api-key-input").val(data.config.api_key);
$("#app-version").html(data.app_version); $("#app-version").html(data.app_version);
$("#jackett-port").val(data.config.port); $("#jackett-port").val(data.config.port);
$("#jackett-basepathoverride").val(data.config.basepathoverride);
basePath = data.config.basepathoverride;
$("#jackett-savedir").val(data.config.blackholedir); $("#jackett-savedir").val(data.config.blackholedir);
$("#jackett-allowext").attr('checked', data.config.external); $("#jackett-allowext").attr('checked', data.config.external);
$("#jackett-allowupdate").attr('checked', data.config.updatedisabled); $("#jackett-allowupdate").attr('checked', data.config.updatedisabled);
@@ -39,7 +43,7 @@ function reloadIndexers() {
$('#indexers').hide(); $('#indexers').hide();
$('#indexers > .indexer').remove(); $('#indexers > .indexer').remove();
$('#unconfigured-indexers').empty(); $('#unconfigured-indexers').empty();
var jqxhr = $.get("/admin/get_indexers", function (data) { var jqxhr = $.get("get_indexers", function (data) {
displayIndexers(data.items); displayIndexers(data.items);
}).fail(function () { }).fail(function () {
doNotify("Error loading indexers, request to Jackett server failed", "danger", "glyphicon glyphicon-alert"); doNotify("Error loading indexers, request to Jackett server failed", "danger", "glyphicon glyphicon-alert");
@@ -52,8 +56,8 @@ function displayIndexers(items) {
$('#unconfigured-indexers-template').empty(); $('#unconfigured-indexers-template').empty();
for (var i = 0; i < items.length; i++) { for (var i = 0; i < items.length; i++) {
var item = items[i]; var item = items[i];
item.torznab_host = resolveUrl("/torznab/" + item.id); item.torznab_host = resolveUrl("/" + basePath + "/torznab/" + item.id);
item.potato_host = resolveUrl("/potato/" + item.id); item.potato_host = resolveUrl("/" + basePath + "/potato/" + item.id);
if (item.configured) if (item.configured)
$('#indexers').append(indexerTemplate(item)); $('#indexers').append(indexerTemplate(item));
else else
@@ -92,7 +96,7 @@ function prepareDeleteButtons() {
var $btn = $(btn); var $btn = $(btn);
var id = $btn.data("id"); var id = $btn.data("id");
$btn.click(function () { $btn.click(function () {
var jqxhr = $.post("/admin/delete_indexer", JSON.stringify({ indexer: id }), function (data) { var jqxhr = $.post("delete_indexer", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") { if (data.result == "error") {
doNotify("Delete error for " + id + "\n" + data.error, "danger", "glyphicon glyphicon-alert"); doNotify("Delete error for " + id + "\n" + data.error, "danger", "glyphicon glyphicon-alert");
} }
@@ -125,7 +129,7 @@ function prepareTestButtons() {
var id = $btn.data("id"); var id = $btn.data("id");
$btn.click(function () { $btn.click(function () {
doNotify("Test started for " + id, "info", "glyphicon glyphicon-transfer"); doNotify("Test started for " + id, "info", "glyphicon glyphicon-transfer");
var jqxhr = $.post("/admin/test_indexer", JSON.stringify({ indexer: id }), function (data) { var jqxhr = $.post("test_indexer", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") { if (data.result == "error") {
doNotify("Test failed for " + id + ": \n" + data.error, "danger", "glyphicon glyphicon-alert"); doNotify("Test failed for " + id + ": \n" + data.error, "danger", "glyphicon glyphicon-alert");
} }
@@ -141,7 +145,7 @@ function prepareTestButtons() {
function displayIndexerSetup(id, link) { function displayIndexerSetup(id, link) {
var jqxhr = $.post("/admin/get_config_form", JSON.stringify({ indexer: id }), function (data) { var jqxhr = $.post("get_config_form", JSON.stringify({ indexer: id }), function (data) {
if (data.result == "error") { if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert"); doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
return; return;
@@ -247,7 +251,7 @@ function populateSetupForm(indexerId, name, config, caps, link) {
$goButton.prop('disabled', true); $goButton.prop('disabled', true);
$goButton.html($('#spinner').html()); $goButton.html($('#spinner').html());
var jqxhr = $.post("/admin/configure_indexer", JSON.stringify(data), function (data) { var jqxhr = $.post("configure_indexer", JSON.stringify(data), function (data) {
if (data.result == "error") { if (data.result == "error") {
if (data.config) { if (data.config) {
populateConfigItems(configForm, data.config); populateConfigItems(configForm, data.config);
@@ -321,7 +325,7 @@ function bindUIButtons() {
}); });
$("#jackett-show-releases").click(function () { $("#jackett-show-releases").click(function () {
var jqxhr = $.get("/admin/GetCache", function (data) { var jqxhr = $.get("GetCache", function (data) {
var releaseTemplate = Handlebars.compile($("#jackett-releases").html()); var releaseTemplate = Handlebars.compile($("#jackett-releases").html());
var item = { releases: data, Title: 'Releases' }; var item = { releases: data, Title: 'Releases' };
var releaseDialog = $(releaseTemplate(item)); var releaseDialog = $(releaseTemplate(item));
@@ -403,7 +407,7 @@ function bindUIButtons() {
$("#jackett-show-search").click(function () { $("#jackett-show-search").click(function () {
$('#select-indexer-modal').remove(); $('#select-indexer-modal').remove();
var jqxhr = $.get("/admin/get_indexers", function (data) { var jqxhr = $.get("get_indexers", function (data) {
var scope = { var scope = {
items: data.items items: data.items
}; };
@@ -459,7 +463,7 @@ function bindUIButtons() {
$('#searchResults').empty(); $('#searchResults').empty();
$('#jackett-search-perform').html($('#spinner').html()); $('#jackett-search-perform').html($('#spinner').html());
var jqxhr = $.post("/admin/search", queryObj, function (data) { var jqxhr = $.post("search", queryObj, function (data) {
$('#jackett-search-perform').html('Search trackers'); $('#jackett-search-perform').html('Search trackers');
var resultsTemplate = Handlebars.compile($("#jackett-search-results").html()); var resultsTemplate = Handlebars.compile($("#jackett-search-results").html());
var results = $('#searchResults'); var results = $('#searchResults');
@@ -534,7 +538,7 @@ function bindUIButtons() {
}); });
$("#view-jackett-logs").click(function () { $("#view-jackett-logs").click(function () {
var jqxhr = $.get("/admin/GetLogs", function (data) { var jqxhr = $.get("GetLogs", function (data) {
var releaseTemplate = Handlebars.compile($("#jackett-logs").html()); var releaseTemplate = Handlebars.compile($("#jackett-logs").html());
var item = { logs: data }; var item = { logs: data };
var releaseDialog = $(releaseTemplate(item)); var releaseDialog = $(releaseTemplate(item));
@@ -548,6 +552,7 @@ function bindUIButtons() {
$("#change-jackett-port").click(function () { $("#change-jackett-port").click(function () {
var jackett_port = $("#jackett-port").val(); var jackett_port = $("#jackett-port").val();
var jackett_basepathoverride = $("#jackett-basepathoverride").val();
var jackett_external = $("#jackett-allowext").is(':checked'); var jackett_external = $("#jackett-allowext").is(':checked');
var jackett_update = $("#jackett-allowupdate").is(':checked'); var jackett_update = $("#jackett-allowupdate").is(':checked');
var jackett_prerelease = $("#jackett-prerelease").is(':checked'); var jackett_prerelease = $("#jackett-prerelease").is(':checked');
@@ -558,21 +563,17 @@ function bindUIButtons() {
updatedisabled: jackett_update, updatedisabled: jackett_update,
prerelease: jackett_prerelease, prerelease: jackett_prerelease,
blackholedir: $("#jackett-savedir").val(), blackholedir: $("#jackett-savedir").val(),
logging: jackett_logging logging: jackett_logging,
basepathoverride: jackett_basepathoverride
}; };
var jqxhr = $.post("/admin/set_config", JSON.stringify(jsonObject), function (data) { var jqxhr = $.post("set_config", JSON.stringify(jsonObject), function (data) {
if (data.result == "error") { if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert"); doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
return; return;
} else { } else {
doNotify("Redirecting you to complete configuration update..", "success", "glyphicon glyphicon-ok"); doNotify("Redirecting you to complete configuration update..", "success", "glyphicon glyphicon-ok");
window.setTimeout(function () { window.setTimeout(function () {
url = window.location.href; window.location.reload(true);
if (data.external) {
window.location.href = url.substr(0, url.lastIndexOf(":") + 1) + data.port;
} else {
window.location.href = 'http://127.0.0.1:' + data.port;
}
}, 3000); }, 3000);
} }
@@ -582,7 +583,7 @@ function bindUIButtons() {
}); });
$("#trigger-updater").click(function () { $("#trigger-updater").click(function () {
var jqxhr = $.get("/admin/trigger_update", function (data) { var jqxhr = $.get("trigger_update", function (data) {
if (data.result == "error") { if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert"); doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");
return; return;
@@ -598,7 +599,7 @@ function bindUIButtons() {
var password = $("#jackett-adminpwd").val(); var password = $("#jackett-adminpwd").val();
var jsonObject = { password: password }; var jsonObject = { password: password };
var jqxhr = $.post("/admin/set_admin_password", JSON.stringify(jsonObject), function (data) { var jqxhr = $.post("set_admin_password", JSON.stringify(jsonObject), function (data) {
if (data.result == "error") { if (data.result == "error") {
doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert"); doNotify("Error: " + data.error, "danger", "glyphicon glyphicon-alert");

View File

@@ -4,27 +4,27 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' /> <link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
<script src="../../libs/filesize.min.js"></script> <script src="../libs/filesize.min.js"></script>
<script src="../../libs/jquery.min.js"></script> <script src="../libs/jquery.min.js"></script>
<script src="../../libs/jquery.dataTables.min.js"></script> <script src="../libs/jquery.dataTables.min.js"></script>
<script src="../../libs/handlebars.min.js"></script> <script src="../libs/handlebars.min.js"></script>
<script src="../../libs/moment.min.js"></script> <script src="../libs/moment.min.js"></script>
<script src="../../libs/handlebarsmoment.js"></script> <script src="../libs/handlebarsmoment.js"></script>
<script src="../../bootstrap/bootstrap.min.js"></script> <script src="../bootstrap/bootstrap.min.js"></script>
<script src="../../libs/bootstrap-notify.js"></script> <script src="../libs/bootstrap-notify.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script> <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
<link href="../../bootstrap/bootstrap.min.css" rel="stylesheet"> <link href="../bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="../../animate.css" rel="stylesheet"> <link href="../animate.css" rel="stylesheet">
<link href="../../custom.css" rel="stylesheet"> <link href="../custom.css" rel="stylesheet">
<link href="../../css/jquery.dataTables.css" rel="stylesheet"> <link href="../css/jquery.dataTables.css" rel="stylesheet">
<link rel="stylesheet" href="../../css/font-awesome.min.css"> <link rel="stylesheet" href="../css/font-awesome.min.css">
<title>Jackett</title> <title>Jackett</title>
</head> </head>
<body> <body>
<div id="page"> <div id="page">
<img id="logo" src="../../jacket_medium.png" alt="Logo" /><span id="header-title">Jackett</span> <img id="logo" src="../jacket_medium.png" alt="Logo" /><span id="header-title">Jackett</span>
<div class="pull-right jackett-apikey"> <div class="pull-right jackett-apikey">
<span class="input-header">API Key: </span> <span class="input-header">API Key: </span>
@@ -84,10 +84,13 @@
Logout Logout
</a> </a>
</div> </div>
<div class="input-area">
<span class="input-header">Base Path Override: </span>
<input id="jackett-basepathoverride" class="form-control input-right" type="text" value="" placeholder="jackett/">
</div>
<div class="input-area"> <div class="input-area">
<span class="input-header">Server port: </span> <span class="input-header">Server port: </span>
<input id="jackett-port" class="form-control input-right" type="text" value="" placeholder="9117"> <input id="jackett-port" class="form-control input-right" type="text" value="" placeholder="9117">
</div> </div>
<div class="input-area"> <div class="input-area">
<span class="input-header">Manual download blackhole directory: </span> <span class="input-header">Manual download blackhole directory: </span>
@@ -172,7 +175,7 @@
<div class="indexer-logo"> <div class="indexer-logo">
<!-- Make section browser searchable --> <!-- Make section browser searchable -->
<span class="hidden-name">{{name}}</span> <span class="hidden-name">{{name}}</span>
<img alt="{{name}}" title="{{name}}" src="../../logos/{{id}}.png" /> <img alt="{{name}}" title="{{name}}" src="../logos/{{id}}.png" />
</div> </div>
<div class="indexer-buttons"> <div class="indexer-buttons">
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}" data-link="{{site_link}}"> <button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}" data-link="{{site_link}}">
@@ -206,7 +209,7 @@
<div class="indexer-logo indexer-setup" data-id="{{id}}" data-link="{{site_link}}"> <div class="indexer-logo indexer-setup" data-id="{{id}}" data-link="{{site_link}}">
<!-- Make section browser searchable --> <!-- Make section browser searchable -->
<span class="hidden-name">{{name}}</span> <span class="hidden-name">{{name}}</span>
<img alt="{{name}}" title="{{name}}" src="../../logos/{{id}}.png" /> <img alt="{{name}}" title="{{name}}" src="../logos/{{id}}.png" />
</div> </div>
</div> </div>
@@ -478,6 +481,6 @@
<span class="spinner glyphicon glyphicon-refresh"></span> <span class="spinner glyphicon glyphicon-refresh"></span>
</script> </script>
<script src="../../custom.js"></script> <script src="../custom.js"></script>
</body> </body>
</html> </html>

View File

@@ -6,28 +6,28 @@
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' /> <link rel='shortcut icon' type='image/x-icon' href='/favicon.ico' />
<script src="../../libs/jquery.min.js"></script> <script src="../libs/jquery.min.js"></script>
<script src="../../libs/jquery.dataTables.min.js"></script> <script src="../libs/jquery.dataTables.min.js"></script>
<script src="../../libs/handlebars.min.js"></script> <script src="../libs/handlebars.min.js"></script>
<script src="../../libs/moment.min.js"></script> <script src="../libs/moment.min.js"></script>
<script src="../../libs/handlebarsmoment.js"></script> <script src="../libs/handlebarsmoment.js"></script>
<script src="../../bootstrap/bootstrap.min.js"></script> <script src="../bootstrap/bootstrap.min.js"></script>
<script src="../../libs/bootstrap-notify.js"></script> <script src="../libs/bootstrap-notify.js"></script>
<link href="../../bootstrap/bootstrap.min.css" rel="stylesheet"> <link href="../bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="../../animate.css" rel="stylesheet"> <link href="../animate.css" rel="stylesheet">
<link href="../../custom.css" rel="stylesheet"> <link href="../custom.css" rel="stylesheet">
<title>Jackett</title> <title>Jackett</title>
</head> </head>
<body> <body>
<div id="page"> <div id="page">
<img id="logo" src="../../jacket_medium.png" /><span id="header-title">Jackett</span> <img id="logo" src="../jacket_medium.png" /><span id="header-title">Jackett</span>
<hr /> <hr />
<h1>Login</h1> <h1>Login</h1>
<form action="../Admin/Dashboard" method="post"> <form action="Dashboard" method="post">
<div class="input-area"> <div class="input-area">
<span class="input-header">Admin password</span> <span class="input-header">Admin password</span>
<input id="password" name="password" class="form-control input-right" type="password"> <input id="password" name="password" class="form-control input-right" type="password">

View File

@@ -80,7 +80,7 @@ namespace Jackett.Controllers
var ctx = Request.GetOwinContext(); var ctx = Request.GetOwinContext();
var authManager = ctx.Authentication; var authManager = ctx.Authentication;
authManager.SignOut("ApplicationCookie"); authManager.SignOut("ApplicationCookie");
return Redirect("/Admin/Dashboard"); return Redirect("Admin/Dashboard");
} }
[HttpGet] [HttpGet]
@@ -318,6 +318,7 @@ namespace Jackett.Controllers
cfg["prerelease"] = serverService.Config.UpdatePrerelease; cfg["prerelease"] = serverService.Config.UpdatePrerelease;
cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword) ? string.Empty : serverService.Config.AdminPassword.Substring(0, 10); cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword) ? string.Empty : serverService.Config.AdminPassword.Substring(0, 10);
cfg["logging"] = Startup.TracingEnabled; cfg["logging"] = Startup.TracingEnabled;
cfg["basepathoverride"] = serverService.Config.BasePathOverride;
jsonReply["config"] = cfg; jsonReply["config"] = cfg;
@@ -349,9 +350,12 @@ namespace Jackett.Controllers
bool updateDisabled = (bool)postData["updatedisabled"]; bool updateDisabled = (bool)postData["updatedisabled"];
bool preRelease = (bool)postData["prerelease"]; bool preRelease = (bool)postData["prerelease"];
bool logging = (bool)postData["logging"]; bool logging = (bool)postData["logging"];
string basePathOverride = (string)postData["basepathoverride"];
Engine.Server.Config.UpdateDisabled = updateDisabled; Engine.Server.Config.UpdateDisabled = updateDisabled;
Engine.Server.Config.UpdatePrerelease = preRelease; Engine.Server.Config.UpdatePrerelease = preRelease;
Engine.Server.Config.BasePathOverride = basePathOverride;
Startup.BasePath = Engine.Server.BasePath();
Engine.Server.SaveConfig(); Engine.Server.SaveConfig();
Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info); Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
@@ -446,7 +450,7 @@ namespace Jackett.Controllers
private void ConfigureCacheResults(List<TrackerCacheResult> results) private void ConfigureCacheResults(List<TrackerCacheResult> results)
{ {
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port); var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
foreach (var result in results) foreach (var result in results)
{ {
var link = result.Link; var link = result.Link;

View File

@@ -117,7 +117,7 @@ namespace Jackett.Controllers
} }
releases = indexer.FilterResults(torznabQuery, releases); releases = indexer.FilterResults(torznabQuery, releases);
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port); var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
var potatoResponse = new TorrentPotatoResponse(); var potatoResponse = new TorrentPotatoResponse();
releases = TorznabUtil.FilterResultsToTitle(releases, torznabQuery.SanitizedSearchTerm, year); releases = TorznabUtil.FilterResultsToTitle(releases, torznabQuery.SanitizedSearchTerm, year);

View File

@@ -100,7 +100,7 @@ namespace Jackett.Controllers
logger.Info(logBuilder.ToString()); logger.Info(logBuilder.ToString());
var serverUrl = string.Format("{0}://{1}:{2}/", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port); var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
var resultPage = new ResultPage(new ChannelInfo var resultPage = new ResultPage(new ChannelInfo
{ {
Title = indexer.DisplayName, Title = indexer.DisplayName,

View File

@@ -23,6 +23,7 @@ namespace Jackett.Models.Config
public string BlackholeDir { get; set; } public string BlackholeDir { get; set; }
public bool UpdateDisabled { get; set; } public bool UpdateDisabled { get; set; }
public bool UpdatePrerelease { get; set; } public bool UpdatePrerelease { get; set; }
public string BasePathOverride { get; set; }
public string[] GetListenAddresses(bool? external = null) public string[] GetListenAddresses(bool? external = null)
{ {

View File

@@ -19,6 +19,7 @@ using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web; using System.Web;
@@ -33,6 +34,7 @@ namespace Jackett.Services
ServerConfig Config { get; } ServerConfig Config { get; }
void SaveConfig(); void SaveConfig();
Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent"); Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent");
string BasePath();
} }
public class ServerService : IServerService public class ServerService : IServerService
@@ -77,6 +79,23 @@ namespace Jackett.Services
return new Uri(proxyLink); return new Uri(proxyLink);
} }
public string BasePath()
{
if (config.BasePathOverride == null || config.BasePathOverride == "") {
return "/";
}
var path = config.BasePathOverride;
if (!path.EndsWith("/"))
{
path = path + "/";
}
if (!path.StartsWith("/"))
{
path = "/" + path;
}
return path;
}
private void LoadConfig() private void LoadConfig()
{ {
// Load config // Load config
@@ -139,6 +158,7 @@ namespace Jackett.Services
logger.Info("Starting web server at " + config.GetListenAddresses()[0]); logger.Info("Starting web server at " + config.GetListenAddresses()[0]);
var startOptions = new StartOptions(); var startOptions = new StartOptions();
config.GetListenAddresses().ToList().ForEach(u => startOptions.Urls.Add(u)); config.GetListenAddresses().ToList().ForEach(u => startOptions.Urls.Add(u));
Startup.BasePath = BasePath();
_server = WebApp.Start<Startup>(startOptions); _server = WebApp.Start<Startup>(startOptions);
logger.Debug("Web server started"); logger.Debug("Web server started");
updater.StartUpdateChecker(); updater.StartUpdateChecker();

View File

@@ -58,6 +58,12 @@ namespace Jackett
set; set;
} }
public static string BasePath
{
get;
set;
}
public void Configuration(IAppBuilder appBuilder) public void Configuration(IAppBuilder appBuilder)
{ {
// Configure Web API for self-host. // Configure Web API for self-host.

View File

@@ -1,4 +1,5 @@
using Microsoft.Owin; using Jackett.Services;
using Microsoft.Owin;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -21,7 +22,9 @@ namespace Jackett.Utils
{ {
// 301 is the status code of permanent redirect // 301 is the status code of permanent redirect
context.Response.StatusCode = 301; context.Response.StatusCode = 301;
context.Response.Headers.Set("Location", "/Admin/Dashboard"); var redir = Startup.BasePath + "Admin/Dashboard";
Engine.Logger.Info("redirecting to " + redir);
context.Response.Headers.Set("Location", redir);
} }
else else
{ {