#43 Honor CancellationTokens in GetClientCertificateAsync.

This commit is contained in:
Chris R 2015-08-07 16:01:36 -07:00
parent a24fd18dc0
commit 28d3b18686
2 changed files with 14 additions and 6 deletions

View File

@ -50,14 +50,20 @@ namespace Microsoft.Net.Http.Server
private int _clientCertError;
private X509Certificate2 _clientCert;
private Exception _clientCertException;
private CancellationTokenRegistration _cancellationRegistration;
internal ClientCertLoader(RequestContext requestContext)
internal ClientCertLoader(RequestContext requestContext, CancellationToken cancellationToken)
{
_requestContext = requestContext;
_tcs = new TaskCompletionSource<object>();
// we will use this overlapped structure to issue async IO to ul
// the event handle will be put in by the BeginHttpApi2.ERROR_SUCCESS() method
Reset(CertBoblSize);
if (cancellationToken.CanBeCanceled)
{
_cancellationRegistration = cancellationToken.Register(RequestContext.AbortDelegate, _requestContext);
}
}
internal X509Certificate2 ClientCert
@ -162,9 +168,8 @@ namespace Microsoft.Net.Http.Server
// ERROR_NOT_FOUND - which means the client did not provide the cert
// If this is important, the server should respond with 403 forbidden
// HTTP.SYS will not do this for you automatically
internal Task LoadClientCertificateAsync(CancellationToken cancellationToken)
internal Task LoadClientCertificateAsync()
{
// TODO: cancellation support? Abort the request?
uint size = CertBoblSize;
bool retry;
do
@ -218,14 +223,15 @@ namespace Microsoft.Net.Http.Server
// May be null
_clientCert = cert;
_clientCertError = certErrors;
_tcs.TrySetResult(null);
Dispose();
_tcs.TrySetResult(null);
}
private void Fail(Exception ex)
{
// TODO: Log
_clientCertException = ex;
Dispose();
_tcs.TrySetResult(null);
}
@ -328,6 +334,7 @@ namespace Microsoft.Net.Http.Server
{
if (disposing)
{
_cancellationRegistration.Dispose();
if (_overlapped != null)
{
_memoryBlob = null;

View File

@ -451,11 +451,12 @@ namespace Microsoft.Net.Http.Server
{
return _clientCert;
}
cancellationToken.ThrowIfCancellationRequested();
ClientCertLoader certLoader = new ClientCertLoader(RequestContext);
ClientCertLoader certLoader = new ClientCertLoader(RequestContext, cancellationToken);
try
{
await certLoader.LoadClientCertificateAsync(cancellationToken).SupressContext();
await certLoader.LoadClientCertificateAsync().SupressContext();
// Populate the environment.
if (certLoader.ClientCert != null)
{