fix issues with subdomain routing in log UI (#358)

This commit is contained in:
Jesse Plamondon-Willard 2017-10-27 21:10:36 -04:00
parent ad5bb5b49a
commit 3f43ebcc0e
9 changed files with 81 additions and 12 deletions

View File

@ -4,6 +4,7 @@ using Microsoft.Extensions.Options;
using StardewModdingAPI.Web.Framework; using StardewModdingAPI.Web.Framework;
using StardewModdingAPI.Web.Framework.ConfigModels; using StardewModdingAPI.Web.Framework.ConfigModels;
using StardewModdingAPI.Web.Framework.LogParser; using StardewModdingAPI.Web.Framework.LogParser;
using StardewModdingAPI.Web.ViewModels;
namespace StardewModdingAPI.Web.Controllers namespace StardewModdingAPI.Web.Controllers
{ {
@ -13,6 +14,9 @@ namespace StardewModdingAPI.Web.Controllers
/********* /*********
** Properties ** Properties
*********/ *********/
/// <summary>The log parser config settings.</summary>
private readonly LogParserConfig Config;
/// <summary>The underlying Pastebin client.</summary> /// <summary>The underlying Pastebin client.</summary>
private readonly PastebinClient PastebinClient; private readonly PastebinClient PastebinClient;
@ -28,10 +32,10 @@ namespace StardewModdingAPI.Web.Controllers
public LogParserController(IOptions<LogParserConfig> configProvider) public LogParserController(IOptions<LogParserConfig> configProvider)
{ {
// init Pastebin client // init Pastebin client
LogParserConfig config = configProvider.Value; this.Config = configProvider.Value;
string version = this.GetType().Assembly.GetName().Version.ToString(3); string version = this.GetType().Assembly.GetName().Version.ToString(3);
string userAgent = string.Format(config.PastebinUserAgent, version); string userAgent = string.Format(this.Config.PastebinUserAgent, version);
this.PastebinClient = new PastebinClient(config.PastebinBaseUrl, userAgent, config.PastebinDevKey); this.PastebinClient = new PastebinClient(this.Config.PastebinBaseUrl, userAgent, this.Config.PastebinDevKey);
} }
/*** /***
@ -42,7 +46,7 @@ namespace StardewModdingAPI.Web.Controllers
[Route("log")] [Route("log")]
public ViewResult Index() public ViewResult Index()
{ {
return this.View("Index"); return this.View("Index", new LogParserModel(this.Config.SectionUrl));
} }
/*** /***

View File

@ -6,6 +6,9 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels
/********* /*********
** Accessors ** Accessors
*********/ *********/
/// <summary>The root URL for the log parser controller.</summary>
public string SectionUrl { get; set; }
/// <summary>The base URL for the Pastebin API.</summary> /// <summary>The base URL for the Pastebin API.</summary>
public string PastebinBaseUrl { get; set; } public string PastebinBaseUrl { get; set; }

View File

@ -1,4 +1,7 @@
using System; using System;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite; using Microsoft.AspNetCore.Rewrite;
namespace StardewModdingAPI.Web.Framework namespace StardewModdingAPI.Web.Framework
@ -7,14 +10,29 @@ namespace StardewModdingAPI.Web.Framework
/// <remarks>Derived from <a href="https://stackoverflow.com/a/44526747/262123" />.</remarks> /// <remarks>Derived from <a href="https://stackoverflow.com/a/44526747/262123" />.</remarks>
internal class RewriteSubdomainRule : IRule internal class RewriteSubdomainRule : IRule
{ {
/*********
** Accessors
*********/
/// <summary>The paths (excluding the hostname portion) to not rewrite.</summary>
public Regex[] ExceptPaths { get; set; }
/*********
** Public methods
*********/
/// <summary>Applies the rule. Implementations of ApplyRule should set the value for <see cref="RewriteContext.Result" /> (defaults to RuleResult.ContinueRules).</summary> /// <summary>Applies the rule. Implementations of ApplyRule should set the value for <see cref="RewriteContext.Result" /> (defaults to RuleResult.ContinueRules).</summary>
/// <param name="context">The rewrite context.</param> /// <param name="context">The rewrite context.</param>
public void ApplyRule(RewriteContext context) public void ApplyRule(RewriteContext context)
{ {
context.Result = RuleResult.ContinueRules; context.Result = RuleResult.ContinueRules;
HttpRequest request = context.HttpContext.Request;
// check ignores
if (this.ExceptPaths?.Any(pattern => pattern.IsMatch(request.Path)) == true)
return;
// get host parts // get host parts
string host = context.HttpContext.Request.Host.Host; string host = request.Host.Host;
string[] parts = host.Split('.'); string[] parts = host.Split('.');
// validate // validate
@ -24,7 +42,7 @@ namespace StardewModdingAPI.Web.Framework
return; return;
// prepend to path // prepend to path
context.HttpContext.Request.Path = $"/{parts[0]}{context.HttpContext.Request.Path}"; request.Path = $"/{parts[0]}{request.Path}";
} }
} }
} }

View File

@ -1,3 +1,4 @@
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Rewrite; using Microsoft.AspNetCore.Rewrite;
@ -64,7 +65,13 @@ namespace StardewModdingAPI.Web
loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); loggerFactory.AddDebug();
app app
.UseRewriter(new RewriteOptions().Add(new RewriteSubdomainRule())) // convert subdomain.smapi.io => smapi.io/subdomain for routing .UseRewriter(
new RewriteOptions()
.Add(new RewriteSubdomainRule
{
ExceptPaths = new[] { new Regex("^/Content", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase) }
})
) // convert subdomain.smapi.io => smapi.io/subdomain for routing
.UseStaticFiles() // wwwroot folder .UseStaticFiles() // wwwroot folder
.UseMvc(); .UseMvc();
} }

