Udostępnij za pośrednictwem


implementacja serwera internetowegoHTTP.sys w ASP.NET Core

Note

Nie jest to najnowsza wersja tego artykułu. Aby uzyskać bieżącą wersję, zobacz artykuł w wersji .NET 10.

Warning

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz .NET i .NET Core Support Policy. Aby zapoznać się z bieżącą wersją, zobacz artykuł w wersji .NET 10.

Przez Tom Dykstra i Chris Ross

HTTP.sys jest serwerem web dla ASP.NET Core który działa tylko w Windows. HTTP.sys jest alternatywą dla Kestrel serwera i oferuje niektóre funkcje, które Kestrel nie zapewniają.

Important

HTTP.sys nie jest zgodna z modułem ASP.NET Core i nie może być używana z usługami IIS lub IIS Express.

HTTP.sys obsługuje następujące funkcje:

  • Windows Authentication
  • Udostępnianie portów
  • Protokół HTTPS z siecią SNI
  • Protokół HTTP/2 za pośrednictwem protokołu TLS (Windows 10 lub nowszy)
  • Protokół HTTP/3 za pośrednictwem protokołu TLS (Windows 11 lub nowszy)
  • Bezpośrednia transmisja plików
  • Buforowanie odpowiedzi
  • WebSockets (Windows 8 lub nowsze)
  • Dostosowywalne deskryptory zabezpieczeń
  • Automatyczne eksmisja puli pamięci

Obsługiwane wersje Windows:

  • Windows 7 lub nowsza
  • Windows Server 2008 R2 lub nowszy

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Kiedy należy używać HTTP.sys

HTTP.sys jest przydatna w przypadku wdrożeń, w których:

  • Istnieje potrzeba uwidocznienia serwera bezpośrednio w Internecie bez korzystania z usług IIS.

    Serwer HTTP.sys komunikuje się bezpośrednio z Internetem

  • Wdrożenie wewnętrzne wymaga funkcji niedostępnej w programie Kestrel. Aby uzyskać więcej informacji, zobacz Kestrel vs. HTTP.sys

    Serwer HTTP.sys komunikuje się bezpośrednio z siecią wewnętrzną

HTTP.sys to dojrzała technologia, która chroni przed wieloma typami ataków i zapewnia niezawodność, bezpieczeństwo i skalowalność pełnoekranowego serwera internetowego. Same usługi IIS są uruchamiane jako odbiornik HTTP na podstawie HTTP.sys.

Obsługa protokołu HTTP/2

HTTP/2 jest włączona dla aplikacji ASP.NET Core po spełnieniu następujących podstawowych wymagań:

Jeśli połączenie HTTP/2 zostanie nawiązane, httpRequest.Protocol zgłasza HTTP/2.

Protokół HTTP/2 jest domyślnie włączony. Jeśli połączenie HTTP/2 nie zostanie nawiązane, połączenie powróci do protokołu HTTP/1.1. W przyszłej wersji Windows będą dostępne flagi konfiguracji HTTP/2, w tym możliwość wyłączenia protokołu HTTP/2 z HTTP.sys.

Obsługa protokołu HTTP/3

HTTP/3 jest włączona dla aplikacji ASP.NET Core po spełnieniu następujących podstawowych wymagań:

  • Windows Server 2022/Windows 11 lub nowszy
  • Używane jest powiązanie URL https.
  • Ustawiono klucz rejestru EnableHttp3.

Poprzednie wersje kompilacji Windows 11 mogą wymagać użycia kompilacji Windows insider.

Protokół HTTP/3 jest wykrywany jako uaktualnienie z protokołu HTTP/1.1 lub HTTP/2 za pośrednictwem nagłówka alt-svc . Oznacza to, że pierwsze żądanie zwykle będzie używać protokołu HTTP/1.1 lub HTTP/2 przed przełączeniem do protokołu HTTP/3. Protokół Http.Sys nie dodaje automatycznie nagłówka alt-svc — musi zostać dodany przez aplikację. Poniższy kod to przykład oprogramowania pośredniczącego, który dodaje alt-svc nagłówek odpowiedzi.

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

Umieść poprzedni kod na początku potoku żądania.

Http.Sys obsługuje również wysyłanie komunikatu protokołu HTTP/2 AltSvc zamiast nagłówka odpowiedzi w celu powiadomienia klienta o dostępności protokołu HTTP/3. Zobacz klucz rejestru EnableAltSvc.

Note

Wymaga to powiązań netsh sslcert, które używają nazw hostów, a nie adresów IP. Zastąp ipport przez hostnameport w poniższych poleceniach netsh http add sslcert i zamień adres IP na nazwę hosta, na przykład www.example.com. Istnieje również znany problem polegający na tym, że użycie hostnameport kończy się niepowodzeniem, chyba że określono parametr certstorename. Domyślnie użyj certstorename=MY.

Uwierzytelnianie w trybie jądra przy użyciu protokołu Kerberos

HTTP.sys deleguje uwierzytelnianie do trybu jądra przy użyciu protokołu uwierzytelniania Kerberos. Uwierzytelnianie w trybie użytkownika nie jest obsługiwane w przypadku protokołu Kerberos i HTTP.sys. Konto komputera musi służyć do odszyfrowywania tokenu/biletu Protokołu Kerberos uzyskanego z Active Directory i przekazywanego przez klienta do serwera w celu uwierzytelnienia użytkownika. Zarejestruj nazwę główną usługi (SPN) dla hosta, a nie użytkownika aplikacji.

Obsługa buforowania odpowiedzi w trybie jądra

W niektórych scenariuszach duże ilości małych zapisów z dużym opóźnieniem mogą spowodować znaczny wpływ na wydajność.HTTP.sys Ten wpływ jest spowodowany brakiem Pipe buforu w implementacji HTTP.sys . Aby zwiększyć wydajność w tych scenariuszach, obsługa buforowania odpowiedzi jest uwzględniana w systemie HTTP.sys. Włącz buforowanie, ustawiając wartość HttpSysOptions.EnableKernelResponseBuffering na true. Buforowanie odpowiedzi powinno być włączone przez aplikację, która wykonuje synchroniczne operacje we/wy lub asynchroniczne operacje we/wy bez więcej niż jednego zaległego zapisu naraz. W tych scenariuszach buforowanie odpowiedzi może znacznie zwiększyć przepływność w przypadku połączeń o dużym opóźnieniu.

Aplikacje, które korzystają z asynchronicznych operacji we/wy i mogą mieć więcej niż jeden nieukończony zapis jednocześnie, nie powinny używać tej flagi. Włączenie tej flagi może spowodować wyższe użycie procesora CPU i pamięci przez HTTP.Sys.

Jak używać HTTP.sys

Konfigurowanie aplikacji ASP.NET Core do używania HTTP.sys

Wywołaj metodę UseHttpSys rozszerzenia podczas kompilowania hosta, określając dowolną wymaganą metodę HttpSysOptions. Poniższy przykład ustawia opcje na wartości domyślne:

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();

Dodatkowa konfiguracja HTTP.sys jest obsługiwana za pośrednictwem ustawień rejestru.

Aby uzyskać więcej informacji na temat opcji HTTP.sys, zobacz HttpSysOptions.

Dostosowywanie deskryptorów zabezpieczeń

Kolejka żądań w HTTP.sys to struktura na poziomie jądra, która tymczasowo przechowuje przychodzące żądania HTTP, dopóki aplikacja nie będzie gotowa do ich przetworzenia. Zarządzanie dostępem do kolejki żądań przy użyciu właściwości RequestQueueSecurityDescriptor w HttpSysOptions. Ustaw jako instancję GenericSecurityDescriptor podczas konfigurowania serwera HTTP.sys.

Dostosowując deskryptor zabezpieczeń, można zezwolić określonym użytkownikom lub grupom na dostęp do kolejki żądań oraz odmówić tego dostępu. Jest to przydatne w sytuacjach, gdy chcesz ograniczyć lub delegować obsługę żądań HTTP.sys na poziomie systemu operacyjnego.

Na przykład poniższy kod umożliwia wszystkim uwierzytelnionym użytkownikom, a odmawia dostępu gościom.

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

Właściwość RequestQueueSecurityDescriptor ma zastosowanie tylko podczas tworzenia nowej kolejki żądań. Właściwość nie ma wpływu na istniejące kolejki żądań.

MaxRequestBodySize

Maksymalny dozwolony rozmiar dowolnej treści żądania w bajtach. Jeśli ustawiono wartość null, maksymalny rozmiar treści żądania jest nieograniczony. Ten limit nie wpływa na połączenia, które zostały uaktualnione, ponieważ są zawsze nieograniczone.

Zalecaną metodą zastąpienia limitu w aplikacji MVC ASP.NET Core dla pojedynczego IActionResult jest użycie atrybutu RequestSizeLimitAttribute w metodzie akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Zgłaszany jest wyjątek, jeśli aplikacja próbuje skonfigurować limit żądania po rozpoczęciu odczytywania żądania przez aplikację. Właściwość IsReadOnly może służyć do wskazania, czy właściwość MaxRequestBodySize jest ustawiona jako tylko do odczytu, co oznacza, że jest za późno na skonfigurowanie limitu.

