Поделиться через


реализация веб-сервераHTTP.sys в ASP.NET Core

Note

Это не последняя версия этой статьи. Текущий выпуск см. в .NET 10 версии этой статьи.

Warning

Эта версия ASP.NET Core больше не поддерживается. Для получения дополнительной информации см. Политику поддержки .NET и .NET Core. См. текущий выпуск в версии .NET 10 этой статьи.

Авторы: Том Дикстра (Tom Dykstra) и Крис Росс (Chris Ross)

HTTP.sys — это сервер web для ASP.NET Core, который выполняется только в Windows. HTTP.sys — это альтернатива серверу Kestrel с некоторыми функциями, которые отсутствуют в Kestrel.

Important

HTTP.sys несовместим с модулем ASP.NET Core и не может использоваться с IIS или IIS Express.

HTTP.sys поддерживает следующие функции:

  • Аутентификация Windows
  • Общий доступ к портам
  • Использование HTTPS с SNI
  • HTTP/2 по протоколу TLS (Windows 10 или более поздней версии)
  • HTTP/3 по протоколу TLS (Windows 11 или более поздней версии)
  • Прямая передача файлов
  • кэширование ответов;
  • WebSockets (Windows 8 или более поздней версии)
  • Настраиваемые дескрипторы безопасности
  • Автоматическое вытеснение пула памяти

Поддерживаемые версии Windows:

  • Windows 7 или более поздней версии
  • Windows Server 2008 R2 или более поздней версии

Просмотреть или скачать образец кода (описание загрузки)

Условия для применения HTTP.sys

HTTP.sys полезен для развертываний в следующих случаях:

  • Когда необходимо напрямую подключить сервер к Интернету, без использования IIS.

    HTTP.sys взаимодействует с Интернетом напрямую.

  • когда для внутренних развертываний нужна функция, отсутствующая в Kestrel. См. сравнение Kestrel и HTTP.sys.

    HTTP.sys взаимодействует с внутренней сетью напрямую

HTTP.sys — это проверенная технология, которая защищает от многих типов атак, а также обеспечивает надежность, безопасность и масштабируемость полнофункционального веб-сервера. Сам IIS работает в роли HTTP-сервера поверх HTTP.sys.

Поддержка HTTP/2

HTTP/2 включен для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2016/Windows 10 или более поздней версии
  • Подключение с согласованием протокола уровня приложений (ALPN).
  • Подключение TLS 1.2 или более поздней версии

Если установлено подключение HTTP/2, HttpRequest.Protocol возвращает HTTP/2.

Протокол HTTP/2 по умолчанию включен. Если не удается установить подключение HTTP/2, применяется резервный вариант HTTP/1.1. В будущем выпуске Windows будут доступны флаги конфигурации HTTP/2, включая возможность отключения HTTP/2 с HTTP.sys.

Поддержка HTTP/3

HTTP/3 включен для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2022/Windows 11 или более поздней версии
  • Используется привязка URL-адреса https.
  • ключ реестра EnableHttp3 установлен.

Предыдущие версии сборки Windows 11 могут потребовать использования сборки Windows insider.

HTTP/3 обнаруживается как обновление с HTTP/1.1 или HTTP/2 с помощью заголовка alt-svc. Это означает, что первый запрос обычно будет использовать HTTP/1.1 или HTTP/2 перед переключением на HTTP/3. Http.Sys не добавляет alt-svc заголовок автоматически, его необходимо добавить приложением. Следующий код - это пример промежуточного программного обеспечения, который добавляет заголовок ответа alt-svc.

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

Поместите предшествующий код в конвейер запросов на раннем этапе.

Чтобы уведомить клиента о доступности HTTP/3, HTTP.Sys также поддерживает отправку сообщения протокола HTTP/2 Alt-Svc вместо заголовка ответа. См. ключ реестра EnableAltSvc.

Note

Для этого требуются привязки sslcert netsh, использующие имена узлов, а не IP-адреса. Замените ipport приведенными hostnameportnetsh http add sslcert ниже командами и замените IP-адрес именем узла, напримерwww.example.com. Существует также известная проблема, при которой использование hostnameport завершается ошибкой, если параметр certstorename не указан. По умолчанию используйте certstorename=MY.

Аутентификация в режиме ядра с использованием Kerberos

HTTP.sys делегирует проверку подлинности в режим ядра, используя протокол Kerberos. Проверка подлинности в режиме пользователя не поддерживается с Kerberos и HTTP.sys. Учетная запись компьютера должна использоваться для расшифровки токена Или билета Kerberos, полученного из Active Directory и перенаправленного клиентом на сервер для проверки подлинности пользователя. Зарегистрируйте имя субъекта-службы (SPN) для узла, а не пользователя приложения.

Поддержка буферизации ответов в режиме ядра

В некоторых сценариях большие объемы небольших операций записи с высокой задержкой могут привести к значительному влиянию HTTP.sysна производительность. Это влияние связано с отсутствием буфера Pipe в HTTP.sys реализации. Для повышения производительности в этих сценариях включена HTTP.sysподдержка буферизации ответов. Включите буферизацию, установив для HttpSysOptions.EnableKernelResponseBuffering значение true. Буферизация ответов должна быть включена приложением, выполняющим синхронный ввод-вывод или асинхронный ввод-вывод с не более чем одной незавершённой записью за раз. В этих сценариях буферизация ответов может значительно повысить пропускную способность по сравнению с подключениями с высокой задержкой.

Приложения, использующие асинхронные операции ввода-вывода и могут иметь несколько одновременно выполняющихся операций записи, не должны использовать этот флаг. Включение этого флага может привести к повышенному использованию центрального процессора и памяти HTTP.Sys.

Способы применения HTTP.sys

Настройка приложения ASP.NET Core для использования HTTP.sys

Вызовите метод расширения UseHttpSys при создании узла, указав все необходимые параметры HttpSysOptions. В следующем примере для параметров задаются значения по умолчанию:

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

Дополнительная настройка HTTP.sys выполняется с помощью параметров реестра.

Дополнительные сведения о параметрах HTTP.sys см. в статье HttpSysOptions.

Настройка дескрипторов безопасности

Очередь запросов в HTTP.sys — это структура уровня ядра, которая временно сохраняет входящие HTTP-запросы, пока приложение не будет готово к обработке. Управление доступом к очереди запросов с помощью свойства RequestQueueSecurityDescriptor в HttpSysOptions. Задайте его как экземпляр GenericSecurityDescriptor, когда будете настраивать сервер HTTP.sys.

Настраивая дескриптор безопасности, вы можете разрешить или запретить определенным пользователям или группам доступ к очереди запросов. Это полезно в сценариях, где требуется ограничить или делегировать обработку запросов HTTP.sys на уровне операционной системы.

Например, следующий код разрешает всем прошедшим проверку подлинности пользователям, но запрещает гостям:

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

Свойство RequestQueueSecurityDescriptor применяется только при создании новой очереди запросов. Это свойство не влияет на существующие очереди запросов.

MaxRequestBodySize

Максимально допустимый размер текста запроса в байтах. Если задано значение null, размер максимального запроса не ограничен. Это ограничение не оказывает влияния на обновленные подключения, которые не имеют ограничений.

Рекомендуемый метод, чтобы переопределить ограничение в приложении MVC ASP.NET Core для одного IActionResult — это использование атрибута RequestSizeLimitAttribute в методе действия.

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

При попытке приложения настроить ограничение для запроса после того, как приложение начало считывать запрос, возникает исключение. Свойство IsReadOnly можно использовать, чтобы указать, что свойство MaxRequestBodySize находится в состоянии только для чтения, что означает, что слишком поздно для настройки ограничения.

Если приложение должно переопределять MaxRequestBodySize по запросу, используйте 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);
});

При использовании Visual Studio убедитесь, что приложение не настроено для запуска IIS или IIS Express.

В Visual Studio профиль запуска по умолчанию предназначен для IIS Express. Чтобы запустить проект в качестве консольного приложения, вручную измените выбранный профиль, как показано на следующем снимке экрана:

Выбор профиля консольного приложения

