public async Task OnAuthentice_Available_Throws() { var builder = CreateHostBuilder(async context => { await context.Response.WriteAsync("Hello World"); }, configureKestrel: kestrelOptions => { kestrelOptions.ListenAnyIP(0, listenOptions => { listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(httpsOptions => { httpsOptions.OnAuthenticate = (_, _) => { }; }); }); }); using var host = builder.Build(); using var client = Http3Helpers.CreateClient(); var exception = await Assert.ThrowsAsync <NotSupportedException>(() => host.StartAsync().DefaultTimeout()); Assert.Equal("The OnAuthenticate callback is not supported with HTTP/3.", exception.Message); }
public async Task ClientCertificate_AllowOrRequire_Available_Invalid_Refused(ClientCertificateMode mode, bool serverAllowInvalid) { var builder = CreateHostBuilder(async context => { var hasCert = context.Connection.ClientCertificate != null; await context.Response.WriteAsync(hasCert.ToString()); }, configureKestrel: kestrelOptions => { kestrelOptions.ListenAnyIP(0, listenOptions => { listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(httpsOptions => { httpsOptions.ServerCertificate = TestResources.GetTestCertificate(); httpsOptions.ClientCertificateMode = mode; if (serverAllowInvalid) { httpsOptions.AllowAnyClientCertificate(); // The self-signed cert is invalid. Let it fail the default checks. } }); }); }); using var host = builder.Build(); using var client = Http3Helpers.CreateClient(includeClientCert: true); await host.StartAsync().DefaultTimeout(); var request = new HttpRequestMessage(HttpMethod.Get, $"https://127.0.0.1:{host.GetPort()}/"); request.Version = HttpVersion.Version30; request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; 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(); }
public async Task ServerCertificateSelector_Invoked() { var builder = CreateHostBuilder(async context => { await context.Response.WriteAsync("Hello World"); }, configureKestrel: kestrelOptions => { kestrelOptions.ListenAnyIP(0, listenOptions => { listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(httpsOptions => { httpsOptions.ServerCertificateSelector = (context, host) => { Assert.Null(context); // The context isn't available durring the quic handshake. Assert.Equal("localhost", host); return(TestResources.GetTestCertificate()); }; }); }); }); using var host = builder.Build(); using var client = Http3Helpers.CreateClient(); await host.StartAsync().DefaultTimeout(); // Using localhost instead of 127.0.0.1 because IPs don't set SNI and the Host header isn't currently used as an override. var request = new HttpRequestMessage(HttpMethod.Get, $"https://localhost:{host.GetPort()}/"); request.Version = HttpVersion.Version30; request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; // https://github.com/dotnet/runtime/issues/57169 Host isn't used for SNI request.Headers.Host = "testhost"; var response = await client.SendAsync(request, CancellationToken.None).DefaultTimeout(); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); Assert.Equal(HttpVersion.Version30, response.Version); Assert.Equal("Hello World", result); await host.StopAsync().DefaultTimeout(); }
public async Task ClientCertificate_AllowOrRequire_Available_Accepted(ClientCertificateMode mode) { var builder = CreateHostBuilder(async context => { var hasCert = context.Connection.ClientCertificate != null; await context.Response.WriteAsync(hasCert.ToString()); }, configureKestrel: kestrelOptions => { kestrelOptions.ListenAnyIP(0, listenOptions => { listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(httpsOptions => { httpsOptions.ServerCertificate = TestResources.GetTestCertificate(); httpsOptions.ClientCertificateMode = mode; httpsOptions.AllowAnyClientCertificate(); }); }); }); using var host = builder.Build(); using var client = Http3Helpers.CreateClient(includeClientCert: true); await host.StartAsync().DefaultTimeout(); var request = new HttpRequestMessage(HttpMethod.Get, $"https://127.0.0.1:{host.GetPort()}/"); request.Version = HttpVersion.Version30; request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; var response = await client.SendAsync(request, CancellationToken.None).DefaultTimeout(); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); Assert.Equal(HttpVersion.Version30, response.Version); Assert.Equal("True", result); await host.StopAsync().DefaultTimeout(); }
public async Task ClientCertificate_Allow_NotAvailable_Optional() { var builder = CreateHostBuilder(async context => { var hasCert = context.Connection.ClientCertificate != null; await context.Response.WriteAsync(hasCert.ToString()); }, configureKestrel: kestrelOptions => { kestrelOptions.ListenAnyIP(0, listenOptions => { listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(httpsOptions => { httpsOptions.ServerCertificate = TestResources.GetTestCertificate(); httpsOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate; httpsOptions.AllowAnyClientCertificate(); }); }); }); using var host = builder.Build(); using var client = Http3Helpers.CreateClient(includeClientCert: false); await host.StartAsync().DefaultTimeout(); var request = new HttpRequestMessage(HttpMethod.Get, $"https://127.0.0.1:{host.GetPort()}/"); request.Version = HttpVersion.Version30; request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; // https://github.com/dotnet/runtime/issues/57308, optional client certs aren't supported. var ex = await Assert.ThrowsAsync <HttpRequestException>(() => client.SendAsync(request, CancellationToken.None).DefaultTimeout()); Assert.StartsWith("Connection has been shutdown by transport.", ex.Message); await host.StopAsync().DefaultTimeout(); }