Jeśli aplikacja powinna zastąpić MaxRequestBodySize żądanie, użyj polecenia 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);
});

Jeśli używasz Visual Studio, upewnij się, że aplikacja nie jest skonfigurowana do uruchamiania usług IIS lub IIS Express.

W Visual Studio domyślnym profilem uruchamiania jest usługa IIS Express. Aby uruchomić projekt jako aplikację konsolową, ręcznie zmień wybrany profil, jak pokazano na poniższym zrzucie ekranu:

Wybieranie profilu aplikacji konsolowej

Konfigurowanie Windows Server

  1. Określ porty do otwarcia dla aplikacji i użyj polecenia cmdlet Windows Firewall lub New-NetFirewallRule polecenia cmdlet programu PowerShell w celu otwarcia portów zapory w celu umożliwienia ruchu do HTTP.sys. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  2. Podczas wdrażania na maszynie wirtualnej Azure otwórz porty w Network Security Group. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  3. W razie potrzeby uzyskaj i zainstaluj certyfikaty X.509.

    W Windows utwórz certyfikaty z podpisem własnym przy użyciu polecenia cmdlet New-SelfSignedCertificate programu PowerShell. Aby zapoznać się z nieobsługiwanym przykładem, zobacz UpdateIISExpressSSLForChrome.ps1.

    Zainstaluj certyfikaty z podpisem własnym lub z podpisem urzędu certyfikacji w magazynie Local Machine>Osobiste.

  4. Jeśli aplikacja jest wdrożeniem zależnym od framework, zainstaluj .NET, .NET Framework lub obie (jeśli aplikacja jest aplikacją .NET przeznaczoną dla platformy .NET).

    • .NET: Jeśli aplikacja wymaga .NET, pobierz i uruchom instalator .NET Runtime z .NET Pobierania. Nie instaluj pełnego zestawu SDK na serwerze.
    • .NET Framework: Jeśli aplikacja wymaga platformy .NET, zobacz przewodnik instalacji platformy .NET Framework. Zainstaluj wymaganą platformę .NET Framework. Instalator najnowszego .NET Framework jest dostępny na stronie .NET Downloads.

    Jeśli aplikacja jest wdrożeniem niezależnym, zawiera środowisko uruchomieniowe. Na serwerze nie jest wymagana instalacja platformy.

  5. Skonfiguruj adresy URL i porty w aplikacji.

    Domyślnie ASP.NET Core wiąże się z http://localhost:5000. Aby skonfigurować prefiksy adresów URL i porty, opcje obejmują:

    • UseUrls
    • urls argument wiersza polecenia
    • ASPNETCORE_URLS zmienna środowiskowa
    • UrlPrefixes

    W poniższym przykładzie kodu pokazano, jak używać UrlPrefixes z lokalnym adresem 10.0.0.4 IP serwera na porcie 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();
    

    UrlPrefixes Zaletą jest to, że komunikat o błędzie jest generowany natychmiast dla nieprawidłowo sformatowanych prefiksów.

    Ustawienia w UrlPrefixes nadpisują ustawienia UseUrls/urls/ASPNETCORE_URLS. W związku z tym zaletą zmiennej środowiskowej UseUrls, urlsi ASPNETCORE_URLS jest to, że łatwiej jest przełączać się między Kestrel i HTTP.sys.

    HTTP.sys rozpoznaje dwa typy symboli wieloznacznych w prefiksach adresów URL:

    • * jest słabym powiązaniem, znanym również jako powiązanie rezerwowe. Jeśli prefiks adresu URL to http://*:5000, a coś innego jest powiązane z portem 5000, to powiązanie nie będzie używane.
    • + jest silnym powiązaniem. Jeśli prefiks adresu URL to http://+:5000, to powiązanie będzie używane przed innymi powiązaniami portu 5000.

    Aby uzyskać więcej informacji, zobacz Ciągi prefiksu URL.

    Warning

    Nie należy używać powiązań z symbolami wieloznacznymi najwyższego poziomu (http://*:80/ i http://+:80). Powiązania z symbolami wieloznacznymi najwyższego poziomu tworzą luki w zabezpieczeniach aplikacji. Dotyczy to zarówno silnych, jak i słabych symboli wieloznacznych. Użyj jawnych nazw hostów lub adresów IP, a nie symboli wieloznacznych. Powiązanie wieloznaczne poddomeny (na przykład *.mysub.com) nie jest zagrożeniem bezpieczeństwa, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Sekcja 7.2: Host i :authority.

    Aplikacje i kontenery często otrzymują tylko port do nasłuchiwania, na przykład port 80, bez dodatkowych ograniczeń, takich jak host lub ścieżka. HTTP_PORTS i HTTPS_PORTS to klucze konfiguracji, które określają porty nasłuchiwania dla serwerów Kestrel i HTTP.sys. Te klucze mogą być określone jako zmienne środowiskowe zdefiniowane poprzez prefiksy DOTNET_ lub ASPNETCORE_, albo bezpośrednio przez inne dane wejściowe konfiguracji, takie jak appsettings.json. Każda z nich jest rozdzieloną średnikami listą wartości portów, jak pokazano w poniższym przykładzie:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    Powyższy przykład jest skrócony dla następującej konfiguracji, która określa schemat (HTTP lub HTTPS) i dowolny host lub adres IP.

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

    Klucze konfiguracji HTTP_PORTS i HTTPS_PORTS mają niższy priorytet i są zastępowane przez adresy URL lub wartości podane bezpośrednio w kodzie. Certyfikaty nadal muszą być konfigurowane oddzielnie za pośrednictwem mechaniki specyficznej dla serwera dla protokołu HTTPS.

    Te klucze konfiguracji są równoważne powiązaniom symboli wieloznacznych najwyższego poziomu. Są one wygodne w środowiskach programistycznych i kontenerowych, ale unikaj symboli wieloznacznych podczas uruchamiania na maszynie, która może również hostować inne usługi.

  6. Wstępnie zarejestrować prefiksy adresów URL na serwerze.

    Wbudowane narzędzie do konfigurowania HTTP.sys jest netsh.exe. netsh.exe służy do rezerwowania prefiksów adresów URL i przypisywania certyfikatów X.509. Narzędzie wymaga uprawnień administratora.

    Użyj narzędzia netsh.exe, aby zarejestrować adresy URL aplikacji:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: Pełny ujednolicony lokalizator zasobów (URL). Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowej nazwy hosta lub lokalnego adresu IP. Adres URL musi zawierać ukośnik końcowy.
    • <USER>: określa nazwę użytkownika lub grupy użytkowników.

    W poniższym przykładzie lokalny adres IP serwera to 10.0.0.4:

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

    Po zarejestrowaniu adresu URL narzędzie odpowiada URL reservation successfully added.

    Aby usunąć zarejestrowany adres URL, użyj delete urlacl polecenia :

    netsh http delete urlacl url=<URL>
    
  7. Zarejestruj certyfikaty X.509 na serwerze.

    Użyj narzędzia netsh.exe, aby zarejestrować certyfikaty dla aplikacji:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: określa lokalny adres IP powiązania. Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowego adresu IP.
    • <PORT>: określa port powiązania.
    • <THUMBPRINT>: odcisk palca certyfikatu X.509.
    • <GUID>: identyfikator GUID wygenerowany przez dewelopera reprezentujący aplikację do celów informacyjnych.

    Do celów referencyjnych zapisz identyfikator GUID w aplikacji jako tag pakietu:

    • W Visual Studio:
      • Otwórz właściwości projektu aplikacji, klikając prawym przyciskiem myszy aplikację w Eksplorator rozwiązań i wybierając pozycję Właściwości.
      • Wybierz kartę Pakiet .
      • Wprowadź identyfikator GUID, który utworzyłeś, w polu Tagi.
    • Jeśli nie używasz Visual Studio:
      • Otwórz plik projektu aplikacji.

      • Dodaj właściwość <PackageTags> do nowej lub istniejącej <PropertyGroup> z identyfikatorem GUID, który utworzyłeś:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags>
        </PropertyGroup>
        

    W poniższym przykładzie:

    • Lokalny adres IP serwera to 10.0.0.4.
    • Generator losowego identyfikatora appid GUID w trybie online zapewnia wartość .
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Po zarejestrowaniu certyfikatu narzędzie odpowiada za pomocą SSL Certificate successfully added.

    Aby usunąć rejestrację certyfikatu, użyj delete sslcert polecenia :

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

    Dokumentacja referencyjna netsh.exe:

  8. Uruchom aplikację.

    Uprawnienia administratora nie są wymagane do uruchamiania aplikacji podczas tworzenia powiązania z hostem lokalnym przy użyciu protokołu HTTP (a nie HTTPS) z numerem portu większym niż 1024. W przypadku innych konfiguracji (na przykład przy użyciu lokalnego adresu IP lub powiązania z portem 443) uruchom aplikację z uprawnieniami administratora.

    Aplikacja odpowiada na publiczny adres IP serwera. W tym przykładzie serwer jest osiągany z Internetu pod jego publicznym adresem IP .104.214.79.47

    W tym przykładzie używany jest certyfikat dewelopera. Strona ładuje się bezpiecznie po ominięciu ostrzeżenia przeglądarki dotyczącego niezaufanego certyfikatu.

    Okno przeglądarki z załadowaną stroną indeksu aplikacji

Scenariusze dotyczące serwera proxy i modułu równoważenia obciążenia

W przypadku aplikacji hostowanych przez HTTP.sys, które współdziałają z żądaniami z Internetu lub sieci firmowej, może być wymagana dodatkowa konfiguracja w przypadku hostowania serwerów proxy i modułów równoważenia obciążenia. Aby uzyskać więcej informacji, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Uzyskiwanie szczegółowych informacji o chronometrażu za pomocą funkcji IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature zawiera szczegółowe informacje o pomiarze czasu dla żądań:

  • Znaczniki czasu są uzyskiwane przy użyciu elementu QueryPerformanceCounter.
  • Częstotliwość sygnatury czasowej można uzyskać za pośrednictwem metody QueryPerformanceFrequency.
  • Indeks chronometrażu można rzutować na HttpSysRequestTimingType, aby wiedzieć, co reprezentuje czas.
  • Wartość może wynosić 0, jeśli czas nie jest dostępny dla bieżącego żądania.
  • Wymaga Windows 10 w wersji 2004, Windows Server 2022 lub nowszej.
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 pobiera znacznik czasu dla podanego typu chronometrażu:

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) zwraca czas, który upłynął między dwoma określonymi pomiarami.

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();

