Merge pull request #2272 from aspnet/release/2.1

Mark HTTP/2 as not supported with an AppContext switch override.
This commit is contained in:
Chris Ross 2018-01-24 15:34:57 -08:00 committed by GitHub
commit a57bc4b3bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 14 deletions

View File

@ -1,4 +1,4 @@
using System.Globalization; using System;
using System.IO; using System.IO;
using System.Net; using System.Net;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
@ -13,6 +13,8 @@ namespace Http2SampleApp
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
AppContext.SetSwitch("Switch.Microsoft.AspNetCore.Server.Kestrel.Experimental.Http2", isEnabled: true);
var hostBuilder = new WebHostBuilder() var hostBuilder = new WebHostBuilder()
.ConfigureLogging((_, factory) => .ConfigureLogging((_, factory) =>
{ {

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -11,18 +7,16 @@ namespace Http2SampleApp
{ {
public class Startup public class Startup
{ {
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ {
app.Run(async (context) => app.Run(context =>
{ {
await context.Response.WriteAsync("Hello World!"); return context.Response.WriteAsync("Hello World! " + context.Request.Protocol);
}); });
} }
} }

View File

@ -495,4 +495,7 @@
<data name="MultipleCertificateSources" xml:space="preserve"> <data name="MultipleCertificateSources" xml:space="preserve">
<value>The endpoint {endpointName} specified multiple certificate sources.</value> <value>The endpoint {endpointName} specified multiple certificate sources.</value>
</data> </data>
<data name="Http2NotSupported" xml:space="preserve">
<value>HTTP/2 support is experimental, see https://go.microsoft.com/fwlink/?linkid=866785 to enable it.</value>
</data>
</root> </root>

View File

@ -19,13 +19,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
/// </summary> /// </summary>
public class ListenOptions : IEndPointInformation, IConnectionBuilder public class ListenOptions : IEndPointInformation, IConnectionBuilder
{ {
internal const string Http2ExperimentSwitch = "Switch.Microsoft.AspNetCore.Server.Kestrel.Experimental.Http2";
private FileHandleType _handleType; private FileHandleType _handleType;
private HttpProtocols _protocols = HttpProtocols.Http1;
internal bool _isHttp2Supported;
private readonly List<Func<ConnectionDelegate, ConnectionDelegate>> _components = new List<Func<ConnectionDelegate, ConnectionDelegate>>(); private readonly List<Func<ConnectionDelegate, ConnectionDelegate>> _components = new List<Func<ConnectionDelegate, ConnectionDelegate>>();
internal ListenOptions(IPEndPoint endPoint) internal ListenOptions(IPEndPoint endPoint)
{ {
Type = ListenType.IPEndPoint; Type = ListenType.IPEndPoint;
IPEndPoint = endPoint; IPEndPoint = endPoint;
AppContext.TryGetSwitch(Http2ExperimentSwitch, out _isHttp2Supported);
} }
internal ListenOptions(string socketPath) internal ListenOptions(string socketPath)
@ -122,8 +127,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
/// <summary> /// <summary>
/// The protocols enabled on this endpoint. /// The protocols enabled on this endpoint.
/// </summary> /// </summary>
/// <remarks>Defaults to HTTP/1.x only.</remarks> /// <remarks>Defaults to HTTP/1.x only. HTTP/2 support is experimental, see
public HttpProtocols Protocols { get; set; } = HttpProtocols.Http1; /// https://go.microsoft.com/fwlink/?linkid=866785 to enable it.</remarks>
public HttpProtocols Protocols
{
get => _protocols;
set
{
if (!_isHttp2Supported && (value == HttpProtocols.Http1AndHttp2 || value == HttpProtocols.Http2))
{
throw new NotSupportedException(CoreStrings.Http2NotSupported);
}
_protocols = value;
}
}
/// <summary> /// <summary>
/// Gets the <see cref="List{IConnectionAdapter}"/> that allows each connection <see cref="System.IO.Stream"/> /// Gets the <see cref="List{IConnectionAdapter}"/> that allows each connection <see cref="System.IO.Stream"/>

View File

@ -1774,6 +1774,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
internal static string FormatMultipleCertificateSources(object endpointName) internal static string FormatMultipleCertificateSources(object endpointName)
=> string.Format(CultureInfo.CurrentCulture, GetString("MultipleCertificateSources", "endpointName"), endpointName); => string.Format(CultureInfo.CurrentCulture, GetString("MultipleCertificateSources", "endpointName"), endpointName);
/// <summary>
/// HTTP/2 support is experimental, see https://go.microsoft.com/fwlink/?linkid=866785 to enable it.
/// </summary>
internal static string Http2NotSupported
{
get => GetString("Http2NotSupported");
}
/// <summary>
/// HTTP/2 support is experimental, see https://go.microsoft.com/fwlink/?linkid=866785 to enable it.
/// </summary>
internal static string FormatHttp2NotSupported()
=> GetString("Http2NotSupported");
private static string GetString(string name, params string[] formatterNames) private static string GetString(string name, params string[] formatterNames)
{ {
var value = _resourceManager.GetString(name); var value = _resourceManager.GetString(name);

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Net; using System.Net;
using Xunit; using Xunit;
@ -14,5 +15,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
Assert.Equal(HttpProtocols.Http1, listenOptions.Protocols); Assert.Equal(HttpProtocols.Http1, listenOptions.Protocols);
} }
[Fact]
public void Http2DisabledByDefault()
{
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
var ex = Assert.Throws<NotSupportedException>(() => listenOptions.Protocols = HttpProtocols.Http1AndHttp2);
Assert.Equal(CoreStrings.Http2NotSupported, ex.Message);
ex = Assert.Throws<NotSupportedException>(() => listenOptions.Protocols = HttpProtocols.Http2);
Assert.Equal(CoreStrings.Http2NotSupported, ex.Message);
}
} }
} }

View File

@ -48,7 +48,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var builder = TransportSelector.GetWebHostBuilder() var builder = TransportSelector.GetWebHostBuilder()
.UseKestrel(options => .UseKestrel(options =>
{ {
options.Listen(IPAddress.Loopback, 0, listenOptions => listenOptions.Protocols = serverProtocols); options.Listen(IPAddress.Loopback, 0, listenOptions =>
{
listenOptions._isHttp2Supported = true;
listenOptions.Protocols = serverProtocols;
});
}) })
.Configure(app => app.Run(context => Task.CompletedTask)); .Configure(app => app.Run(context => Task.CompletedTask));
@ -75,7 +79,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
var builder = TransportSelector.GetWebHostBuilder() var builder = TransportSelector.GetWebHostBuilder()
.ConfigureLogging(loggingBuilder => loggingBuilder.AddProvider(loggerProvider.Object)) .ConfigureLogging(loggingBuilder => loggingBuilder.AddProvider(loggerProvider.Object))
.UseKestrel(options => options.Listen(IPAddress.Loopback, 0, listenOptions => listenOptions.Protocols = serverProtocols)) .UseKestrel(options => options.Listen(IPAddress.Loopback, 0, listenOptions =>
{
listenOptions._isHttp2Supported = true;
listenOptions.Protocols = serverProtocols;
}))
.Configure(app => app.Run(context => Task.CompletedTask)); .Configure(app => app.Run(context => Task.CompletedTask));
using (var host = builder.Build()) using (var host = builder.Build())