Condividi tramite


HTTP.sys implementazione del server web in ASP.NET Core

Note

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 10 di questo articolo.

Warning

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere .NET e .NET Core Support Policy. Per la versione corrente, vedere la versione .NET 10 di questo articolo.

Tom Dykstra e Chris Ross

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

Important

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

HTTP.sys supporta le funzionalità seguenti:

  • Autenticazione Windows
  • Condivisione delle porte
  • HTTPS con SNI
  • HTTP/2 su TLS (Windows 10 o versione successiva)
  • HTTP/3 su TLS (Windows 11 o versione successiva)
  • Trasmissione diretta dei file
  • Memorizzazione nella cache delle risposte
  • WebSocket (Windows 8 o versione successiva)
  • Descrittori di sicurezza personalizzabili
  • Eliminazione automatica del pool di memoria

Versioni di Windows supportate:

  • Windows 7 o versioni successive
  • 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 comunica direttamente con Internet

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

    HTTP.sys comunica direttamente con la rete interna

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 cima a HTTP.sys.

Supporto HTTP/2

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

Se viene stabilita una connessione HTTP/2, HttpRequest.Protocol riporta 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, saranno disponibili flag di configurazione HTTP/2, inclusa la possibilità di disabilitare HTTP/2 con HTTP.sys.

Supporto HTTP/3

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

  • Windows Server 2022/Windows 11 o versioni successive
  • Viene utilizzato un binding URL https.
  • La chiave del Registro di sistema EnableHttp3 è impostata.

Le versioni precedenti di Windows 11 Build possono richiedere l'uso di una build 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 di risposta alt-svc.

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. Consulta la chiave del Registro di sistema EnableAltSvc.

Note

Sono necessarie associazioni netsh sslcert che usano nomi host anziché indirizzi IP. Sostituire ipport con hostnameport nei netsh http add sslcert comandi seguenti e sostituire l'indirizzo IP con il nome host, www.example.comad esempio . Esiste anche un problema noto in cui l'uso hostnameport non riesce a meno che non venga specificato il certstorename parametro . Per impostazione predefinita, utilizzare certstorename=MY.

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. L'account del computer deve essere usato per decrittografare il token/ticket Kerberos ottenuto da Active Directory e inoltrato dal client al server per autenticare l'utente. Registrare il Nome Principale del Servizio (SPN) 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 dovrebbero 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 configura l'host, specificando eventuali HttpSysOptions richiesti. 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 di HTTP.sys, vedere HttpSysOptions.

Personalizzare i descrittori di sicurezza

Una coda di richieste in HTTP.sys è una struttura a livello di kernel che archivia temporaneamente le richieste HTTP in ingresso fino a quando l'applicazione non è pronta per elaborarle. Gestire l'accesso alla coda delle richieste usando la proprietà RequestQueueSecurityDescriptor in HttpSysOptions. Configuralo come un'istanza GenericSecurityDescriptor durante la configurazione del server HTTP.sys.

Personalizzando il descrittore di sicurezza, è possibile consentire o negare l'accesso a utenti o gruppi specifici alla coda delle richieste. Ciò è utile negli scenari in cui si vuole limitare o delegare la gestione delle richieste HTTP.sys a livello di sistema operativo.

Ad esempio, il codice seguente consente l'accesso a tutti gli utenti autenticati ma nega l'accesso agli utenti ospiti.

using System.Security.AccessControl;
using System.Security.Principal;
using Microsoft.AspNetCore.Server.HttpSys;

// Create a new security descriptor
var securityDescriptor = new CommonSecurityDescriptor(isContainer: false, isDS: false, sddlForm: string.Empty);

// Create a discretionary access control list (DACL)
var dacl = new DiscretionaryAcl(isContainer: false, isDS: false, capacity: 2);
dacl.AddAccess(
    AccessControlType.Allow,
    new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
    -1,
    InheritanceFlags.None,
    PropagationFlags.None
);
dacl.AddAccess(
    AccessControlType.Deny,
    new SecurityIdentifier(WellKnownSidType.BuiltinGuestsSid, null),
    -1,
    InheritanceFlags.None,
    PropagationFlags.None
);

