/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Servers/HttpSys/test/FunctionalTests/Http3Tests.cs
261 строка
12 KB
William Godbe
Rename Microsoft.Aspnetcore.Testing to Microsoft.AspNetCore.InternalTesting (#51713)
02 ноя 2023, 03:15
Не верифицирован
02 ноя 2023, 03:15
fc8deca
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net; using System.Net.Http; using System.Net.Quic; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.InternalTesting; using Microsoft.Net.Http.Headers; using Xunit; // Not tested here: Http.Sys supports sending an altsvc HTTP/2 frame if you enable the following reg key. // reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters" /v EnableAltSvc /t REG_DWORD /d 1 /f // However, this only works with certificate bindings that specify a name. We test with the IP based bindings created by IIS Express. // I don't know if the client supports the HTTP/2 altsvc frame. namespace Microsoft.AspNetCore.Server.HttpSys; [MsQuicSupported] // Required by HttpClient [HttpSysHttp3Supported] public class Http3Tests : LoggedTest { [ConditionalFact] public async Task Http3_Direct() { using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => { try { Assert.True(httpContext.Request.IsHttps); await httpContext.Response.WriteAsync(httpContext.Request.Protocol); } catch (Exception ex) { await httpContext.Response.WriteAsync(ex.ToString()); } }, LoggerFactory); var handler = new HttpClientHandler(); // Needed on CI, the IIS Express cert we use isn't trusted there. handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; using var client = new HttpClient(handler); client.DefaultRequestVersion = HttpVersion.Version30; client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact; var response = await client.GetStringAsync(address); Assert.Equal("HTTP/3", response); } [ConditionalFact] public async Task Http3_AltSvcHeader_UpgradeFromHttp1() { var altsvc = ""; using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => { try { Assert.True(httpContext.Request.IsHttps); // Alt-Svc is not supported by Http.Sys, you need to add it yourself. httpContext.Response.Headers.AltSvc = altsvc; await httpContext.Response.WriteAsync(httpContext.Request.Protocol); } catch (Exception ex) { await httpContext.Response.WriteAsync(ex.ToString()); } }, LoggerFactory); altsvc = $@"h3="":{new Uri(address).Port}"""; var handler = new HttpClientHandler(); // Needed on CI, the IIS Express cert we use isn't trusted there. handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; using var client = new HttpClient(handler); client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; // First request is HTTP/1.1, gets an alt-svc response var request = new HttpRequestMessage(HttpMethod.Get, address); request.Version = HttpVersion.Version11; request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; var response1 = await client.SendAsync(request); response1.EnsureSuccessStatusCode(); Assert.Equal("HTTP/1.1", await response1.Content.ReadAsStringAsync()); Assert.Equal(altsvc, response1.Headers.GetValues(HeaderNames.AltSvc).SingleOrDefault()); // Second request is HTTP/3 var response3 = await client.GetStringAsync(address); Assert.Equal("HTTP/3", response3); } [ConditionalFact] public async Task Http3_AltSvcHeader_UpgradeFromHttp2() { var altsvc = ""; using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => { try { Assert.True(httpContext.Request.IsHttps); // Alt-Svc is not supported by Http.Sys, you need to add it yourself. httpContext.Response.Headers.AltSvc = altsvc; await httpContext.Response.WriteAsync(httpContext.Request.Protocol); } catch (Exception ex) { await httpContext.Response.WriteAsync(ex.ToString()); } }, LoggerFactory); altsvc = $@"h3="":{new Uri(address).Port}"""; var handler = new HttpClientHandler(); // Needed on CI, the IIS Express cert we use isn't trusted there. handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; using var client = new HttpClient(handler); client.DefaultRequestVersion = HttpVersion.Version20; client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; // First request is HTTP/2, gets an alt-svc response var response2 = await client.GetAsync(address); response2.EnsureSuccessStatusCode(); Assert.Equal(altsvc, response2.Headers.GetValues(HeaderNames.AltSvc).SingleOrDefault()); Assert.Equal("HTTP/2", await response2.Content.ReadAsStringAsync()); // Second request is HTTP/3 var response3 = await client.GetStringAsync(address); Assert.Equal("HTTP/3", response3); } [ConditionalFact] public async Task Http3_ResponseTrailers() { using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => { try { Assert.True(httpContext.Request.IsHttps); await httpContext.Response.WriteAsync(httpContext.Request.Protocol); httpContext.Response.AppendTrailer("custom", "value"); } catch (Exception ex) { await httpContext.Response.WriteAsync(ex.ToString()); } }, LoggerFactory); var handler = new HttpClientHandler(); // Needed on CI, the IIS Express cert we use isn't trusted there. handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; using var client = new HttpClient(handler); client.DefaultRequestVersion = HttpVersion.Version30; client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact; var response = await client.GetAsync(address); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); Assert.Equal("HTTP/3", result); Assert.Equal("value", response.TrailingHeaders.GetValues("custom").SingleOrDefault()); } [ConditionalFact] public async Task Http3_ResetBeforeHeaders() { using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => { try { Assert.True(httpContext.Request.IsHttps); httpContext.Features.Get<IHttpResetFeature>().Reset(0x010b); // H3_REQUEST_REJECTED } catch (Exception ex) { await httpContext.Response.WriteAsync(ex.ToString()); } }, LoggerFactory); var handler = new HttpClientHandler(); // Needed on CI, the IIS Express cert we use isn't trusted there. handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; using var client = new HttpClient(handler); client.DefaultRequestVersion = HttpVersion.Version30; client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact; var ex = await Assert.ThrowsAsync<HttpRequestException>(() => client.GetAsync(address)); var qex = Assert.IsType<QuicException>(ex.InnerException); Assert.Equal(QuicError.StreamAborted, qex.QuicError); Assert.Equal(0x010b, qex.ApplicationErrorCode.Value); } [ConditionalFact] public async Task Http3_ResetAfterHeaders() { var headersReceived = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => { try { Assert.True(httpContext.Request.IsHttps); await httpContext.Response.Body.FlushAsync(); await headersReceived.Task.DefaultTimeout(); httpContext.Features.Get<IHttpResetFeature>().Reset(0x010c); // H3_REQUEST_CANCELLED } catch (Exception ex) { await httpContext.Response.WriteAsync(ex.ToString()); } }, LoggerFactory); var handler = new HttpClientHandler(); // Needed on CI, the IIS Express cert we use isn't trusted there. handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; using var client = new HttpClient(handler); client.DefaultRequestVersion = HttpVersion.Version30; client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact; var response = await client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead); headersReceived.SetResult(); response.EnsureSuccessStatusCode(); var ex = await Assert.ThrowsAsync<HttpRequestException>(() => response.Content.ReadAsStringAsync()); var qex = Assert.IsType<QuicException>(ex.InnerException?.InnerException?.InnerException); Assert.Equal(QuicError.StreamAborted, qex.QuicError); Assert.Equal(0x010c, qex.ApplicationErrorCode.Value); } [ConditionalFact] public async Task Http3_AppExceptionAfterHeaders_InternalError() { var headersReceived = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => { await httpContext.Response.Body.FlushAsync(); await headersReceived.Task.DefaultTimeout(); throw new Exception("App Exception"); }, LoggerFactory); var handler = new HttpClientHandler(); // Needed on CI, the IIS Express cert we use isn't trusted there. handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; using var client = new HttpClient(handler); client.DefaultRequestVersion = HttpVersion.Version30; client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact; var response = await client.GetAsync(address, HttpCompletionOption.ResponseHeadersRead); headersReceived.SetResult(); response.EnsureSuccessStatusCode(); var ex = await Assert.ThrowsAsync<HttpRequestException>(() => response.Content.ReadAsStringAsync()); var qex = Assert.IsType<QuicException>(ex.InnerException?.InnerException?.InnerException); Assert.Equal(QuicError.StreamAborted, qex.QuicError); Assert.Equal(0x0102, qex.ApplicationErrorCode.Value); // H3_INTERNAL_ERROR } [ConditionalFact] public async Task Http3_Abort_Cancel() { using var server = Utilities.CreateDynamicHttpsServer(out var address, httpContext => { httpContext.Abort(); return Task.CompletedTask; }, LoggerFactory); var handler = new HttpClientHandler(); // Needed on CI, the IIS Express cert we use isn't trusted there. handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; using var client = new HttpClient(handler); client.DefaultRequestVersion = HttpVersion.Version30; client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact; var ex = await Assert.ThrowsAsync<HttpRequestException>(() => client.GetAsync(address)); var qex = Assert.IsType<QuicException>(ex.InnerException); Assert.Equal(QuicError.StreamAborted, qex.QuicError); Assert.Equal(0x010c, qex.ApplicationErrorCode.Value); // H3_REQUEST_CANCELLED } }