Implementazione del server Web HTTP.sys in ASP.NET Core

Tom Dykstra e Chris Ross

HTTP.sys è un server Web per ASP.NET Core che può essere eseguito solo in Windows. HTTP.sys è un'alternativa al Kestrel server e offre alcune funzionalità che Kestrel non forniscono.

Importante

HTTP.sys non è compatibile con il modulo ASP.NET Core e non può essere usato con IIS o IIS Express.

HTTP.sys supporta le funzionalità seguenti:

  • Autenticazione di Windows
  • Condivisione delle porte
  • HTTPS con SNI
  • HTTP/2 su TLS (Windows 10 o versioni successive)
  • Trasmissione diretta dei file
  • Memorizzazione nella cache delle risposte
  • WebSockets (Windows 8 o versioni successive)

Versioni supportate di Windows:

  • Windows 7 o versione successiva
  • Windows Server 2008 R2 o versione successiva

Visualizzare o scaricare il codice di esempio (procedura per il download)

Quando usare HTTP.sys

HTTP.sys è utile per le distribuzioni nei casi seguenti:

  • È necessario esporre il server direttamente a Internet senza usare IIS.

    HTTP.sys communicates directly with the Internet

  • Una distribuzione interna richiede una funzionalità non disponibile in Kestrel. Per altre informazioni, vedere Kestrel vs. HTTP.sys

    HTTP.sys communicates directly with the internal network

HTTP.sys è una tecnologia consolidata che protegge da molti tipi di attacchi e offre l'affidabilità, la sicurezza e la scalabilità di un server Web con funzionalità complete. IIS viene eseguito come listener HTTP in HTTP.sys.

Supporto HTTP/2

HTTP/2 è abilitato per ASP.NET app Core quando vengono soddisfatti i requisiti di base seguenti:

Se viene stabilita una connessione HTTP/2, HttpRequest.Protocol corrisponde a HTTP/2.

HTTP/2 è abilitato per impostazione predefinita. Se non viene stabilita una connessione HTTP/2, la connessione esegue il fallback a HTTP/1.1. In una versione futura di Windows sarà disponibile il flag di configurazione di HTTP/2 e sarà possibile disabilitare il protocollo HTTP/2 con HTTP.sys.

Supporto HTTP/3

HTTP/3 è abilitato per ASP.NET app Core quando vengono soddisfatti i requisiti di base seguenti:

  • Windows Server 2022/Windows 11 o versione successiva
  • Viene usata un'associazione https url.
  • La chiave del Registro di sistema EnableHttp3 è impostata.

Le versioni precedenti di Windows 11 Build possono richiedere l'uso di una build di Windows Insider .

HTTP/3 viene individuato come aggiornamento da HTTP/1.1 o HTTP/2 tramite l'intestazione alt-svc . Ciò significa che la prima richiesta userà normalmente HTTP/1.1 o HTTP/2 prima di passare a HTTP/3. Http.Sys non aggiunge automaticamente l'intestazione alt-svc , ma deve essere aggiunta dall'applicazione. Il codice seguente è un esempio di middleware che aggiunge l'intestazione della alt-svc risposta.

app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});

Inserire il codice precedente nelle prime fasi della pipeline della richiesta.

Http.Sys supporta anche l'invio di un messaggio di protocollo ALTSvc HTTP/2 anziché un'intestazione di risposta per notificare al client che HTTP/3 è disponibile. Vedere la chiave del Registro di sistema EnableAltSvc. Sono necessarie associazioni netsh sslcert che usano nomi host anziché indirizzi IP.

Autenticazione in modalità kernel con Kerberos

Per la delega all'autenticazione in modalità kernel, HTTP.sys usa il protocollo di autenticazione Kerberos. L'autenticazione in modalità utente non è supportata con Kerberos e HTTP.sys. È necessario usare l'account del computer per decrittografare il token/ticket Kerberos ottenuto da Active Directory e inoltrato dal client al server per autenticare l'utente. Registrare il nome dell'entità servizio per l'host, non l'utente dell'app.

Supporto per il buffer delle risposte in modalità kernel

In alcuni scenari, volumi elevati di scritture di piccole dimensioni con latenza elevata possono causare un impatto significativo sulle prestazioni di HTTP.sys. Questo impatto è dovuto alla mancanza di un Pipe buffer nell'implementazione HTTP.sys . Per migliorare le prestazioni in questi scenari, il supporto per il buffer delle risposte è incluso in HTTP.sys. Abilitare il buffering impostando HttpSysOptions.EnableKernelResponseBuffering su true.

Il buffer delle risposte deve essere abilitato da un'app che esegue operazioni di I/O sincrone o I/O asincrone senza più di una scrittura in sospeso alla volta. In questi scenari, il buffer delle risposte può migliorare significativamente la velocità effettiva rispetto alle connessioni a latenza elevata.

Le app che usano operazioni di I/O asincrone e che possono avere più di una scrittura in sospeso alla volta non devono usare questo flag. L'abilitazione di questo flag può comportare un utilizzo di CPU e memoria superiore da HTTP.Sys.

Come usare HTTP.sys

Configurare l'app ASP.NET Core per l'uso di HTTP.sys

Chiamare il metodo di estensione UseHttpSys quando si compila l'host, specificando le eventuali HttpSysOptions necessarie. L'esempio seguente imposta le opzioni sui rispettivi valori predefiniti:

using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys(options =>
{
    options.AllowSynchronousIO = false;
    options.Authentication.Schemes = AuthenticationSchemes.None;
    options.Authentication.AllowAnonymous = true;
    options.MaxConnections = null;
    options.MaxRequestBodySize = 30_000_000;
    options.UrlPrefixes.Add("http://localhost:5005");
});

builder.Services.AddRazorPages();

var app = builder.Build();

Le configurazioni aggiuntive di HTTP.sys vengono gestite tramite impostazioni del Registro di sistema.

Per altre informazioni sulle opzioni HTTP.sys, vedere HttpSysOptions.

MaxRequestBodySize

Dimensioni massime consentite per qualsiasi corpo della richiesta in byte. Con l'impostazione null, le dimensioni massime del corpo della richiesta sono illimitate. Questo limite non ha effetto sulle connessioni aggiornate, che sono sempre illimitate.