// Assign the DACL to the security descriptor
securityDescriptor.DiscretionaryAcl = dacl;

// Configure HTTP.sys options
var builder = WebApplication.CreateBuilder();
builder.WebHost.UseHttpSys(options =>
{
    options.RequestQueueSecurityDescriptor = securityDescriptor;
});

La RequestQueueSecurityDescriptor proprietà si applica solo quando si crea una nuova coda di richieste. La proprietà non influisce sulle code di richieste esistenti.

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'app MVC ASP.NET Core per un singolo IActionResult consiste nell'usare l'attributo RequestSizeLimitAttribute su 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:

Selezionare il profilo dell'applicazione console

Configurare Windows Server

  1. Determinare le porte da aprire per l'app e usare Windows Firewall o New-NetFirewallRule cmdlet di PowerShell 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 esegue la distribuzione in una macchina virtuale Azure, aprire le porte nel gruppo di sicurezza Network. 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 autofirmato usando il cmdlet di PowerShell New-SelfSignedCertificate. Per un esempio non supportato, vedere UpdateIISExpressSSLForChrome.ps1.

    Installare i certificati autofirmati o firmati da CA nell'archivio Computer locale>Personale del server.

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

    • .NET: se l'app richiede .NET, ottenere ed eseguire il programma di installazione .NET Runtime da .NET Downloads. Non installare l'SDK completo nel server.
    • .NET Framework: se l'app richiede .NET Framework, vedere la guida all'installazione di .NET Framework. Installare il framework di .NET necessario. Il programma di installazione per la versione più recente di .NET Framework è disponibile nella pagina .NET Download.

    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 viene 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 e 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.
    • + è una stretta associazione. Se il prefisso URL è http://+:5000, questa associazione verrà usata prima di altre associazioni della porta 5000.

    Per ulteriori informazioni, vedere Stringhe UrlPrefix.

    Warning

    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 wildcard per il sottodominio (ad esempio, *.mysub.com) non rappresenta un rischio per la sicurezza se si controlla l'intero dominio padre, contrariamente a *.com, che rimane vulnerabile. Per altre informazioni, vedere RFC 9110: Sezione 7.2: Host e :authority.

    Le app e i contenitori vengono spesso dati solo una porta per ascoltare, come la porta 80, senza vincoli aggiuntivi come l'host o il 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 prefissi DOTNET_ e ASPNETCORE_, oppure 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 container, ma evita caratteri jolly durante l'esecuzione in un computer che può anche ospitare altri servizi.

  6. Registrare in anticipo i prefissi URL sul 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) completamente qualificato. 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>: impronta digitale 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 con il pulsante destro del mouse sull'app in Esplora soluzioni e selezionando 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 che hai creato:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</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="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    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. Avvia 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.

    Finestra del browser che mostra la pagina di indice dell'app caricata

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'uso con server proxy e servizi di bilanciamento del carico.

