Reload HostFilteringOptions on change

This commit is contained in:
Chris Ross (ASP.NET) 2018-04-11 11:57:46 -07:00
parent f972d15501
commit 0b5cb8a8b8
2 changed files with 65 additions and 3 deletions

View File

@ -5,12 +5,14 @@ using System;
using System.IO;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HostFiltering;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore
{
@ -184,11 +186,20 @@ namespace Microsoft.AspNetCore
})
.ConfigureServices((hostingContext, services) =>
{
var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
services.AddHostFiltering(options =>
// Fallback
services.PostConfigure<HostFilteringOptions>(options =>
{
options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
{
// "AllowedHosts": "localhost;127.0.0.1;[::1]"
var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
// Fall back to "*" to disable.
options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
}
});
// Change notification
services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));
services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
})

View File

@ -1,7 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading;
using Microsoft.AspNetCore.HostFiltering;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Xunit;
namespace Microsoft.AspNetCore.Tests
@ -14,5 +20,50 @@ namespace Microsoft.AspNetCore.Tests
var builder = WebHost.CreateDefaultBuilder(new string[] { "--urls", "http://localhost:5001" });
Assert.Equal("http://localhost:5001", builder.GetSetting(WebHostDefaults.ServerUrlsKey));
}
[Fact]
public void WebHostConfiguration_HostFilterOptionsAreReloadable()
{
var host = WebHost.CreateDefaultBuilder()
.Configure(app => { })
.ConfigureAppConfiguration(configBuilder =>
{
configBuilder.Add(new ReloadableMemorySource());
}).Build();
var config = host.Services.GetRequiredService<IConfiguration>();
var monitor = host.Services.GetRequiredService<IOptionsMonitor<HostFilteringOptions>>();
var options = monitor.CurrentValue;
Assert.Contains("*", options.AllowedHosts);
var changed = new ManualResetEvent(false);
monitor.OnChange(newOptions =>
{
changed.Set();
});
config["AllowedHosts"] = "NewHost";
Assert.True(changed.WaitOne(TimeSpan.FromSeconds(10)));
options = monitor.CurrentValue;
Assert.Contains("NewHost", options.AllowedHosts);
}
private class ReloadableMemorySource : IConfigurationSource
{
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new ReloadableMemoryProvider();
}
}
private class ReloadableMemoryProvider : ConfigurationProvider
{
public override void Set(string key, string value)
{
base.Set(key, value);
OnReload();
}
}
}
}