Customize the WebHostBuilder used

- Call only UseKestrel + some IIS stuff
- Specify the API port in general configuration, warn if legacy.
- Show the default port in SetupWizard.
This commit is contained in:
Jordan Brown
2020-05-25 13:23:34 -04:00
parent 6455aa1ed0
commit 32da2c4be9
5 changed files with 53 additions and 26 deletions
@@ -14,6 +14,11 @@ namespace Tgstation.Server.Host.Configuration
/// </summary>
public const string Section = "General";
/// <summary>
/// The default value of <see cref="ApiPort"/>.
/// </summary>
public const ushort DefaultApiPort = 5000;
/// <summary>
/// The default value for <see cref="ServerInformation.MinimumPasswordLength"/>.
/// </summary>
@@ -39,6 +44,11 @@ namespace Tgstation.Server.Host.Configuration
/// </summary>
const int DefaultRestartTimeout = 10000;
/// <summary>
/// The port the TGS API listens on.
/// </summary>
public ushort ApiPort { get; set; }
/// <summary>
/// A GitHub personal access token to use for bypassing rate limits on requests. Requires no scopes
/// </summary>
@@ -1,6 +1,9 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Host.Core
{
@@ -8,14 +11,25 @@ namespace Tgstation.Server.Host.Core
sealed class ServerPortProivder : IServerPortProvider
{
/// <inheritdoc />
public ushort HttpApiPort { get; }
public ushort HttpApiPort => generalConfiguration.ApiPort;
/// <summary>
/// The <see cref="GeneralConfiguration"/> for the <see cref="ServerPortProivder"/>.
/// </summary>
readonly GeneralConfiguration generalConfiguration;
/// <summary>
/// Initializes a new instance of the <see cref="ServerPortProivder"/> <see langword="class"/>.
/// </summary>
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="generalConfiguration"/>.</param>
/// <param name="configuration">The <see cref="IConfiguration"/> to use.</param>
public ServerPortProivder(IConfiguration configuration)
/// <param name="logger">The <see cref="ILogger"/> to use.</param>
public ServerPortProivder(
IOptions<GeneralConfiguration> generalConfigurationOptions,
IConfiguration configuration,
ILogger<ServerPortProivder> logger)
{
generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
if (configuration == null)
throw new ArgumentNullException(nameof(configuration));
@@ -26,8 +40,13 @@ namespace Tgstation.Server.Host.Core
.GetSection("Url")
.Value;
if (httpEndpoint == null)
throw new InvalidOperationException("Missing required configuration option Kestrel:EndPoints:Http:Url!");
if (generalConfiguration.ApiPort == default && httpEndpoint == null)
throw new InvalidOperationException("Missing required configuration option General:ApiPort!");
if (generalConfiguration.ApiPort != default)
return;
logger.LogWarning("The \"Kestrel\" configuration section is deprecated! Please set your API port using the \"General:ApiPort\" configuration option!");
var splits = httpEndpoint.Split(":", StringSplitOptions.RemoveEmptyEntries);
var portString = splits.Last();
@@ -36,7 +55,7 @@ namespace Tgstation.Server.Host.Core
if (!UInt16.TryParse(portString, out var result))
throw new InvalidOperationException($"Failed to parse HTTP EndPoint port: {httpEndpoint}");
HttpApiPort = result;
generalConfiguration.ApiPort = result;
}
}
}
+12 -1
View File
@@ -1,10 +1,12 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Setup;
@@ -58,8 +60,17 @@ namespace Tgstation.Server.Host
}
var hostBuilder = CreateDefaultBuilder()
.ConfigureWebHostDefaults(webHostBuilder =>
.ConfigureWebHost(webHostBuilder =>
webHostBuilder
.UseKestrel(kestrelOptions =>
{
var serverPortProvider = kestrelOptions.ApplicationServices.GetRequiredService<IServerPortProvider>();
kestrelOptions.ListenAnyIP(
serverPortProvider.HttpApiPort,
listenOptions => listenOptions.Protocols = HttpProtocols.Http1AndHttp2);
})
.UseIIS()
.UseIISIntegration()
.UseApplication(postSetupServices)
.SuppressStatusMessages(true)
.UseShutdownTimeout(TimeSpan.FromMinutes(1)));
+6 -13
View File
@@ -141,7 +141,11 @@ namespace Tgstation.Server.Host.Setup
do
{
await console.WriteAsync("API Port (leave blank for default): ", false, cancellationToken).ConfigureAwait(false);
await console.WriteAsync(
$"API Port (leave blank for default of {GeneralConfiguration.DefaultApiPort}): ",
false,
cancellationToken)
.ConfigureAwait(false);
var portString = await console.ReadLineAsync(false, cancellationToken).ConfigureAwait(false);
if (String.IsNullOrWhiteSpace(portString))
return null;
@@ -732,6 +736,7 @@ namespace Tgstation.Server.Host.Setup
{
await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "Configuration complete! Saving to {0}", userConfigFileName), true, cancellationToken).ConfigureAwait(false);
newGeneralConfiguration.ApiPort = hostingPort ?? GeneralConfiguration.DefaultApiPort;
var map = new Dictionary<string, object>()
{
{ DatabaseConfiguration.Section, databaseConfiguration },
@@ -740,18 +745,6 @@ namespace Tgstation.Server.Host.Setup
{ ControlPanelConfiguration.Section, controlPanelConfiguration }
};
if (hostingPort.HasValue)
map.Add("Kestrel", new
{
EndPoints = new
{
Http = new
{
Url = String.Format(CultureInfo.InvariantCulture, "http://0.0.0.0:{0}", hostingPort)
}
}
});
var json = JsonConvert.SerializeObject(map, Formatting.Indented);
var configBytes = Encoding.UTF8.GetBytes(json);
+1 -7
View File
@@ -1,5 +1,6 @@
{
"General": {
"ApiPort": 5000,
"MinimumPasswordLength": 15,
"GitHubAccessToken": null,
"SetupWizardMode": "AutoDetect",
@@ -17,13 +18,6 @@
"LogLevel": "Debug",
"MicrosoftLogLevel": "Warning"
},
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://0.0.0.0:5000"
}
}
},
"Logging": {
"IncludeScopes": false,
"Debug": {