Настройка Windows Server

  1. Определите порты, которые необходимо открыть для приложения, и используйте брандмауэр Windows или командлет PowerShell New-NetFirewallRule, чтобы открыть порты и разрешить доступ к HTTP.sys. В следующих командах и конфигурации приложения используется порт 443.

  2. При развертывании на виртуальной машине Azure откройте порты в группе безопасности Network. В следующих командах и конфигурации приложения используется порт 443.

  3. При необходимости получите и установите сертификаты X.509.

    В Windows создайте самозаверяющий сертификат с помощью командлета New-SelfSignedCertificate PowerShell. Примеры, которые не поддерживаются, см. в разделе UpdateIISExpressSSLForChrome.ps1.

    Установите самоподписанные или подписанные центром сертификации сертификаты в Локальный компьютер>Личное хранилище сервера.

  4. Если приложение зависит от платформы (развертывание, зависящее от платформы), установите .NET, .NET Framework или оба (если приложение является .NET приложением, предназначенным для платформы .NET Framework).

    • .NET: Если приложению требуется .NET, получите и запустите установщик .NET Runtime из Загрузки .NET. Не устанавливайте полный пакет SDK на сервере.
    • .NET Framework. Если приложению требуется .NET Framework, см. руководство по установке .NET Framework. Установите необходимый .NET Framework. Установщик для последней версии .NET Framework доступен на странице .NET Загрузки.

    Если приложение развертывается автономно, в его развертывание включена среда выполнения. Устанавливать .NET Framework на сервере не нужно.

  5. Настройте URL-адреса и порты в приложении.

    По умолчанию ASP.NET Core привязывается к http://localhost:5000. Чтобы настроить префиксы URL-адресов и порты, используйте следующие параметры:

    • UseUrls
    • Аргументы командной строки urls.
    • Переменная среды ASPNETCORE_URLS.
    • UrlPrefixes

    В следующем примере кода показано, как использовать UrlPrefixes с локальным IP-адресом сервера 10.0.0.4 через порт 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 заключается в том, что при неправильном формате префиксов сразу же создается сообщение об ошибке.

    Этот параметр в UrlPrefixes переопределяет параметры UseUrls/urls/ASPNETCORE_URLS. Таким образом, преимущество переменных средыUseUrls, urls и ASPNETCORE_URLS заключается в возможности быстрого переключения между Kestrel и HTTP.sys.

    HTTP.sys распознает два типа подстановочных карточек в префиксах URL-адресов:

    • * является слабой привязкой, также известной как резервная привязка. Если префикс URL-адреса имеет http://*:5000значение и что-то другое привязано к порту 5000, эта привязка не будет использоваться.
    • + — это сильная привязка Если префикс URL-адреса имеет значение http://+:5000, эта привязка будет использоваться перед другими привязками порта 5000.

    Дополнительные сведения см. в разделе UrlPrefix Strings.

    Warning

    На верхнем уровне привязки с подстановочными знаками (http://*:80/ и http://+:80) не должны использоваться. Связывания с подстановочными символами верхнего уровня создают уязвимости для безопасности приложения. Это относится как к строгим, так и к нестрогим подстановочным знакам. Вместо подстановочных знаков используйте имена узлов или IP-адреса в явном виде. Привязки с подстановочными знаками на уровне дочерних доменов (например, *.mysub.com) не создают таких угроз безопасности, если вы полностью контролируете родительский домен (в отличие от варианта *.com, создающего уязвимость). Дополнительные сведения см. в разделе RFC 9110: раздел 7.2: Host и :authority.

    Приложения и контейнеры часто получают только порт для прослушивания, например, порт 80, без дополнительных ограничений, таких как хост или путь. HTTP_PORTS и HTTPS_PORTS — это ключи конфигурации, указывающие порты прослушивания для Kestrel серверов и HTTP.sys. Эти ключи могут быть указаны в виде переменных среды, определенными с помощью префиксов DOTNET_ или ASPNETCORE_, или напрямую указаны через любые другие средства конфигурации, например appsettings.json. Каждый из них представляет собой список значений портов с запятой, как показано в следующем примере:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    Предыдущий пример представляет собой сокращение следующей конфигурации, которая определяет схему (HTTP или HTTPS) и любой хост или IP-адрес.

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

    Ключи конфигурации HTTP_PORTS и HTTPS_PORTS имеют более низкий приоритет и переопределяются URL-адресами или значениями, предоставленными непосредственно в коде. Сертификаты по-прежнему необходимо настраивать отдельно через механизмы, специфичные для сервера, для HTTPS.

    Эти ключи конфигурации эквивалентны привязкам подстановочных знаков верхнего уровня. Они удобны для сценариев разработки и контейнеров, но избегайте подстановочных знаков, когда вы запускаете программы на компьютере, который может также размещать другие службы.

  6. Предварительно зарегистрируйте префиксы URL-адресов на сервере.

    Встроенным средством для настройки сервера HTTP.sys является netsh.exe. С помощьюnetsh.exe можно зарезервировать префиксы URL-адресов и назначить сертификаты X.509. Для использования этого средства требуются права администратора.

    Используйте средство netsh.exe для регистрации URL-адреса приложения.

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: полностью определенный универсальный указатель ресурсов (URL). Не используйте привязки с подстановочными знаками. Используйте допустимое имя узла или локальный IP-адрес. URL-адрес должен включать косую черту в конце.
    • <USER>: указывает имя пользователя или группы пользователей.

    В следующем примере сервер имеет локальный IP-адрес 10.0.0.4.

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

    При регистрации URL-адреса средство возвращает ответ URL reservation successfully added.

    Чтобы удалить зарегистрированный URL-адрес, используйте команду delete urlacl.

    netsh http delete urlacl url=<URL>
    
  7. Зарегистрируйте сертификаты X.509 на сервере.

    Используйте средство netsh.exe для регистрации сертификатов приложения.

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: указывает локальный IP-адрес привязки. Не используйте привязки с подстановочными знаками. Используйте допустимый IP-адрес.
    • <PORT>: указывает порт для привязки.
    • <THUMBPRINT>: отпечаток сертификата X.509.
    • <GUID>: созданный разработчиком GUID для представления приложения в информационных целях.

    В справочных целях храните GUID в приложении в виде тега пакета.

    • В Visual Studio:
      • Откройте свойства проекта приложения, щелкнув правой кнопкой мыши приложение в Обозреватель решений и выбрав Properties.
      • Перейдите на вкладку Package (Пакет).
      • Введите GUID, который вы создали в поле Tags.
    • Если Visual Studio не используется:
      • Откройте файл проекта приложения.

      • Добавьте свойство <PackageTags> в новый или существующий <PropertyGroup> с созданным вами GUID.

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

    В следующем примере :

    • Локальный IP-адрес сервера — 10.0.0.4.
    • Онлайн-генератор случайных идентификаторов GUID предоставляет значение appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    При регистрации сертификата средство возвращает ответ SSL Certificate successfully added.

    Чтобы удалить регистрацию сертификата, используйте команду delete sslcert.

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

    Дополнительные сведения см. в справочной документации по netsh.exe:

  8. Запустите приложение.

    Если выполнена привязка к localhost через HTTP (не HTTPS) с номером порта больше 1024, для запуска приложения права администратора не требуются. При других конфигурациях (например, при использовании локального IP-адреса или привязки к порту 443) для запуска приложения требуются права администратора.

    Приложение отвечает по общедоступному IP-адресу сервера. В этом примере подключение к серверу происходит через Интернет по общедоступному IP-адресу 104.214.79.47 сервера.

    В этом примере используется сертификат разработки. После обхода предупреждения о ненадежном сертификате браузера происходит безопасная загрузка страницы.

    Окно браузера с отображаемой страницей индекса приложения

Сценарии использования прокси-сервера и подсистемы балансировки нагрузки

Для приложений, размещенных через HTTP.sys, которые обрабатывают запросы из Интернета или корпоративной сети, может потребоваться дополнительная настройка при размещении за прокси-серверами и балансировщиками нагрузки. Дополнительные сведения см. в разделе Configure ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Получение подробных сведений о времени с помощью IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature предоставляет подробные сведения о времени для запросов:

  • Метки времени получаются с помощью QueryPerformanceCounter.
  • Частоту метки времени можно получить с помощью QueryPerformanceFrequency.
  • Индекс синхронизации можно привести к HttpSysRequestTimingType, чтобы узнать, что представляет собой данная синхронизация.
  • Значение может быть равно 0, если время недоступно для текущего запроса.
  • Требуется Windows 10 версии 2004, Windows Server 2022 или более поздней версии.
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 извлекает метку времени для предоставленного типа времени:

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 дает истекшее время между двумя указанными сроками:

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

Расширенные возможности HTTP/2 для поддержки gRPC

Дополнительные возможности HTTP/2 в HTTP.sys поддерживают gRPC, включая поддержку трейлеров ответов и отправку кадров сброса.

Требования для выполнения gRPC в HTTP.sys:

  • Windows 11 сборки 22000 или более поздней версии Windows Server 2022 сборки 20348 или более поздней версии.
  • Подключение TLS 1.2 или более поздней версии.

Trailers

Трейлеры HTTP похожи на заголовки HTTP, за исключением того, что они отправляются после отправки текста ответа. Для IIS и HTTP.sys поддерживаются только трейлеры ответов HTTP/2.

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

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

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

В приведенном выше примере кода:

  • SupportsTrailers обеспечивает поддержку трейлеров для ответа;
  • DeclareTrailer добавляет заданное имя трейлера в заголовок ответа Trailer. Объявлять трейлеры ответа необязательно, но рекомендуется. Вызов DeclareTrailer должен производиться перед отправкой заголовков ответа.
  • AppendTrailer добавляет трейлер.

Reset

Операция сброса позволяет серверу обнулить запрос HTTP/2 с указанным кодом ошибки. Запрос на сброс считается отменённым.

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

Reset в предыдущем примере кода задает код ошибки INTERNAL_ERROR. Дополнительные сведения о кодах ошибок HTTP/2 см. в соответствующем разделе спецификации HTTP/2.

Tracing

Сведения о том, как получить трассировки из HTTP.sys, см. в разделе сценарии управления HTTP.sys.

Автоматическое удаление из пула памяти

Пулы памяти, используемые службами KestrelIIS и HTTP.sys автоматически вытесняют блоки памяти, когда приложение неактивно или находится под низкой нагрузкой. Функция выполняется автоматически и не должна быть включена или настроена вручную.

В версиях .NET более 10 память, выделенная пулом, остается зарезервированной, даже если она не используется. Эта функция автоматического вытеснения снижает общее использование памяти и помогает приложениям реагировать на различные рабочие нагрузки.

Использование метрик пула памяти

Пул памяти по умолчанию, используемый реализацией сервера ASP.NET Core, включает метрики, которые можно использовать для мониторинга и анализа шаблонов использования памяти. Метрики находятся под именем "Майкрософт.AspNetCore.MemoryPool".

Сведения о метриках и их использовании см. в метрики ASP.NET Core.

Управление пулами памяти

Помимо эффективного использования пулов памяти путем вытеснения ненужных блоков памяти, ASP.NET Core предоставляет встроенную IMemoryPoolFactory и реализацию. Она обеспечивает доступность реализации для приложения с помощью внедрения зависимостей.

В следующем примере кода показана простая фоновая служба, которая использует встроенную реализацию фабрики пулов памяти для создания пулов памяти. Эти пулы пользуются функцией автоматического вытеснения:

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

Чтобы использовать фабрику настраиваемого пула памяти, создайте класс, который реализует IMemoryPoolFactory, и зарегистрируйте его с помощью механизма внедрения зависимостей, как показано в следующем примере. Пулы памяти, созданные таким образом, не получают преимущества от функции автоматического вытеснения, если вы не реализуете аналогичную логику вытеснения в пользовательской фабрике:

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

При использовании пула памяти помните о пуле памяти MaxBufferSize.

Дополнительные ресурсы

HTTP.sys — это сервер web для ASP.NET Core, который выполняется только в Windows. HTTP.sys — это альтернатива серверу Kestrel с некоторыми функциями, которые отсутствуют в Kestrel.

Important

HTTP.sys несовместим с модулем ASP.NET Core и не может использоваться с IIS или IIS Express.

HTTP.sys поддерживает следующие функции:

  • Аутентификация Windows
  • Общий доступ к портам
  • Использование HTTPS с SNI
  • HTTP/2 по протоколу TLS (Windows 10 или более поздней версии)
  • Прямая передача файлов
  • кэширование ответов;
  • WebSockets (Windows 8 или более поздней версии)

Поддерживаемые версии Windows:

  • Windows 7 или более поздней версии
  • Windows Server 2008 R2 или более поздней версии

Просмотреть или скачать образец кода (описание загрузки)

Условия для применения HTTP.sys

HTTP.sys полезен для развертываний в следующих случаях:

  • Когда необходимо напрямую подключить сервер к Интернету, без использования IIS.

    HTTP.sys взаимодействует с Интернетом напрямую.

  • когда для внутренних развертываний нужна функция, отсутствующая в Kestrel. См. сравнение Kestrel и HTTP.sys.

    HTTP.sys взаимодействует с внутренней сетью напрямую

HTTP.sys — это проверенная технология, которая защищает от многих типов атак, а также обеспечивает надежность, безопасность и масштабируемость полнофункционального веб-сервера. Сам IIS работает в роли HTTP-сервера поверх HTTP.sys.

Поддержка HTTP/2

HTTP/2 включен для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2016/Windows 10 или более поздней версии
  • Подключение с согласованием протокола уровня приложений (ALPN).
  • Подключение TLS 1.2 или более поздней версии

Если установлено подключение HTTP/2, HttpRequest.Protocol возвращает HTTP/2.

Протокол HTTP/2 по умолчанию включен. Если не удается установить подключение HTTP/2, применяется резервный вариант HTTP/1.1. В будущем выпуске Windows будут доступны флаги конфигурации HTTP/2, включая возможность отключения HTTP/2 с HTTP.sys.

Поддержка HTTP/3

HTTP/3 включен для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2022/Windows 11 или более поздней версии
  • Используется привязка URL-адреса https.
  • ключ реестра EnableHttp3 установлен.

Предыдущие версии сборки Windows 11 могут потребовать использования сборки Windows insider.

HTTP/3 обнаруживается как обновление с HTTP/1.1 или HTTP/2 с помощью заголовка alt-svc. Это означает, что первый запрос обычно будет использовать HTTP/1.1 или HTTP/2 перед переключением на HTTP/3. Http.Sys не добавляет alt-svc заголовок автоматически, его необходимо добавить приложением. Следующий код - это пример промежуточного программного обеспечения, который добавляет заголовок ответа alt-svc.

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

Поместите предшествующий код в конвейер запросов на раннем этапе.

Чтобы уведомить клиента о доступности HTTP/3, HTTP.Sys также поддерживает отправку сообщения протокола HTTP/2 Alt-Svc вместо заголовка ответа. См. ключ реестра EnableAltSvc. Для этого требуются привязки sslcert netsh, использующие имена узлов, а не IP-адреса.

Аутентификация в режиме ядра с использованием Kerberos

HTTP.sys делегирует проверку подлинности в режим ядра, используя протокол Kerberos. Проверка подлинности в режиме пользователя не поддерживается с Kerberos и HTTP.sys. Учетная запись компьютера должна использоваться для расшифровки токена Или билета Kerberos, полученного из Active Directory и перенаправленного клиентом на сервер для проверки подлинности пользователя. Зарегистрируйте имя субъекта-службы (SPN) для узла, а не пользователя приложения.

Способы применения HTTP.sys

Настройка приложения ASP.NET Core для использования HTTP.sys

Вызовите метод расширения UseHttpSys при создании узла, указав все необходимые параметры HttpSysOptions. В следующем примере для параметров задаются значения по умолчанию:

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

Дополнительная настройка HTTP.sys выполняется с помощью параметров реестра.

Дополнительные сведения о параметрах HTTP.sys см. в статье HttpSysOptions.

MaxRequestBodySize

Максимально допустимый размер текста запроса в байтах. Если задано значение null, размер максимального запроса не ограничен. Это ограничение не оказывает влияния на обновленные подключения, которые не имеют ограничений.

Рекомендуемый метод, чтобы переопределить ограничение в приложении MVC ASP.NET Core для одного IActionResult — это использование атрибута RequestSizeLimitAttribute в методе действия.

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

При попытке приложения настроить ограничение для запроса после того, как приложение начало считывать запрос, возникает исключение. Свойство IsReadOnly можно использовать, чтобы указать, что свойство MaxRequestBodySize находится в состоянии только для чтения, что означает, что слишком поздно для настройки ограничения.

Если приложение должно переопределять MaxRequestBodySize по запросу, используйте 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();
    });
}

