Parcourir la source

HTTP/3: Fix failing client cert test (#37578)

James Newton-King il y a 4 ans
Parent
commit
807e865dd1

+ 27 - 10
src/Servers/Kestrel/test/Interop.FunctionalTests/Http3/Http3TlsTests.cs

@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core;
 using Microsoft.AspNetCore.Server.Kestrel.Https;
 using Microsoft.AspNetCore.Testing;
 using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
 using Xunit;
 
 namespace Interop.FunctionalTests.Http3
@@ -149,11 +150,13 @@ namespace Interop.FunctionalTests.Http3
         }
 
         [ConditionalTheory]
-        [InlineData(ClientCertificateMode.RequireCertificate)]
-        [InlineData(ClientCertificateMode.AllowCertificate)]
+        [InlineData(ClientCertificateMode.RequireCertificate, false)]
+        [InlineData(ClientCertificateMode.RequireCertificate, true)]
+        [InlineData(ClientCertificateMode.AllowCertificate, false)]
+        [InlineData(ClientCertificateMode.AllowCertificate, true)]
         [MsQuicSupported]
         [OSSkipCondition(OperatingSystems.MacOSX | OperatingSystems.Linux, SkipReason = "https://github.com/dotnet/aspnetcore/issues/35800")]
-        public async Task ClientCertificate_AllowOrRequire_Available_Invalid_Refused(ClientCertificateMode mode)
+        public async Task ClientCertificate_AllowOrRequire_Available_Invalid_Refused(ClientCertificateMode mode, bool serverAllowInvalid)
         {
             var builder = CreateHostBuilder(async context =>
             {
@@ -168,7 +171,11 @@ namespace Interop.FunctionalTests.Http3
                     {
                         httpsOptions.ServerCertificate = TestResources.GetTestCertificate();
                         httpsOptions.ClientCertificateMode = mode;
-                        // httpsOptions.AllowAnyClientCertificate(); // The self-signed cert is invalid. Let it fail the default checks.
+
+                        if (serverAllowInvalid)
+                        {
+                            httpsOptions.AllowAnyClientCertificate(); // The self-signed cert is invalid. Let it fail the default checks.
+                        }
                     });
                 });
             });
@@ -182,12 +189,22 @@ namespace Interop.FunctionalTests.Http3
             request.Version = HttpVersion.Version30;
             request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
 
-            var ex = await Assert.ThrowsAsync<HttpRequestException>(() => client.SendAsync(request, CancellationToken.None).DefaultTimeout());
-            // This poor error is likely a symptom of https://github.com/dotnet/runtime/issues/57246
-            // QuicListener returns the connection before (or in spite of) the cert validation failing.
-            // There's a race where the stream could be accepted before the connection is aborted.
-            var qex = Assert.IsType<QuicOperationAbortedException>(ex.InnerException);
-            Assert.Equal("Operation aborted.", qex.Message);
+            var sendTask = client.SendAsync(request, CancellationToken.None);
+
+            if (!serverAllowInvalid)
+            {
+                // In .NET 6 there is a race condition between throwing HttpRequestException and QuicException.
+                // Unable to test the exact error.
+                var ex = await Assert.ThrowsAnyAsync<Exception>(() => sendTask).DefaultTimeout();
+                Logger.LogInformation(ex, "SendAsync successfully threw error.");
+            }
+            else
+            {
+                // Because we can't verify the exact error reason, check that the cert is the cause be successfully
+                // making a call when invalid certs are allowed.
+                var response = await sendTask.DefaultTimeout();
+                response.EnsureSuccessStatusCode();
+            }
 
             await host.StopAsync().DefaultTimeout();
         }