From 28d3b1868638868acf5b730e0c2cb52268758581 Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 7 Aug 2015 16:01:36 -0700 Subject: [PATCH] #43 Honor CancellationTokens in GetClientCertificateAsync. --- .../RequestProcessing/ClientCertLoader.cs | 15 +++++++++++---- .../RequestProcessing/Request.cs | 5 +++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/ClientCertLoader.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/ClientCertLoader.cs index e859c97964..8ae8305a87 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/ClientCertLoader.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/ClientCertLoader.cs @@ -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(); // 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; diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs index 51333996fc..146f0cf81e 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/Request.cs @@ -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) {