При использовании Visual Studio убедитесь, что приложение не настроено для запуска IIS или IIS Express.

В Visual Studio профиль запуска по умолчанию предназначен для IIS Express. Чтобы запустить проект в качестве консольного приложения, вручную измените выбранный профиль, как показано на следующем снимке экрана:

Выбор профиля консольного приложения

Настройка Windows Server

  1. Определите порты, которые необходимо открыть для приложения, и используйте брандмауэр Windows или командлет PowerShell New-NetFirewallRule, чтобы открыть порты и разрешить доступ к HTTP.sys. В следующих командах и конфигурации приложения используется порт 443.

  2. При развертывании на виртуальной машине Azure откройте порты в группе безопасности Network. В следующих командах и конфигурации приложения используется порт 443.

  3. При необходимости получите и установите сертификаты X.509.

    В Windows создайте самозаверяющий сертификат с помощью командлета New-SelfSignedCertificate PowerShell. Примеры, которые не поддерживаются, см. в разделе UpdateIISExpressSSLForChrome.ps1.

    Установите самоподписанные или подписанные центром сертификации сертификаты в Локальный компьютер>Личное хранилище сервера.

  4. Если приложение зависит от платформы (развертывание, зависящее от платформы), установите .NET, .NET Framework или оба (если приложение является .NET приложением, предназначенным для платформы .NET Framework).

    • .NET: Если приложению требуется .NET, получите и запустите установщик .NET Runtime из Загрузки .NET. Не устанавливайте полный пакет SDK на сервере.
    • .NET Framework. Если приложению требуется .NET Framework, см. руководство по установке .NET Framework. Установите необходимый .NET Framework. Установщик для последней версии .NET Framework доступен на странице .NET Загрузки.

    Если приложение развертывается автономно, в его развертывание включена среда выполнения. Устанавливать .NET Framework на сервере не нужно.

  5. Настройте URL-адреса и порты в приложении.

    По умолчанию ASP.NET Core привязывается к http://localhost:5000. Чтобы настроить префиксы URL-адресов и порты, используйте следующие параметры:

    • UseUrls
    • Аргументы командной строки urls.
    • Переменная среды ASPNETCORE_URLS.
    • UrlPrefixes

    В следующем примере кода показано, как использовать UrlPrefixes с локальным IP-адресом сервера 10.0.0.4 через порт 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 заключается в том, что при неправильном формате префиксов сразу же создается сообщение об ошибке.

    Этот параметр в UrlPrefixes переопределяет параметры UseUrls/urls/ASPNETCORE_URLS. Таким образом, преимущество переменных средыUseUrls, urls и ASPNETCORE_URLS заключается в возможности быстрого переключения между Kestrel и HTTP.sys.

    HTTP.sys использует форматы строк UrlPrefix API HTTP-сервера.

    Warning

    На верхнем уровне привязки с подстановочными знаками (http://*:80/ и http://+:80) не должны использоваться. Связывания с подстановочными символами верхнего уровня создают уязвимости для безопасности приложения. Это относится как к строгим, так и к нестрогим подстановочным знакам. Вместо подстановочных знаков используйте имена узлов или IP-адреса в явном виде. Привязки с подстановочными знаками на уровне дочерних доменов (например, *.mysub.com) не создают таких угроз безопасности, если вы полностью контролируете родительский домен (в отличие от варианта *.com, создающего уязвимость). Дополнительные сведения см. в разделе RFC 9110: раздел 7.2: Host и :authority.

  6. Предварительно зарегистрируйте префиксы URL-адресов на сервере.

    Встроенным средством для настройки сервера HTTP.sys является netsh.exe. С помощьюnetsh.exe можно зарезервировать префиксы URL-адресов и назначить сертификаты X.509. Для использования этого средства требуются права администратора.

    Используйте средство netsh.exe для регистрации URL-адреса приложения.

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: полностью определенный универсальный указатель ресурсов (URL). Не используйте привязки с подстановочными знаками. Используйте допустимое имя узла или локальный IP-адрес. URL-адрес должен включать косую черту в конце.
    • <USER>: указывает имя пользователя или группы пользователей.

    В следующем примере сервер имеет локальный IP-адрес 10.0.0.4.

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

    При регистрации URL-адреса средство возвращает ответ URL reservation successfully added.

    Чтобы удалить зарегистрированный URL-адрес, используйте команду delete urlacl.

    netsh http delete urlacl url=<URL>
    
  7. Зарегистрируйте сертификаты X.509 на сервере.

    Используйте средство netsh.exe для регистрации сертификатов приложения.

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: указывает локальный IP-адрес привязки. Не используйте привязки с подстановочными знаками. Используйте допустимый IP-адрес.
    • <PORT>: указывает порт для привязки.
    • <THUMBPRINT>: отпечаток сертификата X.509.
    • <GUID>: созданный разработчиком GUID для представления приложения в информационных целях.

    В справочных целях храните GUID в приложении в виде тега пакета.

    • В Visual Studio:
      • Откройте свойства проекта приложения, щелкнув правой кнопкой мыши приложение в Обозреватель решений и выбрав Properties.
      • Перейдите на вкладку Package (Пакет).
      • Введите GUID, который вы создали в поле Tags.
    • Если Visual Studio не используется:
      • Откройте файл проекта приложения.

      • Добавьте свойство <PackageTags> в новый или существующий <PropertyGroup> с созданным вами GUID.

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

    В следующем примере :

    • Локальный IP-адрес сервера — 10.0.0.4.
    • Онлайн-генератор случайных идентификаторов GUID предоставляет значение appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    При регистрации сертификата средство возвращает ответ SSL Certificate successfully added.

    Чтобы удалить регистрацию сертификата, используйте команду delete sslcert.

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

    Дополнительные сведения см. в справочной документации по netsh.exe:

  8. Запустите приложение.

    Если выполнена привязка к localhost через HTTP (не HTTPS) с номером порта больше 1024, для запуска приложения права администратора не требуются. При других конфигурациях (например, при использовании локального IP-адреса или привязки к порту 443) для запуска приложения требуются права администратора.

    Приложение отвечает по общедоступному IP-адресу сервера. В этом примере подключение к серверу происходит через Интернет по общедоступному IP-адресу 104.214.79.47 сервера.

    В этом примере используется сертификат разработки. После обхода предупреждения о ненадежном сертификате браузера происходит безопасная загрузка страницы.

    Окно браузера с отображаемой страницей индекса приложения

Сценарии использования прокси-сервера и подсистемы балансировки нагрузки

Для приложений, размещенных через HTTP.sys, которые обрабатывают запросы из Интернета или корпоративной сети, может потребоваться дополнительная настройка при размещении за прокси-серверами и балансировщиками нагрузки. Дополнительные сведения см. в разделе Configure ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Расширенные возможности HTTP/2 для поддержки gRPC

Дополнительные возможности HTTP/2 в HTTP.sys поддерживают gRPC, включая поддержку трейлеров ответов и отправку кадров сброса.

Требования для выполнения gRPC в HTTP.sys:

  • Windows 11 сборки 22000 или более поздней версии Windows Server 2022 сборки 20348 или более поздней версии.
  • Подключение TLS 1.2 или более поздней версии.

Trailers

Трейлеры HTTP похожи на заголовки HTTP, за исключением того, что они отправляются после отправки текста ответа. Для IIS и HTTP.sys поддерживаются только трейлеры ответов HTTP/2.

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

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

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

В приведенном выше примере кода:

  • SupportsTrailers обеспечивает поддержку трейлеров для ответа;
  • DeclareTrailer добавляет заданное имя трейлера в заголовок ответа Trailer. Объявлять трейлеры ответа необязательно, но рекомендуется. Вызов DeclareTrailer должен производиться перед отправкой заголовков ответа.
  • AppendTrailer добавляет трейлер.

Reset

Операция сброса позволяет серверу обнулить запрос HTTP/2 с указанным кодом ошибки. Запрос на сброс считается отменённым.

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

Reset в предыдущем примере кода задает код ошибки INTERNAL_ERROR. Дополнительные сведения о кодах ошибок HTTP/2 см. в соответствующем разделе спецификации HTTP/2.

Дополнительные ресурсы

HTTP.sys — это сервер web для ASP.NET Core, который выполняется только в Windows. HTTP.sys — это альтернатива серверу Kestrel с некоторыми функциями, которые отсутствуют в Kestrel.

Important

HTTP.sys несовместим с модулем ASP.NET Core и не может использоваться с IIS или IIS Express.

HTTP.sys поддерживает следующие функции:

  • Аутентификация Windows
  • Общий доступ к портам
  • Использование HTTPS с SNI
  • HTTP/2 по протоколу TLS (Windows 10 или более поздней версии)
  • Прямая передача файлов
  • кэширование ответов;
  • WebSockets (Windows 8 или более поздней версии)

Поддерживаемые версии Windows:

  • Windows 7 или более поздней версии
  • Windows Server 2008 R2 или более поздней версии

Просмотреть или скачать образец кода (описание загрузки)

Условия для применения HTTP.sys

HTTP.sys полезен для развертываний в следующих случаях:

  • Когда необходимо напрямую подключить сервер к Интернету, без использования IIS.

    HTTP.sys взаимодействует с Интернетом напрямую.

  • когда для внутренних развертываний нужна функция, отсутствующая в Kestrel. См. сравнение Kestrel и HTTP.sys.

    HTTP.sys взаимодействует с внутренней сетью напрямую

HTTP.sys — это проверенная технология, которая защищает от многих типов атак, а также обеспечивает надежность, безопасность и масштабируемость полнофункционального веб-сервера. Сам IIS работает в роли HTTP-сервера поверх HTTP.sys.

Поддержка HTTP/2

HTTP/2 включен для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2016/Windows 10 или более поздней версии
  • Подключение с согласованием протокола уровня приложений (ALPN).
  • Подключение TLS 1.2 или более поздней версии

Если установлено подключение HTTP/2, HttpRequest.Protocol возвращает HTTP/2.

Протокол HTTP/2 по умолчанию включен. Если не удается установить подключение HTTP/2, применяется резервный вариант HTTP/1.1. В будущем выпуске Windows будут доступны флаги конфигурации HTTP/2, включая возможность отключения HTTP/2 с HTTP.sys.

Аутентификация в режиме ядра с использованием Kerberos

HTTP.sys делегирует проверку подлинности в режим ядра, используя протокол Kerberos. Проверка подлинности в режиме пользователя не поддерживается с Kerberos и HTTP.sys. Учетная запись компьютера должна использоваться для расшифровки токена Или билета Kerberos, полученного из Active Directory и перенаправленного клиентом на сервер для проверки подлинности пользователя. Зарегистрируйте имя субъекта-службы (SPN) для узла, а не пользователя приложения.

Способы применения HTTP.sys

Настройка приложения ASP.NET Core для использования HTTP.sys

Вызовите метод расширения UseHttpSys при создании узла, указав все необходимые параметры HttpSysOptions. В следующем примере для параметров задаются значения по умолчанию:

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

Дополнительная настройка HTTP.sys выполняется с помощью параметров реестра.

параметрыHTTP.sys

Property Description Default
AllowSynchronousIO Указывает, разрешен ли синхронные операции ввода-вывода для HttpContext.Request.Body и HttpContext.Response.Body. false
Authentication.AllowAnonymous Разрешает анонимные запросы. true
Authentication.Schemes Указывает разрешенные схемы аутентификации. Может быть изменен в любое время до удаления прослушивателя. Значения предоставляются перечислением AuthenticationSchemes: Basic, Kerberos, Negotiate, None и NTLM. None
EnableResponseCaching Попытка кэширования в режиме ядра для ответов с допустимыми заголовками. Ответ не может включать заголовки Set-Cookie, Vary или Pragma. Он должен включать заголовок Cache-Control, который public, а также либо значение shared-max-age или max-age, либо заголовок Expires. true
Http503Verbosity Поведение HTTP.sys при отклонении запросов из-за условий ограничения скорости. Http503VerbosityLevel.
Базовый
MaxAccepts Максимальное количество одновременных принятий. 5 × окружающая среда.
КоличествоПроцессоров
MaxConnections Максимальное число одновременных подключений для принятия. Используйте -1 для бесконечности. Используйте null для использования параметра реестра на уровне компьютера. null
(machine-wide
setting)
MaxRequestBodySize См. раздел MaxRequestBodySize. 30000000 байт
(~28,6 МБ)
RequestQueueLimit Максимально допустимое число запросов в очереди. 1000
RequestQueueMode Указывает, отвечает ли сервер за создание и настройку очереди запросов или он должен подключаться к существующей очереди.
Большинство имеющихся параметров конфигурации не применяются при подключении к существующей очереди.
RequestQueueMode.Create
RequestQueueName Имя очереди запросов HTTP.sys. null (анонимная очередь)
ThrowWriteExceptions Указывает, следует ли вызывать исключение или завершать работу нормально, когда запись текста ответа завершается ошибкой из-за отключения клиента. false
(в обычном режиме)
Timeouts Открывает конфигурацию TimeoutManager HTTP.sys, которую также можно настроить в реестре. Следуйте по API ссылкам, чтобы узнать больше о каждом параметре, включая значения по умолчанию:
  • TimeoutManager.DrainEntityBody: время, разрешенное API HTTP-сервера для очистки тела сущности в подключении Keep-Alive.
  • TimeoutManager.EntityBody: время, разрешенное для поступления текста сущности запроса.
  • TimeoutManager.HeaderWait: время, разрешено для API HTTP-сервера для анализа заголовка запроса.
  • TimeoutManager.IdleConnection: время, разрешенное для простоя подключения.
  • TimeoutManager.MinSendBytesPerSecond: минимальная скорость отправки ответа.
  • TimeoutManager.RequestQueue: время, разрешено для того, чтобы запрос оставался в очереди запросов, прежде чем приложение выберет его.
UrlPrefixes Укажите UrlPrefixCollection для регистрации в HTTP.sys. Самым полезным является UrlPrefixCollection.Add, поскольку он используется для добавления префикса к коллекции. Могут быть изменены в любое время до удаления прослушивателя.

MaxRequestBodySize

Максимально допустимый размер текста запроса в байтах. Если задано значение null, размер максимального запроса не ограничен. Это ограничение не оказывает влияния на обновленные подключения, которые не имеют ограничений.

Рекомендуемый метод, чтобы переопределить ограничение в приложении MVC ASP.NET Core для одного IActionResult — это использование атрибута RequestSizeLimitAttribute в методе действия.

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

При попытке приложения настроить ограничение для запроса после того, как приложение начало считывать запрос, возникает исключение. Свойство IsReadOnly можно использовать, чтобы указать, что свойство MaxRequestBodySize находится в состоянии только для чтения, что означает, что слишком поздно для настройки ограничения.

Если приложение должно переопределять MaxRequestBodySize по запросу, используйте 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();
    });
}