Ottenere informazioni dettagliate sulla tempistica con IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature fornisce informazioni dettagliate sulla tempistica per le richieste:

  • I timestamp vengono ottenuti usando QueryPerformanceCounter.
  • La frequenza del timestamp può essere ottenuta tramite QueryPerformanceFrequency.
  • L'indice del timing può essere convertito in HttpSysRequestTimingType per sapere cosa rappresenta tale timing.
  • Il valore può essere 0 se il tempo non è disponibile per la richiesta corrente.
  • Richiede Windows 10 versione 2004, Windows Server 2022 o successiva.
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](/dotnet/api/microsoft.aspnetcore.server.httpsys.ihttpsysrequesttimingfeature.trygetelapsedtime restituisce 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.

Trailers

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

Nell'esempio precedente di codice:

  • SupportsTrailers assicura il supporto dei trailer 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.

Tracing

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

Rimozione automatica dal pool di memoria

I pool di memoria usati da Kestrel, IIS e HTTP.sys rimuove automaticamente blocchi di memoria quando l'applicazione è inattiva o sotto carico ridotto. La funzionalità viene eseguita automaticamente e non deve essere abilitata o configurata manualmente.

Nelle versioni di .NET precedenti a 10, la memoria allocata dal pool rimane riservata, anche se non in uso. Questa funzionalità di rimozione automatica riduce l'utilizzo complessivo della memoria e consente alle applicazioni di rimanere reattive in carichi di lavoro diversi.

Utilizzare le metriche del pool di memoria

Il pool di memoria predefinito usato dalle implementazioni del server ASP.NET Core include metriche, che possono essere usate per monitorare e analizzare i modelli di utilizzo della memoria. Le metriche si trovano sotto il nome "Microsoft.AspNetCore.MemoryPool".

Per informazioni sulle metriche e su come usarle, vedere ASP.NET Core metriche.

Gestire i pool di memoria

Oltre a usare i pool di memoria in modo efficiente rimuovendo blocchi di memoria non sufficienti, ASP.NET Core fornisce un IMemoryPoolFactory e un'implementazione. Rende l'implementazione disponibile per l'applicazione tramite iniezione di dipendenza.

L'esempio di codice seguente illustra un semplice servizio in background che usa l'implementazione predefinita della factory del pool di memoria per creare pool di memoria. Questi pool traggono vantaggio dalla funzionalità di rimozione automatica:

public class MyBackgroundService : BackgroundService
{
    private readonly MemoryPool<byte> _memoryPool;

    public MyBackgroundService(IMemoryPoolFactory<byte> factory)
    {
        _memoryPool = factory.Create();
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await Task.Delay(20, stoppingToken);
                // do work that needs memory
                // consider checking _memoryPool.MaxBufferSize
                var rented = _memoryPool.Rent(100);
                rented.Dispose();
            }
            catch (OperationCanceledException)
            {
                return;
            }
        }
    }
}

Per usare una factory del pool di memoria personalizzata, creare una classe che implementa IMemoryPoolFactory e registrarla con l'iniezione delle dipendenze, come illustrato nell'esempio seguente. I pool di memoria creati in questo modo non traggono vantaggio dalla funzionalità di rimozione automatica, a meno che non si implementi una logica di rimozione simile nella factory personalizzata:

services.AddSingleton<IMemoryPoolFactory<byte>,
CustomMemoryPoolFactory>();

public class CustomMemoryPoolFactory : IMemoryPoolFactory<byte>
{
    public MemoryPool<byte> Create()
    {
        // Return a custom MemoryPool implementation
        // or the default, as is shown here.
        return MemoryPool<byte>.Shared;
    }
}

Quando si usa un pool di memoria, tenere presente il parametro del pool MaxBufferSize.

Risorse aggiuntive

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

Important

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

HTTP.sys supporta le funzionalità seguenti:

  • Autenticazione Windows
  • Condivisione delle porte
  • HTTPS con SNI
  • HTTP/2 su TLS (Windows 10 o versione successiva)
  • Trasmissione diretta dei file
  • Memorizzazione nella cache delle risposte
  • WebSocket (Windows 8 o versione successiva)

Versioni di Windows supportate:

  • Windows 7 o versioni successive
  • 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 comunica direttamente con Internet

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

    HTTP.sys comunica direttamente con la rete interna

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 cima a HTTP.sys.

Supporto HTTP/2

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

Se viene stabilita una connessione HTTP/2, HttpRequest.Protocol riporta 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, saranno disponibili flag di configurazione HTTP/2, inclusa la possibilità di disabilitare HTTP/2 con HTTP.sys.

Supporto HTTP/3

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

  • Windows Server 2022/Windows 11 o versioni successive
  • Viene utilizzato un binding URL https.
  • La chiave del Registro di sistema EnableHttp3 è impostata.

