From ad2149f5f0453ac4a209882afb56fb766ee58d42 Mon Sep 17 00:00:00 2001 From: "Chris Ross (ASP.NET)" Date: Fri, 29 Dec 2017 12:33:34 -0800 Subject: [PATCH] Change ApplicationProtocol to ReadOnlyMemory #2182 --- samples/Http2SampleApp/Http2SampleApp.csproj | 4 +++- samples/Http2SampleApp/testCert.pfx | Bin 0 -> 2483 bytes .../Features/ITlsApplicationProtocolFeature.cs | 5 +++-- src/Kestrel.Core/Internal/HttpConnection.cs | 9 ++++++--- .../Internal/HttpsConnectionAdapter.cs | 15 +-------------- .../Internal/TlsConnectionFeature.cs | 2 +- src/Kestrel.Core/Kestrel.Core.csproj | 2 +- 7 files changed, 15 insertions(+), 22 deletions(-) create mode 100644 samples/Http2SampleApp/testCert.pfx diff --git a/samples/Http2SampleApp/Http2SampleApp.csproj b/samples/Http2SampleApp/Http2SampleApp.csproj index 683e6e4041..cd660a6c80 100644 --- a/samples/Http2SampleApp/Http2SampleApp.csproj +++ b/samples/Http2SampleApp/Http2SampleApp.csproj @@ -15,7 +15,9 @@ - + + PreserveNewest + diff --git a/samples/Http2SampleApp/testCert.pfx b/samples/Http2SampleApp/testCert.pfx new file mode 100644 index 0000000000000000000000000000000000000000..7118908c2d730670c16e9f8b2c532a262c951989 GIT binary patch literal 2483 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 literal 0 HcmV?d00001 diff --git a/src/Kestrel.Core/Features/ITlsApplicationProtocolFeature.cs b/src/Kestrel.Core/Features/ITlsApplicationProtocolFeature.cs index 7ad37730d5..8adca3f0e8 100644 --- a/src/Kestrel.Core/Features/ITlsApplicationProtocolFeature.cs +++ b/src/Kestrel.Core/Features/ITlsApplicationProtocolFeature.cs @@ -1,11 +1,12 @@ // 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 { - string ApplicationProtocol { get; } + ReadOnlyMemory ApplicationProtocol { get; } } } diff --git a/src/Kestrel.Core/Internal/HttpConnection.cs b/src/Kestrel.Core/Internal/HttpConnection.cs index 1ac4945ae4..2288e99413 100644 --- a/src/Kestrel.Core/Internal/HttpConnection.cs +++ b/src/Kestrel.Core/Internal/HttpConnection.cs @@ -23,6 +23,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal { public class HttpConnection : ITimeoutControl, IConnectionTimeoutFeature, IRequestProcessor { + private static readonly ReadOnlyMemory Http2Id = new[] { (byte)'h', (byte)'2' }; + private readonly HttpConnectionContext _context; private readonly TaskCompletionSource _socketClosedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); @@ -303,7 +305,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal private HttpProtocols SelectProtocol() { var hasTls = _context.ConnectionFeatures.Get() != null; - var applicationProtocol = _context.ConnectionFeatures.Get()?.ApplicationProtocol; + var applicationProtocol = _context.ConnectionFeatures.Get()?.ApplicationProtocol + ?? new ReadOnlyMemory(); var http1Enabled = (_context.Protocols & HttpProtocols.Http1) == HttpProtocols.Http1; var http2Enabled = (_context.Protocols & HttpProtocols.Http2) == HttpProtocols.Http2; @@ -319,7 +322,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal error = CoreStrings.EndPointRequiresTlsForHttp1AndHttp2; } - if (!http1Enabled && http2Enabled && hasTls && applicationProtocol != "h2") + if (!http1Enabled && http2Enabled && hasTls && !Http2Id.Span.SequenceEqual(applicationProtocol.Span)) { error = CoreStrings.EndPointHttp2NotNegotiated; } @@ -330,7 +333,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal return HttpProtocols.None; } - return http2Enabled && (!hasTls || applicationProtocol == "h2") ? HttpProtocols.Http2 : HttpProtocols.Http1; + return http2Enabled && (!hasTls || Http2Id.Span.SequenceEqual(applicationProtocol.Span)) ? 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 cae7d60b2f..5022462886 100644 --- a/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs +++ b/src/Kestrel.Core/Internal/HttpsConnectionAdapter.cs @@ -160,20 +160,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal } #if NETCOREAPP2_1 - // 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(); - } - + feature.ApplicationProtocol = sslStream.NegotiatedApplicationProtocol.Protocol; 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 d5d7983d8e..a914024131 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 string ApplicationProtocol { get; set; } + public ReadOnlyMemory 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 2f6ea2a3bb..59b66b7373 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 + netstandard2.0;netcoreapp2.1 true aspnetcore;kestrel true