Usare HTTP/3 con HttpClient

HTTP/3 è la terza versione principale standardizzata di recente di HTTP. HTTP/3 usa la stessa semantica di HTTP/1.1 e HTTP/2: a tutte le versioni si applicano i medesimi metodi di richiesta, codici di stato e campi dei messaggi. Le differenze stanno nel trasporto sottostante. Sia HTTP/1.1 che HTTP/2 usano TCP come protocollo di trasporto. HTTP/3 usa una tecnologia di trasporto sviluppata appositamente e denominata QUIC.

HTTP/3 e QUIC offrono entrambi diversi vantaggi rispetto a HTTP/1.1 e HTTP/2:

  • Tempo di risposta più rapido per la prima richiesta. QUIC e HTTP/3 negoziano la connessione con meno round trip tra il client e il server. La prima richiesta raggiunge il server più velocemente.
  • Esperienza migliorata quando si verifica una perdita di pacchetti di connessione. HTTP/2 esegue il multiplexing di più richieste tramite una connessione TCP. La perdita di pacchetti sulla connessione influisce su tutte le richieste. Questo problema è denominato "blocco head-of-line". Poiché QUIC fornisce il multiplexing nativo, i pacchetti persi influiscono solo sulle richieste in cui i dati sono stati persi.
  • Supporta la transizione tra reti. Questa funzionalità è utile per i dispositivi mobili in cui è comune passare dalla rete Wi-Fi alla rete cellulare quando un dispositivo mobile cambia posizione. Attualmente, durante il cambio di rete le connessioni HTTP/1.1 e HTTP/2 hanno esito negativo e restituiscono un errore. Un'app o un Web browser deve ripetere tutte le eventuali richieste HTTP non riuscite. HTTP/3 consente all'app o al Web browser di continuare senza problemi quando cambia la rete. HttpClient e Kestrel non supportano le transizioni di rete in .NET 7. Il supporto potrebbe essere disponibile in una versione futura.

Importante

Le app configurate per sfruttare i vantaggi di HTTP/3 devono essere progettate per supportare anche HTTP/1.1 e HTTP/2. Se vengono identificati problemi in HTTP/3, è consigliabile disabilitare HTTP/3 fino a quando non vengono risolti in una versione futura di .NET.

Impostazioni HttpClient

La versione HTTP può essere configurata impostando HttpRequestMessage.Version su 3.0. Tuttavia, poiché non tutti i router, i firewall e i proxy supportano correttamente HTTP/3, è consigliabile configurare HTTP/3 insieme a HTTP/1.1 e HTTP/2. In HttpClient è possibile eseguire questa operazione specificando:

Dipendenze della piattaforma

HTTP/3 usa QUIC come protocollo di trasporto. L'implementazione .NET di HTTP/3 usa MsQuic per fornire la funzionalità QUIC. Di conseguenza, il supporto .NET di HTTP/3 dipende dai requisiti della piattaforma MsQuic. Per altre informazioni su come installare MsQuic, vedere Dipendenze della piattaforma QUIC. Se la piattaforma in cui è in esecuzione HttpClient non ha tutti i requisiti per HTTP/3, questa versione è disabilitata.

Uso di HttpClient

Nell'esempio di codice seguente vengono usate istruzioni di primo livello e viene illustrato come specificare HTTP3 nella richiesta:

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

Supporto di HTTP/3 in .NET 6

In .NET 6 HTTP/3 è disponibile come funzionalità di anteprima perché la specifica HTTP/3 non era ancora finalizzata. In HTTP/3 con .NET 6 possono verificarsi problemi di comportamento o prestazioni. Per altre informazioni sulle funzionalità di anteprima, vedere la specifica delle funzionalità di anteprima.

Per abilitare il supporto HTTP/3 in .NET 6, includere il nodo RuntimeHostConfigurationOption nel file di progetto per abilitare HTTP/3 con HttpClient:

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

In alternativa, è possibile chiamare System.AppContext.SetSwitch dal codice dell'app o impostare la variabile di ambiente DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP3SUPPORT su true. Per altre informazioni, vedere Variabili di ambiente .NET: DOTNET_SYSTEM_NET_HTTP_*.

Il motivo per cui è necessario un flag di configurazione per HTTP/3 è proteggere le app da interruzioni future quando si usano i criteri di versione RequestVersionOrHigher. Quando si chiama un server che attualmente usa HTTP/1.1 e HTTP/2, se il server viene successivamente aggiornato a HTTP/3, il client tenterà di usare HTTP/3 e sarà potenzialmente non compatibile perché lo standard non è finale e potrebbe quindi cambiare dopo il rilascio di .NET 6.

.NET 6 è compatibile solo con le versioni 1.9.x di libmsquic. Libmsquic 2.x non è compatibile con .NET 6 a causa di modifiche che causano interruzioni nella libreria. Libmsquic riceve gli aggiornamenti alla versione 1.9.x quando sono necessari per incorporare correzioni di sicurezza.

Server HTTP/3

HTTP/3 è supportato da ASP.NET con il server Kestrel in .NET 6 (in anteprima) e .NET 7 (completamente supportato). Per altre informazioni, vedere Usare HTTP/3 con il server Web Kestrel ASP.NET Core.

Server di test pubblici

Cloudflare ospita un sito dedicato a HTTP/3 per testare il client all'indirizzo https://cloudflare-quic.com.

Vedi anche