Le versioni precedenti di Windows 11 Build possono richiedere l'uso di una build 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 di risposta alt-svc.

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. Consulta 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. L'account del computer deve essere usato per decrittografare il token/ticket Kerberos ottenuto da Active Directory e inoltrato dal client al server per autenticare l'utente. Registrare il Nome Principale del Servizio (SPN) 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 configura l'host, specificando eventuali HttpSysOptions richiesti. 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 di 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'app MVC ASP.NET Core per un singolo IActionResult consiste nell'usare l'attributo RequestSizeLimitAttribute su 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:

Selezionare il profilo dell'applicazione console

Configurare Windows Server

  1. Determinare le porte da aprire per l'app e usare Windows Firewall o New-NetFirewallRule cmdlet di PowerShell 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 esegue la distribuzione in una macchina virtuale Azure, aprire le porte nel gruppo di sicurezza Network. 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 autofirmato usando il cmdlet di PowerShell New-SelfSignedCertificate. Per un esempio non supportato, vedere UpdateIISExpressSSLForChrome.ps1.

    Installare i certificati autofirmati o firmati da CA nell'archivio Computer locale>Personale del server.

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

    • .NET: se l'app richiede .NET, ottenere ed eseguire il programma di installazione .NET Runtime da .NET Downloads. Non installare l'SDK completo nel server.
    • .NET Framework: se l'app richiede .NET Framework, vedere la guida all'installazione di .NET Framework. Installare il framework di .NET necessario. Il programma di installazione per la versione più recente di .NET Framework è disponibile nella pagina .NET Download.

    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 viene 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 e HTTP.sys.

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

    Warning

    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 wildcard per il sottodominio (ad esempio, *.mysub.com) non rappresenta un rischio per la sicurezza se si controlla l'intero dominio padre, contrariamente a *.com, che rimane vulnerabile. Per altre informazioni, vedere RFC 9110: Sezione 7.2: Host e :authority.

  6. Registrare in anticipo i prefissi URL sul 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) completamente qualificato. 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>: impronta digitale 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 con il pulsante destro del mouse sull'app in Esplora soluzioni e selezionando 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 che hai creato:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</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="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    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. Avvia 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.

    Finestra del browser che mostra la pagina di indice dell'app caricata

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'uso con server proxy e servizi di bilanciamento del carico.

Funzionalità avanzate http/2 per supportare gRPC

Altre funzionalità HTTP/2 in HTTP.sys supportano gRPC, tra cui il supporto per i trailer di risposta e l'invio di frame di reset.

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.

Trailers

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

Nell'esempio precedente di codice:

  • SupportsTrailers assicura il supporto dei trailer 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 eseguito solo in Windows. HTTP.sys è un'alternativa al Kestrel server e offre alcune funzionalità che Kestrel non forniscono.

Important

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

HTTP.sys supporta le funzionalità seguenti:

  • Autenticazione Windows
  • Condivisione delle porte
  • HTTPS con SNI
  • HTTP/2 su TLS (Windows 10 o versione successiva)
  • Trasmissione diretta dei file
  • Memorizzazione nella cache delle risposte
  • WebSocket (Windows 8 o versione successiva)

Versioni di Windows supportate:

  • Windows 7 o versioni successive
  • 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 comunica direttamente con Internet

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

    HTTP.sys comunica direttamente con la rete interna

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 cima a 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 riporta 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, saranno disponibili flag di configurazione HTTP/2, inclusa la possibilità di disabilitare 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. L'account del computer deve essere usato per decrittografare il token/ticket Kerberos ottenuto da Active Directory e inoltrato dal client al server per autenticare l'utente. Registrare il Nome Principale del Servizio (SPN) 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 configura l'host, specificando eventuali HttpSysOptions richiesti. 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 diHTTP.sys