Il metodo consigliato per ignorare il limite in un'applicazione ASP.NET Core MVC per un singolo IActionResult prevede l'uso dell'attributo RequestSizeLimitAttribute in un metodo di azione:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Se l'app tenta di configurare il limite per una richiesta dopo che l'app ha avviato la lettura della richiesta stessa, viene generata un'eccezione. È possibile usare una proprietà IsReadOnly per indicare se la proprietà MaxRequestBodySize è in stato di sola lettura e pertanto è troppo tardi per configurare il limite.

Se l'app deve eseguire l'override di MaxRequestBodySize per ogni richiesta, usare IHttpMaxRequestBodySizeFeature:

app.Use((context, next) =>
{
    context.Features.GetRequiredFeature<IHttpMaxRequestBodySizeFeature>()
                                             .MaxRequestBodySize = 10 * 1024;

    var server = context.RequestServices
        .GetRequiredService<IServer>();
    var serverAddressesFeature = server.Features
                                 .GetRequiredFeature<IServerAddressesFeature>();

    var addresses = string.Join(", ", serverAddressesFeature.Addresses);

    var loggerFactory = context.RequestServices
        .GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    logger.LogInformation("Addresses: {addresses}", addresses);

    return next(context);
});

Se si usa Visual Studio, assicurarsi che l'app non sia configurata per l'esecuzione di IIS o IIS Express.

In Visual Studio il profilo di avvio predefinito è per IIS Express. Per eseguire il progetto come app console, modificare manualmente il profilo selezionato, come illustrato nello screenshot seguente:

Select console app profile

Configurare Windows Server

  1. Determinare le porte da aprire per l'app e usare Windows Firewall o il cmdlet di PowerShell New-NetFirewallRule per aprire le porte del firewall per consentire al traffico di raggiungere HTTP.sys. Nei comandi seguenti e nella configurazione dell'app, viene usata la porta 443.

  2. Quando si distribuisce una macchina virtuale di Azure, aprire le porte nel gruppo di sicurezza di rete. Nei comandi seguenti e nella configurazione dell'app, viene usata la porta 443.

  3. Ottenere e installare i certificati X.509, se necessario.

    In Windows, creare certificati autofirmati con il cmdlet di PowerShell New-SelfSignedCertificate. Per un esempio non supportato, vedere UpdateIISExpressSSLForChrome.ps1.

    Installare i certificati autofirmati o con firma nell'archivio Computer locale>Personale del server.

  4. Se l'app è una distribuzione dipendente dal framework, installare .NET Core, .NET Framework o entrambi (se l'app è un'app .NET Core destinata a .NET Framework).

    • .NET Core: se l'app richiede .NET Core, ottenere ed eseguire il programma di installazione del runtime .NET Core dai download di .NET Core. Non installare l'SDK completo nel server.
    • .NET Framework: se l'app richiede .NET Framework, vedere la guida all'installazione di .NET Framework. Installare la versione di .NET Framework richiesta. Il programma di installazione per la versione più recente di .NET Framework è disponibile dalla pagina di download per .NET Core.

    Se l'app è una distribuzione autonoma include il runtime nella distribuzione. Non è richiesta l'installazione di un framework nel server.

  5. Configurare gli URL e le porte nell'app.

    Per impostazione predefinita, ASP.NET Core è associato a http://localhost:5000. Per configurare le porte e i prefissi URL, è possibile usare:

    • UseUrls
    • L'argomento della riga di comando urls
    • La variabile di ambiente ASPNETCORE_URLS
    • UrlPrefixes

    L'esempio di codice seguente mostra come usare UrlPrefixes con l'indirizzo IP locale del server 10.0.0.4 sulla porta 443:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.WebHost.UseHttpSys(options =>
    {
        options.UrlPrefixes.Add("https://10.0.0.4:443");
    });
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    

    Un vantaggio offerto da UrlPrefixes è che viene generato immediatamente un messaggio di errore per i prefissi non formattati correttamente.

    Le impostazioni di UrlPrefixes sostituiscono le impostazioni UseUrls/urls/ASPNETCORE_URLS. Pertanto, un vantaggio di UseUrls, urlse la ASPNETCORE_URLS variabile di ambiente è che è più facile passare da Kestrel a HTTP.sys.

    HTTP.sys riconosce due tipi di caratteri jolly nei prefissi URL:

    • *è un'associazione debole, nota anche come associazione di fallback. Se il prefisso URL è http://*:5000e qualcos'altro è associato alla porta 5000, questa associazione non verrà usata.
    • + è un binding sicuro. Se il prefisso URL è http://+:5000, questa associazione verrà usata prima di altre associazioni della porta 5000.

    Per altre informazioni, vedere Stringhe urlPrefix.

    Avviso

    Le associazioni con caratteri jolly di livello superiore (http://*:80/ e http://+:80) non devono essere usate, poiché possono creare vulnerabilità a livello di sicurezza nell'app. Questo concetto vale sia per i caratteri jolly sicuri che vulnerabili. Usare nomi host o indirizzi IP espliciti al posto di caratteri jolly. L'associazione con caratteri jolly del sottodominio (ad esempio, *.mysub.com) non costituisce un rischio per la sicurezza se viene controllato l'intero dominio padre (a differenza di *.com, che è vulnerabile). Per altre informazioni, vedere RFC 9110: Sezione 7.2: Host e :authority.

    Le app e i contenitori vengono spesso assegnati solo a una porta in ascolto, ad esempio la porta 80, senza vincoli aggiuntivi come host o percorso. HTTP_PORTS e HTTPS_PORTS sono chiavi di configurazione che specificano le porte di ascolto per i Kestrel server e HTTP.sys. Queste chiavi possono essere specificate come variabili di ambiente definite con i DOTNET_ prefissi o ASPNETCORE_ specificate direttamente tramite qualsiasi altro input di configurazione, ad esempio appsettings.json. Ogni è un elenco delimitato da punto e virgola di valori di porta, come illustrato nell'esempio seguente:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    L'esempio precedente è abbreviato per la configurazione seguente, che specifica lo schema (HTTP o HTTPS) e qualsiasi host o IP.

    ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/
    

    Le chiavi di configurazione HTTP_PORTS e HTTPS_PORTS sono priorità più bassa e vengono sostituite da URL o valori forniti direttamente nel codice. I certificati devono comunque essere configurati separatamente tramite meccanismi specifici del server per HTTPS.

    Queste chiavi di configurazione sono equivalenti alle associazioni con caratteri jolly di primo livello. Sono utili per scenari di sviluppo e contenitori, ma evitare caratteri jolly durante l'esecuzione in un computer che può anche ospitare altri servizi.

  6. Pre-registrare i prefissi URL nel server.

    Lo strumento predefinito per la configurazione di HTTP.sys è netsh.exe. Netsh.exe viene usato per riservare i prefissi URL e assegnare i certificati X.509. Per questo strumento sono necessari privilegi di amministratore.

    Usare lo strumento netsh.exe per registrare gli URL per l'app:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: URL (Uniform Resource Locator) completo. Non usare un'associazione con caratteri jolly. Usare un nome host valido o un indirizzo IP locale. L'URL deve includere una barra finale.
    • <USER>: specifica il nome dell'utente o del gruppo di utenti.

    Nell'esempio seguente, l'indirizzo IP locale del server è 10.0.0.4:

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    Quando viene registrato un URL, lo strumento risponde con URL reservation successfully added.

    Per eliminare un URL registrato, usare il comando delete urlacl:

    netsh http delete urlacl url=<URL>
    
  7. Registrare i certificati X.509 nel server.

    Usare lo strumento netsh.exe per registrare i certificati per l'app:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: specifica l'indirizzo IP locale per l'associazione. Non usare un'associazione con caratteri jolly. Usare un indirizzo IP valido.
    • <PORT>: specifica la porta per l'associazione.
    • <THUMBPRINT>: identificazione personale del certificato X.509.
    • <GUID>: GUID generato dallo sviluppatore per rappresentare l'app a scopo informativo.

    A scopo di riferimento, archiviare il GUID nell'app come tag di pacchetto:

    • In Visual Studio:
      • Aprire le proprietà del progetto dell'app facendo clic sull'app con il pulsante destro del mouse in Esplora soluzioni e scegliendo Proprietà.
      • Selezionare la scheda Pacchetto.
      • Immettere il GUID creato nel campo Tag.
    • Quando non si usa Visual Studio:
      • Aprire il file di progetto dell'app.

      • Aggiungere una proprietà <PackageTags> a un <PropertyGroup> nuovo o esistente con il GUID creato:

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    Nell'esempio seguente:

    • L'indirizzo IP locale del server è 10.0.0.4.
    • Un generatore di GUID casuali online fornisce il valore appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    Quando viene registrato un certificato, lo strumento risponde con SSL Certificate successfully added.

    Per eliminare la registrazione di un certificato, usare il comando delete sslcert:

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Documentazione di riferimento per netsh.exe:

  8. Eseguire l'app.

    Non sono necessari i privilegi di amministratore per eseguire l'app con binding a localhost tramite HTTP (non HTTPS) con un numero di porta maggiore di 1024. Per altre configurazioni (ad esempio, l'uso di un indirizzo IP locale o il binding sulla porta 443), eseguire l'app con i privilegi di amministratore.

    L'app risponde all'indirizzo IP pubblico del server. In questo esempio, il server è raggiungibile da Internet al relativo indirizzo IP pubblico 104.214.79.47.

    In questo esempio viene usato un certificato di sviluppo. La pagina viene caricata in modo sicuro dopo aver ignorato l'avviso di certificato non attendibile del browser.

    Browser window showing the app's Index page loaded