Zaawansowane funkcje HTTP/2 do obsługi gRPC

Dodatkowe funkcje HTTP/2 w HTTP.sys obsługują gRPC, w tym obsługę trailerów odpowiedzi i wysyłanie ramek reset.

Wymagania dotyczące uruchamiania usługi gRPC z HTTP.sys:

  • Windows 11 kompilacji 22000 lub nowszej Windows Server 2022 kompilacji 20348 lub nowszej.
  • Połączenie TLS 1.2 lub nowsze.

Trailers

Trailery HTTP są podobne do nagłówków HTTP, z tym wyjątkiem, że są wysyłane po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że przyczepy są obsługiwane w odpowiedzi.
  • DeclareTrailer dodaje daną nazwę przyczepy do nagłówka Trailer odpowiedzi. Deklarowanie przyczep odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi to być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza przyczepę.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

Tracing

Aby uzyskać informacje na temat pobierania śladów z HTTP.sys, zobacz scenariusze zarządzania HTTP.sys.

Automatyczna eksmisja z puli pamięci

Pule pamięci używane przez Kestrel, IIS i HTTP.sys automatycznie usuwają bloki pamięci, gdy aplikacja jest bezczynna lub pod niskim obciążeniem. Funkcja jest uruchamiana automatycznie i nie musi być włączona ani skonfigurowana ręcznie.

W wersjach .NET starszych niż 10 pamięć przydzielona przez pulę pozostaje zarezerwowana, nawet jeśli nie jest używana. Ta funkcja automatycznego usuwania zmniejsza ogólne użycie pamięci i pomaga aplikacjom pozostać responsywnymi przy różnych obciążeniach.

Korzystanie z metryk puli pamięci

Domyślna pula pamięci używana przez implementacje serwera ASP.NET Core obejmuje metryki, których można użyć do monitorowania i analizowania wzorców użycia pamięci. Metryki są pod nazwą "Microsoft.AspNetCore.MemoryPool".

Aby uzyskać informacje o metrykach i sposobie ich używania, zobacz ASP.NET Core metrics.

Zarządzanie pulami pamięci

Oprócz efektywnego zarządzania pulami pamięci poprzez usuwanie niepotrzebnych bloków, ASP.NET Core zapewnia wbudowaną IMemoryPoolFactory i jej implementację. Dzięki iniekcji zależności implementacja jest dostępna dla aplikacji.

Poniższy przykład kodu przedstawia prostą usługę działającą w tle, która używa wbudowanej implementacji fabryki puli pamięci do tworzenia pul pamięci. Te pule korzystają z funkcji automatycznego eksmitowania:

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

Aby użyć niestandardowej fabryki puli pamięci, utwórz klasę, która implementuje IMemoryPoolFactory i zarejestruj ją za pomocą iniekcji zależności, jak w poniższym przykładzie. Pule pamięci utworzone w ten sposób nie korzystają z funkcji automatycznego usuwania, chyba że implementujesz podobną logikę usuwania w fabryce dostosowanej.

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

Jeśli używasz puli pamięci, należy pamiętać o puli MaxBufferSize.

Dodatkowe zasoby

HTTP.sys jest serwerem web dla ASP.NET Core który działa tylko w Windows. HTTP.sys jest alternatywą dla Kestrel serwera i oferuje niektóre funkcje, które Kestrel nie zapewniają.

Important

HTTP.sys nie jest zgodna z modułem ASP.NET Core i nie może być używana z usługami IIS lub IIS Express.

HTTP.sys obsługuje następujące funkcje:

  • Windows Authentication
  • Udostępnianie portów
  • Protokół HTTPS z siecią SNI
  • Protokół HTTP/2 za pośrednictwem protokołu TLS (Windows 10 lub nowszy)
  • Bezpośrednia transmisja plików
  • Buforowanie odpowiedzi
  • WebSockets (Windows 8 lub nowsze)

Obsługiwane wersje Windows:

  • Windows 7 lub nowsza
  • Windows Server 2008 R2 lub nowszy

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Kiedy należy używać HTTP.sys

HTTP.sys jest przydatna w przypadku wdrożeń, w których:

  • Istnieje potrzeba uwidocznienia serwera bezpośrednio w Internecie bez korzystania z usług IIS.

    Serwer HTTP.sys komunikuje się bezpośrednio z Internetem

  • Wdrożenie wewnętrzne wymaga funkcji niedostępnej w programie Kestrel. Aby uzyskać więcej informacji, zobacz Kestrel vs. HTTP.sys

    Serwer HTTP.sys komunikuje się bezpośrednio z siecią wewnętrzną

HTTP.sys to dojrzała technologia, która chroni przed wieloma typami ataków i zapewnia niezawodność, bezpieczeństwo i skalowalność pełnoekranowego serwera internetowego. IIS samo w sobie działa jako odbiornik HTTP w oparciu o HTTP.sys.

Obsługa protokołu HTTP/2

HTTP/2 jest włączona dla aplikacji ASP.NET Core po spełnieniu następujących podstawowych wymagań:

Jeśli połączenie HTTP/2 zostanie nawiązane, httpRequest.Protocol zgłasza HTTP/2.

Protokół HTTP/2 jest domyślnie włączony. Jeśli połączenie HTTP/2 nie zostanie nawiązane, połączenie powróci do protokołu HTTP/1.1. W przyszłej wersji Windows będą dostępne flagi konfiguracji HTTP/2, w tym możliwość wyłączenia protokołu HTTP/2 z HTTP.sys.

Obsługa protokołu HTTP/3

HTTP/3 jest włączona dla aplikacji ASP.NET Core po spełnieniu następujących podstawowych wymagań:

  • Windows Server 2022/Windows 11 lub nowszy
  • Używane jest powiązanie adresu URL.
  • Ustawiono klucz rejestru EnableHttp3.

Poprzednie wersje kompilacji Windows 11 mogą wymagać użycia kompilacji Windows insider.

Protokół HTTP/3 jest wykrywany jako uaktualnienie z protokołu HTTP/1.1 lub HTTP/2 za pośrednictwem nagłówka alt-svc . Oznacza to, że pierwsze żądanie zwykle będzie używać protokołu HTTP/1.1 lub HTTP/2 przed przełączeniem do protokołu HTTP/3. Protokół Http.Sys nie dodaje automatycznie nagłówka alt-svc — musi zostać dodany przez aplikację. Poniższy kod to przykład oprogramowania pośredniczącego, który dodaje alt-svc nagłówek odpowiedzi.

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

Umieść poprzedni kod na początku potoku żądania.

Http.Sys obsługuje również wysyłanie komunikatu protokołu HTTP/2 AltSvc zamiast nagłówka odpowiedzi w celu powiadomienia klienta o dostępności protokołu HTTP/3. Zobacz klucz rejestru EnableAltSvc. Wymaga to powiązań netsh sslcert, które używają nazw hostów, a nie adresów IP.

Uwierzytelnianie w trybie jądra przy użyciu protokołu Kerberos

HTTP.sys deleguje uwierzytelnianie do trybu jądra przy użyciu protokołu uwierzytelniania Kerberos. Uwierzytelnianie w trybie użytkownika nie jest obsługiwane w przypadku protokołu Kerberos i HTTP.sys. Konto komputera musi służyć do odszyfrowywania tokenu/biletu Protokołu Kerberos uzyskanego z Active Directory i przekazywanego przez klienta do serwera w celu uwierzytelnienia użytkownika. Zarejestruj nazwę główną usługi (SPN) dla hosta, a nie użytkownika aplikacji.

