Skip to content

Update ITlsHandshakeFeature.HostName API + misc. improvements in HttpSys calls #48788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public interface ITlsHandshakeFeature
/// Gets the host name from the "server_name" (SNI) extension of the client hello if present.
/// See <see href="https://www.rfc-editor.org/rfc/rfc6066#section-3">RFC 6066</see>.
/// </summary>
string? HostName => null;
string HostName => string.Empty;
#endif

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Microsoft.AspNetCore.Connections.Features.IConnectionMetricsTagsFeature
Microsoft.AspNetCore.Connections.Features.IConnectionMetricsTagsFeature.Tags.get -> System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string!, object?>>!
Microsoft.AspNetCore.Connections.Features.IConnectionNamedPipeFeature
Microsoft.AspNetCore.Connections.Features.IConnectionNamedPipeFeature.NamedPipe.get -> System.IO.Pipes.NamedPipeServerStream!
Microsoft.AspNetCore.Connections.Features.ITlsHandshakeFeature.HostName.get -> string?
Microsoft.AspNetCore.Connections.Features.ITlsHandshakeFeature.HostName.get -> string!
Microsoft.AspNetCore.Connections.Features.ITlsHandshakeFeature.NegotiatedCipherSuite.get -> System.Net.Security.TlsCipherSuite?
Microsoft.AspNetCore.Connections.IConnectionListenerFactorySelector
Microsoft.AspNetCore.Connections.IConnectionListenerFactorySelector.CanBind(System.Net.EndPoint! endpoint) -> bool
Expand Down
9 changes: 5 additions & 4 deletions src/Servers/HttpSys/src/NativeInterop/HttpApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,10 @@ internal static unsafe partial uint HttpCreateRequestQueue(HTTPAPI_VERSION versi

[LibraryImport(HTTPAPI, SetLastError = true)]
internal static unsafe partial uint HttpDelegateRequestEx(SafeHandle pReqQueueHandle, SafeHandle pDelegateQueueHandle, ulong requestId,
ulong delegateUrlGroupId, ulong propertyInfoSetSize, HTTP_DELEGATE_REQUEST_PROPERTY_INFO* pRequestPropertyBuffer);
ulong delegateUrlGroupId, uint propertyInfoSetSize, HTTP_DELEGATE_REQUEST_PROPERTY_INFO* pRequestPropertyBuffer);

[LibraryImport(HTTPAPI, SetLastError = true)]
internal static unsafe partial uint HttpQueryRequestProperty(SafeHandle requestQueueHandle, ulong requestId, HTTP_REQUEST_PROPERTY propertyId,
void* qualifier, ulong qualifierSize, void* output, ulong outputSize, ulong* bytesReturned, IntPtr overlapped);
internal delegate uint HttpGetRequestPropertyInvoker(SafeHandle requestQueueHandle, ulong requestId, HTTP_REQUEST_PROPERTY propertyId,
void* qualifier, uint qualifierSize, void* output, uint outputSize, uint* bytesReturned, IntPtr overlapped);

internal delegate uint HttpSetRequestPropertyInvoker(SafeHandle requestQueueHandle, ulong requestId, HTTP_REQUEST_PROPERTY propertyId, void* input, uint inputSize, IntPtr overlapped);

Expand Down Expand Up @@ -123,6 +122,7 @@ internal static HTTP_API_VERSION ApiVersion
}