Scenari con server proxy e servizi di bilanciamento del carico

Per le app ospitate da HTTP.sys che interagiscono con richieste da Internet o da una rete aziendale, potrebbero essere necessari interventi di configurazione aggiuntivi in caso di hosting dietro server proxy e servizi di bilanciamento del carico. Per altre informazioni, vedere Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico.

Ottenere informazioni dettagliate sulla tempistica con IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature fornisce informazioni dettagliate sulla tempistica per le richieste:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
    
    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timestamps = feature.Timestamps;

    for (var i = 0; i < timestamps.Length; i++)
    {
        var timestamp = timestamps[i];
        var timingType = (HttpSysRequestTimingType)i;

        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

IHttpSysRequestTimingFeature.TryGetTimestamp recupera il timestamp per il tipo di intervallo specificato:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetTimestamp(timingType, out var timestamp))
    {
        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }
    else
    {
        logger.LogInformation("Timestamp {timingType}: not available for the "
                                           + "current request",    timingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

IHttpSysRequestTimingFeature.TryGetElapsedTime fornisce il tempo trascorso tra due intervalli specificati:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var startingTimingType = HttpSysRequestTimingType.RequestRoutingStart;
    var endingTimingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetElapsedTime(startingTimingType, endingTimingType, out var elapsed))
    {
        logger.LogInformation(
            "Elapsed time {startingTimingType} to {endingTimingType}: {elapsed}",
            startingTimingType,
            endingTimingType,
            elapsed);
    }
    else
    {
        logger.LogInformation(
            "Elapsed time {startingTimingType} to {endingTimingType}:"
            + " not available for the current request.",
            startingTimingType,
            endingTimingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

Funzionalità avanzate http/2 per supportare gRPC

Altre funzionalità HTTP/2 in HTTP.sys supportano gRPC, incluso il supporto per i trailer di risposta e l'invio di fotogrammi di reimpostazione.

Requisiti per eseguire gRPC con HTTP.sys:

  • Windows 11 Build 22000 o versione successiva, Windows Server 2022 Build 20348 o versione successiva.
  • Connessione TLS 1.2 o successiva.

Trailer

I trailer HTTP sono simili alle intestazioni HTTP, tranne che vengono inviati dopo l'invio del corpo della risposta. Per IIS e HTTP.sys, sono supportati solo i trailer di risposta HTTP/2.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

Nel codice di esempio precedente:

  • SupportsTrailers assicura che i trailer siano supportati per la risposta.
  • DeclareTrailer aggiunge il nome del trailer specificato all'intestazione della Trailer risposta. La dichiarazione dei trailer di una risposta è facoltativa, ma consigliata. Se DeclareTrailer viene chiamato, deve essere prima dell'invio delle intestazioni di risposta.
  • AppendTrailer aggiunge il trailer.

Reset

La reimpostazione consente al server di reimpostare una richiesta HTTP/2 con un codice di errore specificato. Una richiesta di reimpostazione viene considerata interrotta.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset nell'esempio di codice precedente specifica il INTERNAL_ERROR codice di errore. Per altre informazioni sui codici di errore HTTP/2, vedere la sezione relativa al codice di errore della specifica HTTP/2.

Tracciabilità

Per informazioni su come ottenere tracce da HTTP.sys, vedere Scenari di gestibilità HTTP.sys.

Risorse aggiuntive

HTTP.sys è un server Web per ASP.NET Core che può essere eseguito solo in Windows. HTTP.sys è un'alternativa al Kestrel server e offre alcune funzionalità che Kestrel non forniscono.

Importante

HTTP.sys non è compatibile con il modulo ASP.NET Core e non può essere usato con IIS o IIS Express.

HTTP.sys supporta le funzionalità seguenti:

  • Autenticazione di Windows
  • Condivisione delle porte
  • HTTPS con SNI
  • HTTP/2 su TLS (Windows 10 o versioni successive)
  • Trasmissione diretta dei file
  • Memorizzazione nella cache delle risposte
  • WebSockets (Windows 8 o versioni successive)

Versioni supportate di Windows:

  • Windows 7 o versione successiva
  • Windows Server 2008 R2 o versione successiva

Visualizzare o scaricare il codice di esempio (procedura per il download)

Quando usare HTTP.sys

HTTP.sys è utile per le distribuzioni nei casi seguenti:

  • È necessario esporre il server direttamente a Internet senza usare IIS.

    HTTP.sys communicates directly with the Internet

  • Una distribuzione interna richiede una funzionalità non disponibile in Kestrel. Per altre informazioni, vedere Kestrel vs. HTTP.sys

    HTTP.sys communicates directly with the internal network

HTTP.sys è una tecnologia consolidata che protegge da molti tipi di attacchi e offre l'affidabilità, la sicurezza e la scalabilità di un server Web con funzionalità complete. IIS viene eseguito come listener HTTP in HTTP.sys.

Supporto HTTP/2

HTTP/2 è abilitato per ASP.NET app Core quando vengono soddisfatti i requisiti di base seguenti:

Se viene stabilita una connessione HTTP/2, HttpRequest.Protocol corrisponde a HTTP/2.

HTTP/2 è abilitato per impostazione predefinita. Se non viene stabilita una connessione HTTP/2, la connessione esegue il fallback a HTTP/1.1. In una versione futura di Windows sarà disponibile il flag di configurazione di HTTP/2 e sarà possibile disabilitare il protocollo HTTP/2 con HTTP.sys.

Supporto HTTP/3

HTTP/3 è abilitato per ASP.NET app Core quando vengono soddisfatti i requisiti di base seguenti:

  • Windows Server 2022/Windows 11 o versione successiva
  • Viene usata un'associazione https url.
  • La chiave del Registro di sistema EnableHttp3 è impostata.

Le versioni precedenti di Windows 11 Build possono richiedere l'uso di una build di Windows Insider .

HTTP/3 viene individuato come aggiornamento da HTTP/1.1 o HTTP/2 tramite l'intestazione alt-svc . Ciò significa che la prima richiesta userà normalmente HTTP/1.1 o HTTP/2 prima di passare a HTTP/3. Http.Sys non aggiunge automaticamente l'intestazione alt-svc , ma deve essere aggiunta dall'applicazione. Il codice seguente è un esempio di middleware che aggiunge l'intestazione della alt-svc risposta.

app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});

Inserire il codice precedente nelle prime fasi della pipeline della richiesta.

Http.Sys supporta anche l'invio di un messaggio di protocollo ALTSvc HTTP/2 anziché un'intestazione di risposta per notificare al client che HTTP/3 è disponibile. Vedere la chiave del Registro di sistema EnableAltSvc. Sono necessarie associazioni netsh sslcert che usano nomi host anziché indirizzi IP.

Autenticazione in modalità kernel con Kerberos

Per la delega all'autenticazione in modalità kernel, HTTP.sys usa il protocollo di autenticazione Kerberos. L'autenticazione in modalità utente non è supportata con Kerberos e HTTP.sys. È necessario usare l'account del computer per decrittografare il token/ticket Kerberos ottenuto da Active Directory e inoltrato dal client al server per autenticare l'utente. Registrare il nome dell'entità servizio per l'host, non l'utente dell'app.

Come usare HTTP.sys

Configurare l'app ASP.NET Core per l'uso di HTTP.sys

Chiamare il metodo di estensione UseHttpSys quando si compila l'host, specificando le eventuali HttpSysOptions necessarie. L'esempio seguente imposta le opzioni sui rispettivi valori predefiniti:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseHttpSys(options =>
            {
                options.AllowSynchronousIO = false;
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = null;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5005");
            });
            webBuilder.UseStartup<Startup>();
        });