Jak używać HTTP.sys

Konfigurowanie aplikacji ASP.NET Core do używania HTTP.sys

Wywołaj metodę UseHttpSys rozszerzenia podczas kompilowania hosta, określając dowolną wymaganą metodę HttpSysOptions. Poniższy przykład ustawia opcje na wartości domyślne:

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

Dodatkowa konfiguracja HTTP.sys jest obsługiwana za pośrednictwem ustawień rejestru.

Aby uzyskać więcej informacji na temat opcji HTTP.sys, zobacz HttpSysOptions.

MaxRequestBodySize

Maksymalny dozwolony rozmiar dowolnej treści żądania w bajtach. Jeśli ustawiono wartość null, maksymalny rozmiar treści żądania jest nieograniczony. Ten limit nie wpływa na połączenia, które zostały uaktualnione, ponieważ są zawsze nieograniczone.

Zalecaną metodą zastąpienia limitu w aplikacji MVC ASP.NET Core dla pojedynczego IActionResult jest użycie atrybutu RequestSizeLimitAttribute w metodzie akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Zgłaszany jest wyjątek, jeśli aplikacja próbuje skonfigurować limit żądania po rozpoczęciu odczytywania żądania przez aplikację. Właściwość IsReadOnly może służyć do wskazania, czy właściwość MaxRequestBodySize jest ustawiona jako tylko do odczytu, co oznacza, że jest za późno na skonfigurowanie limitu.

Jeśli aplikacja powinna zastąpić MaxRequestBodySize żądanie, użyj polecenia 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();
    });
}

Jeśli używasz Visual Studio, upewnij się, że aplikacja nie jest skonfigurowana do uruchamiania usług IIS lub IIS Express.

W Visual Studio domyślnym profilem uruchamiania jest usługa IIS Express. Aby uruchomić projekt jako aplikację konsolową, ręcznie zmień wybrany profil, jak pokazano na poniższym zrzucie ekranu:

Wybieranie profilu aplikacji konsolowej