Property Description 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 di HTTP.sys quando si rifiutano le richieste a causa di condizioni di throttling. Http503VerbosityLevel.
Basico
MaxAccepts Numero massimo di accettazioni simultanee. 5 × Ambiente.
ConteggioProcessori
MaxConnections Numero massimo di connessioni simultanee da accettare. Usare -1 per un numero infinito. Utilizzare null per impostare l'impostazione dell'intero computer nel registro di sistema. null
(machine-wide
setting)
MaxRequestBodySize Vedere la sezione MaxRequestBodySize. 300000000 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 della richiesta di 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 se devono essere completate normalmente. false
(completa normalmente)
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'app MVC ASP.NET Core per un singolo IActionResult consiste nell'usare l'attributo RequestSizeLimitAttribute su 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:

Selezionare il profilo dell'applicazione console

Configurare Windows Server

  1. Determinare le porte da aprire per l'app e usare Windows Firewall o New-NetFirewallRule cmdlet di PowerShell 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 esegue la distribuzione in una macchina virtuale Azure, aprire le porte nel gruppo di sicurezza Network. 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 autofirmato usando il cmdlet di PowerShell New-SelfSignedCertificate. Per un esempio non supportato, vedere UpdateIISExpressSSLForChrome.ps1.

    Installare i certificati autofirmati o firmati da CA nell'archivio Computer locale>Personale del server.

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

    • .NET: se l'app richiede .NET, ottenere ed eseguire il programma di installazione .NET Runtime da .NET Downloads. Non installare l'SDK completo nel server.
    • .NET Framework: se l'app richiede .NET Framework, vedere la guida all'installazione di .NET Framework. Installare il framework di .NET necessario. Il programma di installazione per la versione più recente di .NET Framework è disponibile nella pagina .NET Download.

    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 viene 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 e HTTP.sys.

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

    Warning

    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 wildcard per il sottodominio (ad esempio, *.mysub.com) non rappresenta un rischio per la sicurezza se si controlla l'intero dominio padre, contrariamente a *.com, che rimane vulnerabile. Per altre informazioni, vedere RFC 9110: Sezione 7.2: Host e :authority.

  6. Registrare in anticipo i prefissi URL sul 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) completamente qualificato. 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>: impronta digitale 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 con il pulsante destro del mouse sull'app in Esplora soluzioni e selezionando 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 che hai creato:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</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="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    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. Avvia 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.

    Finestra del browser che mostra la pagina di indice dell'app caricata

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'uso con server proxy e servizi di bilanciamento del carico.

Funzionalità avanzate http/2 per supportare gRPC

Altre funzionalità HTTP/2 in HTTP.sys supportano gRPC, tra cui il supporto per i trailer di risposta e l'invio di frame di reset.

Requisiti per eseguire gRPC con HTTP.sys:

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

Trailers

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

Nell'esempio precedente di codice:

  • SupportsTrailers assicura il supporto dei trailer 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 eseguito solo in Windows. HTTP.sys è un'alternativa al Kestrel server e offre alcune funzionalità che Kestrel non forniscono.

Important

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

HTTP.sys supporta le funzionalità seguenti:

  • Autenticazione Windows
  • Condivisione delle porte
  • HTTPS con SNI
  • HTTP/2 su TLS (Windows 10 o versione successiva)
  • HTTP/3 su TLS (Windows 11 o versione successiva)
  • Trasmissione diretta dei file
  • Memorizzazione nella cache delle risposte
  • WebSocket (Windows 8 o versione successiva)
  • Descrittori di sicurezza personalizzabili

Versioni di Windows supportate:

  • Windows 7 o versioni successive
  • 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 comunica direttamente con Internet

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

    HTTP.sys comunica direttamente con la rete interna

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 cima a HTTP.sys.

Supporto HTTP/2

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

Se viene stabilita una connessione HTTP/2, HttpRequest.Protocol riporta 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, saranno disponibili flag di configurazione HTTP/2, inclusa la possibilità di disabilitare HTTP/2 con HTTP.sys.