Le configurazioni aggiuntive di HTTP.sys vengono gestite tramite impostazioni del Registro di sistema.

Per altre informazioni sulle opzioni HTTP.sys, vedere HttpSysOptions.

MaxRequestBodySize

Dimensioni massime consentite per qualsiasi corpo della richiesta in byte. Con l'impostazione null, le dimensioni massime del corpo della richiesta sono illimitate. Questo limite non ha effetto sulle connessioni aggiornate, che sono sempre illimitate.

Il metodo consigliato per ignorare il limite in un'applicazione ASP.NET Core MVC per un singolo IActionResult prevede l'uso dell'attributo RequestSizeLimitAttribute in un metodo di azione:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Se l'app tenta di configurare il limite per una richiesta dopo che l'app ha avviato la lettura della richiesta stessa, viene generata un'eccezione. È possibile usare una proprietà IsReadOnly per indicare se la proprietà MaxRequestBodySize è in stato di sola lettura e pertanto è troppo tardi per configurare il limite.

Se l'app deve eseguire l'override di MaxRequestBodySize per ogni richiesta, usare IHttpMaxRequestBodySizeFeature:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    ILogger<Startup> logger, IServer server)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        var serverAddressesFeature = 
            app.ServerFeatures.Get<IServerAddressesFeature>();
        var addresses = string.Join(", ", serverAddressesFeature?.Addresses);

        logger.LogInformation("Addresses: {Addresses}", addresses);

        await next.Invoke();
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Se si usa Visual Studio, assicurarsi che l'app non sia configurata per l'esecuzione di IIS o IIS Express.