При использовании Visual Studio убедитесь, что приложение не настроено для запуска IIS или IIS Express.

В Visual Studio профиль запуска по умолчанию предназначен для IIS Express. Чтобы запустить проект как консольное приложение, измените выбранный профиль вручную, как показано на следующем снимке экрана.

Выбор профиля консольного приложения

Настройка Windows Server

  1. Определите порты, которые необходимо открыть для приложения, и используйте брандмауэр Windows или командлет PowerShell New-NetFirewallRule, чтобы открыть порты и разрешить доступ к HTTP.sys. В следующих командах и конфигурации приложения используется порт 443.

  2. При развертывании на виртуальной машине Azure откройте порты в группе безопасности Network. В следующих командах и конфигурации приложения используется порт 443.

  3. При необходимости получите и установите сертификаты X.509.

    В Windows создайте самозаверяющий сертификат с помощью командлета New-SelfSignedCertificate PowerShell. Примеры, которые не поддерживаются, см. в разделе UpdateIISExpressSSLForChrome.ps1.

    Установите самоподписанные или подписанные центром сертификации сертификаты в Локальный компьютер>Личное хранилище сервера.

  4. Если приложение зависит от платформы (развертывание, зависящее от платформы), установите .NET, .NET Framework или оба (если приложение является .NET приложением, предназначенным для платформы .NET Framework).

    • .NET: Если приложению требуется .NET, получите и запустите установщик .NET Runtime из Загрузки .NET. Не устанавливайте полный пакет SDK на сервере.
    • .NET Framework. Если приложению требуется .NET Framework, см. руководство по установке .NET Framework. Установите необходимый .NET Framework. Установщик для последней версии .NET Framework доступен на странице .NET Загрузки.

    Если приложение развертывается автономно, в его развертывание включена среда выполнения. Устанавливать .NET Framework на сервере не нужно.

  5. Настройте URL-адреса и порты в приложении.

    По умолчанию ASP.NET Core привязывается к http://localhost:5000. Чтобы настроить префиксы URL-адресов и порты, используйте следующие параметры:

    • UseUrls
    • Аргументы командной строки urls.
    • Переменная среды ASPNETCORE_URLS.
    • UrlPrefixes

    В следующем примере кода показано, как использовать UrlPrefixes с локальным IP-адресом сервера 10.0.0.4 через порт 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 заключается в том, что при неправильном формате префиксов сразу же создается сообщение об ошибке.

    Этот параметр в UrlPrefixes переопределяет параметры UseUrls/urls/ASPNETCORE_URLS. Таким образом, преимущество переменных средыUseUrls, urls и ASPNETCORE_URLS заключается в возможности быстрого переключения между Kestrel и HTTP.sys.

    HTTP.sys использует форматы строк UrlPrefix API HTTP-сервера.

    Warning

    На верхнем уровне привязки с подстановочными знаками (http://*:80/ и http://+:80) не должны использоваться. Связывания с подстановочными символами верхнего уровня создают уязвимости для безопасности приложения. Это относится как к строгим, так и к нестрогим подстановочным знакам. Вместо подстановочных знаков используйте имена узлов или IP-адреса в явном виде. Привязки с подстановочными знаками на уровне дочерних доменов (например, *.mysub.com) не создают таких угроз безопасности, если вы полностью контролируете родительский домен (в отличие от варианта *.com, создающего уязвимость). Дополнительные сведения см. в разделе RFC 9110: раздел 7.2: Host и :authority.

  6. Предварительно зарегистрируйте префиксы URL-адресов на сервере.

    Встроенным средством для настройки сервера HTTP.sys является netsh.exe. С помощьюnetsh.exe можно зарезервировать префиксы URL-адресов и назначить сертификаты X.509. Для использования этого средства требуются права администратора.

    Используйте средство netsh.exe для регистрации URL-адреса приложения.

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: полностью определенный универсальный указатель ресурсов (URL). Не используйте привязки с подстановочными знаками. Используйте допустимое имя узла или локальный IP-адрес. URL-адрес должен включать косую черту в конце.
    • <USER>: указывает имя пользователя или группы пользователей.

    В следующем примере сервер имеет локальный IP-адрес 10.0.0.4.

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

    При регистрации URL-адреса средство возвращает ответ URL reservation successfully added.

    Чтобы удалить зарегистрированный URL-адрес, используйте команду delete urlacl.

    netsh http delete urlacl url=<URL>
    
  7. Зарегистрируйте сертификаты X.509 на сервере.

    Используйте средство netsh.exe для регистрации сертификатов приложения.

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: указывает локальный IP-адрес привязки. Не используйте привязки с подстановочными знаками. Используйте допустимый IP-адрес.
    • <PORT>: указывает порт для привязки.
    • <THUMBPRINT>: отпечаток сертификата X.509.
    • <GUID>: созданный разработчиком GUID для представления приложения в информационных целях.

    В справочных целях храните GUID в приложении в виде тега пакета.

    • В Visual Studio:
      • Откройте свойства проекта приложения, щелкнув правой кнопкой мыши приложение в Обозреватель решений и выбрав Properties.
      • Перейдите на вкладку Package (Пакет).
      • Введите GUID, который вы создали в поле Tags.
    • Если Visual Studio не используется:
      • Откройте файл проекта приложения.

      • Добавьте свойство <PackageTags> в новый или существующий <PropertyGroup> с созданным вами GUID.

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

    В следующем примере :

    • Локальный IP-адрес сервера — 10.0.0.4.
    • Онлайн-генератор случайных идентификаторов GUID предоставляет значение appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    При регистрации сертификата средство возвращает ответ SSL Certificate successfully added.

    Чтобы удалить регистрацию сертификата, используйте команду delete sslcert.

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

    Дополнительные сведения см. в справочной документации по netsh.exe:

  8. Запустите приложение.

    Если выполнена привязка к localhost через HTTP (не HTTPS) с номером порта больше 1024, для запуска приложения права администратора не требуются. При других конфигурациях (например, при использовании локального IP-адреса или привязки к порту 443) для запуска приложения требуются права администратора.

    Приложение отвечает по общедоступному IP-адресу сервера. В этом примере подключение к серверу происходит через Интернет по общедоступному IP-адресу 104.214.79.47 сервера.

    В этом примере используется сертификат разработки. После обхода предупреждения о ненадежном сертификате браузера происходит безопасная загрузка страницы.

    Окно браузера с отображаемой страницей индекса приложения

Сценарии использования прокси-сервера и подсистемы балансировки нагрузки

Для приложений, размещенных через HTTP.sys, которые обрабатывают запросы из Интернета или корпоративной сети, может потребоваться дополнительная настройка при размещении за прокси-серверами и балансировщиками нагрузки. Дополнительные сведения см. в разделе Configure ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Расширенные возможности HTTP/2 для поддержки gRPC

Дополнительные возможности HTTP/2 в HTTP.sys поддерживают gRPC, включая поддержку трейлеров ответов и отправку кадров сброса.

Требования для выполнения gRPC в HTTP.sys:

  • Windows 10, сборка ОС 19041.508 или более поздняя версия
  • Подключение TLS 1.2 или более поздней версии

Trailers

Трейлеры HTTP похожи на заголовки HTTP, за исключением того, что они отправляются после отправки текста ответа. Для IIS и HTTP.sys поддерживаются только трейлеры ответов HTTP/2.

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

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

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

В приведенном выше примере кода:

  • SupportsTrailers обеспечивает поддержку трейлеров для ответа;
  • DeclareTrailer добавляет заданное имя трейлера в заголовок ответа Trailer. Объявлять трейлеры ответа необязательно, но рекомендуется. Вызов DeclareTrailer должен производиться перед отправкой заголовков ответа.
  • AppendTrailer добавляет трейлер.

Reset

Операция сброса позволяет серверу обнулить запрос HTTP/2 с указанным кодом ошибки. Запрос на сброс считается отменённым.

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

Reset в предыдущем примере кода задает код ошибки INTERNAL_ERROR. Дополнительные сведения о кодах ошибок HTTP/2 см. в соответствующем разделе спецификации HTTP/2.

Дополнительные ресурсы

HTTP.sys — это сервер web для ASP.NET Core, который выполняется только в Windows. HTTP.sys — это альтернатива серверу Kestrel с некоторыми функциями, которые отсутствуют в Kestrel.

Important

HTTP.sys несовместим с модулем ASP.NET Core и не может использоваться с IIS или IIS Express.

HTTP.sys поддерживает следующие функции:

  • Аутентификация Windows
  • Общий доступ к портам
  • Использование HTTPS с SNI
  • HTTP/2 по протоколу TLS (Windows 10 или более поздней версии)
  • HTTP/3 по протоколу TLS (Windows 11 или более поздней версии)
  • Прямая передача файлов
  • кэширование ответов;
  • WebSockets (Windows 8 или более поздней версии)
  • Настраиваемые дескрипторы безопасности

Поддерживаемые версии Windows:

  • Windows 7 или более поздней версии
  • Windows Server 2008 R2 или более поздней версии

Просмотреть или скачать образец кода (описание загрузки)

Условия для применения HTTP.sys

HTTP.sys полезен для развертываний в следующих случаях:

  • Когда необходимо напрямую подключить сервер к Интернету, без использования IIS.

    HTTP.sys взаимодействует с Интернетом напрямую.

  • когда для внутренних развертываний нужна функция, отсутствующая в Kestrel. См. сравнение Kestrel и HTTP.sys.

    HTTP.sys взаимодействует с внутренней сетью напрямую

HTTP.sys — это проверенная технология, которая защищает от многих типов атак, а также обеспечивает надежность, безопасность и масштабируемость полнофункционального веб-сервера. Сам IIS работает в роли HTTP-сервера поверх HTTP.sys.

Поддержка HTTP/2

HTTP/2 включен для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2016/Windows 10 или более поздней версии
  • Подключение с согласованием протокола уровня приложений (ALPN).
  • Подключение TLS 1.2 или более поздней версии

Если установлено подключение HTTP/2, HttpRequest.Protocol возвращает HTTP/2.

Протокол HTTP/2 по умолчанию включен. Если не удается установить подключение HTTP/2, применяется резервный вариант HTTP/1.1. В будущем выпуске Windows будут доступны флаги конфигурации HTTP/2, включая возможность отключения HTTP/2 с HTTP.sys.

Поддержка HTTP/3

HTTP/3 включен для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2022/Windows 11 или более поздней версии
  • Используется привязка URL-адреса https.
  • ключ реестра EnableHttp3 установлен.

Предыдущие версии сборки Windows 11 могут потребовать использования сборки Windows insider.

HTTP/3 обнаруживается как обновление с HTTP/1.1 или HTTP/2 с помощью заголовка alt-svc. Это означает, что первый запрос обычно будет использовать HTTP/1.1 или HTTP/2 перед переключением на HTTP/3. Http.Sys не добавляет alt-svc заголовок автоматически, его необходимо добавить приложением. Следующий код - это пример промежуточного программного обеспечения, который добавляет заголовок ответа alt-svc.

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

Поместите предшествующий код в конвейер запросов на раннем этапе.

Чтобы уведомить клиента о доступности HTTP/3, HTTP.Sys также поддерживает отправку сообщения протокола HTTP/2 Alt-Svc вместо заголовка ответа. См. ключ реестра EnableAltSvc. Для этого требуются привязки sslcert netsh, использующие имена узлов, а не IP-адреса.

Аутентификация в режиме ядра с использованием Kerberos

HTTP.sys делегирует проверку подлинности в режим ядра, используя протокол Kerberos. Проверка подлинности в режиме пользователя не поддерживается с Kerberos и HTTP.sys. Учетная запись компьютера должна использоваться для расшифровки токена Или билета Kerberos, полученного из Active Directory и перенаправленного клиентом на сервер для проверки подлинности пользователя. Зарегистрируйте имя субъекта-службы (SPN) для узла, а не пользователя приложения.

Поддержка буферизации ответов в режиме ядра

В некоторых сценариях большие объемы небольших операций записи с высокой задержкой могут привести к значительному влиянию HTTP.sysна производительность. Это влияние связано с отсутствием буфера Pipe в HTTP.sys реализации. Для повышения производительности в этих сценариях включена HTTP.sysподдержка буферизации ответов. Включите буферизацию, установив для HttpSysOptions.EnableKernelResponseBuffering значение true. Буферизация ответов должна быть включена приложением, выполняющим синхронный ввод-вывод или асинхронный ввод-вывод с не более чем одной незавершённой записью за раз. В этих сценариях буферизация ответов может значительно повысить пропускную способность по сравнению с подключениями с высокой задержкой.

Приложения, использующие асинхронные операции ввода-вывода и могут иметь несколько одновременно выполняющихся операций записи, не должны использовать этот флаг. Включение этого флага может привести к повышенному использованию центрального процессора и памяти HTTP.Sys.

Способы применения HTTP.sys

Настройка приложения ASP.NET Core для использования HTTP.sys

Вызовите метод расширения UseHttpSys при создании узла, указав все необходимые параметры HttpSysOptions. В следующем примере для параметров задаются значения по умолчанию:

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

Дополнительная настройка HTTP.sys выполняется с помощью параметров реестра.

Дополнительные сведения о параметрах HTTP.sys см. в статье HttpSysOptions.

MaxRequestBodySize

Максимально допустимый размер текста запроса в байтах. Если задано значение null, размер максимального запроса не ограничен. Это ограничение не оказывает влияния на обновленные подключения, которые не имеют ограничений.

Рекомендуемый метод, чтобы переопределить ограничение в приложении MVC ASP.NET Core для одного IActionResult — это использование атрибута RequestSizeLimitAttribute в методе действия.

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

При попытке приложения настроить ограничение для запроса после того, как приложение начало считывать запрос, возникает исключение. Свойство IsReadOnly можно использовать, чтобы указать, что свойство MaxRequestBodySize находится в состоянии только для чтения, что означает, что слишком поздно для настройки ограничения.

Если приложение должно переопределять MaxRequestBodySize по запросу, используйте 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);
});

