HttpClient에서 HTTP/3 사용

HTTP/3은 세 번째이자 최근 표준화된 HTTP의 주 버전입니다. HTTP/3은 HTTP/1.1 및 HTTP/2와 동일한 의미 체계를 사용하기 때문에 동일한 요청 메서드, 상태 코드 및 메시지 필드가 모든 버전에 적용됩니다. 기본 전송에 차이가 있습니다. HTTP/1.1과 HTTP/2 모두 TCP를 전송으로 사용합니다. HTTP/3은 HTTP/3과 함께 개발된 QUIC이라는 전송 기술을 사용합니다.

HTTP/3과 QUIC는 모두 HTTP/1.1과 HTTP/2에 비해 몇 가지 혜택이 있습니다.

  • 첫 번째 요청에 대한 응답 시간이 더 빠릅니다. QUIC와 HTTP/3은 연결을 협상할 때 클라이언트와 서버 간의 왕복 횟수가 더 적습니다. 첫 번째 요청이 서버에 더 빨리 도달합니다.
  • 연결 패킷 손실이 있을 때의 환경이 개선되었습니다. HTTP/2는 하나의 TCP 연결을 통해 여러 요청을 멀티플렉싱합니다. 연결의 패킷 손실은 모든 요청에 영향을 미칩니다. 이 문제를 ‘HOC(head-of-line) 블로킹’이라고 합니다. QUIC는 네이티브 멀티플렉싱을 제공하기 때문에 손실된 패킷은 데이터가 손실된 요청에만 영향을 미칩니다.
  • 네트워크 간 전환을 지원합니다. 이 기능은 모바일 디바이스가 위치를 변경할 때 WIFI와 셀룰러 네트워크 사이의 전환이 흔히 일어나는 모바일 디바이스에 유용합니다. 현재 HTTP/1.1 및 HTTP/2는 네트워크를 전환할 때 오류가 발생하여 연결에 실패합니다. 앱 또는 웹 브라우저는 실패한 HTTP 요청을 다시 시도해야 합니다. HTTP/3을 사용하면 네트워크가 변경될 때도 앱 또는 웹 브라우저가 원활하게 지속될 수 있습니다. HttpClient 및 Kestrel은 .NET 7에서 네트워크 전환을 지원하지 않습니다. 향후 릴리스에서는 지원될 수 있을 것입니다.

Important

HTTP/3을 활용하도록 구성된 앱은 HTTP/1.1 및 HTTP/2도 지원하도록 디자인되어야 합니다. HTTP/3에서 문제가 식별되면 .NET의 향후 릴리스에서 문제가 해결될 때까지 HTTP/3을 사용하지 않도록 설정하는 것이 좋습니다.

HttpClient 설정

HTTP 버전은 HttpRequestMessage.Version을 3.0으로 설정하여 구성할 수 있습니다. 그러나 모든 라우터, 방화벽 및 프록시가 HTTP/3을 제대로 지원하는 것은 아니므로 HTTP/3을 HTTP/1.1 및 HTTP/2와 함께 구성하는 것이 좋습니다. HttpClient에서는 다음을 지정하여 이를 수행할 수 있습니다.

플랫폼 종속성

HTTP/3에서는 QUIC를 전송 프로토콜로 사용합니다. HTTP/3의 .NET 구현에서는 MsQuic를 사용하여 QUIC 기능을 제공합니다. 결과적으로 HTTP/3의 .NET 지원은 MsQuic 플랫폼 요구 사항에 따라 달라집니다. MsQuic 설치 방법에 대한 자세한 내용은 QUIC 플랫폼 종속성을 참조하세요. HttpClient에서 실행되는 플랫폼에 HTTP/3에 대한 모든 요구 사항이 없는 경우에는 사용하지 않도록 설정됩니다.

HttpClient 사용

다음 코드 예제에서는 최상위 문을 사용하고 요청에서 HTTP3을 지정하는 방법을 보여 줍니다.

// See https://aka.ms/new-console-template for more information
using System.Net;

using var client = new HttpClient
{
    DefaultRequestVersion =  HttpVersion.Version30,
    DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact
};

Console.WriteLine("--- localhost:5001 ---");

HttpResponseMessage resp = await client.GetAsync("https://localhost:5001/");
string body = await resp.Content.ReadAsStringAsync();

Console.WriteLine(
    $"status: {resp.StatusCode}, version: {resp.Version}, " +
    $"body: {body.Substring(0, Math.Min(100, body.Length))}");

.NET 6의 HTTP/3 지원

.NET 6에서는 HTTP/3 사양이 아직 완성되지 않았기 때문에 HTTP/3을 미리 보기 기능으로 사용할 수 있습니다. .NET 6을 사용하는 HTTP/3에는 동작 또는 성능 문제가 있을 수 있습니다. 미리 보기 기능에 관한 자세한 내용은 미리 보기 기능 사양을 참조하세요.

.NET 6에서 HTTP/3 지원을 사용하도록 설정하려면 프로젝트 파일에 RuntimeHostConfigurationOption 노드를 포함하여 HttpClient로 HTTP/3을 사용하도록 설정합니다.

<ItemGroup>
    <RuntimeHostConfigurationOption Value="true"
        Include="System.Net.SocketsHttpHandler.Http3Support" />
</ItemGroup>

또는 앱 코드에서 System.AppContext.SetSwitch를 호출하거나 DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP3SUPPORT 환경 변수를 true로 설정할 수 있습니다. 자세한 내용은 .NET 환경 변수: DOTNET_SYSTEM_NET_HTTP_*를 참조하세요.

HTTP/3에 대한 구성 플래그가 필요한 이유는 버전 정책 RequestVersionOrHigher를 사용할 때 향후 중단으로부터 앱을 보호하는 것입니다. 현재 HTTP/1.1 및 HTTP/2를 사용하는 서버를 호출할 때 서버가 나중에 HTTP/3으로 업그레이드되는 경우 클라이언트는 HTTP/3을 사용하려고 하며 표준이 최종이 아니어서 .NET 6이 릴리스된 후 변경될 수 있으므로 호환되지 않을 수 있습니다.

.NET 6은 libmsquic의 1.9.x 버전과만 호환됩니다. Libmsquic 2.x는 라이브러리의 호환성이 손상되는 변경으로 인해 .NET 6과 호환되지 않습니다. Libmsquic는 보안 픽스를 통합하는 데 필요한 경우 1.9.x에 대한 업데이트를 받습니다.

HTTP/3 서버

HTTP/3은 .NET 6(미리 보기) 및 .NET 7(완전히 지원됨)의 Kestrel 서버를 통해 ASP.NET에서 지원됩니다. 자세한 내용은 ASP.NET Core Kestrel 웹 서버에서 HTTP/3 사용을 참조하세요.

퍼블릭 테스트 서버

Cloudflare는 https://cloudflare-quic.com에서 클라이언트를 테스트하는 데 사용할 수 있는 HTTP/3용 사이트를 호스팅합니다.

참고 항목