In Visual Studio il profilo di avvio predefinito è per IIS Express. Per eseguire il progetto come app console, modificare manualmente il profilo selezionato, come illustrato nello screenshot seguente:

Select console app profile

Configurare Windows Server

  1. Determinare le porte da aprire per l'app e usare Windows Firewall o il cmdlet di PowerShell New-NetFirewallRule per aprire le porte del firewall per consentire al traffico di raggiungere HTTP.sys. Nei comandi seguenti e nella configurazione dell'app, viene usata la porta 443.

  2. Quando si distribuisce una macchina virtuale di Azure, aprire le porte nel gruppo di sicurezza di rete. Nei comandi seguenti e nella configurazione dell'app, viene usata la porta 443.

  3. Ottenere e installare i certificati X.509, se necessario.

    In Windows, creare certificati autofirmati con il cmdlet di PowerShell New-SelfSignedCertificate. Per un esempio non supportato, vedere UpdateIISExpressSSLForChrome.ps1.

    Installare i certificati autofirmati o con firma nell'archivio Computer locale>Personale del server.

  4. Se l'app è una distribuzione dipendente dal framework, installare .NET Core, .NET Framework o entrambi (se l'app è un'app .NET Core destinata a .NET Framework).

    • .NET Core: se l'app richiede .NET Core, ottenere ed eseguire il programma di installazione del runtime .NET Core dai download di .NET Core. Non installare l'SDK completo nel server.
    • .NET Framework: se l'app richiede .NET Framework, vedere la guida all'installazione di .NET Framework. Installare la versione di .NET Framework richiesta. Il programma di installazione per la versione più recente di .NET Framework è disponibile dalla pagina di download per .NET Core.

    Se l'app è una distribuzione autonoma include il runtime nella distribuzione. Non è richiesta l'installazione di un framework nel server.

  5. Configurare gli URL e le porte nell'app.

    Per impostazione predefinita, ASP.NET Core è associato a http://localhost:5000. Per configurare le porte e i prefissi URL, è possibile usare:

    • UseUrls
    • L'argomento della riga di comando urls
    • La variabile di ambiente ASPNETCORE_URLS
    • UrlPrefixes

    L'esempio di codice seguente mostra come usare UrlPrefixes con l'indirizzo IP locale del server 10.0.0.4 sulla porta 443:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.UrlPrefixes.Add("https://10.0.0.4:443");
                });
                webBuilder.UseStartup<Startup>();
            });
    

    Un vantaggio offerto da UrlPrefixes è che viene generato immediatamente un messaggio di errore per i prefissi non formattati correttamente.

    Le impostazioni di UrlPrefixes sostituiscono le impostazioni UseUrls/urls/ASPNETCORE_URLS. Pertanto, un vantaggio di UseUrls, urlse la ASPNETCORE_URLS variabile di ambiente è che è più facile passare da Kestrel a HTTP.sys.

    HTTP.sys usa i formati di stringa UrlPrefix dell'API del server HTTP.

    Avviso

    Le associazioni con caratteri jolly di livello superiore (http://*:80/ e http://+:80) non devono essere usate, poiché possono creare vulnerabilità a livello di sicurezza nell'app. Questo concetto vale sia per i caratteri jolly sicuri che vulnerabili. Usare nomi host o indirizzi IP espliciti al posto di caratteri jolly. L'associazione con caratteri jolly del sottodominio (ad esempio, *.mysub.com) non costituisce un rischio per la sicurezza se viene controllato l'intero dominio padre (a differenza di *.com, che è vulnerabile). Per altre informazioni, vedere RFC 9110: Sezione 7.2: Host e :authority.

  6. Pre-registrare i prefissi URL nel server.

    Lo strumento predefinito per la configurazione di HTTP.sys è netsh.exe. Netsh.exe viene usato per riservare i prefissi URL e assegnare i certificati X.509. Per questo strumento sono necessari privilegi di amministratore.

    Usare lo strumento netsh.exe per registrare gli URL per l'app:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: URL (Uniform Resource Locator) completo. Non usare un'associazione con caratteri jolly. Usare un nome host valido o un indirizzo IP locale. L'URL deve includere una barra finale.
    • <USER>: specifica il nome dell'utente o del gruppo di utenti.

    Nell'esempio seguente, l'indirizzo IP locale del server è 10.0.0.4:

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    Quando viene registrato un URL, lo strumento risponde con URL reservation successfully added.

    Per eliminare un URL registrato, usare il comando delete urlacl:

    netsh http delete urlacl url=<URL>
    
  7. Registrare i certificati X.509 nel server.

    Usare lo strumento netsh.exe per registrare i certificati per l'app:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: specifica l'indirizzo IP locale per l'associazione. Non usare un'associazione con caratteri jolly. Usare un indirizzo IP valido.
    • <PORT>: specifica la porta per l'associazione.
    • <THUMBPRINT>: identificazione personale del certificato X.509.
    • <GUID>: GUID generato dallo sviluppatore per rappresentare l'app a scopo informativo.

    A scopo di riferimento, archiviare il GUID nell'app come tag di pacchetto:

    • In Visual Studio:
      • Aprire le proprietà del progetto dell'app facendo clic sull'app con il pulsante destro del mouse in Esplora soluzioni e scegliendo Proprietà.
      • Selezionare la scheda Pacchetto.
      • Immettere il GUID creato nel campo Tag.
    • Quando non si usa Visual Studio:
      • Aprire il file di progetto dell'app.

      • Aggiungere una proprietà <PackageTags> a un <PropertyGroup> nuovo o esistente con il GUID creato:

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    Nell'esempio seguente:

    • L'indirizzo IP locale del server è 10.0.0.4.
    • Un generatore di GUID casuali online fornisce il valore appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    Quando viene registrato un certificato, lo strumento risponde con SSL Certificate successfully added.

    Per eliminare la registrazione di un certificato, usare il comando delete sslcert:

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Documentazione di riferimento per netsh.exe:

  8. Eseguire l'app.

    Non sono necessari i privilegi di amministratore per eseguire l'app con binding a localhost tramite HTTP (non HTTPS) con un numero di porta maggiore di 1024. Per altre configurazioni (ad esempio, l'uso di un indirizzo IP locale o il binding sulla porta 443), eseguire l'app con i privilegi di amministratore.

    L'app risponde all'indirizzo IP pubblico del server. In questo esempio, il server è raggiungibile da Internet al relativo indirizzo IP pubblico 104.214.79.47.

    In questo esempio viene usato un certificato di sviluppo. La pagina viene caricata in modo sicuro dopo aver ignorato l'avviso di certificato non attendibile del browser.

    Browser window showing the app's Index page loaded

