Uso de HTTP/3 con HttpClient

HTTP/3 es la tercera y recientemente estandarizada versión principal de HTTP. HTTP/3 usa la misma semántica que HTTP/1.1 y HTTP/2: los mismos métodos de solicitud, códigos de estado y campos de mensaje se aplican a todas las versiones. Las diferencias están en el transporte subyacente. Tanto en HTTP/1.1 como en HTTP/2 se usa TCP como transporte. HTTP/3 usa una nueva tecnología de transporte desarrollada junto con HTTP/3 denominada QUIC.

HTTP/3 y QUIC tienen varias ventajas en comparación con HTTP/1.1 y HTTP/2:

  • Tiempo de respuesta más rápido para la primera solicitud. QUIC y HTTP/3 negocian la conexión en menos recorridos de ida y vuelta entre el cliente y el servidor. La primera solicitud llega más rápido al servidor.
  • Experiencia mejorada cuando hay pérdida de paquetes de conexión. HTTP/2 realiza la multiplexación de varias solicitudes por medio de una conexión TCP. La pérdida de paquetes en la conexión afecta a todas las solicitudes. Este problema se denomina "bloqueo de encabezado de línea". Como QUIC proporciona multiplexación nativa, los paquetes perdidos solo afectan a las solicitudes en las que se han perdido datos.
  • Admite la transición entre redes. Esta característica es útil para dispositivos móviles en los que es habitual cambiar entre redes Wi-Fi y móviles a medida que un dispositivo móvil cambia de ubicación. Actualmente, se producirá un error en las conexiones HTTP/1.1 y HTTP/2 al cambiar de red. Una aplicación o un explorador web tendrán que reintentar las solicitudes HTTP con error. HTTP/3 permite que la aplicación o el explorador web continúen sin problemas cuando cambia una red. HttpClient y Kestrel no admiten transiciones de red en .NET 7. Es posible que esté disponible en una versión futura.

Importante

Las aplicaciones configuradas para aprovechar las ventajas de HTTP/3 deben diseñarse para admitir también HTTP/1.1 y HTTP/2. Si se identifican problemas en HTTP/3, se recomienda deshabilitar HTTP/3 hasta que los problemas se resuelvan en una versión futura de .NET.

Configuración de HttpClient

La versión de HTTP se puede configurar estableciendo HttpRequestMessage.Version en 3.0. Sin embargo, como no todos los enrutadores, firewalls y servidores proxy admiten correctamente HTTP/3, se recomienda configurarlo junto con HTTP/1.1 y HTTP/2. En HttpClient, esto se puede hacer especificando lo siguiente:

Dependencias de la plataforma

En HTTP/3 se usa QUIC como protocolo de transporte. En la implementación de HTTP/3 en .NET se usa MsQuic para proporcionar la funcionalidad de QUIC. Como resultado, la compatibilidad de .NET con HTTP/3 depende de los requisitos de la plataforma MsQuic. Para obtener más información sobre cómo instalar MsQuic, vea dependencias de la plataforma QUIC. Si la plataforma en la que se ejecuta HttpClient no tiene todos los requisitos para HTTP/3, se deshabilita.

Usar HttpClient

En el ejemplo de código siguiente, se usan instrucciones de nivel superior y se muestra cómo especificar HTTP/3 en la solicitud:

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

Compatibilidad con HTTP/3 en .NET 6

En .NET 6, HTTP/3 está disponible como característica en versión preliminar porque la especificación HTTP/3 aún no se había finalizado. Los problemas de comportamiento o rendimiento pueden existir en HTTP/3 con .NET 6. Para obtener más información sobre las características en versión preliminar, consulte la especificación de características en versión preliminar.

Para habilitar la compatibilidad con HTTP/3 en .NET 6, incluya el nodo RuntimeHostConfigurationOption en el archivo de proyecto para habilitar HTTP/3 con HttpClient:

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

Como alternativa, puede llamar a System.AppContext.SetSwitch desde el código de la aplicación o establecer la variable de entorno DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP3SUPPORT en true. Para obtener más información, consulte Variables de entorno de .NET: DOTNET_SYSTEM_NET_HTTP_*.

La razón para requerir una marca de configuración para HTTP/3 es proteger las aplicaciones frente a futuras interrupciones al usar la directiva de versión RequestVersionOrHigher. Al llamar a un servidor que actualmente usa HTTP/1.1 y HTTP/2, si el servidor se actualiza posteriormente a HTTP/3, el cliente intentaría usar HTTP/3 y podría ser incompatible, ya que el estándar no es final y, por tanto, puede cambiar después de la publicación de .NET 6.

.NET 6 solo es compatible con las versiones 1.9.x de libmsquic. Libmsquic 2.x no es compatible con .NET 6 debido a cambios importantes en la biblioteca. Libmsquic recibe actualizaciones de la versión 1.9.x cuando sea necesario para incorporar correcciones de seguridad.

Servidor HTTP/3

HTTP/3 es compatible con ASP.NET con el servidor Kestrel en .NET 6 (como versión preliminar) y .NET 7 (es totalmente compatible). Para obtener más información, consulte Uso de HTTP/3 con el servidor web Kestrel de ASP.NET Core.

Servidores de prueba públicos

Cloudflare hospeda un sitio para HTTP/3 que se puede usar para probar el cliente en https://cloudflare-quic.com.

Consulte también