diff --git a/samples/Http2SampleApp/Http2SampleApp.csproj b/samples/Http2SampleApp/Http2SampleApp.csproj index cd660a6c80..683e6e4041 100644 --- a/samples/Http2SampleApp/Http2SampleApp.csproj +++ b/samples/Http2SampleApp/Http2SampleApp.csproj @@ -15,9 +15,7 @@ - - PreserveNewest - + diff --git a/samples/Http2SampleApp/testCert.pfx b/samples/Http2SampleApp/testCert.pfx deleted file mode 100644 index 7118908c2d..0000000000 Binary files a/samples/Http2SampleApp/testCert.pfx and /dev/null differ diff --git a/src/Kestrel.Core/Features/ITlsApplicationProtocolFeature.cs b/src/Kestrel.Core/Features/ITlsApplicationProtocolFeature.cs index 8adca3f0e8..7ad37730d5 100644 --- a/src/Kestrel.Core/Features/ITlsApplicationProtocolFeature.cs +++ b/src/Kestrel.Core/Features/ITlsApplicationProtocolFeature.cs @@ -1,12 +1,11 @@ // 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; - namespace Microsoft.AspNetCore.Server.Kestrel.Core.Features { + // TODO: this should be merged with ITlsConnectionFeature public interface ITlsApplicationProtocolFeature { - ReadOnlyMemory ApplicationProtocol { get; } + string ApplicationProtocol { get; } } } diff --git a/src/Kestrel.Core/Internal/HttpConnection.cs b/src/Kestrel.Core/Internal/HttpConnection.cs index fcd2c314a8..1ac4945ae4 100644 --- a/src/Kestrel.Core/Internal/HttpConnection.cs +++ b/src/Kestrel.Core/Internal/HttpConnection.cs @@ -23,8 +23,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal { public class HttpConnection : ITimeoutControl, IConnectionTimeoutFeature, IRequestProcessor { - private static readonly ReadOnlyMemory Http2Id = new ReadOnlyMemory(new[] { (byte)'h', (byte)'2' }); - private readonly HttpConnectionContext _context; private readonly TaskCompletionSource _socketClosedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); @@ -305,8 +303,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal private HttpProtocols SelectProtocol() { var hasTls = _context.ConnectionFeatures.Get() != null; - var applicationProtocol = _context.ConnectionFeatures.Get()?.ApplicationProtocol - ?? new ReadOnlyMemory(); + var applicationProtocol = _context.ConnectionFeatures.Get()?.ApplicationProtocol; var http1Enabled = (_context.Protocols & HttpProtocols.Http1) == HttpProtocols.Http1; var http2Enabled = (_context.Protocols & HttpProtocols.Http2) == HttpProtocols.Http2; @@ -322,7 +319,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal error = CoreStrings.EndPointRequiresTlsForHttp1AndHttp2; } - if (!http1Enabled && http2Enabled && hasTls && !Http2Id.SequenceEqual(applicationProtocol)) + if (!http1Enabled && http2Enabled && hasTls && applicationProtocol != "h2") { error = CoreStrings.EndPointHttp2NotNegotiated; } @@ -333,7 +330,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal return HttpProtocols.None; } - return http2Enabled && (!hasTls || Http2Id.SequenceEqual(applicationProtocol)) ? HttpProtocols.Http2 : HttpProtocols.Http1; + return http2Enabled && (!hasTls || applicationProtocol == "h2") ? HttpProtocols.Http2 : HttpProtocols.Http1; } public void Tick(DateTimeOffset now) diff --git a/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs b/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs index 5022462886..cae7d60b2f 100644 --- a/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs +++ b/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs @@ -160,7 +160,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal } #if NETCOREAPP2_1 - feature.ApplicationProtocol = sslStream.NegotiatedApplicationProtocol.Protocol; + // Don't allocate in the common case, see https://github.com/dotnet/corefx/issues/25432 + if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http11) + { + feature.ApplicationProtocol = "http/1.1"; + } + else if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2) + { + feature.ApplicationProtocol = "h2"; + } + else + { + feature.ApplicationProtocol = sslStream.NegotiatedApplicationProtocol.ToString(); + } + context.Features.Set(feature); #endif feature.ClientCertificate = ConvertToX509Certificate2(sslStream.RemoteCertificate); diff --git a/src/Kestrel.Core/Internal/TlsConnectionFeature.cs b/src/Kestrel.Core/Internal/TlsConnectionFeature.cs index a914024131..d5d7983d8e 100644 --- a/src/Kestrel.Core/Internal/TlsConnectionFeature.cs +++ b/src/Kestrel.Core/Internal/TlsConnectionFeature.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal { public X509Certificate2 ClientCertificate { get; set; } - public ReadOnlyMemory ApplicationProtocol { get; set; } + public string ApplicationProtocol { get; set; } public Task GetClientCertificateAsync(CancellationToken cancellationToken) { diff --git a/src/Kestrel.Core/Kestrel.Core.csproj b/src/Kestrel.Core/Kestrel.Core.csproj index 59b66b7373..2f6ea2a3bb 100644 --- a/src/Kestrel.Core/Kestrel.Core.csproj +++ b/src/Kestrel.Core/Kestrel.Core.csproj @@ -4,7 +4,7 @@ Microsoft.AspNetCore.Server.Kestrel.Core Microsoft.AspNetCore.Server.Kestrel.Core Core components of ASP.NET Core Kestrel cross-platform web server. - netstandard2.0;netcoreapp2.1 + netstandard2.0 true aspnetcore;kestrel true