Scenari con server proxy e servizi di bilanciamento del carico

Per le app ospitate da HTTP.sys che interagiscono con richieste da Internet o da una rete aziendale, potrebbero essere necessari interventi di configurazione aggiuntivi in caso di hosting dietro server proxy e servizi di bilanciamento del carico. Per altre informazioni, vedere Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico.

Funzionalità avanzate http/2 per supportare gRPC

Altre funzionalità HTTP/2 in HTTP.sys supportano gRPC, incluso il supporto per i trailer di risposta e l'invio di fotogrammi di reimpostazione.

Requisiti per eseguire gRPC con HTTP.sys:

  • Windows 11 Build 22000 o versione successiva, Windows Server 2022 Build 20348 o versione successiva.
  • Connessione TLS 1.2 o successiva.

Trailer

I trailer HTTP sono simili alle intestazioni HTTP, tranne che vengono inviati dopo l'invio del corpo della risposta. Per IIS e HTTP.sys, sono supportati solo i trailer di risposta HTTP/2.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

Nel codice di esempio precedente:

  • SupportsTrailers assicura che i trailer siano supportati per la risposta.
  • DeclareTrailer aggiunge il nome del trailer specificato all'intestazione della Trailer risposta. La dichiarazione dei trailer di una risposta è facoltativa, ma consigliata. Se DeclareTrailer viene chiamato, deve essere prima dell'invio delle intestazioni di risposta.
  • AppendTrailer aggiunge il trailer.

Reset

La reimpostazione consente al server di reimpostare una richiesta HTTP/2 con un codice di errore specificato. Una richiesta di reimpostazione viene considerata interrotta.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset nell'esempio di codice precedente specifica il INTERNAL_ERROR codice di errore. Per altre informazioni sui codici di errore HTTP/2, vedere la sezione relativa al codice di errore della specifica HTTP/2.

Risorse aggiuntive

HTTP.sys è un server Web per ASP.NET Core che può essere eseguito solo in Windows. HTTP.sys è un'alternativa al Kestrel server e offre alcune funzionalità che Kestrel non forniscono.

Importante

HTTP.sys non è compatibile con il modulo ASP.NET Core e non può essere usato con IIS o IIS Express.

HTTP.sys supporta le funzionalità seguenti:

  • Autenticazione di Windows
  • Condivisione delle porte
  • HTTPS con SNI
  • HTTP/2 su TLS (Windows 10 o versioni successive)
  • Trasmissione diretta dei file
  • Memorizzazione nella cache delle risposte
  • WebSockets (Windows 8 o versioni successive)

Versioni supportate di Windows:

  • Windows 7 o versione successiva
  • Windows Server 2008 R2 o versione successiva

Visualizzare o scaricare il codice di esempio (procedura per il download)

Quando usare HTTP.sys

HTTP.sys è utile per le distribuzioni nei casi seguenti:

  • È necessario esporre il server direttamente a Internet senza usare IIS.

    HTTP.sys communicates directly with the Internet

  • Una distribuzione interna richiede una funzionalità non disponibile in Kestrel. Per altre informazioni, vedere Kestrel vs. HTTP.sys

    HTTP.sys communicates directly with the internal network

HTTP.sys è una tecnologia consolidata che protegge da molti tipi di attacchi e offre l'affidabilità, la sicurezza e la scalabilità di un server Web con funzionalità complete. IIS viene eseguito come listener HTTP in HTTP.sys.

Supporto HTTP/2

HTTP/2 è abilitato per le app ASP.NET Core se vengono soddisfatti i requisiti di base seguenti:

Se viene stabilita una connessione HTTP/2, HttpRequest.Protocol corrisponde a HTTP/2.

HTTP/2 è abilitato per impostazione predefinita. Se non viene stabilita una connessione HTTP/2, la connessione esegue il fallback a HTTP/1.1. In una versione futura di Windows sarà disponibile il flag di configurazione di HTTP/2 e sarà possibile disabilitare il protocollo HTTP/2 con HTTP.sys.

Autenticazione in modalità kernel con Kerberos

Per la delega all'autenticazione in modalità kernel, HTTP.sys usa il protocollo di autenticazione Kerberos. L'autenticazione in modalità utente non è supportata con Kerberos e HTTP.sys. È necessario usare l'account del computer per decrittografare il token/ticket Kerberos ottenuto da Active Directory e inoltrato dal client al server per autenticare l'utente. Registrare il nome dell'entità servizio per l'host, non l'utente dell'app.

Come usare HTTP.sys

Configurare l'app ASP.NET Core per l'uso di HTTP.sys

Chiamare il metodo di estensione UseHttpSys quando si compila l'host, specificando le eventuali HttpSysOptions necessarie. L'esempio seguente imposta le opzioni sui rispettivi valori predefiniti:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseHttpSys(options =>
            {
                options.AllowSynchronousIO = false;
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = null;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5005");
            });
            webBuilder.UseStartup<Startup>();
        });

Le configurazioni aggiuntive di HTTP.sys vengono gestite tramite impostazioni del Registro di sistema.

Opzioni di HTTP.sys