internal static SafeLibraryHandle? HttpApiModule { get; private set; }
internal static HttpGetRequestPropertyInvoker? HttpGetRequestProperty { get; private set; }
internal static HttpSetRequestPropertyInvoker? HttpSetRequestProperty { get; private set; }
[MemberNotNullWhen(true, nameof(HttpSetRequestProperty))]
internal static bool SupportsTrailers { get; private set; }
Expand All @@ -147,6 +147,7 @@ private static void InitHttpApi(ushort majorVersion, ushort minorVersion)
if (supported)
{
HttpApiModule = SafeLibraryHandle.Open(HTTPAPI);
HttpGetRequestProperty = HttpApiModule.GetProcAddress<HttpGetRequestPropertyInvoker>("HttpQueryRequestProperty", throwIfNotFound: false);
HttpSetRequestProperty = HttpApiModule.GetProcAddress<HttpSetRequestPropertyInvoker>("HttpSetRequestProperty", throwIfNotFound: false);
SupportsReset = HttpSetRequestProperty != null;
SupportsTrailers = IsFeatureSupported(HTTP_FEATURE_ID.HttpFeatureResponseTrailers);
Expand Down
3 changes: 2 additions & 1 deletion src/Servers/HttpSys/src/RequestProcessing/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ internal Request(RequestContext requestContext)

User = RequestContext.GetUser();

SniHostName = string.Empty;
if (IsHttps)
{
GetTlsHandshakeResults();
Expand Down Expand Up @@ -327,7 +328,7 @@ private AspNetCore.HttpSys.Internal.SocketAddress LocalEndPoint

internal WindowsPrincipal User { get; }

public string? SniHostName { get; private set; }
public string SniHostName { get; private set; }

public SslProtocols Protocol { get; private set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ bool IHttpBodyControlFeature.AllowSynchronousIO

int ITlsHandshakeFeature.KeyExchangeStrength => Request.KeyExchangeStrength;

string? ITlsHandshakeFeature.HostName => Request.SniHostName;
string ITlsHandshakeFeature.HostName => Request.SniHostName;

IReadOnlyDictionary<int, ReadOnlyMemory<byte>> IHttpSysRequestInfoFeature.RequestInfo => Request.RequestInfo;

Expand Down
10 changes: 6 additions & 4 deletions src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpSys.Internal;
using Microsoft.Extensions.Logging;
using static Microsoft.AspNetCore.HttpSys.Internal.UnsafeNclNativeMethods;

namespace Microsoft.AspNetCore.Server.HttpSys;

Expand Down Expand Up @@ -228,25 +227,28 @@ internal void ForceCancelRequest()

internal unsafe HttpApiTypes.HTTP_REQUEST_PROPERTY_SNI GetClientSni()
{
if (HttpApi.HttpGetRequestProperty != null)
{
var buffer = new byte[HttpApiTypes.SniPropertySizeInBytes];
fixed (byte* pBuffer = buffer)
{
var statusCode = HttpApi.HttpQueryRequestProperty(
var statusCode = HttpApi.HttpGetRequestProperty(
Server.RequestQueue.Handle,
RequestId,
HttpApiTypes.HTTP_REQUEST_PROPERTY.HttpRequestPropertySni,
qualifier: null,
qualifierSize: 0,
(void*)pBuffer,
(ulong)buffer.Length,
(uint)buffer.Length,
bytesReturned: null,
IntPtr.Zero);

if (statusCode == ErrorCodes.ERROR_SUCCESS)
if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
{
return Marshal.PtrToStructure<HttpApiTypes.HTTP_REQUEST_PROPERTY_SNI>((IntPtr)pBuffer);
}
}
}

return default;
}
Expand Down
1 change: 0 additions & 1 deletion src/Servers/HttpSys/test/FunctionalTests/HttpsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Data.Common;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public X509Certificate2? ClientCertificate
}
}

public string? HostName { get; set; }
public string HostName { get; set; } = string.Empty;

public ReadOnlyMemory<byte> ApplicationProtocol => _sslStream.NegotiatedApplicationProtocol.Protocol;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ private Task DoOptionsBasedHandshakeAsync(ConnectionContext context, SslStream s
{
selector = (sender, name) =>
{
feature.HostName = name;
feature.HostName = name ?? string.Empty;
var cert = _serverCertificateSelector(context, name);
if (cert != null)
{
Expand Down
5 changes: 2 additions & 3 deletions src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using Microsoft.AspNetCore.Http;
Expand Down Expand Up @@ -109,8 +108,8 @@ internal struct HTTP_REQUEST_PROPERTY_STREAM_ERROR
internal uint ErrorCode;
}

internal const int HTTP_REQUEST_PROPERTY_SNI_HOST_MAX_LENGTH = 255;
internal const int SniPropertySizeInBytes = (sizeof(ushort) * (HTTP_REQUEST_PROPERTY_SNI_HOST_MAX_LENGTH + 1)) + sizeof(ulong);
private const int HTTP_REQUEST_PROPERTY_SNI_HOST_MAX_LENGTH = 255;
internal const int SniPropertySizeInBytes = (sizeof(ushort) * (HTTP_REQUEST_PROPERTY_SNI_HOST_MAX_LENGTH + 1)) + sizeof(uint);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Size = SniPropertySizeInBytes)]
internal struct HTTP_REQUEST_PROPERTY_SNI
Expand Down