Convert TLS connection adapter to connection middleware (#11109)
This commit is contained in:
parent
0b5d4baa07
commit
689b052509
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal
|
|||
public AdaptedPipeline(IDuplexPipe transport,
|
||||
Pipe inputPipe,
|
||||
Pipe outputPipe,
|
||||
IKestrelTrace log,
|
||||
ILogger log,
|
||||
int minAllocBufferSize)
|
||||
{
|
||||
TransportStream = new RawStream(transport.Input, transport.Output, throwOnCancelled: true);
|
||||
|
|
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal
|
|||
|
||||
public Pipe Output { get; }
|
||||
|
||||
public IKestrelTrace Log { get; }
|
||||
public ILogger Log { get; }
|
||||
|
||||
PipeReader IDuplexPipe.Input => Input.Reader;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO.Pipelines;
|
||||
using System.Net.Security;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
|
@ -96,5 +97,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https
|
|||
_handshakeTimeout = value != Timeout.InfiniteTimeSpan ? value : TimeSpan.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
internal PipeScheduler Scheduler { get; set; } = PipeScheduler.ThreadPool;
|
||||
|
||||
internal long? MaxInputBufferSize { get; set; }
|
||||
|
||||
internal long? MaxOutputBufferSize { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,64 +215,90 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
|
||||
private void StopProcessingNextRequest()
|
||||
{
|
||||
ProtocolSelectionState previousState;
|
||||
lock (_protocolSelectionLock)
|
||||
{
|
||||
previousState = _protocolSelectionState;
|
||||
|
||||
switch (_protocolSelectionState)
|
||||
{
|
||||
case ProtocolSelectionState.Initializing:
|
||||
CloseUninitializedConnection(new ConnectionAbortedException(CoreStrings.ServerShutdownDuringConnectionInitialization));
|
||||
_protocolSelectionState = ProtocolSelectionState.Aborted;
|
||||
break;
|
||||
case ProtocolSelectionState.Selected:
|
||||
_requestProcessor.StopProcessingNextRequest();
|
||||
break;
|
||||
case ProtocolSelectionState.Aborted:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (previousState)
|
||||
{
|
||||
case ProtocolSelectionState.Initializing:
|
||||
CloseUninitializedConnection(new ConnectionAbortedException(CoreStrings.ServerShutdownDuringConnectionInitialization));
|
||||
break;
|
||||
case ProtocolSelectionState.Selected:
|
||||
_requestProcessor.StopProcessingNextRequest();
|
||||
break;
|
||||
case ProtocolSelectionState.Aborted:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInputOrOutputCompleted()
|
||||
{
|
||||
ProtocolSelectionState previousState;
|
||||
lock (_protocolSelectionLock)
|
||||
{
|
||||
previousState = _protocolSelectionState;
|
||||
|
||||
switch (_protocolSelectionState)
|
||||
{
|
||||
case ProtocolSelectionState.Initializing:
|
||||
// OnReader/WriterCompleted callbacks are not wired until after leaving the Initializing state.
|
||||
Debug.Assert(false);
|
||||
|
||||
CloseUninitializedConnection(new ConnectionAbortedException("HttpConnection.OnInputOrOutputCompleted() called while in the ProtocolSelectionState.Initializing state!?"));
|
||||
_protocolSelectionState = ProtocolSelectionState.Aborted;
|
||||
break;
|
||||
case ProtocolSelectionState.Selected:
|
||||
_requestProcessor.OnInputOrOutputCompleted();
|
||||
break;
|
||||
case ProtocolSelectionState.Aborted:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (previousState)
|
||||
{
|
||||
case ProtocolSelectionState.Initializing:
|
||||
// ConnectionClosed callback is not wired up until after leaving the Initializing state.
|
||||
Debug.Assert(false);
|
||||
|
||||
CloseUninitializedConnection(new ConnectionAbortedException("HttpConnection.OnInputOrOutputCompleted() called while in the ProtocolSelectionState.Initializing state!?"));
|
||||
break;
|
||||
case ProtocolSelectionState.Selected:
|
||||
_requestProcessor.OnInputOrOutputCompleted();
|
||||
break;
|
||||
case ProtocolSelectionState.Aborted:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Abort(ConnectionAbortedException ex)
|
||||
{
|
||||
ProtocolSelectionState previousState;
|
||||
|
||||
lock (_protocolSelectionLock)
|
||||
{
|
||||
switch (_protocolSelectionState)
|
||||
{
|
||||
case ProtocolSelectionState.Initializing:
|
||||
CloseUninitializedConnection(ex);
|
||||
break;
|
||||
case ProtocolSelectionState.Selected:
|
||||
_requestProcessor.Abort(ex);
|
||||
break;
|
||||
case ProtocolSelectionState.Aborted:
|
||||
break;
|
||||
}
|
||||
|
||||
previousState = _protocolSelectionState;
|
||||
_protocolSelectionState = ProtocolSelectionState.Aborted;
|
||||
}
|
||||
|
||||
switch (previousState)
|
||||
{
|
||||
case ProtocolSelectionState.Initializing:
|
||||
CloseUninitializedConnection(ex);
|
||||
break;
|
||||
case ProtocolSelectionState.Selected:
|
||||
_requestProcessor.Abort(ex);
|
||||
break;
|
||||
case ProtocolSelectionState.Aborted:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Stream> ApplyConnectionAdaptersAsync(RawStream stream)
|
||||
|
|
@ -365,6 +391,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
private void CloseUninitializedConnection(ConnectionAbortedException abortReason)
|
||||
{
|
||||
_context.ConnectionContext.Abort(abortReason);
|
||||
|
||||
if (_context.ConnectionAdapters.Count > 0)
|
||||
{
|
||||
_adaptedTransport.Input.Complete();
|
||||
_adaptedTransport.Output.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTimeout(TimeoutReason reason)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication;
|
||||
|
|
@ -16,27 +17,27 @@ using Microsoft.AspNetCore.Http.Features;
|
|||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
||||
{
|
||||
internal class HttpsConnectionAdapter : IConnectionAdapter
|
||||
internal class HttpsConnectionMiddleware
|
||||
{
|
||||
private static readonly ClosedAdaptedConnection _closedAdaptedConnection = new ClosedAdaptedConnection();
|
||||
private readonly ConnectionDelegate _next;
|
||||
|
||||
private readonly HttpsConnectionAdapterOptions _options;
|
||||
private readonly ILogger _logger;
|
||||
private readonly X509Certificate2 _serverCertificate;
|
||||
private readonly Func<ConnectionContext, string, X509Certificate2> _serverCertificateSelector;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public HttpsConnectionAdapter(HttpsConnectionAdapterOptions options)
|
||||
: this(options, loggerFactory: null)
|
||||
public HttpsConnectionMiddleware(ConnectionDelegate next, HttpsConnectionAdapterOptions options)
|
||||
: this(next, options, loggerFactory: NullLoggerFactory.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
public HttpsConnectionAdapter(HttpsConnectionAdapterOptions options, ILoggerFactory loggerFactory)
|
||||
public HttpsConnectionMiddleware(ConnectionDelegate next, HttpsConnectionAdapterOptions options, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
|
|
@ -49,6 +50,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
|||
throw new NotSupportedException(CoreStrings.HTTP2NoTlsOsx);
|
||||
}
|
||||
|
||||
_next = next;
|
||||
// capture the certificate now so it can't be switched after validation
|
||||
_serverCertificate = options.ServerCertificate;
|
||||
_serverCertificateSelector = options.ServerCertificateSelector;
|
||||
|
|
@ -69,18 +71,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
|||
}
|
||||
|
||||
_options = options;
|
||||
_logger = loggerFactory?.CreateLogger<HttpsConnectionAdapter>() ?? (ILogger)NullLogger.Instance;
|
||||
_logger = loggerFactory?.CreateLogger<HttpsConnectionMiddleware>();
|
||||
}
|
||||
|
||||
public bool IsHttps => true;
|
||||
|
||||
public Task<IAdaptedConnection> OnConnectionAsync(ConnectionAdapterContext context)
|
||||
public Task OnConnectionAsync(ConnectionContext context)
|
||||
{
|
||||
// Don't trust SslStream not to block.
|
||||
return Task.Run(() => InnerOnConnectionAsync(context));
|
||||
}
|
||||
|
||||
private async Task<IAdaptedConnection> InnerOnConnectionAsync(ConnectionAdapterContext context)
|
||||
private async Task InnerOnConnectionAsync(ConnectionContext context)
|
||||
{
|
||||
SslStream sslStream;
|
||||
bool certificateRequired;
|
||||
|
|
@ -88,14 +86,43 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
|||
context.Features.Set<ITlsConnectionFeature>(feature);
|
||||
context.Features.Set<ITlsHandshakeFeature>(feature);
|
||||
|
||||
// TODO: Handle the cases where this can be null
|
||||
var memoryPoolFeature = context.Features.Get<IMemoryPoolFeature>();
|
||||
|
||||
var inputPipeOptions = new PipeOptions
|
||||
(
|
||||
pool: memoryPoolFeature.MemoryPool,
|
||||
readerScheduler: _options.Scheduler,
|
||||
writerScheduler: PipeScheduler.Inline,
|
||||
pauseWriterThreshold: _options.MaxInputBufferSize ?? 0,
|
||||
resumeWriterThreshold: _options.MaxInputBufferSize / 2 ?? 0,
|
||||
useSynchronizationContext: false,
|
||||
minimumSegmentSize: memoryPoolFeature.MemoryPool.GetMinimumSegmentSize()
|
||||
);
|
||||
|
||||
var outputPipeOptions = new PipeOptions
|
||||
(
|
||||
pool: memoryPoolFeature.MemoryPool,
|
||||
readerScheduler: PipeScheduler.Inline,
|
||||
writerScheduler: PipeScheduler.Inline,
|
||||
pauseWriterThreshold: _options.MaxOutputBufferSize ?? 0,
|
||||
resumeWriterThreshold: _options.MaxOutputBufferSize / 2 ?? 0,
|
||||
useSynchronizationContext: false,
|
||||
minimumSegmentSize: memoryPoolFeature.MemoryPool.GetMinimumSegmentSize()
|
||||
);
|
||||
|
||||
// TODO: eventually make SslDuplexStream : Stream, IDuplexPipe to avoid RawStream allocation and pipe allocations
|
||||
var adaptedPipeline = new AdaptedPipeline(context.Transport, new Pipe(inputPipeOptions), new Pipe(outputPipeOptions), _logger, memoryPoolFeature.MemoryPool.GetMinimumAllocSize());
|
||||
var transportStream = adaptedPipeline.TransportStream;
|
||||
|
||||
if (_options.ClientCertificateMode == ClientCertificateMode.NoCertificate)
|
||||
{
|
||||
sslStream = new SslStream(context.ConnectionStream);
|
||||
sslStream = new SslStream(transportStream);
|
||||
certificateRequired = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sslStream = new SslStream(context.ConnectionStream,
|
||||
sslStream = new SslStream(transportStream,
|
||||
leaveInnerStreamOpen: false,
|
||||
userCertificateValidationCallback: (sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
|
|
@ -132,69 +159,66 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
|||
certificateRequired = true;
|
||||
}
|
||||
|
||||
var timeoutFeature = context.Features.Get<IConnectionTimeoutFeature>();
|
||||
timeoutFeature.SetTimeout(_options.HandshakeTimeout);
|
||||
|
||||
try
|
||||
using (var cancellationTokeSource = new CancellationTokenSource(_options.HandshakeTimeout))
|
||||
using (cancellationTokeSource.Token.UnsafeRegister(state => ((ConnectionContext)state).Abort(), context))
|
||||
{
|
||||
// Adapt to the SslStream signature
|
||||
ServerCertificateSelectionCallback selector = null;
|
||||
if (_serverCertificateSelector != null)
|
||||
try
|
||||
{
|
||||
selector = (sender, name) =>
|
||||
// Adapt to the SslStream signature
|
||||
ServerCertificateSelectionCallback selector = null;
|
||||
if (_serverCertificateSelector != null)
|
||||
{
|
||||
context.Features.Set(sslStream);
|
||||
var cert = _serverCertificateSelector(context.ConnectionContext, name);
|
||||
if (cert != null)
|
||||
selector = (sender, name) =>
|
||||
{
|
||||
EnsureCertificateIsAllowedForServerAuth(cert);
|
||||
}
|
||||
return cert;
|
||||
context.Features.Set(sslStream);
|
||||
var cert = _serverCertificateSelector(context, name);
|
||||
if (cert != null)
|
||||
{
|
||||
EnsureCertificateIsAllowedForServerAuth(cert);
|
||||
}
|
||||
return cert;
|
||||
};
|
||||
}
|
||||
|
||||
var sslOptions = new SslServerAuthenticationOptions
|
||||
{
|
||||
ServerCertificate = _serverCertificate,
|
||||
ServerCertificateSelectionCallback = selector,
|
||||
ClientCertificateRequired = certificateRequired,
|
||||
EnabledSslProtocols = _options.SslProtocols,
|
||||
CertificateRevocationCheckMode = _options.CheckCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
|
||||
ApplicationProtocols = new List<SslApplicationProtocol>()
|
||||
};
|
||||
|
||||
// This is order sensitive
|
||||
if ((_options.HttpProtocols & HttpProtocols.Http2) != 0)
|
||||
{
|
||||
sslOptions.ApplicationProtocols.Add(SslApplicationProtocol.Http2);
|
||||
// https://tools.ietf.org/html/rfc7540#section-9.2.1
|
||||
sslOptions.AllowRenegotiation = false;
|
||||
}
|
||||
|
||||
if ((_options.HttpProtocols & HttpProtocols.Http1) != 0)
|
||||
{
|
||||
sslOptions.ApplicationProtocols.Add(SslApplicationProtocol.Http11);
|
||||
}
|
||||
|
||||
_options.OnAuthenticate?.Invoke(context, sslOptions);
|
||||
|
||||
await sslStream.AuthenticateAsServerAsync(sslOptions, CancellationToken.None);
|
||||
}
|
||||
|
||||
var sslOptions = new SslServerAuthenticationOptions
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
ServerCertificate = _serverCertificate,
|
||||
ServerCertificateSelectionCallback = selector,
|
||||
ClientCertificateRequired = certificateRequired,
|
||||
EnabledSslProtocols = _options.SslProtocols,
|
||||
CertificateRevocationCheckMode = _options.CheckCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
|
||||
ApplicationProtocols = new List<SslApplicationProtocol>()
|
||||
};
|
||||
|
||||
// This is order sensitive
|
||||
if ((_options.HttpProtocols & HttpProtocols.Http2) != 0)
|
||||
{
|
||||
sslOptions.ApplicationProtocols.Add(SslApplicationProtocol.Http2);
|
||||
// https://tools.ietf.org/html/rfc7540#section-9.2.1
|
||||
sslOptions.AllowRenegotiation = false;
|
||||
_logger?.LogDebug(2, CoreStrings.AuthenticationTimedOut);
|
||||
sslStream.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((_options.HttpProtocols & HttpProtocols.Http1) != 0)
|
||||
catch (Exception ex) when (ex is IOException || ex is AuthenticationException)
|
||||
{
|
||||
sslOptions.ApplicationProtocols.Add(SslApplicationProtocol.Http11);
|
||||
_logger?.LogDebug(1, ex, CoreStrings.AuthenticationFailed);
|
||||
sslStream.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
_options.OnAuthenticate?.Invoke(context.ConnectionContext, sslOptions);
|
||||
|
||||
await sslStream.AuthenticateAsServerAsync(sslOptions, CancellationToken.None);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
_logger.LogDebug(2, CoreStrings.AuthenticationTimedOut);
|
||||
sslStream.Dispose();
|
||||
return _closedAdaptedConnection;
|
||||
}
|
||||
catch (Exception ex) when (ex is IOException || ex is AuthenticationException)
|
||||
{
|
||||
_logger.LogDebug(1, ex, CoreStrings.AuthenticationFailed);
|
||||
sslStream.Dispose();
|
||||
return _closedAdaptedConnection;
|
||||
}
|
||||
finally
|
||||
{
|
||||
timeoutFeature.CancelTimeout();
|
||||
}
|
||||
|
||||
feature.ApplicationProtocol = sslStream.NegotiatedApplicationProtocol.Protocol;
|
||||
|
|
@ -208,7 +232,31 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
|||
feature.KeyExchangeStrength = sslStream.KeyExchangeStrength;
|
||||
feature.Protocol = sslStream.SslProtocol;
|
||||
|
||||
return new HttpsAdaptedConnection(sslStream);
|
||||
var original = context.Transport;
|
||||
|
||||
try
|
||||
{
|
||||
context.Transport = adaptedPipeline;
|
||||
|
||||
using (sslStream)
|
||||
{
|
||||
try
|
||||
{
|
||||
adaptedPipeline.RunAsync(sslStream);
|
||||
|
||||
await _next(context);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await adaptedPipeline.CompleteAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Restore the original so that it gets closed appropriately
|
||||
context.Transport = original;
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureCertificateIsAllowedForServerAuth(X509Certificate2 certificate)
|
||||
|
|
@ -233,31 +281,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
|||
|
||||
return new X509Certificate2(certificate);
|
||||
}
|
||||
|
||||
private class HttpsAdaptedConnection : IAdaptedConnection
|
||||
{
|
||||
private readonly SslStream _sslStream;
|
||||
|
||||
public HttpsAdaptedConnection(SslStream sslStream)
|
||||
{
|
||||
_sslStream = sslStream;
|
||||
}
|
||||
|
||||
public Stream ConnectionStream => _sslStream;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_sslStream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private class ClosedAdaptedConnection : IAdaptedConnection
|
||||
{
|
||||
public Stream ConnectionStream { get; } = new ClosedStream();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
|||
}
|
||||
|
||||
// EndpointDefaults or configureEndpoint may have added an https adapter.
|
||||
if (https && !listenOptions.ConnectionAdapters.Any(f => f.IsHttps))
|
||||
if (https && !listenOptions.IsTls)
|
||||
{
|
||||
if (httpsOptions.ServerCertificate == null && httpsOptions.ServerCertificateSelector == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Pipelines;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
|
|
|
|||
|
|
@ -89,23 +89,35 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
|
||||
public IServiceProvider ApplicationServices => KestrelServerOptions?.ApplicationServices;
|
||||
|
||||
internal string Scheme
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsHttp)
|
||||
{
|
||||
return IsTls ? "https" : "http";
|
||||
}
|
||||
return "tcp";
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsHttp { get; set; } = true;
|
||||
|
||||
internal bool IsTls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of this endpoint to display on command-line when the web server starts.
|
||||
/// </summary>
|
||||
internal virtual string GetDisplayName()
|
||||
{
|
||||
var scheme = ConnectionAdapters.Any(f => f.IsHttps)
|
||||
? "https"
|
||||
: "http";
|
||||
|
||||
switch (EndPoint)
|
||||
{
|
||||
case IPEndPoint _:
|
||||
return $"{scheme}://{IPEndPoint}";
|
||||
return $"{Scheme}://{IPEndPoint}";
|
||||
case UnixDomainSocketEndPoint _:
|
||||
return $"{scheme}://unix:{EndPoint}";
|
||||
return $"{Scheme}://unix:{EndPoint}";
|
||||
case FileHandleEndPoint _:
|
||||
return $"{scheme}://<file handle>";
|
||||
return $"{Scheme}://<file handle>";
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Https.Internal;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
|
|
@ -185,6 +186,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
{
|
||||
throw new InvalidOperationException(CoreStrings.NoCertSpecifiedNoDevelopmentCertificateFound);
|
||||
}
|
||||
|
||||
return listenOptions.UseHttps(options);
|
||||
}
|
||||
|
||||
|
|
@ -199,6 +201,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
listenOptions.UseHttps(options);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -211,10 +214,20 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
/// <returns>The <see cref="ListenOptions"/>.</returns>
|
||||
public static ListenOptions UseHttps(this ListenOptions listenOptions, HttpsConnectionAdapterOptions httpsOptions)
|
||||
{
|
||||
var loggerFactory = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService<ILoggerFactory>();
|
||||
var loggerFactory = listenOptions.KestrelServerOptions?.ApplicationServices.GetRequiredService<ILoggerFactory>() ?? NullLoggerFactory.Instance;
|
||||
|
||||
// Set the list of protocols from listen options
|
||||
httpsOptions.HttpProtocols = listenOptions.Protocols;
|
||||
listenOptions.ConnectionAdapters.Add(new HttpsConnectionAdapter(httpsOptions, loggerFactory));
|
||||
httpsOptions.MaxInputBufferSize = listenOptions.KestrelServerOptions?.Limits.MaxRequestBufferSize;
|
||||
httpsOptions.MaxOutputBufferSize = listenOptions.KestrelServerOptions?.Limits.MaxResponseBufferSize;
|
||||
|
||||
listenOptions.IsTls = true;
|
||||
|
||||
listenOptions.Use(next =>
|
||||
{
|
||||
var middleware = new HttpsConnectionMiddleware(next, httpsOptions, loggerFactory);
|
||||
return middleware.OnConnectionAsync;
|
||||
});
|
||||
return listenOptions;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
/// </summary>
|
||||
internal override string GetDisplayName()
|
||||
{
|
||||
var scheme = ConnectionAdapters.Any(f => f.IsHttps)
|
||||
? "https"
|
||||
: "http";
|
||||
|
||||
return $"{scheme}://localhost:{IPEndPoint.Port}";
|
||||
return $"{Scheme}://localhost:{IPEndPoint.Port}";
|
||||
}
|
||||
|
||||
internal override async Task BindAsync(AddressBindContext context)
|
||||
|
|
@ -78,6 +74,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
{
|
||||
KestrelServerOptions = KestrelServerOptions,
|
||||
Protocols = Protocols,
|
||||
IsTls = IsTls
|
||||
};
|
||||
|
||||
options._middleware.AddRange(_middleware);
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
StartDummyApplication(server);
|
||||
|
||||
Assert.True(server.Options.ListenOptions.Any());
|
||||
Assert.Contains(server.Options.ListenOptions[0].ConnectionAdapters, adapter => adapter.IsHttps);
|
||||
Assert.True(server.Options.ListenOptions[0].IsTls);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,8 +168,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests
|
|||
Assert.True(ran1);
|
||||
Assert.True(ran2);
|
||||
|
||||
Assert.NotNull(serverOptions.ListenOptions[0].ConnectionAdapters.Where(adapter => adapter.IsHttps).SingleOrDefault());
|
||||
Assert.Null(serverOptions.ListenOptions[1].ConnectionAdapters.Where(adapter => adapter.IsHttps).SingleOrDefault());
|
||||
Assert.True(serverOptions.ListenOptions[0].IsTls);
|
||||
Assert.False(serverOptions.ListenOptions[1].IsTls);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -210,8 +210,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests
|
|||
Assert.True(ran2);
|
||||
|
||||
// You only get Https once per endpoint.
|
||||
Assert.NotNull(serverOptions.ListenOptions[0].ConnectionAdapters.Where(adapter => adapter.IsHttps).SingleOrDefault());
|
||||
Assert.NotNull(serverOptions.ListenOptions[1].ConnectionAdapters.Where(adapter => adapter.IsHttps).SingleOrDefault());
|
||||
Assert.True(serverOptions.ListenOptions[0].IsTls);
|
||||
Assert.True(serverOptions.ListenOptions[1].IsTls);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -42,12 +42,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
}
|
||||
|
||||
public TestServer(RequestDelegate app, TestServiceContext context, ListenOptions listenOptions)
|
||||
: this(app, context, listenOptions, _ => { })
|
||||
: this(app, context, options => options.ListenOptions.Add(listenOptions), _ => { })
|
||||
{
|
||||
}
|
||||
|
||||
public TestServer(RequestDelegate app, TestServiceContext context, ListenOptions listenOptions, Action<IServiceCollection> configureServices)
|
||||
: this(app, context, options => options.ListenOptions.Add(listenOptions), configureServices)
|
||||
public TestServer(RequestDelegate app, TestServiceContext context, Action<ListenOptions> configureListenOptions)
|
||||
: this(app, context, options =>
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
{
|
||||
KestrelServerOptions = options
|
||||
};
|
||||
configureListenOptions(listenOptions);
|
||||
options.ListenOptions.Add(listenOptions);
|
||||
}, _ => { })
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
|
|||
var ex = Assert.Throws<NotSupportedException>(() => new TestServer(context =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}, new TestServiceContext(LoggerFactory),
|
||||
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
kestrelOptions =>
|
||||
{
|
||||
kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions =>
|
||||
|
|
@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
|
|||
"ALPN: " + tlsFeature.ApplicationProtocol.Length);
|
||||
|
||||
return context.Response.WriteAsync("hello world " + context.Request.Protocol);
|
||||
}, new TestServiceContext(LoggerFactory),
|
||||
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
kestrelOptions =>
|
||||
{
|
||||
kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions =>
|
||||
|
|
@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
|
|||
"ALPN: " + tlsFeature.ApplicationProtocol.Length);
|
||||
|
||||
return context.Response.WriteAsync("hello world " + context.Request.Protocol);
|
||||
}, new TestServiceContext(LoggerFactory),
|
||||
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
kestrelOptions =>
|
||||
{
|
||||
kestrelOptions.Listen(IPAddress.Loopback, 0, listenOptions =>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
|
|||
.Setup(m => m.Http2ConnectionClosing(It.IsAny<string>()))
|
||||
.Callback(() => requestStopping.SetResult(null));
|
||||
|
||||
var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object);
|
||||
var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object) { ExpectedConnectionMiddlewareCount = 1 };
|
||||
|
||||
testContext.InitializeHeartbeat();
|
||||
|
||||
|
|
@ -111,7 +111,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2
|
|||
|
||||
var testContext = new TestServiceContext(LoggerFactory)
|
||||
{
|
||||
MemoryPoolFactory = memoryPoolFactory.Create
|
||||
MemoryPoolFactory = memoryPoolFactory.Create,
|
||||
ExpectedConnectionMiddlewareCount = 1
|
||||
};
|
||||
|
||||
TestApplicationErrorLogger.ThrowOnUngracefulShutdown = false;
|
||||
|
|
|
|||
|
|
@ -583,18 +583,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
MinResponseDataRate = new MinDataRate(bytesPerSecond: 1024 * 1024, gracePeriod: TimeSpan.FromSeconds(2))
|
||||
}
|
||||
}
|
||||
},
|
||||
ExpectedConnectionMiddlewareCount = 1
|
||||
};
|
||||
|
||||
testContext.InitializeHeartbeat();
|
||||
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions { ServerCertificate = certificate })
|
||||
}
|
||||
};
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = certificate });
|
||||
}
|
||||
|
||||
using (var server = new TestServer(async context =>
|
||||
{
|
||||
|
|
@ -621,7 +619,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
|||
{
|
||||
await aborted.Task.DefaultTimeout();
|
||||
}
|
||||
}, testContext, listenOptions))
|
||||
}, testContext, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.Http2
|
|||
private static X509Certificate2 _x509Certificate2 = TestResources.GetTestCertificate();
|
||||
|
||||
[ConditionalFact]
|
||||
[SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/7000 ")]
|
||||
[SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/7000")]
|
||||
public async Task TlsHandshakeRejectsTlsLessThan12()
|
||||
{
|
||||
using (var server = new TestServer(context =>
|
||||
|
|
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.Http2
|
|||
|
||||
return context.Response.WriteAsync("hello world " + context.Request.Protocol);
|
||||
},
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1},
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = HttpProtocols.Http2;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using System.Security.Cryptography.X509Certificates;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Connections.Features;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
|
|
@ -34,15 +35,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public async Task CanReadAndWriteWithHttpsConnectionAdapter()
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 })
|
||||
}
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 });
|
||||
};
|
||||
|
||||
await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
var result = await server.HttpClientSlim.PostAsync($"https://localhost:{server.Port}/",
|
||||
new FormUrlEncodedContent(new[] {
|
||||
|
|
@ -57,12 +55,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public async Task HandshakeDetailsAreAvailable()
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 })
|
||||
}
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 });
|
||||
};
|
||||
|
||||
await using (var server = new TestServer(context =>
|
||||
|
|
@ -78,7 +73,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
Assert.True(tlsFeature.KeyExchangeStrength >= 0, "KeyExchangeStrength"); // May be 0 on mac
|
||||
|
||||
return context.Response.WriteAsync("hello world");
|
||||
}, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false);
|
||||
Assert.Equal("hello world", result);
|
||||
|
|
@ -88,20 +83,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public async Task RequireCertificateFailsWhenNoCertificate()
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0));
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ConnectionAdapters =
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.RequireCertificate
|
||||
})
|
||||
}
|
||||
};
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.RequireCertificate
|
||||
});
|
||||
|
||||
|
||||
await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
await using (var server = new TestServer(App, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, listenOptions))
|
||||
{
|
||||
await Assert.ThrowsAnyAsync<Exception>(
|
||||
() => server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/"));
|
||||
|
|
@ -111,17 +100,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public async Task AllowCertificateContinuesWhenNoCertificate()
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.AllowCertificate
|
||||
})
|
||||
}
|
||||
};
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.AllowCertificate
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context =>
|
||||
{
|
||||
|
|
@ -129,7 +115,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
Assert.NotNull(tlsFeature);
|
||||
Assert.Null(tlsFeature.ClientCertificate);
|
||||
return context.Response.WriteAsync("hello world");
|
||||
}, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false);
|
||||
Assert.Equal("hello world", result);
|
||||
|
|
@ -139,7 +125,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public void ThrowsWhenNoServerCertificateIsProvided()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new HttpsConnectionAdapter(
|
||||
Assert.Throws<ArgumentException>(() => new HttpsConnectionMiddleware(context => Task.CompletedTask,
|
||||
new HttpsConnectionAdapterOptions())
|
||||
);
|
||||
}
|
||||
|
|
@ -147,15 +133,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public async Task UsesProvidedServerCertificate()
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 })
|
||||
}
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 });
|
||||
};
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -173,24 +156,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
public async Task UsesProvidedServerCertificateSelector()
|
||||
{
|
||||
var selectorCalled = 0;
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
ServerCertificateSelector = (connection, name) =>
|
||||
{
|
||||
ServerCertificateSelector = (connection, name) =>
|
||||
{
|
||||
Assert.NotNull(connection);
|
||||
Assert.NotNull(connection.Features.Get<SslStream>());
|
||||
Assert.Equal("localhost", name);
|
||||
selectorCalled++;
|
||||
return _x509Certificate2;
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
Assert.NotNull(connection);
|
||||
Assert.NotNull(connection.Features.Get<SslStream>());
|
||||
Assert.Equal("localhost", name);
|
||||
selectorCalled++;
|
||||
return _x509Certificate2;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -209,28 +190,26 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
public async Task UsesProvidedServerCertificateSelectorEachTime()
|
||||
{
|
||||
var selectorCalled = 0;
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
ServerCertificateSelector = (connection, name) =>
|
||||
{
|
||||
ServerCertificateSelector = (connection, name) =>
|
||||
Assert.NotNull(connection);
|
||||
Assert.NotNull(connection.Features.Get<SslStream>());
|
||||
Assert.Equal("localhost", name);
|
||||
selectorCalled++;
|
||||
if (selectorCalled == 1)
|
||||
{
|
||||
Assert.NotNull(connection);
|
||||
Assert.NotNull(connection.Features.Get<SslStream>());
|
||||
Assert.Equal("localhost", name);
|
||||
selectorCalled++;
|
||||
if (selectorCalled == 1)
|
||||
{
|
||||
return _x509Certificate2;
|
||||
}
|
||||
return _x509Certificate2NoExt;
|
||||
return _x509Certificate2;
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
return _x509Certificate2NoExt;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -259,21 +238,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
public async Task UsesProvidedServerCertificateSelectorValidatesEkus()
|
||||
{
|
||||
var selectorCalled = 0;
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
ServerCertificateSelector = (features, name) =>
|
||||
{
|
||||
ServerCertificateSelector = (features, name) =>
|
||||
{
|
||||
selectorCalled++;
|
||||
return TestResources.GetTestCertificate("eku.code_signing.pfx");
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
selectorCalled++;
|
||||
return TestResources.GetTestCertificate("eku.code_signing.pfx");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -292,25 +269,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
public async Task UsesProvidedServerCertificateSelectorOverridesServerCertificate()
|
||||
{
|
||||
var selectorCalled = 0;
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
ServerCertificate = _x509Certificate2NoExt,
|
||||
ServerCertificateSelector = (connection, name) =>
|
||||
{
|
||||
ServerCertificate = _x509Certificate2NoExt,
|
||||
ServerCertificateSelector = (connection, name) =>
|
||||
{
|
||||
Assert.NotNull(connection);
|
||||
Assert.NotNull(connection.Features.Get<SslStream>());
|
||||
Assert.Equal("localhost", name);
|
||||
selectorCalled++;
|
||||
return _x509Certificate2;
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
Assert.NotNull(connection);
|
||||
Assert.NotNull(connection.Features.Get<SslStream>());
|
||||
Assert.Equal("localhost", name);
|
||||
selectorCalled++;
|
||||
return _x509Certificate2;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -329,21 +304,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
public async Task UsesProvidedServerCertificateSelectorFailsIfYouReturnNull()
|
||||
{
|
||||
var selectorCalled = 0;
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
ServerCertificateSelector = (features, name) =>
|
||||
{
|
||||
ServerCertificateSelector = (features, name) =>
|
||||
{
|
||||
selectorCalled++;
|
||||
return null;
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
selectorCalled++;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -363,19 +336,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[InlineData(HttpProtocols.Http1AndHttp2)] // Make sure Http/1.1 doesn't regress with Http/2 enabled.
|
||||
public async Task CertificatePassedToHttpContext(HttpProtocols httpProtocols)
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
Protocols = httpProtocols,
|
||||
ConnectionAdapters =
|
||||
listenOptions.Protocols = httpProtocols;
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
|
||||
})
|
||||
}
|
||||
};
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context =>
|
||||
{
|
||||
|
|
@ -384,7 +354,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
Assert.NotNull(tlsFeature.ClientCertificate);
|
||||
Assert.NotNull(context.Connection.ClientCertificate);
|
||||
return context.Response.WriteAsync("hello world");
|
||||
}, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
}, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -401,15 +371,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public async Task HttpsSchemePassedToRequestFeature()
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 })
|
||||
}
|
||||
};
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2 });
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => context.Response.WriteAsync(context.Request.Scheme), new TestServiceContext(LoggerFactory), listenOptions))
|
||||
await using (var server = new TestServer(context => context.Response.WriteAsync(context.Request.Scheme), new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
var result = await server.HttpClientSlim.GetStringAsync($"https://localhost:{server.Port}/", validateCertificate: false);
|
||||
Assert.Equal("https", result);
|
||||
|
|
@ -419,20 +386,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public async Task DoesNotSupportTls10()
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
|
||||
})
|
||||
}
|
||||
};
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => context.Response.WriteAsync("hello world"), new TestServiceContext(LoggerFactory), listenOptions))
|
||||
|
||||
await using (var server = new TestServer(context => context.Response.WriteAsync("hello world"), new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
// SslStream is used to ensure the certificate is actually passed to the server
|
||||
// HttpClient might not send the certificate because it is invalid or it doesn't match any
|
||||
|
|
@ -453,26 +418,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
public async Task ClientCertificateValidationGetsCalledWithNotNullParameters(ClientCertificateMode mode)
|
||||
{
|
||||
var clientCertificateValidationCalled = false;
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = mode,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = mode,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
clientCertificateValidationCalled = true;
|
||||
Assert.NotNull(certificate);
|
||||
Assert.NotNull(chain);
|
||||
return true;
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
clientCertificateValidationCalled = true;
|
||||
Assert.NotNull(certificate);
|
||||
Assert.NotNull(chain);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -490,20 +452,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[InlineData(ClientCertificateMode.RequireCertificate)]
|
||||
public async Task ValidationFailureRejectsConnection(ClientCertificateMode mode)
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = mode,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => false
|
||||
})
|
||||
}
|
||||
};
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = mode,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => false
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -519,19 +478,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[InlineData(ClientCertificateMode.RequireCertificate)]
|
||||
public async Task RejectsConnectionOnSslPolicyErrorsWhenNoValidation(ClientCertificateMode mode)
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = mode
|
||||
})
|
||||
}
|
||||
};
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = mode
|
||||
});
|
||||
}
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
using (var connection = server.CreateConnection())
|
||||
{
|
||||
|
|
@ -545,18 +501,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
[Fact]
|
||||
public async Task CertificatePassedToHttpContextIsNotDisposed()
|
||||
{
|
||||
var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0))
|
||||
void ConfigureListenOptions(ListenOptions listenOptions)
|
||||
{
|
||||
ConnectionAdapters =
|
||||
listenOptions.UseHttps(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
|
||||
})
|
||||
}
|
||||
};
|
||||
ServerCertificate = _x509Certificate2,
|
||||
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
|
||||
ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true
|
||||
});
|
||||
}
|
||||
|
||||
RequestDelegate app = context =>
|
||||
{
|
||||
|
|
@ -568,7 +521,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
return context.Response.WriteAsync("hello world");
|
||||
};
|
||||
|
||||
await using (var server = new TestServer(app, new TestServiceContext(LoggerFactory), listenOptions))
|
||||
await using (var server = new TestServer(app, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions))
|
||||
{
|
||||
// SslStream is used to ensure the certificate is actually passed to the server
|
||||
// HttpClient might not send the certificate because it is invalid or it doesn't match any
|
||||
|
|
@ -591,7 +544,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
var cert = new X509Certificate2(certPath, "testPassword");
|
||||
Assert.Empty(cert.Extensions.OfType<X509EnhancedKeyUsageExtension>());
|
||||
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
new HttpsConnectionMiddleware(context => Task.CompletedTask, new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = cert,
|
||||
});
|
||||
|
|
@ -609,7 +562,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
var eku = Assert.Single(cert.Extensions.OfType<X509EnhancedKeyUsageExtension>());
|
||||
Assert.NotEmpty(eku.EnhancedKeyUsages);
|
||||
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
new HttpsConnectionMiddleware(context => Task.CompletedTask, new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = cert,
|
||||
});
|
||||
|
|
@ -628,7 +581,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
Assert.NotEmpty(eku.EnhancedKeyUsages);
|
||||
|
||||
var ex = Assert.Throws<InvalidOperationException>(() =>
|
||||
new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions
|
||||
new HttpsConnectionMiddleware(context => Task.CompletedTask, new HttpsConnectionAdapterOptions
|
||||
{
|
||||
ServerCertificate = cert,
|
||||
}));
|
||||
|
|
@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
LoggerFactory.AddProvider(loggerProvider);
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(TestResources.GetTestCertificate());
|
||||
|
|
@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
LoggerFactory.AddProvider(loggerProvider);
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(TestResources.GetTestCertificate());
|
||||
|
|
@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
}
|
||||
}
|
||||
},
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(TestResources.GetTestCertificate());
|
||||
|
|
@ -237,7 +237,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
tcs.SetException(ex);
|
||||
}
|
||||
},
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(TestResources.GetTestCertificate());
|
||||
|
|
@ -268,7 +268,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
LoggerFactory.AddProvider(loggerProvider);
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(TestResources.GetTestCertificate());
|
||||
|
|
@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
LoggerFactory.AddProvider(loggerProvider);
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(TestResources.GetTestCertificate());
|
||||
|
|
@ -313,7 +313,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
var loggerProvider = new HandshakeErrorLoggerProvider();
|
||||
LoggerFactory.AddProvider(loggerProvider);
|
||||
|
||||
var testContext = new TestServiceContext(LoggerFactory);
|
||||
var testContext = new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 };
|
||||
var heartbeatManager = new HeartbeatManager(testContext.ConnectionManager);
|
||||
|
||||
var handshakeStartedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
|
@ -326,7 +326,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
listenOptions.UseHttps(o =>
|
||||
{
|
||||
o.ServerCertificate = new X509Certificate2(TestResources.GetTestCertificate());
|
||||
o.OnAuthenticate = (_, __) => handshakeStartedTcs.SetResult(null);
|
||||
o.OnAuthenticate = (_, __) =>
|
||||
{
|
||||
handshakeStartedTcs.SetResult(null);
|
||||
};
|
||||
|
||||
handshakeTimeout = o.HandshakeTimeout;
|
||||
});
|
||||
|
|
@ -358,7 +361,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
LoggerFactory.AddProvider(loggerProvider);
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(TestResources.GetTestCertificate());
|
||||
|
|
@ -390,7 +393,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
var onAuthenticateCalled = false;
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(httpsOptions =>
|
||||
|
|
@ -426,7 +429,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
var onAuthenticateCalled = false;
|
||||
|
||||
await using (var server = new TestServer(context => Task.CompletedTask,
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 },
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(httpsOptions =>
|
||||
|
|
@ -462,7 +465,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
|
||||
public ILogger CreateLogger(string categoryName)
|
||||
{
|
||||
if (categoryName == TypeNameHelper.GetTypeDisplayName(typeof(HttpsConnectionAdapter)))
|
||||
if (categoryName == TypeNameHelper.GetTypeDisplayName(typeof(HttpsConnectionMiddleware)))
|
||||
{
|
||||
return FilterLogger;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
context.Response.ContentLength = 12;
|
||||
return context.Response.WriteAsync("Hello World!");
|
||||
},
|
||||
new TestServiceContext(LoggerFactory),
|
||||
new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1},
|
||||
listenOptions =>
|
||||
{
|
||||
listenOptions.UseConnectionLogging();
|
||||
|
|
|
|||
Loading…
Reference in New Issue