Usar HTTP/3 com HttpClient

HTTP/3 é a terceira versão principal, que foi padronizada recentemente, do HTTP. O HTTP/3 usa a mesma semântica que HTTP/1.1 e HTTP/2: os mesmos métodos de solicitação, códigos de status e campos de mensagem se aplicam a todas as versões. As diferenças estão no transporte subjacente. Tanto HTTP/1.1 quanto HTTP/2 usam TCP como transporte. O HTTP/3 usa uma tecnologia de transporte que foi desenvolvida com ele chamada QUIC.

HTTP/3 e QUIC têm uma série de benefícios em comparação com HTTP/1.1 e HTTP/2:

  • Tempo de resposta mais rápido na primeira solicitação. QUIC e HTTP/3 negociam a conexão em menos viagens de ida e volta entre o cliente e o servidor. A primeira solicitação alcança o servidor mais rapidamente.
  • Experiência aprimorada quando há perda de pacote de conexão. O HTTP/2 multiplexa várias solicitações por meio de uma conexão TCP. A perda de pacote na conexão afeta todas as solicitações. Esse problema é chamado de "bloqueio de cabeçalho". Como o QUIC fornece multiplexação nativa, os pacotes perdidos afetam apenas as solicitações em que os dados foram perdidos.
  • Dá suporte à transição entre redes. Esse recurso é útil para dispositivos móveis em que é comum alternar entre redes Wi-Fi e celulares quando um dispositivo móvel muda de local. Atualmente, as conexões HTTP/1.1 e HTTP/2 falham e apresentam um erro ao alternar redes. Um aplicativo ou navegador da Web deve repetir as solicitações HTTP com falha. O HTTP/3 permite que o aplicativo ou navegador da Web continue perfeitamente quando uma rede é alterada. HttpClient e Kestrel não dão suporte a transições de rede no .NET 7. Eles pode estar disponíveis em uma versão futura.

Importante

Os aplicativos configurados para aproveitar HTTP/3 devem ser projetados para também dar suporte a HTTP/1.1 e HTTP/2. Caso sejam identificados problemas no HTTP/3, é recomendável desabilitá-lo até que sejam resolvidos em uma versão futura do .NET.

Configurações do HttpClient

A versão HTTP pode ser configurada definindo HttpRequestMessage.Version para 3.0. No entanto, como nem todos os roteadores, firewalls e proxies dão suporte adequado a HTTP/3, recomenda-se configurar o HTTP/3 junto com HTTP/1.1 e HTTP/2. No HttpClient, isso pode ser feito especificando:

Dependências de plataforma

O HTTP/3 usa QUIC como seu protocolo de transporte. A implementação do .NET do HTTP/3 usa o MsQuic para fornecer funcionalidade QUIC. Como resultado, o suporte do .NET para HTTP/3 depende dos requisitos da plataforma MsQuic. Para obter mais informações sobre como instalar o MsQuic, consulte Dependências da plataforma QUIC. Se a plataforma na qual o HttpClient está em execução não tiver todos os requisitos para HTTP/3, ela será desabilitada.

Usando HttpClient

O exemplo de código a seguir usa instruções de nível superior e demonstra como especificar HTTP3 na solicitação:

// 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))}");

Suporte para HTTP/3 no .NET 6

No .NET 6, o HTTP/3 está disponível como uma versão prévia do recurso porque a especificação do HTTP/3 ainda não foi finalizada. Problemas de comportamento ou de desempenho podem existir no HTTP/3 com o .NET 6. Para obter mais informações sobre recursos de visualização, consulte A especificação de recursos de visualização.

Para habilitar o suporte a HTTP/3 no .NET 6, inclua o nó RuntimeHostConfigurationOption no arquivo de projeto para habilitar o HTTP/3 com HttpClient:

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

Como alternativa, você pode chamar System.AppContext.SetSwitch do código do aplicativo ou definir a variável de ambiente DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP3SUPPORT como true. Para obter mais informações, confira Variáveis de ambiente do .NET: DOTNET_SYSTEM_NET_HTTP_*.

O motivo para exigir um sinalizador de configuração para o HTTP/3 é proteger os aplicativos contra interrupções futuras ao usar a política de versão RequestVersionOrHigher. Ao chamar um servidor que atualmente usa HTTP/1.1 e HTTP/2, se o servidor posteriormente for atualizado para HTTP/3, o cliente tentará usar HTTP/3 e potencialmente será incompatível, pois o padrão não é final e, portanto, pode ser alterado após o lançamento do .NET 6.

O .NET 6 só é compatível com as versões 1.9.x do libmsquic. O Libmsquic 2.x não é compatível com o .NET 6 devido a alterações interruptivas na biblioteca. O Libmsquic receberá atualizações para 1.9.x quando necessário para incorporar correções de segurança.

Servidor HTTP/3

O HTTP/3 é compatível com ASP.NET com o servidor Kestrel no .NET 6 (como versão prévia) e no .NET 7 (totalmente compatível). Para obter mais informações, consulte Usar HTTP/3 com o servidor Web ASP.NET Core Kestrel.

Servidores de teste públicos

O Cloudflare hospeda um site para HTTP/3 que pode ser usado para testar o cliente em https://cloudflare-quic.com.

Confira também