Konfigurowanie Windows Server

  1. Określ porty do otwarcia dla aplikacji i użyj polecenia cmdlet Windows Firewall lub New-NetFirewallRule polecenia cmdlet programu PowerShell w celu otwarcia portów zapory w celu umożliwienia ruchu do HTTP.sys. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  2. Podczas wdrażania na maszynie wirtualnej Azure otwórz porty w Network Security Group. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  3. W razie potrzeby uzyskaj i zainstaluj certyfikaty X.509.

    W Windows utwórz certyfikaty z podpisem własnym przy użyciu polecenia cmdlet New-SelfSignedCertificate programu PowerShell. Aby zapoznać się z nieobsługiwanym przykładem, zobacz UpdateIISExpressSSLForChrome.ps1.

    Zainstaluj certyfikaty z podpisem własnym lub z podpisem urzędu certyfikacji w magazynie Local Machine>Osobiste.

  4. Jeśli aplikacja jest wdrożeniem zależnym od framework, zainstaluj .NET, .NET Framework lub obie (jeśli aplikacja jest aplikacją .NET przeznaczoną dla platformy .NET).

    • .NET: Jeśli aplikacja wymaga .NET, uzyskaj i uruchom instalator .NET Runtime z .NET Downloads. Nie instaluj pełnego zestawu SDK na serwerze.
    • .NET Framework: Jeśli aplikacja wymaga platformy .NET, zobacz przewodnik instalacji platformy .NET Framework. Zainstaluj wymaganą platformę .NET Framework. Instalator najnowszego .NET Framework jest dostępny na stronie .NET Downloads.

    Jeśli aplikacja jest samodzielnym wdrożeniem, zawiera w sobie środowisko uruchomieniowe. Na serwerze nie jest wymagana instalacja platformy.

  5. Skonfiguruj adresy URL i porty w aplikacji.

    Domyślnie ASP.NET Core wiąże się z http://localhost:5000. Aby skonfigurować prefiksy adresów URL i porty, opcje obejmują:

    • UseUrls
    • urls argument wiersza polecenia
    • ASPNETCORE_URLS zmienna środowiskowa
    • UrlPrefixes

    W poniższym przykładzie kodu pokazano, jak używać UrlPrefixes z lokalnym adresem 10.0.0.4 IP serwera na porcie 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>();
            });
    

    UrlPrefixes Zaletą jest to, że komunikat o błędzie jest generowany natychmiast dla nieprawidłowo sformatowanych prefiksów.

    Ustawienia w UrlPrefixes zastępują ustawienia UseUrls/urls/ASPNETCORE_URLS. W związku z tym zaletą zmiennej środowiskowej UseUrls, urlsi ASPNETCORE_URLS jest to, że łatwiej jest przełączać się między Kestrel i HTTP.sys.

    HTTP.sys używa formatów ciągów UrlPrefix interfejsu API serwera HTTP.

    Warning

    Nie należy używać powiązań z symbolami wieloznacznymi najwyższego poziomu (http://*:80/ i http://+:80). Powiązania z symbolami wieloznacznymi najwyższego poziomu tworzą luki w zabezpieczeniach aplikacji. Dotyczy to zarówno silnych, jak i słabych symboli wieloznacznych. Użyj jawnych nazw hostów lub adresów IP, a nie symboli wieloznacznych. Powiązanie wieloznaczne poddomeny (na przykład *.mysub.com) nie jest zagrożeniem bezpieczeństwa, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Sekcja 7.2: Host i :authority.

  6. Wstępne zarejestrowanie prefiksów adresów URL na serwerze.

    Wbudowane narzędzie do konfigurowania HTTP.sys jest netsh.exe. netsh.exe służy do rezerwowania prefiksów adresów URL i przypisywania certyfikatów X.509. Narzędzie wymaga uprawnień administratora.

    Użyj narzędzia netsh.exe, aby zarejestrować adresy URL aplikacji:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: pełny ujednolicony lokalizator zasobów (URL). Nie używaj wiązania z symbolem wieloznacznym. Użyj prawidłowej nazwy hosta lub lokalnego adresu IP. Adres URL musi zawierać ukośnik końcowy.
    • <USER>: określa nazwę użytkownika lub grupy użytkowników.

    W poniższym przykładzie lokalny adres IP serwera to 10.0.0.4:

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

    Po zarejestrowaniu adresu URL narzędzie odpowiada URL reservation successfully added.

    Aby usunąć zarejestrowany adres URL, użyj delete urlacl polecenia :

    netsh http delete urlacl url=<URL>
    
  7. Zarejestruj certyfikaty X.509 na serwerze.

    Użyj narzędzia netsh.exe, aby zarejestrować certyfikaty dla aplikacji:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: określa lokalny adres IP powiązania. Nie używaj powiązania z symbolami wieloznacznymi. Użyj prawidłowego adresu IP.
    • <PORT>: określa port powiązania.
    • <THUMBPRINT>: odcisk palca certyfikatu X.509.
    • <GUID>: identyfikator GUID wygenerowany przez dewelopera reprezentujący aplikację do celów informacyjnych.

    Do celów referencyjnych zapisz identyfikator GUID w aplikacji jako tag pakietu:

    • W Visual Studio:
      • Otwórz właściwości projektu aplikacji, klikając prawym przyciskiem myszy aplikację w Eksplorator rozwiązań i wybierając pozycję Właściwości.
      • Wybierz kartę Pakiet .
      • Wprowadź identyfikator GUID, który utworzyłeś, w polu Tagi.
    • Jeśli nie używasz Visual Studio:
      • Otwórz plik projektu aplikacji.

      • Dodaj właściwość <PackageTags> do nowej lub istniejącej <PropertyGroup> z identyfikatorem GUID, który utworzyłeś:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags>
        </PropertyGroup>
        

    W poniższym przykładzie:

    • Lokalny adres IP serwera to 10.0.0.4.
    • Generator losowego identyfikatora appid GUID w trybie online zapewnia wartość .
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Po zarejestrowaniu certyfikatu narzędzie odpowiada za pomocą SSL Certificate successfully added.

    Aby usunąć rejestrację certyfikatu, użyj delete sslcert polecenia :

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

    Dokumentacja referencyjna netsh.exe:

  8. Uruchom aplikację.

    Uprawnienia administratora nie są wymagane do uruchamiania aplikacji podczas tworzenia powiązania z hostem lokalnym przy użyciu protokołu HTTP (a nie HTTPS) z numerem portu większym niż 1024. W przypadku innych konfiguracji (na przykład przy użyciu lokalnego adresu IP lub powiązania z portem 443) uruchom aplikację z uprawnieniami administratora.

    Aplikacja odpowiada na publiczny adres IP serwera. W tym przykładzie serwer jest osiągany z Internetu pod jego publicznym adresem IP .104.214.79.47

    W tym przykładzie używany jest certyfikat dewelopera. Strona ładuje się bezpiecznie po ominięciu ostrzeżenia przeglądarki dotyczącego niezaufanego certyfikatu.

    Okno przeglądarki z załadowaną stroną indeksu aplikacji

Scenariusze dotyczące serwera proxy i modułu równoważenia obciążenia

W przypadku aplikacji hostowanych przez HTTP.sys, które współdziałają z żądaniami z Internetu lub sieci firmowej, może być wymagana dodatkowa konfiguracja w przypadku hostowania serwerów proxy i modułów równoważenia obciążenia. Aby uzyskać więcej informacji, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Zaawansowane funkcje HTTP/2 do obsługi gRPC

Dodatkowe funkcje HTTP/2 w HTTP.sys obsługują gRPC, w tym obsługę trailerów odpowiedzi i wysyłanie ramek reset.

Wymagania dotyczące uruchamiania usługi gRPC z HTTP.sys:

  • Windows 11 kompilacji 22000 lub nowszej Windows Server 2022 kompilacji 20348 lub nowszej.
  • Połączenie TLS 1.2 lub nowsze.

Trailers

Trailery HTTP są podobne do nagłówków HTTP, z tym wyjątkiem, że są wysyłane po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że przyczepy są obsługiwane w odpowiedzi.
  • DeclareTrailer dodaje daną nazwę przyczepy do nagłówka Trailer odpowiedzi. Deklarowanie przyczep odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi to być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza przyczepę.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

Dodatkowe zasoby

HTTP.sys jest serwerem web dla ASP.NET Core który działa tylko w Windows. HTTP.sys jest alternatywą dla Kestrel serwera i oferuje niektóre funkcje, które Kestrel nie zapewniają.

Important

HTTP.sys nie jest zgodna z modułem ASP.NET Core i nie może być używana z usługami IIS lub IIS Express.

HTTP.sys obsługuje następujące funkcje:

  • Windows Authentication
  • Udostępnianie portów
  • Protokół HTTPS z siecią SNI
  • Protokół HTTP/2 za pośrednictwem protokołu TLS (Windows 10 lub nowszy)
  • Bezpośrednia transmisja plików
  • Buforowanie odpowiedzi
  • WebSockets (Windows 8 lub nowsze)

Obsługiwane wersje Windows:

  • Windows 7 lub nowsza
  • Windows Server 2008 R2 lub nowszy

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Kiedy należy używać HTTP.sys

HTTP.sys jest przydatna w przypadku wdrożeń, w których:

  • Istnieje potrzeba uwidocznienia serwera bezpośrednio w Internecie bez korzystania z usług IIS.

    Serwer HTTP.sys komunikuje się bezpośrednio z Internetem

  • Wdrożenie wewnętrzne wymaga funkcji niedostępnej w programie Kestrel. Aby uzyskać więcej informacji, zobacz Kestrel vs. HTTP.sys

    Serwer HTTP.sys komunikuje się bezpośrednio z siecią wewnętrzną

HTTP.sys to dojrzała technologia, która chroni przed wieloma typami ataków i zapewnia niezawodność, bezpieczeństwo i skalowalność pełnoekranowego serwera internetowego. IIS sam działa jako odbiornik HTTP korzystający z HTTP.sys.

Obsługa protokołu HTTP/2

HTTP/2 jest włączona dla aplikacji ASP.NET Core, jeśli spełnione są następujące podstawowe wymagania:

Jeśli połączenie HTTP/2 zostanie nawiązane, httpRequest.Protocol zgłasza HTTP/2.

Protokół HTTP/2 jest domyślnie włączony. Jeśli połączenie HTTP/2 nie zostanie nawiązane, połączenie powróci do protokołu HTTP/1.1. W przyszłej wersji Windows będą dostępne flagi konfiguracji HTTP/2, w tym możliwość wyłączenia protokołu HTTP/2 z HTTP.sys.

Uwierzytelnianie w trybie jądra przy użyciu protokołu Kerberos

HTTP.sys deleguje do uwierzytelniania w tryb jądra przy użyciu protokołu uwierzytelniania Kerberos. Uwierzytelnianie w trybie użytkownika nie jest obsługiwane w przypadku protokołu Kerberos i HTTP.sys. Konto komputera musi służyć do odszyfrowywania tokenu/biletu Protokołu Kerberos uzyskanego z Active Directory i przekazywanego przez klienta do serwera w celu uwierzytelnienia użytkownika. Zarejestruj nazwę główną usługi (SPN) dla hosta, a nie użytkownika aplikacji.

Jak używać HTTP.sys

Konfigurowanie aplikacji ASP.NET Core do używania HTTP.sys

Wywołaj metodę rozszerzającą UseHttpSys podczas kompilowania hosta, określając wszelkie wymagane HttpSysOptions. Poniższy przykład ustawia opcje na wartości domyślne:

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

Dodatkowa konfiguracja HTTP.sys jest obsługiwana za pośrednictwem ustawień rejestru.

opcje HTTP.sys

Property Description Default
AllowSynchronousIO Określ, czy dane wejściowe/wyjściowe synchroniczne są dozwolone dla parametrów HttpContext.Request.Body i HttpContext.Response.Body. false
Authentication.AllowAnonymous Zezwalaj na żądania anonimowe. true
Authentication.Schemes Określ dozwolone schematy uwierzytelniania. Może być modyfikowany w dowolnej chwili przed usunięciem nasłuchiwacza. Wartości są dostarczane przez wyliczenie AuthenticationSchemes: Basic, Kerberos, Negotiate, None i NTLM. None
EnableResponseCaching Spróbuj buforowania trybu jądra dla odpowiedzi z odpowiednimi nagłówkami. Odpowiedź może nie zawierać nagłówków Set-Cookie, Vary lub Pragma. Musi zawierać nagłówek Cache-Control, który jest public oraz wartość shared-max-age albo max-age, lub nagłówek Expires. true
Http503Verbosity Zachowanie HTTP.sys podczas odrzucania żądań z powodu warunków ograniczania przepustowości. Http503VerbosityLevel.
Podstawowy
MaxAccepts Maksymalna liczba jednoczesnych akceptacji. 5 × Środowisko.
LiczbaProcesorów
MaxConnections Maksymalna liczba współbieżnych połączeń do zaakceptowania. Użyj -1 do oznaczenia nieskończoności. Użyj null do użycia ustawienia maszyny na poziomie systemu. null
(machine-wide
setting)
MaxRequestBodySize Zobacz sekcję MaxRequestBodySize . 30000000 bajtów
(~28,6 MB)
RequestQueueLimit Maksymalna liczba żądań, które można kolejkować. 1000
RequestQueueMode Wskazuje to, czy serwer jest odpowiedzialny za tworzenie i konfigurowanie kolejki żądań, czy też należy dołączyć go do istniejącej kolejki.
Większość dostępnych opcji konfiguracji nie ma zastosowania przy dołączaniu do istniejącej kolejki.
RequestQueueMode.Create
RequestQueueName Nazwa kolejki żądań HTTP.sys. null (Kolejka anonimowa)
ThrowWriteExceptions Wskaż, czy w przypadku niepowodzenia zapisu treści odpowiedzi z powodu rozłączenia klienta, powinny być zgłaszane wyjątki, czy proces powinien zakończyć się normalnie. false
(ukończone normalnie)
Timeouts Uwidocznij konfigurację HTTP.sys TimeoutManager , która może być również skonfigurowana w rejestrze. Skorzystaj z linków interfejsu API, aby dowiedzieć się więcej o każdym ustawieniu, w tym wartościach domyślnych:
UrlPrefixes Określ UrlPrefixCollection, aby zarejestrować w HTTP.sys. Najbardziej przydatna jest funkcja UrlPrefixCollection.Add, która służy do dodawania prefiksu do kolekcji. Mogą one być modyfikowane w dowolnym momencie przed zakończeniem używania nasłuchiwacza.

MaxRequestBodySize

Maksymalny dozwolony rozmiar dowolnej treści żądania w bajtach. Jeśli ustawiono wartość null, maksymalny rozmiar treści żądania jest nieograniczony. To ograniczenie nie dotyczy uaktualnionych połączeń, które są zawsze nieograniczone.

Zalecaną metodą zastąpienia limitu w aplikacji MVC ASP.NET Core dla pojedynczego IActionResult jest użycie atrybutu RequestSizeLimitAttribute w metodzie akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Zgłaszany jest wyjątek, jeśli aplikacja próbuje skonfigurować limit żądania po rozpoczęciu odczytywania żądania przez aplikację. Właściwość IsReadOnly może służyć do wskazania, czy MaxRequestBodySize właściwość jest w trybie tylko do odczytu, co oznacza, że jest zbyt późno na skonfigurowanie limitu.

Jeśli aplikacja powinna zastąpić MaxRequestBodySize na każde żądanie, użyj 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();
    });
}

Jeśli używasz Visual Studio, upewnij się, że aplikacja nie jest skonfigurowana do uruchamiania usług IIS lub IIS Express.

W Visual Studio domyślnym profilem uruchamiania jest usługa IIS Express. Aby uruchomić projekt jako aplikację konsolową, ręcznie zmień wybrany profil, jak pokazano na poniższym zrzucie ekranu:

Wybieranie profilu aplikacji konsolowej