Proprietà Descrizione Default
AllowSynchronousIO Controllare se l'input e/o l'output sincroni sono consentiti per HttpContext.Request.Body e HttpContext.Response.Body. false
Authentication.AllowAnonymous Consentire richieste anonime. true
Authentication.Schemes Specificare gli schemi di autenticazione consentiti. Può essere modificata in qualsiasi momento prima dell'eliminazione del listener. I valori sono forniti dall'enumerazione AuthenticationSchemes: Basic, Kerberos, Negotiate, None e NTLM. None
EnableResponseCaching Tentare la memorizzazione nella cache in modalità kernel per le risposte con intestazioni idonee. La risposta potrebbe non includere intestazioni Set-Cookie, Vary o Pragma. Deve includere un'intestazione Cache-Controlpublic con valore shared-max-age o max-age o un'intestazione Expires. true
Http503Verbosity Comportamento HTTP.sys quando si rifiutano le richieste a causa di condizioni di limitazione. Http503VerbosityLevel.
Base
MaxAccepts Numero massimo di accettazioni simultanee. 5 × Ambiente.
ProcessorCount
MaxConnections Numero massimo di connessioni simultanee da accettare. Usare -1 per un numero infinito. Usare null per usare l'impostazione a livello di computer del Registro di sistema. null
(a livello di computer
impostazione)
MaxRequestBodySize Vedere la sezione MaxRequestBodySize. 30000000 byte
(~28,6 MB)
RequestQueueLimit Numero massimo di richieste che è possibile accodare. 1000
RequestQueueMode Indica se il server è responsabile della creazione e della configurazione della coda delle richieste o se deve essere collegato a una coda esistente.
La maggior parte delle opzioni di configurazione esistenti non si applica quando si collega a una coda esistente.
RequestQueueMode.Create
RequestQueueName Nome della coda di richieste HTTP.sys. null (coda anonima)
ThrowWriteExceptions Indica se le scritture del corpo della risposta che hanno esito negativo a causa di disconnessioni del client devono generare eccezioni o vengono completate normalmente. false
(completamento normale)
Timeouts Espone la configurazione di TimeoutManager HTTP.sys, che può essere configurata anche nel Registro di sistema. Seguire i collegamenti API per altre informazioni su ogni impostazione, inclusi i valori predefiniti:
UrlPrefixes Specificare l'elemento UrlPrefixCollection da registrare con HTTP.sys. L'elemento più utile è UrlPrefixCollection.Add, che viene usato per aggiungere un prefisso alla raccolta. Queste impostazioni possono essere modificate in qualsiasi momento prima dell'eliminazione del listener.

MaxRequestBodySize

Dimensioni massime consentite per qualsiasi corpo della richiesta in byte. Con l'impostazione null, le dimensioni massime del corpo della richiesta sono illimitate. Questo limite non ha effetto sulle connessioni aggiornate, che sono sempre illimitate.

Il metodo consigliato per ignorare il limite in un'applicazione ASP.NET Core MVC per un singolo IActionResult prevede l'uso dell'attributo RequestSizeLimitAttribute in un metodo di azione:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Se l'app tenta di configurare il limite per una richiesta dopo che l'app ha avviato la lettura della richiesta stessa, viene generata un'eccezione. È possibile usare una proprietà IsReadOnly per indicare se la proprietà MaxRequestBodySize è in stato di sola lettura e pertanto è troppo tardi per configurare il limite.

Se l'app deve eseguire l'override di MaxRequestBodySize per ogni richiesta, usare IHttpMaxRequestBodySizeFeature:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    ILogger<Startup> logger, IServer server)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        var serverAddressesFeature = 
            app.ServerFeatures.Get<IServerAddressesFeature>();
        var addresses = string.Join(", ", serverAddressesFeature?.Addresses);

        logger.LogInformation("Addresses: {Addresses}", addresses);

        await next.Invoke();
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Se si usa Visual Studio, assicurarsi che l'app non sia configurata per l'esecuzione di IIS o IIS Express.

In Visual Studio il profilo di avvio predefinito è per IIS Express. Per eseguire il progetto come app console, modificare manualmente il profilo selezionato, come illustrato nello screenshot seguente:

Select console app profile