View File

@ -0,0 +1,26 @@
namespace StardewModdingAPI.Web.ViewModels
{
/// <summary>The view model for the log parser page.</summary>
public class LogParserModel
{
/*********
** Accessors
*********/
/// <summary>The root URL for the log parser controller.</summary>
public string SectionUrl { get; set; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
public LogParserModel() { }
/// <summary>Construct an instance.</summary>
/// <param name="sectionUrl">The root URL for the log parser controller.</param>
public LogParserModel(string sectionUrl)
{
this.SectionUrl = sectionUrl;
}
}
}

View File

@ -1,12 +1,18 @@
@{ @{
ViewData["Title"] = "SMAPI log parser"; ViewData["Title"] = "SMAPI log parser";
} }
@model StardewModdingAPI.Web.ViewModels.LogParserModel
@section Head { @section Head {
<link rel="stylesheet" href="~/Content/css/log-parser.css" /> <link rel="stylesheet" href="~/Content/css/log-parser.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.min.js" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.min.js" crossorigin="anonymous"></script>
<script src="~/Content/js/log-parser.js"></script> <script src="~/Content/js/log-parser.js"></script>
<style type="text/css" id="modflags"></style> <style type="text/css" id="modflags"></style>
<script>
$(function() {
smapi.logParser('@Model.SectionUrl');
});
</script>
} }
@********* @*********

View File

@ -1,4 +1,4 @@
{ {
"Logging": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"LogLevel": { "LogLevel": {
@ -6,5 +6,8 @@
"System": "Information", "System": "Information",
"Microsoft": "Information" "Microsoft": "Information"
} }
},
"LogParser": {
"SectionUrl": "http://localhost:59482/log/"
} }
} }

View File

@ -28,6 +28,7 @@
"NexusModUrlFormat": "mods/{0}" "NexusModUrlFormat": "mods/{0}"
}, },
"LogParser": { "LogParser": {
"SectionUrl": "https://log.smapi.io/",
"PastebinBaseUrl": "https://pastebin.com/", "PastebinBaseUrl": "https://pastebin.com/",
"PastebinUserAgent": "SMAPI/{0} (+https://github.com/Pathoschild/SMAPI)", "PastebinUserAgent": "SMAPI/{0} (+https://github.com/Pathoschild/SMAPI)",
"PastebinDevKey": "b8219d942109d1e60ebb14fbb45f06f9" "PastebinDevKey": "b8219d942109d1e60ebb14fbb45f06f9"

View File

@ -1,6 +1,7 @@
/* globals $, LZString */ /* globals $, LZString */
$(function() { var smapi = smapi || {};
smapi.logParser = function(sectionUrl) {
/********* /*********
** Initialisation ** Initialisation
*********/ *********/
@ -75,7 +76,7 @@ $(function() {
$ $
.ajax({ .ajax({
type: "POST", type: "POST",
url: "/log/save", url: sectionUrl + "/save",
data: JSON.stringify(paste), data: JSON.stringify(paste),
contentType: "application/json" // sent to API contentType: "application/json" // sent to API
}) })
@ -273,7 +274,7 @@ $(function() {
function getData() { function getData() {
$("#uploader").attr("data-text", "Loading..."); $("#uploader").attr("data-text", "Loading...");
$("#uploader").fadeIn(); $("#uploader").fadeIn();
$.get("/log/fetch/" + location.search.substring(1), function(data) { $.get(sectionUrl + "/fetch/" + location.search.substring(1), function(data) {
if (data.success) { if (data.success) {
$("#input").val(LZString.decompressFromUTF16(data.content) || data.content); $("#input").val(LZString.decompressFromUTF16(data.content) || data.content);
loadData(); loadData();
@ -284,4 +285,4 @@ $(function() {
$("#uploader").fadeOut(); $("#uploader").fadeOut();
}); });
} }
}); };