Konfigurowanie Windows Server

  1. Określ porty do otwarcia dla aplikacji i użyj cmdletów programu PowerShell: Windows Firewall lub New-NetFirewallRule, aby otworzyć porty zapory i umożliwić ruch do HTTP.sys. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  2. Podczas wdrażania na maszynie wirtualnej Azure otwórz porty w Network Security Group. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  3. W razie potrzeby uzyskaj i zainstaluj certyfikaty X.509.

    W Windows utwórz certyfikaty z podpisem własnym przy użyciu polecenia cmdlet New-SelfSignedCertificate programu PowerShell. Aby zapoznać się z nieobsługiwanym przykładem, zobacz UpdateIISExpressSSLForChrome.ps1.

    Zainstaluj certyfikaty z podpisem własnym lub z podpisem urzędu certyfikacji w magazynie Local Machine>Osobistym serwera.

  4. Jeśli aplikacja jest wdrożeniem zależnym od framework, zainstaluj .NET, .NET Framework lub obie (jeśli aplikacja jest aplikacją .NET przeznaczoną dla platformy .NET).

    • .NET: Jeśli aplikacja wymaga .NET, uzyskaj i uruchom instalator .NET Runtime z Pobrane .NET. Nie instaluj pełnego zestawu SDK na serwerze.
    • .NET Framework: Jeśli aplikacja wymaga platformy .NET, zobacz przewodnik instalacji platformy .NET Framework. Zainstaluj wymaganą platformę .NET Framework. Instalator najnowszej platformy .NET jest dostępny na stronie .NET Do pobrania.

    Jeśli aplikacja jest wdrożeniem samodzielnym, aplikacja zawiera środowisko uruchomieniowe we wdrożeniu. Na serwerze nie jest wymagana instalacja platformy.

  5. Skonfiguruj adresy URL i porty w aplikacji.

    Domyślnie ASP.NET Core wiąże się z http://localhost:5000. Aby skonfigurować prefiksy adresów URL i porty, opcje obejmują:

    • UseUrls
    • urls argument wiersza polecenia
    • ASPNETCORE_URLS zmienna środowiskowa
    • UrlPrefixes

    W poniższym przykładzie kodu pokazano, jak używać UrlPrefixes z lokalnym adresem 10.0.0.4 IP serwera na porcie 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>();
            });
    

    UrlPrefixes Zaletą jest to, że komunikat o błędzie jest generowany natychmiast dla nieprawidłowo sformatowanych prefiksów.

    Ustawienia w UrlPrefixes zastępują ustawienia UseUrls/urls/ASPNETCORE_URLS. W związku z tym zaletą zmiennej środowiskowej UseUrls, urlsi ASPNETCORE_URLS jest to, że łatwiej jest przełączać się między Kestrel i HTTP.sys.

    HTTP.sys używa formatów ciągów znaków UrlPrefix interfejsu API serwera HTTP.

    Warning

    Nie należy używać powiązań z symbolami wieloznacznymi najwyższego poziomu (http://*:80/ i http://+:80). Powiązania z symbolami wieloznacznymi najwyższego poziomu tworzą luki w zabezpieczeniach aplikacji. Dotyczy to zarówno silnych, jak i słabych symboli wieloznacznych. Użyj jawnych nazw hostów lub adresów IP, a nie symboli wieloznacznych. Powiązanie wieloznaczne poddomeny (na przykład *.mysub.com) nie jest zagrożeniem bezpieczeństwa, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Sekcja 7.2: Host i :authority.

  6. Wstępne zarejestrowanie prefiksów adresów URL na serwerze.

    Wbudowane narzędzie do konfigurowania HTTP.sys jest netsh.exe. netsh.exe służy do rezerwowania prefiksów adresów URL i przypisywania certyfikatów X.509. Narzędzie wymaga uprawnień administratora.

    Użyj narzędzia netsh.exe, aby zarejestrować adresy URL aplikacji:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: w pełni kwalifikowany ujednolicony lokalizator zasobów (URL). Nie używaj powiązania z symbolami wieloznacznymi. Użyj prawidłowej nazwy hosta lub lokalnego adresu IP. Adres URL musi zawierać ukośnik końcowy.
    • <USER>: określa nazwę użytkownika lub grupy użytkowników.

    W poniższym przykładzie lokalny adres IP serwera to 10.0.0.4:

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

    Po zarejestrowaniu adresu URL narzędzie odpowiada za pomocą URL reservation successfully added.

    Aby usunąć zarejestrowany adres URL, użyj delete urlacl polecenia :

    netsh http delete urlacl url=<URL>
    
  7. Zarejestruj certyfikaty X.509 na serwerze.

    Użyj narzędzia netsh.exe, aby zarejestrować certyfikaty dla aplikacji:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: określa lokalny adres IP powiązania. Nie używaj powiązania z symbolami wieloznacznymi. Użyj prawidłowego adresu IP.
    • <PORT>: określa port powiązania.
    • <THUMBPRINT>: odcisk palca certyfikatu X.509.
    • <GUID>: identyfikator GUID wygenerowany przez dewelopera reprezentujący aplikację do celów informacyjnych.

    Do celów referencyjnych zapisz identyfikator GUID w aplikacji jako tag pakietu:

    • W Visual Studio:
      • Otwórz właściwości projektu aplikacji, klikając prawym przyciskiem myszy aplikację w Eksplorator rozwiązań i wybierając pozycję Właściwości.
      • Wybierz kartę Pakiet .
      • Wprowadź identyfikator GUID, który utworzyłeś w polu Tagi.
    • Jeśli nie używasz Visual Studio:
      • Otwórz plik projektu aplikacji.

      • Dodaj właściwość <PackageTags> do nowej lub istniejącej <PropertyGroup>, używając utworzonego przez ciebie identyfikatora GUID.

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags>
        </PropertyGroup>
        

    W poniższym przykładzie:

    • Lokalny adres IP serwera to 10.0.0.4.
    • Generator online losowych identyfikatorów GUID dostarcza wartość appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Po zarejestrowaniu certyfikatu narzędzie odpowiada za pomocą SSL Certificate successfully added.

    Aby usunąć rejestrację certyfikatu, użyj delete sslcert polecenia :

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

    Dokumentacja referencyjna netsh.exe:

  8. Uruchom aplikację.

    Uprawnienia administratora nie są wymagane do uruchamiania aplikacji podczas tworzenia powiązania z hostem lokalnym przy użyciu protokołu HTTP (a nie HTTPS) z numerem portu większym niż 1024. W przypadku innych konfiguracji (na przykład przy użyciu lokalnego adresu IP lub powiązania z portem 443) uruchom aplikację z uprawnieniami administratora.

    Aplikacja odpowiada na publiczny adres IP serwera. W tym przykładzie serwer jest osiągany z Internetu pod jego publicznym adresem IP .104.214.79.47

    W tym przykładzie używany jest certyfikat dewelopera. Strona ładuje się bezpiecznie po ominięciu ostrzeżenia przeglądarki dotyczącego niezaufanego certyfikatu.

    Okno przeglądarki z załadowaną stroną indeksu aplikacji

Scenariusze dotyczące serwera proxy i modułu równoważenia obciążenia

W przypadku aplikacji hostowanych przez HTTP.sys, które współdziałają z żądaniami z Internetu lub sieci firmowej, może być wymagana dodatkowa konfiguracja w przypadku hostowania serwerów proxy i modułów równoważenia obciążenia. Aby uzyskać więcej informacji, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Zaawansowane funkcje HTTP/2 do obsługi gRPC

Dodatkowe funkcje HTTP/2 w HTTP.sys obsługują gRPC, w tym obsługę trailerów odpowiedzi i wysyłanie ramek reset.

Wymagania dotyczące uruchamiania usługi gRPC z HTTP.sys:

  • Windows 10, kompilacja systemu operacyjnego 19041.508 lub nowsza
  • Połączenie TLS 1.2 lub nowsze

Trailers

Trailery HTTP są podobne do nagłówków HTTP, z tym wyjątkiem, że są wysyłane po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że przyczepy są obsługiwane w odpowiedzi.
  • DeclareTrailer dodaje daną nazwę przyczepy do nagłówka Trailer odpowiedzi. Deklarowanie przyczep odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi to być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza przyczepę.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

Dodatkowe zasoby

HTTP.sys jest serwerem web dla ASP.NET Core który działa tylko w Windows. HTTP.sys jest alternatywą dla Kestrel serwera i oferuje niektóre funkcje, które Kestrel nie zapewniają.

Important

HTTP.sys nie jest zgodna z modułem ASP.NET Core i nie może być używana z usługami IIS lub IIS Express.

HTTP.sys obsługuje następujące funkcje:

  • Windows Authentication
  • Udostępnianie portów
  • Protokół HTTPS z siecią SNI
  • Protokół HTTP/2 za pośrednictwem protokołu TLS (Windows 10 lub nowszy)
  • Protokół HTTP/3 za pośrednictwem protokołu TLS (Windows 11 lub nowszy)
  • Bezpośrednia transmisja plików
  • Buforowanie odpowiedzi
  • WebSockets (Windows 8 lub nowsze)
  • Dostosowywalne deskryptory zabezpieczeń

Obsługiwane wersje Windows:

  • Windows 7 lub nowsza
  • Windows Server 2008 R2 lub nowszy

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Kiedy należy używać HTTP.sys

HTTP.sys jest przydatna w przypadku wdrożeń, w których:

  • Istnieje potrzeba uwidocznienia serwera bezpośrednio w Internecie bez korzystania z usług IIS.

    Serwer HTTP.sys komunikuje się bezpośrednio z Internetem

  • Wdrożenie wewnętrzne wymaga funkcji niedostępnej w programie Kestrel. Aby uzyskać więcej informacji, zobacz Kestrel vs. HTTP.sys

    Serwer HTTP.sys komunikuje się bezpośrednio z siecią wewnętrzną

HTTP.sys to dojrzała technologia, która chroni przed wieloma typami ataków i zapewnia niezawodność, bezpieczeństwo i skalowalność pełnoekranowego serwera internetowego. IIS sam działa jako odbiornik HTTP korzystający z HTTP.sys.

Obsługa protokołu HTTP/2

HTTP/2 jest włączona dla aplikacji ASP.NET Core po spełnieniu następujących podstawowych wymagań:

Jeśli połączenie HTTP/2 zostanie nawiązane, httpRequest.Protocol zgłasza HTTP/2.

Protokół HTTP/2 jest domyślnie włączony. Jeśli połączenie HTTP/2 nie zostanie nawiązane, połączenie powróci do protokołu HTTP/1.1. W przyszłej wersji Windows będą dostępne flagi konfiguracji HTTP/2, w tym możliwość wyłączenia protokołu HTTP/2 z HTTP.sys.

Obsługa protokołu HTTP/3

HTTP/3 jest włączona dla aplikacji ASP.NET Core po spełnieniu następujących podstawowych wymagań:

  • Windows Server 2022/Windows 11 lub nowszy
  • Używane jest powiązanie adresu URL.
  • Ustawiono klucz rejestru EnableHttp3.

Poprzednie wersje kompilacji Windows 11 mogą wymagać użycia kompilacji Windows insider.

Protokół HTTP/3 jest wykrywany jako uaktualnienie z protokołu HTTP/1.1 lub HTTP/2 za pośrednictwem nagłówka alt-svc . Oznacza to, że pierwsze żądanie zwykle będzie używać protokołu HTTP/1.1 lub HTTP/2 przed przełączeniem do protokołu HTTP/3. Protokół Http.Sys nie dodaje automatycznie nagłówka alt-svc — musi zostać dodany przez aplikację. Poniższy kod to przykład oprogramowania pośredniczącego, który dodaje alt-svc nagłówek odpowiedzi.

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

Umieść poprzedni kod na początku potoku żądania.

Http.Sys obsługuje również wysyłanie komunikatu protokołu HTTP/2 AltSvc zamiast nagłówka odpowiedzi w celu powiadomienia klienta o dostępności protokołu HTTP/3. Zobacz klucz rejestru EnableAltSvc. Wymaga to powiązań netsh sslcert, które używają nazw hostów, a nie adresów IP.

Uwierzytelnianie w trybie jądra przy użyciu protokołu Kerberos

HTTP.sys deleguje uwierzytelnianie do trybu jądra przy użyciu protokołu uwierzytelniania Kerberos. Uwierzytelnianie w trybie użytkownika nie jest obsługiwane w przypadku protokołu Kerberos i HTTP.sys. Konto komputera musi służyć do odszyfrowywania tokenu/biletu Protokołu Kerberos uzyskanego z Active Directory i przekazywanego przez klienta do serwera w celu uwierzytelnienia użytkownika. Zarejestruj nazwę główną usługi (SPN) dla hosta, a nie użytkownika aplikacji.

Obsługa buforowania odpowiedzi w trybie jądra

W niektórych scenariuszach duże ilości małych zapisów z dużym opóźnieniem mogą spowodować znaczny wpływ na wydajność.HTTP.sys Ten wpływ jest spowodowany brakiem Pipe buforu w implementacji HTTP.sys . Aby zwiększyć wydajność w tych scenariuszach, obsługa buforowania odpowiedzi jest uwzględniana w systemie HTTP.sys. Włącz buforowanie, ustawiając wartość HttpSysOptions.EnableKernelResponseBuffering na true. Buforowanie odpowiedzi powinno być włączone przez aplikację, która wykonuje synchroniczne operacje we/wy lub asynchroniczne operacje we/wy bez więcej niż jednego zaległego zapisu naraz. W tych scenariuszach buforowanie odpowiedzi może znacznie zwiększyć przepływność w przypadku połączeń o dużym opóźnieniu.

Aplikacje, które korzystają z asynchronicznych operacji we/wy i mogą mieć więcej niż jeden nieukończony zapis jednocześnie, nie powinny używać tej flagi. Włączenie tej flagi może spowodować wyższe użycie procesora CPU i pamięci przez HTTP.Sys.

Jak używać HTTP.sys

Konfigurowanie aplikacji ASP.NET Core do używania HTTP.sys

Wywołaj metodę UseHttpSys rozszerzenia podczas kompilowania hosta, określając dowolną wymaganą metodę HttpSysOptions. Poniższy przykład ustawia opcje na wartości domyślne:

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();

Dodatkowa konfiguracja HTTP.sys jest obsługiwana za pośrednictwem ustawień rejestru.

Aby uzyskać więcej informacji na temat opcji HTTP.sys, zobacz HttpSysOptions.

MaxRequestBodySize

Maksymalny dozwolony rozmiar dowolnej treści żądania w bajtach. Jeśli ustawiono wartość null, maksymalny rozmiar treści żądania jest nieograniczony. Ten limit nie wpływa na połączenia, które zostały uaktualnione, ponieważ są zawsze nieograniczone.

Zalecaną metodą zastąpienia limitu w aplikacji MVC ASP.NET Core dla pojedynczego IActionResult jest użycie atrybutu RequestSizeLimitAttribute w metodzie akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Zgłaszany jest wyjątek, jeśli aplikacja próbuje skonfigurować limit żądania po rozpoczęciu odczytywania żądania przez aplikację. Właściwość IsReadOnly może służyć do wskazania, czy właściwość MaxRequestBodySize jest ustawiona jako tylko do odczytu, co oznacza, że jest za późno na skonfigurowanie limitu.

Jeśli aplikacja powinna zastąpić MaxRequestBodySize żądanie, użyj polecenia 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);
});