Supporto HTTP/3

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

  • Windows Server 2022/Windows 11 o versioni successive
  • Viene utilizzato un binding URL https.
  • La chiave del Registro di sistema EnableHttp3 è impostata.

Le versioni precedenti di Windows 11 Build possono richiedere l'uso di una build 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 di risposta alt-svc.

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. Consulta 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. L'account del computer deve essere usato per decrittografare il token/ticket Kerberos ottenuto da Active Directory e inoltrato dal client al server per autenticare l'utente. Registrare il Nome Principale del Servizio (SPN) 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 dovrebbero 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 configura l'host, specificando eventuali HttpSysOptions richiesti. 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 di 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'app MVC ASP.NET Core per un singolo IActionResult consiste nell'usare l'attributo RequestSizeLimitAttribute su 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:

Selezionare il profilo dell'applicazione console

Configurare Windows Server

  1. Determinare le porte da aprire per l'app e usare Windows Firewall o New-NetFirewallRule cmdlet di PowerShell 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 esegue la distribuzione in una macchina virtuale Azure, aprire le porte nel gruppo di sicurezza Network. 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 autofirmato usando il cmdlet di PowerShell New-SelfSignedCertificate. Per un esempio non supportato, vedere UpdateIISExpressSSLForChrome.ps1.

    Installare i certificati autofirmati o firmati da CA nell'archivio Computer locale>Personale del server.

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

    • .NET: se l'app richiede .NET, ottenere ed eseguire il programma di installazione .NET Runtime da .NET Downloads. Non installare l'SDK completo nel server.
    • .NET Framework: se l'app richiede .NET Framework, vedere la guida all'installazione di .NET Framework. Installare il framework di .NET necessario. Il programma di installazione per la versione più recente di .NET Framework è disponibile nella pagina .NET Download.

    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 viene 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 e 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.
    • + è una stretta associazione. Se il prefisso URL è http://+:5000, questa associazione verrà usata prima di altre associazioni della porta 5000.

    Per ulteriori informazioni, vedere Stringhe UrlPrefix.

    Warning

    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 wildcard per il sottodominio (ad esempio, *.mysub.com) non rappresenta un rischio per la sicurezza se si controlla l'intero dominio padre, contrariamente a *.com, che rimane vulnerabile. Per altre informazioni, vedere RFC 9110: Sezione 7.2: Host e :authority.

    Le app e i contenitori vengono spesso dati solo una porta per ascoltare, come la porta 80, senza vincoli aggiuntivi come l'host o il 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 prefissi DOTNET_ e ASPNETCORE_, oppure 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 container, ma evita caratteri jolly durante l'esecuzione in un computer che può anche ospitare altri servizi.

  6. Registrare in anticipo i prefissi URL sul 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) completamente qualificato. 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>: impronta digitale 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 con il pulsante destro del mouse sull'app in Esplora soluzioni e selezionando 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 che hai creato:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</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="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    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. Avvia 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.

    Finestra del browser che mostra la pagina di indice dell'app caricata

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'uso con server proxy e servizi di bilanciamento del carico.

Ottenere informazioni dettagliate sulla tempistica con IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature fornisce informazioni dettagliate sulla tempistica per le richieste:

  • I timestamp vengono ottenuti usando QueryPerformanceCounter.
  • La frequenza del timestamp può essere ottenuta tramite QueryPerformanceFrequency.
  • L'indice del timing può essere convertito in HttpSysRequestTimingType per sapere cosa rappresenta tale timing.
  • Il valore può essere 0 se il tempo non è disponibile per la richiesta corrente.
  • Richiede Windows 10 versione 2004, Windows Server 2022 o successiva.
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](/dotnet/api/microsoft.aspnetcore.server.httpsys.ihttpsysrequesttimingfeature.trygetelapsedtime restituisce 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, tra cui il supporto per i trailer di risposta e l'invio di frame di reset.

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.

Trailers

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

Nell'esempio precedente di codice:

  • SupportsTrailers assicura il supporto dei trailer 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.

Tracing

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

Risorse aggiuntive