Configurare Windows Server

  1. Determinare le porte da aprire per l'app e usare Windows Firewall o il cmdlet di PowerShell New-NetFirewallRule per aprire le porte del firewall per consentire al traffico di raggiungere HTTP.sys. Nei comandi seguenti e nella configurazione dell'app, viene usata la porta 443.

  2. Quando si distribuisce una macchina virtuale di Azure, aprire le porte nel gruppo di sicurezza di rete. Nei comandi seguenti e nella configurazione dell'app, viene usata la porta 443.

  3. Ottenere e installare i certificati X.509, se necessario.

    In Windows, creare certificati autofirmati con il cmdlet di PowerShell New-SelfSignedCertificate. Per un esempio non supportato, vedere UpdateIISExpressSSLForChrome.ps1.

    Installare i certificati autofirmati o con firma nell'archivio Computer locale>Personale del server.

  4. Se l'app è una distribuzione dipendente dal framework, installare .NET Core, .NET Framework o entrambi (se l'app è un'app .NET Core destinata a .NET Framework).

    • .NET Core: se l'app richiede .NET Core, ottenere ed eseguire il programma di installazione del runtime .NET Core dai download di .NET Core. Non installare l'SDK completo nel server.
    • .NET Framework: se l'app richiede .NET Framework, vedere la guida all'installazione di .NET Framework. Installare la versione di .NET Framework richiesta. Il programma di installazione per la versione più recente di .NET Framework è disponibile dalla pagina di download per .NET Core.

    Se l'app è una distribuzione autonoma include il runtime nella distribuzione. Non è richiesta l'installazione di un framework nel server.

  5. Configurare gli URL e le porte nell'app.

    Per impostazione predefinita, ASP.NET Core è associato a http://localhost:5000. Per configurare le porte e i prefissi URL, è possibile usare:

    • UseUrls
    • L'argomento della riga di comando urls
    • La variabile di ambiente ASPNETCORE_URLS
    • UrlPrefixes

    L'esempio di codice seguente mostra come usare UrlPrefixes con l'indirizzo IP locale del server 10.0.0.4 sulla porta 443:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.UrlPrefixes.Add("https://10.0.0.4:443");
                });
                webBuilder.UseStartup<Startup>();
            });
    

    Un vantaggio offerto da UrlPrefixes è che viene generato immediatamente un messaggio di errore per i prefissi non formattati correttamente.

    Le impostazioni di UrlPrefixes sostituiscono le impostazioni UseUrls/urls/ASPNETCORE_URLS. Pertanto, un vantaggio di UseUrls, urlse la ASPNETCORE_URLS variabile di ambiente è che è più facile passare da Kestrel a HTTP.sys.

    HTTP.sys usa i formati di stringa UrlPrefix dell'API del server HTTP.

    Avviso

    Le associazioni con caratteri jolly di livello superiore (http://*:80/ e http://+:80) non devono essere usate, poiché possono creare vulnerabilità a livello di sicurezza nell'app. Questo concetto vale sia per i caratteri jolly sicuri che vulnerabili. Usare nomi host o indirizzi IP espliciti al posto di caratteri jolly. L'associazione con caratteri jolly del sottodominio (ad esempio, *.mysub.com) non costituisce un rischio per la sicurezza se viene controllato l'intero dominio padre (a differenza di *.com, che è vulnerabile). Per altre informazioni, vedere RFC 9110: Sezione 7.2: Host e :authority.

  6. Pre-registrare i prefissi URL nel server.

    Lo strumento predefinito per la configurazione di HTTP.sys è netsh.exe. Netsh.exe viene usato per riservare i prefissi URL e assegnare i certificati X.509. Per questo strumento sono necessari privilegi di amministratore.

    Usare lo strumento netsh.exe per registrare gli URL per l'app:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: URL (Uniform Resource Locator) completo. Non usare un'associazione con caratteri jolly. Usare un nome host valido o un indirizzo IP locale. L'URL deve includere una barra finale.
    • <USER>: specifica il nome dell'utente o del gruppo di utenti.

    Nell'esempio seguente, l'indirizzo IP locale del server è 10.0.0.4:

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    Quando viene registrato un URL, lo strumento risponde con URL reservation successfully added.

    Per eliminare un URL registrato, usare il comando delete urlacl:

    netsh http delete urlacl url=<URL>
    
  7. Registrare i certificati X.509 nel server.

    Usare lo strumento netsh.exe per registrare i certificati per l'app:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: specifica l'indirizzo IP locale per l'associazione. Non usare un'associazione con caratteri jolly. Usare un indirizzo IP valido.
    • <PORT>: specifica la porta per l'associazione.
    • <THUMBPRINT>: identificazione personale del certificato X.509.
    • <GUID>: GUID generato dallo sviluppatore per rappresentare l'app a scopo informativo.

    A scopo di riferimento, archiviare il GUID nell'app come tag di pacchetto:

    • In Visual Studio:
      • Aprire le proprietà del progetto dell'app facendo clic sull'app con il pulsante destro del mouse in Esplora soluzioni e scegliendo Proprietà.
      • Selezionare la scheda Pacchetto.
      • Immettere il GUID creato nel campo Tag.
    • Quando non si usa Visual Studio:
      • Aprire il file di progetto dell'app.

      • Aggiungere una proprietà <PackageTags> a un <PropertyGroup> nuovo o esistente con il GUID creato:

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    Nell'esempio seguente:

    • L'indirizzo IP locale del server è 10.0.0.4.
    • Un generatore di GUID casuali online fornisce il valore appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    Quando viene registrato un certificato, lo strumento risponde con SSL Certificate successfully added.

    Per eliminare la registrazione di un certificato, usare il comando delete sslcert:

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Documentazione di riferimento per netsh.exe:

  8. Eseguire l'app.

    Non sono necessari i privilegi di amministratore per eseguire l'app con binding a localhost tramite HTTP (non HTTPS) con un numero di porta maggiore di 1024. Per altre configurazioni (ad esempio, l'uso di un indirizzo IP locale o il binding sulla porta 443), eseguire l'app con i privilegi di amministratore.

    L'app risponde all'indirizzo IP pubblico del server. In questo esempio, il server è raggiungibile da Internet al relativo indirizzo IP pubblico 104.214.79.47.

    In questo esempio viene usato un certificato di sviluppo. La pagina viene caricata in modo sicuro dopo aver ignorato l'avviso di certificato non attendibile del browser.

    Browser window showing the app's Index page loaded

Scenari con server proxy e servizi di bilanciamento del carico

Per le app ospitate da HTTP.sys che interagiscono con richieste da Internet o da una rete aziendale, potrebbero essere necessari interventi di configurazione aggiuntivi in caso di hosting dietro server proxy e servizi di bilanciamento del carico. Per altre informazioni, vedere Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico.

Funzionalità avanzate http/2 per supportare gRPC

Altre funzionalità HTTP/2 in HTTP.sys supportano gRPC, incluso il supporto per i trailer di risposta e l'invio di fotogrammi di reimpostazione.

Requisiti per eseguire gRPC con HTTP.sys:

  • Windows 10, Build del sistema operativo 19041.508 o versione successiva
  • Connessione TLS 1.2 o successiva

Trailer

I trailer HTTP sono simili alle intestazioni HTTP, tranne che vengono inviati dopo l'invio del corpo della risposta. Per IIS e HTTP.sys, sono supportati solo i trailer di risposta HTTP/2.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

Nel codice di esempio precedente:

  • SupportsTrailers assicura che i trailer siano supportati per la risposta.
  • DeclareTrailer aggiunge il nome del trailer specificato all'intestazione della Trailer risposta. La dichiarazione dei trailer di una risposta è facoltativa, ma consigliata. Se DeclareTrailer viene chiamato, deve essere prima dell'invio delle intestazioni di risposta.
  • AppendTrailer aggiunge il trailer.

Reset

La reimpostazione consente al server di reimpostare una richiesta HTTP/2 con un codice di errore specificato. Una richiesta di reimpostazione viene considerata interrotta.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset nell'esempio di codice precedente specifica il INTERNAL_ERROR codice di errore. Per altre informazioni sui codici di errore HTTP/2, vedere la sezione relativa al codice di errore della specifica HTTP/2.

Risorse aggiuntive