Jeśli używasz Visual Studio, upewnij się, że aplikacja nie jest skonfigurowana do uruchamiania usług IIS lub IIS Express.

W Visual Studio domyślnym profilem uruchamiania jest usługa IIS Express. Aby uruchomić projekt jako aplikację konsolową, ręcznie zmień wybrany profil, jak pokazano na poniższym zrzucie ekranu:

Wybieranie profilu aplikacji konsolowej

Konfigurowanie Windows Server

  1. Określ porty do otwarcia dla aplikacji i użyj polecenia cmdlet Windows Firewall lub New-NetFirewallRule polecenia cmdlet programu PowerShell w celu otwarcia portów zapory w celu umożliwienia ruchu do HTTP.sys. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  2. Podczas wdrażania na maszynie wirtualnej Azure otwórz porty w Network Security Group. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  3. W razie potrzeby uzyskaj i zainstaluj certyfikaty X.509.

    W Windows utwórz certyfikaty z podpisem własnym przy użyciu polecenia cmdlet New-SelfSignedCertificate programu PowerShell. Aby zapoznać się z nieobsługiwanym przykładem, zobacz UpdateIISExpressSSLForChrome.ps1.

    Zainstaluj certyfikaty z podpisem własnym lub z podpisem urzędu certyfikacji w magazynie Local Machine>Osobistym serwera.

  4. Jeśli aplikacja jest wdrożeniem zależnym od framework, zainstaluj .NET, .NET Framework lub obie (jeśli aplikacja jest aplikacją .NET przeznaczoną dla platformy .NET).

    • .NET: Jeśli aplikacja wymaga .NET, uzyskaj i uruchom instalator .NET Runtime z Pobrane .NET. Nie instaluj pełnego zestawu SDK na serwerze.
    • .NET Framework: Jeśli aplikacja wymaga platformy .NET, zobacz przewodnik instalacji platformy .NET Framework. Zainstaluj wymaganą platformę .NET Framework. Instalator najnowszej platformy .NET jest dostępny na stronie .NET Do pobrania.

    Jeśli aplikacja jest wdrożeniem samodzielnym, aplikacja zawiera środowisko uruchomieniowe we wdrożeniu. Na serwerze nie jest wymagana instalacja platformy.

  5. Skonfiguruj adresy URL i porty w aplikacji.

    Domyślnie ASP.NET Core wiąże się z http://localhost:5000. Aby skonfigurować prefiksy adresów URL i porty, opcje obejmują:

    • UseUrls
    • urls argument wiersza polecenia
    • ASPNETCORE_URLS zmienna środowiskowa
    • UrlPrefixes

    W poniższym przykładzie kodu pokazano, jak używać UrlPrefixes z lokalnym adresem 10.0.0.4 IP serwera na porcie 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();
    

    UrlPrefixes Zaletą jest to, że komunikat o błędzie jest generowany natychmiast dla nieprawidłowo sformatowanych prefiksów.

    Ustawienia w UrlPrefixes zastępują ustawienia UseUrls/urls/ASPNETCORE_URLS. W związku z tym zaletą zmiennej środowiskowej UseUrls, urlsi ASPNETCORE_URLS jest to, że łatwiej jest przełączać się między Kestrel i HTTP.sys.

    HTTP.sys rozpoznaje dwa typy symboli wieloznacznych w prefiksach adresów URL:

    • * jest słabym powiązaniem, znanym również jako powiązanie rezerwowe. Jeśli prefiks adresu URL to http://*:5000, a coś innego jest powiązane z portem 5000, to powiązanie nie będzie używane.
    • + jest silnym powiązaniem. Jeśli prefiks adresu URL to http://+:5000, to powiązanie będzie używane przed innymi powiązaniami portu 5000.

    Aby uzyskać więcej informacji, zobacz UrlPrefix Strings.

    Warning

    Nie należy używać powiązań z symbolami wieloznacznymi najwyższego poziomu (http://*:80/ i http://+:80). Powiązania z symbolami wieloznacznymi najwyższego poziomu tworzą luki w zabezpieczeniach aplikacji. Dotyczy to zarówno silnych, jak i słabych symboli wieloznacznych. Użyj jawnych nazw hostów lub adresów IP, a nie symboli wieloznacznych. Powiązanie wieloznaczne poddomeny (na przykład *.mysub.com) nie jest zagrożeniem bezpieczeństwa, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Sekcja 7.2: Host i :authority.

    Aplikacje i kontenery często otrzymują tylko port do nasłuchiwania, na przykład port 80, bez dodatkowych ograniczeń, takich jak host lub ścieżka. HTTP_PORTS i HTTPS_PORTS to klucze konfiguracji, które określają porty nasłuchiwania dla Kestrel oraz serwerów HTTP.sys. Te klucze mogą być określone jako zmienne środowiskowe zdefiniowane z prefiksami DOTNET_ lub ASPNETCORE_ albo określone bezpośrednio poprzez inne dane wejściowe konfiguracji, takie jak appsettings.json. Każda z nich jest rozdzieloną średnikami listą wartości portów, jak pokazano w poniższym przykładzie:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    Powyższy przykład jest skrócony dla następującej konfiguracji, która określa schemat (HTTP lub HTTPS) i dowolny host lub adres IP.

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

    Klucze konfiguracji HTTP_PORTS i HTTPS_PORTS mają niższy priorytet i są zastępowane przez adresy URL lub wartości podane bezpośrednio w kodzie. Certyfikaty nadal muszą być konfigurowane oddzielnie za pośrednictwem mechaniki specyficznej dla serwera dla protokołu HTTPS.

    Te klucze konfiguracji są równoważne powiązaniom symboli wieloznacznych najwyższego poziomu. Są one wygodne w scenariuszach tworzenia i kontenera, ale unikaj symboli wieloznacznych podczas uruchamiania na maszynie, która może również hostować inne usługi.

  6. Wstępne zarejestrowanie prefiksów adresów URL na serwerze.

    Wbudowane narzędzie do konfigurowania HTTP.sys jest netsh.exe. netsh.exe służy do rezerwowania prefiksów adresów URL i przypisywania certyfikatów X.509. Narzędzie wymaga uprawnień administratora.

    Użyj narzędzia netsh.exe, aby zarejestrować adresy URL aplikacji:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: w pełni kwalifikowany ujednolicony lokalizator zasobów (URL). Nie używaj powiązania z symbolami wieloznacznymi. Użyj prawidłowej nazwy hosta lub lokalnego adresu IP. Adres URL musi zawierać ukośnik końcowy.
    • <USER>: określa nazwę użytkownika lub grupy użytkowników.

    W poniższym przykładzie lokalny adres IP serwera to 10.0.0.4:

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

    Po zarejestrowaniu adresu URL narzędzie odpowiada za pomocą URL reservation successfully added.

    Aby usunąć zarejestrowany adres URL, użyj delete urlacl polecenia :

    netsh http delete urlacl url=<URL>
    
  7. Zarejestruj certyfikaty X.509 na serwerze.

    Użyj narzędzia netsh.exe, aby zarejestrować certyfikaty dla aplikacji:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: określa lokalny adres IP powiązania. Nie używaj powiązania z symbolami wieloznacznymi. Użyj prawidłowego adresu IP.
    • <PORT>: określa port powiązania.
    • <THUMBPRINT>: odcisk palca certyfikatu X.509.
    • <GUID>: identyfikator GUID wygenerowany przez dewelopera reprezentujący aplikację do celów informacyjnych.

    Do celów referencyjnych zapisz identyfikator GUID w aplikacji jako tag pakietu:

    • W Visual Studio:
      • Otwórz właściwości projektu aplikacji, klikając prawym przyciskiem myszy aplikację w Eksplorator rozwiązań i wybierając pozycję Właściwości.
      • Wybierz kartę Pakiet .
      • Wprowadź identyfikator GUID, który utworzyłeś w polu Tagi.
    • Jeśli nie używasz Visual Studio:
      • Otwórz plik projektu aplikacji.

      • Dodaj właściwość <PackageTags> do nowej lub istniejącej <PropertyGroup>, używając utworzonego przez ciebie identyfikatora GUID.

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags>
        </PropertyGroup>
        

    W poniższym przykładzie:

    • Lokalny adres IP serwera to 10.0.0.4.
    • Generator online losowych identyfikatorów GUID dostarcza wartość appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Po zarejestrowaniu certyfikatu narzędzie odpowiada za pomocą SSL Certificate successfully added.

    Aby usunąć rejestrację certyfikatu, użyj delete sslcert polecenia :

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

    Dokumentacja referencyjna netsh.exe:

  8. Uruchom aplikację.

    Uprawnienia administratora nie są wymagane do uruchamiania aplikacji podczas tworzenia powiązania z hostem lokalnym przy użyciu protokołu HTTP (a nie HTTPS) z numerem portu większym niż 1024. W przypadku innych konfiguracji (na przykład przy użyciu lokalnego adresu IP lub powiązania z portem 443) uruchom aplikację z uprawnieniami administratora.

    Aplikacja odpowiada na publiczny adres IP serwera. W tym przykładzie serwer jest osiągany z Internetu pod jego publicznym adresem IP .104.214.79.47

    W tym przykładzie używany jest certyfikat dewelopera. Strona ładuje się bezpiecznie po ominięciu ostrzeżenia przeglądarki dotyczącego niezaufanego certyfikatu.

    Okno przeglądarki z załadowaną stroną indeksu aplikacji

Scenariusze dotyczące serwera proxy i modułu równoważenia obciążenia

W przypadku aplikacji hostowanych przez HTTP.sys, które współdziałają z żądaniami z Internetu lub sieci firmowej, może być wymagana dodatkowa konfiguracja w przypadku hostowania serwerów proxy i modułów równoważenia obciążenia. Aby uzyskać więcej informacji, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Uzyskiwanie szczegółowych informacji o chronometrażu za pomocą funkcji IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature zawiera szczegółowe informacje o pomiarze czasu dla żądań:

  • Znaczniki czasu są uzyskiwane przy użyciu elementu QueryPerformanceCounter.
  • Częstotliwość sygnatury czasowej można uzyskać za pośrednictwem metody QueryPerformanceFrequency.
  • Indeks chronometrażu można rzutować na HttpSysRequestTimingType, aby wiedzieć, co reprezentuje czas.
  • Wartość może wynosić 0, jeśli czas nie jest dostępny dla bieżącego żądania.
  • Wymaga Windows 10 w wersji 2004, Windows Server 2022 lub nowszej.
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 pobiera znacznik czasu dla podanego typu chronometrażu:

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) zwraca czas, który upłynął między dwoma określonymi pomiarami.

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();

Zaawansowane funkcje HTTP/2 do obsługi gRPC

Dodatkowe funkcje HTTP/2 w HTTP.sys obsługują gRPC, w tym obsługę trailerów odpowiedzi i wysyłanie ramek resetu.

Wymagania dotyczące uruchamiania usługi gRPC z HTTP.sys:

  • Windows 11 kompilacji 22000 lub nowszej Windows Server 2022 kompilacji 20348 lub nowszej.
  • Połączenie TLS 1.2 lub nowsze.

Trailers

Trailery HTTP są podobne do nagłówków HTTP, z tym wyjątkiem, że są wysyłane po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że przyczepy są obsługiwane w odpowiedzi.
  • DeclareTrailer dodaje daną nazwę przyczepy do nagłówka Trailer odpowiedzi. Deklarowanie przyczep odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi to być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza przyczepę.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

Tracing

Aby uzyskać informacje na temat pobierania śladów z HTTP.sys, zobacz scenariusze zarządzania HTTP.sys.

Dodatkowe zasoby