При использовании Visual Studio убедитесь, что приложение не настроено для запуска IIS или IIS Express.

В Visual Studio профиль запуска по умолчанию предназначен для IIS Express. Чтобы запустить проект в качестве консольного приложения, вручную измените выбранный профиль, как показано на следующем снимке экрана:

Выбор профиля консольного приложения

Настройка Windows Server

  1. Определите порты, которые необходимо открыть для приложения, и используйте брандмауэр Windows или командлет PowerShell New-NetFirewallRule, чтобы открыть порты и разрешить доступ к HTTP.sys. В следующих командах и конфигурации приложения используется порт 443.

  2. При развертывании на виртуальной машине Azure откройте порты в группе безопасности Network. В следующих командах и конфигурации приложения используется порт 443.

  3. При необходимости получите и установите сертификаты X.509.

    В Windows создайте самозаверяющий сертификат с помощью командлета New-SelfSignedCertificate PowerShell. Примеры, которые не поддерживаются, см. в разделе UpdateIISExpressSSLForChrome.ps1.

    Установите самоподписанные или подписанные центром сертификации сертификаты в Локальный компьютер>Личное хранилище сервера.

  4. Если приложение зависит от платформы (развертывание, зависящее от платформы), установите .NET, .NET Framework или оба (если приложение является .NET приложением, предназначенным для платформы .NET Framework).

    • .NET: Если приложению требуется .NET, получите и запустите установщик .NET Runtime из Загрузки .NET. Не устанавливайте полный пакет SDK на сервере.
    • .NET Framework. Если приложению требуется .NET Framework, см. руководство по установке .NET Framework. Установите необходимый .NET Framework. Установщик для последней версии .NET Framework доступен на странице .NET Загрузки.

    Если приложение развертывается автономно, в его развертывание включена среда выполнения. Устанавливать .NET Framework на сервере не нужно.

  5. Настройте URL-адреса и порты в приложении.

    По умолчанию ASP.NET Core привязывается к http://localhost:5000. Чтобы настроить префиксы URL-адресов и порты, используйте следующие параметры:

    • UseUrls
    • Аргументы командной строки urls.
    • Переменная среды ASPNETCORE_URLS.
    • UrlPrefixes

    В следующем примере кода показано, как использовать UrlPrefixes с локальным IP-адресом сервера 10.0.0.4 через порт 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 заключается в том, что при неправильном формате префиксов сразу же создается сообщение об ошибке.

    Этот параметр в UrlPrefixes переопределяет параметры UseUrls/urls/ASPNETCORE_URLS. Таким образом, преимущество переменных средыUseUrls, urls и ASPNETCORE_URLS заключается в возможности быстрого переключения между Kestrel и HTTP.sys.

    HTTP.sys распознает два типа подстановочных карточек в префиксах URL-адресов:

    • * является слабой привязкой, также известной как резервная привязка. Если префикс URL-адреса имеет http://*:5000значение и что-то другое привязано к порту 5000, эта привязка не будет использоваться.
    • + — это сильная привязка Если префикс URL-адреса имеет значение http://+:5000, эта привязка будет использоваться перед другими привязками порта 5000.

    Дополнительные сведения см. в разделе UrlPrefix Strings.

    Warning

    На верхнем уровне привязки с подстановочными знаками (http://*:80/ и http://+:80) не должны использоваться. Связывания с подстановочными символами верхнего уровня создают уязвимости для безопасности приложения. Это относится как к строгим, так и к нестрогим подстановочным знакам. Вместо подстановочных знаков используйте имена узлов или IP-адреса в явном виде. Привязки с подстановочными знаками на уровне дочерних доменов (например, *.mysub.com) не создают таких угроз безопасности, если вы полностью контролируете родительский домен (в отличие от варианта *.com, создающего уязвимость). Дополнительные сведения см. в разделе RFC 9110: раздел 7.2: Host и :authority.

    Приложения и контейнеры часто получают только порт для прослушивания, например, порт 80, без дополнительных ограничений, таких как хост или путь. HTTP_PORTS и HTTPS_PORTS — это ключи конфигурации, указывающие порты прослушивания для Kestrel серверов и HTTP.sys. Эти ключи могут быть указаны в виде переменных среды, определенными с помощью префиксов DOTNET_ или ASPNETCORE_, или напрямую указаны через любые другие средства конфигурации, например appsettings.json. Каждый из них представляет собой список значений портов с запятой, как показано в следующем примере:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    Предыдущий пример представляет собой сокращение следующей конфигурации, которая определяет схему (HTTP или HTTPS) и любой хост или IP-адрес.

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

    Ключи конфигурации HTTP_PORTS и HTTPS_PORTS имеют более низкий приоритет и переопределяются URL-адресами или значениями, предоставленными непосредственно в коде. Сертификаты по-прежнему необходимо настраивать отдельно через механизмы, специфичные для сервера, для HTTPS.

    Эти ключи конфигурации эквивалентны привязкам подстановочных знаков верхнего уровня. Они удобны для сценариев разработки и контейнеров, но избегайте подстановочных знаков, когда вы запускаете программы на компьютере, который может также размещать другие службы.

  6. Предварительно зарегистрируйте префиксы URL-адресов на сервере.

    Встроенным средством для настройки сервера HTTP.sys является netsh.exe. С помощьюnetsh.exe можно зарезервировать префиксы URL-адресов и назначить сертификаты X.509. Для использования этого средства требуются права администратора.

    Используйте средство netsh.exe для регистрации URL-адреса приложения.

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: полностью определенный универсальный указатель ресурсов (URL). Не используйте привязки с подстановочными знаками. Используйте допустимое имя узла или локальный IP-адрес. URL-адрес должен включать косую черту в конце.
    • <USER>: указывает имя пользователя или группы пользователей.

    В следующем примере сервер имеет локальный IP-адрес 10.0.0.4.

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

    При регистрации URL-адреса средство возвращает ответ URL reservation successfully added.

    Чтобы удалить зарегистрированный URL-адрес, используйте команду delete urlacl.

    netsh http delete urlacl url=<URL>
    
  7. Зарегистрируйте сертификаты X.509 на сервере.

    Используйте средство netsh.exe для регистрации сертификатов приложения.

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: указывает локальный IP-адрес привязки. Не используйте привязки с подстановочными знаками. Используйте допустимый IP-адрес.
    • <PORT>: указывает порт для привязки.
    • <THUMBPRINT>: отпечаток сертификата X.509.
    • <GUID>: созданный разработчиком GUID для представления приложения в информационных целях.

    В справочных целях храните GUID в приложении в виде тега пакета.

    • В Visual Studio:
      • Откройте свойства проекта приложения, щелкнув правой кнопкой мыши приложение в Обозреватель решений и выбрав Properties.
      • Перейдите на вкладку Package (Пакет).
      • Введите GUID, который вы создали в поле Tags.
    • Если Visual Studio не используется:
      • Откройте файл проекта приложения.

      • Добавьте свойство <PackageTags> в новый или существующий <PropertyGroup> с созданным вами GUID.

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

    В следующем примере :

    • Локальный IP-адрес сервера — 10.0.0.4.
    • Онлайн-генератор случайных идентификаторов GUID предоставляет значение appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    При регистрации сертификата средство возвращает ответ SSL Certificate successfully added.

    Чтобы удалить регистрацию сертификата, используйте команду delete sslcert.

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

    Дополнительные сведения см. в справочной документации по netsh.exe:

  8. Запустите приложение.

    Если выполнена привязка к localhost через HTTP (не HTTPS) с номером порта больше 1024, для запуска приложения права администратора не требуются. При других конфигурациях (например, при использовании локального IP-адреса или привязки к порту 443) для запуска приложения требуются права администратора.

    Приложение отвечает по общедоступному IP-адресу сервера. В этом примере подключение к серверу происходит через Интернет по общедоступному IP-адресу 104.214.79.47 сервера.

    В этом примере используется сертификат разработки. После обхода предупреждения о ненадежном сертификате браузера происходит безопасная загрузка страницы.

    Окно браузера с отображаемой страницей индекса приложения

Сценарии использования прокси-сервера и подсистемы балансировки нагрузки

Для приложений, размещенных через HTTP.sys, которые обрабатывают запросы из Интернета или корпоративной сети, может потребоваться дополнительная настройка при размещении за прокси-серверами и балансировщиками нагрузки. Дополнительные сведения см. в разделе Configure ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Получение подробных сведений о времени с помощью IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature предоставляет подробные сведения о времени для запросов:

  • Метки времени получаются с помощью QueryPerformanceCounter.
  • Частоту метки времени можно получить с помощью QueryPerformanceFrequency.
  • Индекс синхронизации можно привести к HttpSysRequestTimingType, чтобы узнать, что представляет собой данная синхронизация.
  • Значение может быть равно 0, если время недоступно для текущего запроса.
  • Требуется Windows 10 версии 2004, Windows Server 2022 или более поздней версии.
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 извлекает метку времени для предоставленного типа времени:

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 дает истекшее время между двумя указанными сроками:

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

Расширенные возможности HTTP/2 для поддержки gRPC

Дополнительные возможности HTTP/2 в HTTP.sys поддерживают gRPC, включая поддержку трейлеров ответов и отправку кадров сброса.

Требования для выполнения gRPC в HTTP.sys:

  • Windows 11 сборки 22000 или более поздней версии Windows Server 2022 сборки 20348 или более поздней версии.
  • Подключение TLS 1.2 или более поздней версии.

Trailers

Трейлеры HTTP похожи на заголовки HTTP, за исключением того, что они отправляются после отправки текста ответа. Для IIS и HTTP.sys поддерживаются только трейлеры ответов HTTP/2.

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

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

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

В приведенном выше примере кода:

  • SupportsTrailers обеспечивает поддержку трейлеров для ответа;
  • DeclareTrailer добавляет заданное имя трейлера в заголовок ответа Trailer. Объявлять трейлеры ответа необязательно, но рекомендуется. Вызов DeclareTrailer должен производиться перед отправкой заголовков ответа.
  • AppendTrailer добавляет трейлер.

Reset

Операция сброса позволяет серверу обнулить запрос HTTP/2 с указанным кодом ошибки. Запрос на сброс считается отменённым.

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

Reset в предыдущем примере кода задает код ошибки INTERNAL_ERROR. Дополнительные сведения о кодах ошибок HTTP/2 см. в соответствующем разделе спецификации HTTP/2.

Tracing

Сведения о том, как получить трассировки из HTTP.sys, см. в разделе сценарии управления HTTP.sys.

Дополнительные ресурсы