Partilhar via


HTTP.sys implementação de servidor web no ASP.NET Core

Note

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.

Warning

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 10 deste artigo.

Por Tom Dykstra e Chris Ross

HTTP.sys é um servidor web para ASP.NET Core que só é executado no Windows. HTTP.sys é uma alternativa ao Kestrel servidor e oferece alguns recursos que Kestrel não fornecem.

Important

HTTP.sys não é compatível com o ASP.NET Core Module e não pode ser usado com o IIS ou o IIS Express.

HTTP.sys suporta os seguintes recursos:

  • Autenticação do Windows
  • Partilha de portas
  • HTTPS com SNI
  • HTTP/2 sobre TLS (Windows 10 ou posterior)
  • HTTP/3 sobre TLS (Windows 11 ou posterior)
  • Transmissão direta de arquivos
  • Caching de resposta
  • WebSockets (Windows 8 ou posterior)
  • Descritores de segurança personalizáveis
  • Remoção automática do pool de memória

Versões suportadas do Windows:

  • Windows 7 ou posterior
  • Windows Server 2008 R2 ou posterior

Visualizar ou descarregar amostra de código (como descarregar)

Quando usar HTTP.sys

HTTP.sys é útil para implantações onde:

  • Há uma necessidade de expor o servidor diretamente à Internet sem usar o IIS.

    HTTP.sys comunica diretamente com a Internet

  • Uma implantação interna requer um recurso não disponível no Kestrel. Para obter mais informações, consulte Kestrel vs. HTTP.sys

    HTTP.sys comunica diretamente com a rede interna

HTTP.sys é uma tecnologia madura que protege contra muitos tipos de ataques e fornece a robustez, segurança e escalabilidade de um servidor Web completo. O próprio IIS é executado como um ouvinte HTTP sobre HTTP.sys.

Suporte HTTP/2

HTTP/2 é habilitado para aplicativos ASP.NET Core quando os seguintes requisitos básicos são atendidos:

Se uma conexão HTTP/2 for estabelecida, HttpRequest.Protocol relata HTTP/2.

HTTP/2 é ativado por padrão. Se uma conexão HTTP/2 não for estabelecida, a conexão retornará para HTTP/1.1. Em uma versão futura do Windows, sinalizadores de configuração HTTP/2 estarão disponíveis, incluindo a capacidade de desabilitar HTTP/2 com HTTP.sys.

Suporte HTTP/3

HTTP/3 é habilitado para aplicativos ASP.NET Core quando os seguintes requisitos básicos são atendidos:

As versões anteriores do Windows 11 Build podem exigir o uso de uma compilação do Windows Insider .

HTTP/3 é descoberto como uma atualização de HTTP/1.1 ou HTTP/2 através do alt-svc cabeçalho. Isso significa que a primeira solicitação normalmente usará HTTP/1.1 ou HTTP/2 antes de mudar para HTTP/3. Http.Sys não adiciona automaticamente o alt-svc cabeçalho, ele deve ser adicionado pelo aplicativo. O código seguinte é um exemplo de middleware que adiciona o cabeçalho de resposta alt-svc.

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

Coloque o código anterior no início do pipeline de solicitação.

Http.Sys também suporta o envio de uma mensagem de protocolo AltSvc HTTP/2 em vez de um cabeçalho de resposta para notificar o cliente de que HTTP/3 está disponível. Consulte a chave de registo EnableAltSvc. Isso requer ligações netsh sslcert que usam nomes de host em vez de endereços IP.

Autenticação em modo kernel com Kerberos

HTTP.sys delega a autenticação no modo kernel com o protocolo de autenticação Kerberos. A autenticação de modo de usuário não é suportada com Kerberos e HTTP.sys. A conta da máquina deve ser usada para descriptografar o token/tíquete Kerberos obtido do Ative Directory e encaminhado pelo cliente para o servidor para autenticar o usuário. Registre o SPN (Nome da Entidade de Serviço) para o host, não para o usuário do aplicativo.

Suporte para buffer de resposta em modo kernel

Em alguns cenários, altos volumes de pequenas gravações com alta latência podem causar um impacto significativo no desempenho de HTTP.sys. Este impacto deve-se à falta de um buffer de Pipe na implementação HTTP.sys. Para melhorar o desempenho nesses cenários, o suporte para buffer de resposta está incluído no HTTP.sys. Habilite o buffer definindo HttpSysOptions.EnableKernelResponseBuffering como true. O buffer de resposta deve ser ativado por uma aplicação que faça E/S síncrona ou E/S assíncrona, com não mais de uma gravação pendente de cada vez. Nesses cenários, o buffer de resposta pode melhorar significativamente a taxa de transferência em conexões de alta latência.

Os aplicativos que usam E/S assíncrona e que podem ter mais de uma gravação pendente por vez não devem usar esse sinalizador. Ativar esse sinalizador pode resultar em maior uso de CPU e memória por HTTP.Sys.

Como usar HTTP.sys

Configurar a aplicação ASP.NET Core para usar HTTP.sys

Chame o método de extensão UseHttpSys ao criar o host, especificando qualquer HttpSysOptions necessário. O exemplo a seguir define opções para seus valores padrão:

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

A configuração HTTP.sys adicional é tratada através das definições do registo.

Para mais informações sobre as opções de HTTP.sys, consulte HttpSysOptions.

Personalizar descritores de segurança

Uma fila de solicitações no HTTP.sys é uma estrutura de nível de kernel que armazena temporariamente solicitações HTTP de entrada até que seu aplicativo esteja pronto para processá-las. Gerencie o acesso à fila de solicitações usando a propriedade RequestQueueSecurityDescriptor em HttpSysOptions. Defina-o como uma GenericSecurityDescriptor instância ao configurar o servidor HTTP.sys.

Ao personalizar o descritor de segurança, você pode permitir ou negar o acesso de usuários ou grupos específicos à fila de solicitações. Isso é útil em cenários em que você deseja restringir ou delegar HTTP.sys tratamento de solicitações no nível do sistema operacional.

Por exemplo, o código a seguir permite todos os usuários autenticados, mas nega convidados:

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

A RequestQueueSecurityDescriptor propriedade se aplica somente ao criar uma nova fila de solicitações. A propriedade não afeta as filas de solicitação existentes.

MaxRequestBodySize

O tamanho máximo permitido de qualquer corpo de solicitação em bytes. Quando definido como null, o tamanho máximo do corpo da solicitação é ilimitado. Esse limite não tem efeito sobre as conexões atualizadas, que são sempre ilimitadas.

A forma recomendada para ultrapassar o limite numa aplicação ASP.NET Core MVC para um único IActionResult é utilizar o atributo RequestSizeLimitAttribute num método de ação.

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Uma exceção será lançada se o aplicativo tentar configurar o limite em uma solicitação depois que o aplicativo começar a ler a solicitação. Uma IsReadOnly propriedade pode ser usada para indicar se a MaxRequestBodySize propriedade está em um estado somente leitura, o que significa que é tarde demais para configurar o limite.

Se o aplicativo deve substituir MaxRequestBodySize por pedido, utilize o IHttpMaxRequestBodySizeFeature.

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

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

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

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

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

    return next(context);
});

Se estiver usando o Visual Studio, verifique se o aplicativo não está configurado para executar o IIS ou o IIS Express.

No Visual Studio, o perfil de inicialização padrão é para o IIS Express. Para executar o projeto como um aplicativo de console, altere manualmente o perfil selecionado, conforme mostrado na captura de tela a seguir:

Selecionar perfil do aplicativo de console

Configurar Windows Server

  1. Determine as portas a serem abertas para o aplicativo e use o Firewall do Windows ou o cmdlet New-NetFirewallRule PowerShell para abrir portas de firewall para permitir que o tráfego alcance HTTP.sys. Nos comandos a seguir e na configuração do aplicativo, a porta 443 é usada.

  2. Ao implantar em uma VM do Azure, abra as portas no Grupo de Segurança de Rede. Nos comandos a seguir e na configuração do aplicativo, a porta 443 é usada.

  3. Obtenha e instale certificados X.509, se necessário.

    No Windows, crie certificados autoassinados usando o cmdletNew-SelfSignedCertificate PowerShell. Para obter um exemplo sem suporte, consulte UpdateIISExpressSSLForChrome.ps1.

    Instale certificados autoassinados ou assinados por CA na loja Máquina Local>Pessoal do servidor.

  4. Se a aplicação for uma implantação dependente de framework, instale o .NET, o .NET Framework ou ambos (se a aplicação for uma aplicação .NET dirigida ao .NET Framework).

    • .NET: Se o aplicativo exigir o .NET, obtenha e execute o instalador do .NET Runtime a partir de Downloads do .NET. Não instale o SDK completo no servidor.
    • .NET Framework: Se o aplicativo exigir o .NET Framework, consulte o guia de instalação do .NET Framework. Instale o .NET Framework necessário. O instalador do .NET Framework mais recente está disponível na página Downloads do .NET .

    Se o aplicativo for uma implantação independente, o aplicativo incluirá o tempo de execução em sua implantação. Nenhuma instalação de estrutura é necessária no servidor.

  5. Configure URLs e portas no aplicativo.

    Por padrão, ASP.NET Core se liga a http://localhost:5000. Para configurar prefixos e portas de URL, as opções incluem:

    • UseUrls
    • urls argumento de linha de comando
    • ASPNETCORE_URLS variável de ambiente
    • UrlPrefixes

    O exemplo de código a seguir mostra como usar UrlPrefixes com o endereço 10.0.0.4 IP local do servidor na porta 443:

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

    Uma vantagem de UrlPrefixes é que uma mensagem de erro é gerada imediatamente para prefixos formatados incorretamente.

    As configurações em UrlPrefixes substituem as configurações em UseUrls/urls/ASPNETCORE_URLS. Portanto, uma vantagem de UseUrls, urls, e a ASPNETCORE_URLS variável de ambiente é que é mais fácil alternar entre Kestrel e HTTP.sys.

    HTTP.sys reconhece dois tipos de curingas na definição de prefixos de URL.

    • * é uma ligação fraca, também conhecida como ligação de fallback. Se o prefixo da URL for http://*:5000, e algo mais estiver vinculado à porta 5000, essa associação não será usada.
    • + é uma forte vinculação. Se o prefixo da URL for http://+:5000, essa associação será usada antes de outras ligações da porta 5000.

    Para obter mais informações, consulte UrlPrefix Strings.

    Warning

    As ligações genéricas de nível superior (http://*:80/ e http://+:80) não devem ser usadas. As ligações curinga de nível superior criam vulnerabilidades na segurança da aplicação. Isso aplica-se tanto a curingas fortes como a fracos. Use nomes de host explícitos ou endereços IP em vez de curingas. A vinculação de curinga de subdomínio (por exemplo, *.mysub.com) não é um risco de segurança se você controlar todo o domínio pai (ao contrário do *.com, que é vulnerável). Para obter mais informações, consulte RFC 9110: Seção 7.2: Host e :authority.

    Aplicativos e contêineres geralmente recebem apenas uma porta para escutar, como a porta 80, sem restrições adicionais, como host ou caminho. HTTP_PORTS e HTTPS_PORTS são chaves de configuração que especificam as portas de escuta para os servidores Kestrel e HTTP.sys. Essas chaves podem ser especificadas como variáveis de ambiente definidas com os prefixos DOTNET_ ou ASPNETCORE_, ou especificadas diretamente por meio de qualquer outra entrada de configuração, como appsettings.json. Cada um é uma lista delimitada por ponto-e-vírgula de valores de porta, conforme mostrado no exemplo a seguir:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    O exemplo anterior é uma abreviação para a configuração a seguir, que especifica o esquema (HTTP ou HTTPS) e qualquer host ou IP.

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

    As chaves de configuração HTTP_PORTS e HTTPS_PORTS são de prioridade mais baixa e são substituídas por URLs ou valores fornecidos diretamente no código. Os certificados ainda precisam ser configurados separadamente por meio de mecânicas específicas do servidor para HTTPS.

    Essas chaves de configuração correspondem às associações curinga de nível superior. Eles são convenientes para cenários de desenvolvimento e contentores, mas evite o uso de curingas ao executar em uma máquina que também possa hospedar outros serviços.

  6. Pré-registrar prefixos de URL no servidor.

    A ferramenta interna para configurar HTTP.sys é netsh.exe. netsh.exe é usado para reservar prefixos de URL e atribuir certificados X.509. A ferramenta requer privilégios de administrador.

    Use a ferramenta netsh.exe para registrar URLs para o aplicativo:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: O URL (Uniform Resource Locator) totalmente qualificado. Não use uma vinculação curinga. Use um nome de host válido ou um endereço IP local. O URL deve incluir uma barra final.
    • <USER>: Especifica o nome do usuário ou grupo de usuários.

    No exemplo a seguir, o endereço IP local do servidor é 10.0.0.4:

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

    Quando um URL é registrado, a ferramenta responde com URL reservation successfully added.

    Para excluir uma URL registrada, use o delete urlacl comando:

    netsh http delete urlacl url=<URL>
    
  7. Registre certificados X.509 no servidor.

    Use a ferramenta netsh.exe para registrar certificados para o aplicativo:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: Especifica o endereço IP local para a ligação. Não use uma vinculação curinga. Use um endereço IP válido.
    • <PORT>: Especifica a porta para a ligação.
    • <THUMBPRINT>: A impressão digital do certificado X.509.
    • <GUID>: Um GUID gerado pelo desenvolvedor para representar o aplicativo para fins informativos.

    Para fins de referência, armazene o GUID no aplicativo como uma tag de pacote:

    • No Visual Studio:
      • Abra as propriedades do projeto do aplicativo clicando com o botão direito do mouse no aplicativo no Gerenciador de Soluções e selecionando Propriedades.
      • Selecione a guia Pacote .
      • Insira o GUID que você criou no campo Tags .
    • Quando não estiver usando o Visual Studio:
      • Abra o arquivo de projeto do aplicativo.

      • Adicione uma <PackageTags> propriedade a uma nova ou existente <PropertyGroup> com o GUID que você criou:

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

    No exemplo a seguir:

    • O endereço IP local do servidor é 10.0.0.4.
    • Um gerador de GUID aleatório online fornece o valor appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Quando um certificado é registrado, a ferramenta responde com SSL Certificate successfully added.

    Para excluir um registro de certificado, use o delete sslcert comando:

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

    Documentação de referência para netsh.exe:

  8. Execute o aplicativo.

    Os privilégios de administrador não são necessários para executar o aplicativo ao vincular ao localhost usando HTTP (não HTTPS) com um número de porta maior que 1024. Para outras configurações (por exemplo, usando um endereço IP local ou vinculando à porta 443), execute o aplicativo com privilégios de administrador.

    O aplicativo responde no endereço IP público do servidor. Neste exemplo, o servidor é alcançado a partir da Internet em seu endereço IP público de 104.214.79.47.

    Um certificado de desenvolvimento é usado neste exemplo. A página é carregada com segurança depois de ignorar o aviso de certificado não confiável do navegador.

    Janela do navegador mostrando a página Índice do aplicativo carregada

Cenários de servidor proxy e balanceador de carga

Para aplicativos hospedados por HTTP.sys que interagem com solicitações da Internet ou de uma rede corporativa, pode ser necessária uma configuração adicional ao hospedar atrás de servidores proxy e balanceadores de carga. Para obter mais informações, consulte Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga.

Obtenha informações detalhadas sobre o tempo com IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature fornece informações detalhadas de tempo para solicitações:

  • Os carimbos de data/hora são obtidos utilizando o QueryPerformanceCounter.
  • A frequência de carimbo de data/hora pode ser obtida através de QueryPerformanceFrequency.
  • O índice do tempo pode ser convertido para HttpSysRequestTimingType para saber o que o tempo representa.
  • O valor pode ser 0 se o tempo não estiver disponível para a solicitação atual.
  • Requer o Windows 10 versão 2004, Windows Server 2022 ou posterior.
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

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

    var timestamps = feature.Timestamps;

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

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

    return next(context);
});

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

app.Run();

IHttpSysRequestTimingFeature.TryGetTimestamp recupera o carimbo de data/hora para o tipo de tempo fornecido:

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 fornece o tempo decorrido entre dois tempos especificados:

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

Recursos avançados de HTTP/2 para suportar gRPC

Recursos adicionais de HTTP/2 no HTTP.sys suportam gRPC, incluindo suporte para trailers de resposta e envio de quadros de redefinição.

Requisitos para executar o gRPC com HTTP.sys:

  • Windows 11 Build 22000 ou posterior, Windows Server 2022 Build 20348 ou posterior.
  • Conexão TLS 1.2 ou posterior.

Trailers

Os trailers HTTP são semelhantes aos cabeçalhos HTTP, exceto que são enviados após o corpo da resposta ser enviado. Para o IIS e o HTTP.sys, apenas trailers de resposta HTTP/2 são suportados.

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

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

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

No código de exemplo anterior:

  • SupportsTrailers garante que os reboques são suportados para a resposta.
  • DeclareTrailer adiciona o nome do trailer fornecido ao cabeçalho de resposta Trailer. Declarar os trailers de uma resposta é opcional, mas recomendado. Se DeclareTrailer for chamado, deve ser antes que os cabeçalhos de resposta sejam enviados.
  • AppendTrailer anexa o trailer.

Reset

Reset permite que o servidor redefina uma solicitação HTTP/2 com um código de erro especificado. Um pedido de reinicialização é considerado abortado.

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

Reset no exemplo de código anterior especifica o código de erro INTERNAL_ERROR. Para obter mais informações sobre códigos de erro HTTP/2, visite a seção código de erro de especificação HTTP/2.

Tracing

Para obter informações sobre como obter registos de HTTP.sys, consulte HTTP.sys Cenários de Gerenciabilidade.

Expulsão automática do pool de memória

Os pools de memória usados pelo Kestrel, IIS e HTTP.sys removem automaticamente os blocos de memória quando o aplicativo está ocioso ou sob baixa carga. O recurso é executado automaticamente e não precisa ser ativado ou configurado manualmente.

Em versões do .NET anteriores a 10, a memória alocada pelo pool permanece reservada, mesmo quando não está em uso. Esse recurso de remoção automática reduz o uso geral de memória e ajuda os aplicativos a permanecerem responsivos sob cargas de trabalho variáveis.

Usar métricas do pool de memória

O pool de memória padrão usado pelas implementações do servidor ASP.NET Core inclui métricas, que podem ser usadas para monitorar e analisar padrões de uso de memória. As métricas estão sob o nome "Microsoft.AspNetCore.MemoryPool".

Para obter informações sobre métricas e como usá-las, consulte ASP.NET métricas principais.

Gerenciar pools de memória

Além de usar pools de memória de forma eficiente, removendo blocos de memória desnecessários, o ASP.NET Core fornece um IMemoryPoolFactory integrado e uma implementação. Ele torna a implementação disponível para seu aplicativo por meio de injeção de dependência.

O exemplo de código a seguir mostra um serviço em segundo plano simples que usa a implementação de fábrica do pool de memória interno para criar pools de memória. Estas piscinas beneficiam da funcionalidade de despejo automático:

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

Para usar uma fábrica de pool de memória personalizada, crie uma classe que implemente IMemoryPoolFactory e registre-a com injeção de dependência, como faz o exemplo a seguir. Os pools de memória criados dessa forma também se beneficiam do recurso de remoção automática:

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

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

Quando você estiver usando um pool de memória, esteja ciente do pool MaxBufferSize.

Recursos adicionais

HTTP.sys é um servidor web para ASP.NET Core que só é executado no Windows. HTTP.sys é uma alternativa ao Kestrel servidor e oferece alguns recursos que Kestrel não fornecem.

Important

HTTP.sys não é compatível com o ASP.NET Core Module e não pode ser usado com o IIS ou o IIS Express.

HTTP.sys suporta os seguintes recursos:

  • Autenticação do Windows
  • Partilha de portas
  • HTTPS com SNI
  • HTTP/2 sobre TLS (Windows 10 ou posterior)
  • Transmissão direta de arquivos
  • Caching de resposta
  • WebSockets (Windows 8 ou posterior)

Versões suportadas do Windows:

  • Windows 7 ou posterior
  • Windows Server 2008 R2 ou posterior

Visualizar ou descarregar amostra de código (como descarregar)

Quando usar HTTP.sys

HTTP.sys é útil para implantações onde:

  • Há uma necessidade de expor o servidor diretamente à Internet sem usar o IIS.

    HTTP.sys comunica diretamente com a Internet

  • Uma implantação interna requer um recurso não disponível no Kestrel. Para obter mais informações, consulte Kestrel vs. HTTP.sys

    HTTP.sys comunica diretamente com a rede interna

HTTP.sys é uma tecnologia madura que protege contra muitos tipos de ataques e fornece a robustez, segurança e escalabilidade de um servidor Web completo. O próprio IIS é executado como um ouvinte HTTP sobre HTTP.sys.

Suporte HTTP/2

HTTP/2 é habilitado para aplicativos ASP.NET Core quando os seguintes requisitos básicos são atendidos:

Se uma conexão HTTP/2 for estabelecida, HttpRequest.Protocol relata HTTP/2.

HTTP/2 é ativado por padrão. Se uma conexão HTTP/2 não for estabelecida, a conexão retornará para HTTP/1.1. Em uma versão futura do Windows, sinalizadores de configuração HTTP/2 estarão disponíveis, incluindo a capacidade de desabilitar HTTP/2 com HTTP.sys.

Suporte HTTP/3

HTTP/3 é habilitado para aplicativos ASP.NET Core quando os seguintes requisitos básicos são atendidos:

As versões anteriores do Windows 11 Build podem exigir o uso de uma compilação do Windows Insider .

HTTP/3 é descoberto como uma atualização de HTTP/1.1 ou HTTP/2 através do alt-svc cabeçalho. Isso significa que a primeira solicitação normalmente usará HTTP/1.1 ou HTTP/2 antes de mudar para HTTP/3. Http.Sys não adiciona automaticamente o alt-svc cabeçalho, ele deve ser adicionado pelo aplicativo. O código seguinte é um exemplo de middleware que adiciona o cabeçalho de resposta alt-svc.

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

Coloque o código anterior no início do pipeline de solicitação.

Http.Sys também suporta o envio de uma mensagem de protocolo AltSvc HTTP/2 em vez de um cabeçalho de resposta para notificar o cliente de que HTTP/3 está disponível. Consulte a chave de registo EnableAltSvc. Isso requer ligações netsh sslcert que usam nomes de host em vez de endereços IP.

Autenticação em modo kernel com Kerberos

HTTP.sys delega a autenticação no modo kernel com o protocolo de autenticação Kerberos. A autenticação de modo de usuário não é suportada com Kerberos e HTTP.sys. A conta da máquina deve ser usada para descriptografar o token/tíquete Kerberos obtido do Ative Directory e encaminhado pelo cliente para o servidor para autenticar o usuário. Registre o SPN (Nome da Entidade de Serviço) para o host, não para o usuário do aplicativo.

Como usar HTTP.sys

Configurar a aplicação ASP.NET Core para usar HTTP.sys

Chame o método de extensão UseHttpSys ao criar o host, especificando qualquer HttpSysOptions necessário. O exemplo a seguir define opções para seus valores padrão:

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

A configuração HTTP.sys adicional é tratada através das definições do registo.

Para mais informações sobre as opções de HTTP.sys, consulte HttpSysOptions.

MaxRequestBodySize

O tamanho máximo permitido de qualquer corpo de solicitação em bytes. Quando definido como null, o tamanho máximo do corpo da solicitação é ilimitado. Esse limite não tem efeito sobre as conexões atualizadas, que são sempre ilimitadas.

A forma recomendada para ultrapassar o limite numa aplicação ASP.NET Core MVC para um único IActionResult é utilizar o atributo RequestSizeLimitAttribute num método de ação.

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Uma exceção será lançada se o aplicativo tentar configurar o limite em uma solicitação depois que o aplicativo começar a ler a solicitação. Uma IsReadOnly propriedade pode ser usada para indicar se a MaxRequestBodySize propriedade está em um estado somente leitura, o que significa que é tarde demais para configurar o limite.

Se o aplicativo deve substituir MaxRequestBodySize por pedido, utilize o IHttpMaxRequestBodySizeFeature.

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

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

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

        await next.Invoke();
    });

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

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

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

Se estiver usando o Visual Studio, verifique se o aplicativo não está configurado para executar o IIS ou o IIS Express.

No Visual Studio, o perfil de inicialização padrão é para o IIS Express. Para executar o projeto como um aplicativo de console, altere manualmente o perfil selecionado, conforme mostrado na captura de tela a seguir:

Selecionar perfil do aplicativo de console

Configurar Windows Server

  1. Determine as portas a serem abertas para o aplicativo e use o Firewall do Windows ou o cmdlet New-NetFirewallRule PowerShell para abrir portas de firewall para permitir que o tráfego alcance HTTP.sys. Nos comandos a seguir e na configuração do aplicativo, a porta 443 é usada.

  2. Ao implantar em uma VM do Azure, abra as portas no Grupo de Segurança de Rede. Nos comandos a seguir e na configuração do aplicativo, a porta 443 é usada.

  3. Obtenha e instale certificados X.509, se necessário.

    No Windows, crie certificados autoassinados usando o cmdletNew-SelfSignedCertificate PowerShell. Para obter um exemplo sem suporte, consulte UpdateIISExpressSSLForChrome.ps1.

    Instale certificados autoassinados ou assinados por CA na loja Máquina Local>Pessoal do servidor.

  4. Se a aplicação for uma implantação dependente de framework, instale o .NET, o .NET Framework ou ambos (se a aplicação for uma aplicação .NET dirigida ao .NET Framework).

    • .NET: Se o aplicativo exigir o .NET, obtenha e execute o instalador do .NET Runtime a partir de Downloads do .NET. Não instale o SDK completo no servidor.
    • .NET Framework: Se o aplicativo exigir o .NET Framework, consulte o guia de instalação do .NET Framework. Instale o .NET Framework necessário. O instalador do .NET Framework mais recente está disponível na página Downloads do .NET .

    Se o aplicativo for uma implantação independente, o aplicativo incluirá o tempo de execução em sua implantação. Nenhuma instalação de estrutura é necessária no servidor.

  5. Configure URLs e portas no aplicativo.

    Por padrão, ASP.NET Core se liga a http://localhost:5000. Para configurar prefixos e portas de URL, as opções incluem:

    • UseUrls
    • urls argumento de linha de comando
    • ASPNETCORE_URLS variável de ambiente
    • UrlPrefixes

    O exemplo de código a seguir mostra como usar UrlPrefixes com o endereço 10.0.0.4 IP local do servidor na porta 443:

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

    Uma vantagem de UrlPrefixes é que uma mensagem de erro é gerada imediatamente para prefixos formatados incorretamente.

    As configurações em UrlPrefixes substituem as configurações em UseUrls/urls/ASPNETCORE_URLS. Portanto, uma vantagem de UseUrls, urls, e a ASPNETCORE_URLS variável de ambiente é que é mais fácil alternar entre Kestrel e HTTP.sys.

    HTTP.sys usa os formatos de cadeia de caracteres de UrlPrefix da API do Servidor HTTP.

    Warning

    As ligações genéricas de nível superior (http://*:80/ e http://+:80) não devem ser usadas. As ligações curinga de nível superior criam vulnerabilidades na segurança da aplicação. Isso aplica-se tanto a curingas fortes como a fracos. Use nomes de host explícitos ou endereços IP em vez de curingas. A vinculação de curinga de subdomínio (por exemplo, *.mysub.com) não é um risco de segurança se você controlar todo o domínio pai (ao contrário do *.com, que é vulnerável). Para obter mais informações, consulte RFC 9110: Seção 7.2: Host e :authority.

  6. Pré-registrar prefixos de URL no servidor.

    A ferramenta interna para configurar HTTP.sys é netsh.exe. netsh.exe é usado para reservar prefixos de URL e atribuir certificados X.509. A ferramenta requer privilégios de administrador.

    Use a ferramenta netsh.exe para registrar URLs para o aplicativo:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: O URL (Uniform Resource Locator) totalmente qualificado. Não use uma vinculação curinga. Use um nome de host válido ou um endereço IP local. O URL deve incluir uma barra final.
    • <USER>: Especifica o nome do usuário ou grupo de usuários.

    No exemplo a seguir, o endereço IP local do servidor é 10.0.0.4:

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

    Quando um URL é registrado, a ferramenta responde com URL reservation successfully added.

    Para excluir uma URL registrada, use o delete urlacl comando:

    netsh http delete urlacl url=<URL>
    
  7. Registre certificados X.509 no servidor.

    Use a ferramenta netsh.exe para registrar certificados para o aplicativo:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: Especifica o endereço IP local para a ligação. Não use uma vinculação curinga. Use um endereço IP válido.
    • <PORT>: Especifica a porta para a ligação.
    • <THUMBPRINT>: A impressão digital do certificado X.509.
    • <GUID>: Um GUID gerado pelo desenvolvedor para representar o aplicativo para fins informativos.

    Para fins de referência, armazene o GUID no aplicativo como uma tag de pacote:

    • No Visual Studio:
      • Abra as propriedades do projeto do aplicativo clicando com o botão direito do mouse no aplicativo no Gerenciador de Soluções e selecionando Propriedades.
      • Selecione a guia Pacote .
      • Insira o GUID que você criou no campo Tags .
    • Quando não estiver usando o Visual Studio:
      • Abra o arquivo de projeto do aplicativo.

      • Adicione uma <PackageTags> propriedade a uma nova ou existente <PropertyGroup> com o GUID que você criou:

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

    No exemplo a seguir:

    • O endereço IP local do servidor é 10.0.0.4.
    • Um gerador de GUID aleatório online fornece o valor appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Quando um certificado é registrado, a ferramenta responde com SSL Certificate successfully added.

    Para excluir um registro de certificado, use o delete sslcert comando:

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

    Documentação de referência para netsh.exe:

  8. Execute o aplicativo.

    Os privilégios de administrador não são necessários para executar o aplicativo ao vincular ao localhost usando HTTP (não HTTPS) com um número de porta maior que 1024. Para outras configurações (por exemplo, usando um endereço IP local ou vinculando à porta 443), execute o aplicativo com privilégios de administrador.

    O aplicativo responde no endereço IP público do servidor. Neste exemplo, o servidor é alcançado a partir da Internet em seu endereço IP público de 104.214.79.47.

    Um certificado de desenvolvimento é usado neste exemplo. A página é carregada com segurança depois de ignorar o aviso de certificado não confiável do navegador.

    Janela do navegador mostrando a página Índice do aplicativo carregada

Cenários de servidor proxy e balanceador de carga

Para aplicativos hospedados por HTTP.sys que interagem com solicitações da Internet ou de uma rede corporativa, pode ser necessária uma configuração adicional ao hospedar atrás de servidores proxy e balanceadores de carga. Para obter mais informações, consulte Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga.

Recursos avançados de HTTP/2 para suportar gRPC

Recursos adicionais de HTTP/2 no HTTP.sys suportam gRPC, incluindo suporte para trailers de resposta e envio de quadros de redefinição.

Requisitos para executar o gRPC com HTTP.sys:

  • Windows 11 Build 22000 ou posterior, Windows Server 2022 Build 20348 ou posterior.
  • Conexão TLS 1.2 ou posterior.

Trailers

Os trailers HTTP são semelhantes aos cabeçalhos HTTP, exceto que são enviados após o corpo da resposta ser enviado. Para o IIS e o HTTP.sys, apenas trailers de resposta HTTP/2 são suportados.

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

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

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

No código de exemplo anterior:

  • SupportsTrailers garante que os reboques são suportados para a resposta.
  • DeclareTrailer adiciona o nome do trailer fornecido ao cabeçalho de resposta Trailer. Declarar os trailers de uma resposta é opcional, mas recomendado. Se DeclareTrailer for chamado, deve ser antes que os cabeçalhos de resposta sejam enviados.
  • AppendTrailer anexa o trailer.

Reset

Reset permite que o servidor redefina uma solicitação HTTP/2 com um código de erro especificado. Um pedido de reinicialização é considerado abortado.

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

Reset no exemplo de código anterior especifica o código de erro INTERNAL_ERROR. Para obter mais informações sobre códigos de erro HTTP/2, visite a seção código de erro de especificação HTTP/2.

Recursos adicionais

HTTP.sys é um servidor web para ASP.NET Core que só é executado no Windows. HTTP.sys é uma alternativa ao Kestrel servidor e oferece alguns recursos que Kestrel não fornecem.

Important

HTTP.sys não é compatível com o ASP.NET Core Module e não pode ser usado com o IIS ou o IIS Express.

HTTP.sys suporta os seguintes recursos:

  • Autenticação do Windows
  • Partilha de portas
  • HTTPS com SNI
  • HTTP/2 sobre TLS (Windows 10 ou posterior)
  • Transmissão direta de arquivos
  • Caching de resposta
  • WebSockets (Windows 8 ou posterior)

Versões suportadas do Windows:

  • Windows 7 ou posterior
  • Windows Server 2008 R2 ou posterior

Visualizar ou descarregar amostra de código (como descarregar)

Quando usar HTTP.sys

HTTP.sys é útil para implantações onde:

  • Há uma necessidade de expor o servidor diretamente à Internet sem usar o IIS.

    HTTP.sys comunica diretamente com a Internet

  • Uma implantação interna requer um recurso não disponível no Kestrel. Para obter mais informações, consulte Kestrel vs. HTTP.sys

    HTTP.sys comunica diretamente com a rede interna

HTTP.sys é uma tecnologia madura que protege contra muitos tipos de ataques e fornece a robustez, segurança e escalabilidade de um servidor Web completo. O próprio IIS é executado como um ouvinte HTTP sobre HTTP.sys.

Suporte HTTP/2

HTTP/2 é habilitado para aplicativos ASP.NET Core se os seguintes requisitos básicos forem atendidos:

Se uma conexão HTTP/2 for estabelecida, HttpRequest.Protocol relata HTTP/2.

HTTP/2 é ativado por padrão. Se uma conexão HTTP/2 não for estabelecida, a conexão retornará para HTTP/1.1. Em uma versão futura do Windows, sinalizadores de configuração HTTP/2 estarão disponíveis, incluindo a capacidade de desabilitar HTTP/2 com HTTP.sys.

Autenticação em modo kernel com Kerberos

HTTP.sys delega a autenticação no modo kernel com o protocolo de autenticação Kerberos. A autenticação de modo de usuário não é suportada com Kerberos e HTTP.sys. A conta da máquina deve ser usada para descriptografar o token/tíquete Kerberos obtido do Ative Directory e encaminhado pelo cliente para o servidor para autenticar o usuário. Registre o SPN (Nome da Entidade de Serviço) para o host, não para o usuário do aplicativo.

Como usar HTTP.sys

Configurar a aplicação ASP.NET Core para usar HTTP.sys

Chame o método de extensão UseHttpSys ao criar o host, especificando qualquer HttpSysOptions necessário. O exemplo a seguir define opções para seus valores padrão:

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

A configuração HTTP.sys adicional é tratada através das definições do registo.

HTTP.sys opções

Property Description Default
AllowSynchronousIO Controle se a entrada/saída síncrona é permitida para o HttpContext.Request.Body e HttpContext.Response.Body. false
Authentication.AllowAnonymous Permitir pedidos anónimos. true
Authentication.Schemes Especifique os esquemas de autenticação permitidos. Pode ser modificado a qualquer momento antes de remover o ouvinte. Os valores são fornecidos pelo enum AuthenticationSchemes: Basic, Kerberos, Negotiate, None, e NTLM. None
EnableResponseCaching Tente armazenar em cache no modo kernel respostas com cabeçalhos qualificados. A resposta pode não incluir Set-Cookie, Varyou Pragma cabeçalhos. Deve incluir um cabeçalho Cache-Control que seja public e que tenha um valor shared-max-age ou max-age, ou então um cabeçalho Expires. true
Http503Verbosity O comportamento HTTP.sys ao rejeitar solicitações devido a condições de controlo de fluxo. http503VerbosityLevel.
Básico
MaxAccepts O número máximo de aceitações simultâneas. 5 × Ambiente.
NúmeroDeProcessadores
MaxConnections O número máximo de conexões simultâneas a serem aceitas. Use -1 para infinito. Use null para usar a configuração de toda a máquina do Registro. null
(machine-wide
setting)
MaxRequestBodySize Consulte a seção MaxRequestBodySize . 30000000 bytes
(~28,6 MB)
RequestQueueLimit O número máximo de pedidos que podem ser colocados em fila. 1000
RequestQueueMode Isso indica se o servidor é responsável por criar e configurar a fila de solicitações ou se ele deve ser anexado a uma fila existente.
A maioria das opções de configuração existentes não se aplica ao anexar a uma fila existente.
RequestQueueMode.Create
RequestQueueName O nome da fila de solicitações HTTP.sys. null (Fila anónima)
ThrowWriteExceptions Indique se as gravações do corpo da resposta que falham devido a desconexões do cliente devem gerar exceções ou ser concluídas normalmente. false
(completo normalmente)
Timeouts Exponha a configuração HTTP.sys TimeoutManager , que também pode ser configurada no registro. Siga os links da API para saber mais sobre cada configuração, incluindo os valores padrão:
UrlPrefixes Especifique o UrlPrefixCollection para se registrar com HTTP.sys. O mais útil é UrlPrefixCollection.Add, que é usado para adicionar um prefixo à coleção. Estes podem ser modificados a qualquer momento antes de descartar o ouvinte.

MaxRequestBodySize

O tamanho máximo permitido de qualquer corpo de solicitação em bytes. Quando definido como null, o tamanho máximo do corpo da solicitação é ilimitado. Esse limite não tem efeito sobre as conexões atualizadas, que são sempre ilimitadas.

A forma recomendada para ultrapassar o limite numa aplicação ASP.NET Core MVC para um único IActionResult é utilizar o atributo RequestSizeLimitAttribute num método de ação.

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Uma exceção será lançada se o aplicativo tentar configurar o limite em uma solicitação depois que o aplicativo começar a ler a solicitação. Uma IsReadOnly propriedade pode ser usada para indicar se a MaxRequestBodySize propriedade está em um estado somente leitura, o que significa que é tarde demais para configurar o limite.

Se o aplicativo deve substituir MaxRequestBodySize por pedido, utilize o IHttpMaxRequestBodySizeFeature.

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

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

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

        await next.Invoke();
    });

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

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

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

Se estiver usando o Visual Studio, verifique se o aplicativo não está configurado para executar o IIS ou o IIS Express.

No Visual Studio, o perfil de inicialização padrão é para o IIS Express. Para executar o projeto como um aplicativo de console, altere manualmente o perfil selecionado, conforme mostrado na captura de tela a seguir:

Selecionar perfil do aplicativo de console

Configurar Windows Server

  1. Determine as portas a serem abertas para o aplicativo e use o Firewall do Windows ou o cmdlet New-NetFirewallRule PowerShell para abrir portas de firewall para permitir que o tráfego alcance HTTP.sys. Nos comandos a seguir e na configuração do aplicativo, a porta 443 é usada.

  2. Ao implantar em uma VM do Azure, abra as portas no Grupo de Segurança de Rede. Nos comandos a seguir e na configuração do aplicativo, a porta 443 é usada.

  3. Obtenha e instale certificados X.509, se necessário.

    No Windows, crie certificados autoassinados usando o cmdletNew-SelfSignedCertificate PowerShell. Para obter um exemplo sem suporte, consulte UpdateIISExpressSSLForChrome.ps1.

    Instale certificados autoassinados ou assinados por CA na loja Máquina Local>Pessoal do servidor.

  4. Se a aplicação for uma implantação dependente de framework, instale o .NET, o .NET Framework ou ambos (se a aplicação for uma aplicação .NET dirigida ao .NET Framework).

    • .NET: Se o aplicativo exigir o .NET, obtenha e execute o instalador do .NET Runtime a partir de Downloads do .NET. Não instale o SDK completo no servidor.
    • .NET Framework: Se o aplicativo exigir o .NET Framework, consulte o guia de instalação do .NET Framework. Instale o .NET Framework necessário. O instalador do .NET Framework mais recente está disponível na página Downloads do .NET .

    Se o aplicativo for uma implantação independente, o aplicativo incluirá o tempo de execução em sua implantação. Nenhuma instalação de estrutura é necessária no servidor.

  5. Configure URLs e portas no aplicativo.

    Por padrão, ASP.NET Core se liga a http://localhost:5000. Para configurar prefixos e portas de URL, as opções incluem:

    • UseUrls
    • urls argumento de linha de comando
    • ASPNETCORE_URLS variável de ambiente
    • UrlPrefixes

    O exemplo de código a seguir mostra como usar UrlPrefixes com o endereço 10.0.0.4 IP local do servidor na porta 443:

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

    Uma vantagem de UrlPrefixes é que uma mensagem de erro é gerada imediatamente para prefixos formatados incorretamente.

    As configurações em UrlPrefixes substituem as configurações em UseUrls/urls/ASPNETCORE_URLS. Portanto, uma vantagem de UseUrls, urls, e a ASPNETCORE_URLS variável de ambiente é que é mais fácil alternar entre Kestrel e HTTP.sys.

    HTTP.sys usa os formatos de cadeia de caracteres de UrlPrefix da API do Servidor HTTP.

    Warning

    As ligações genéricas de nível superior (http://*:80/ e http://+:80) não devem ser usadas. As ligações curinga de nível superior criam vulnerabilidades na segurança da aplicação. Isso aplica-se tanto a curingas fortes como a fracos. Use nomes de host explícitos ou endereços IP em vez de curingas. A vinculação de curinga de subdomínio (por exemplo, *.mysub.com) não é um risco de segurança se você controlar todo o domínio pai (ao contrário do *.com, que é vulnerável). Para obter mais informações, consulte RFC 9110: Seção 7.2: Host e :authority.

  6. Pré-registrar prefixos de URL no servidor.

    A ferramenta interna para configurar HTTP.sys é netsh.exe. netsh.exe é usado para reservar prefixos de URL e atribuir certificados X.509. A ferramenta requer privilégios de administrador.

    Use a ferramenta netsh.exe para registrar URLs para o aplicativo:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: O URL (Uniform Resource Locator) totalmente qualificado. Não use uma vinculação curinga. Use um nome de host válido ou um endereço IP local. O URL deve incluir uma barra final.
    • <USER>: Especifica o nome do usuário ou grupo de usuários.

    No exemplo a seguir, o endereço IP local do servidor é 10.0.0.4:

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

    Quando um URL é registrado, a ferramenta responde com URL reservation successfully added.

    Para excluir uma URL registrada, use o delete urlacl comando:

    netsh http delete urlacl url=<URL>
    
  7. Registre certificados X.509 no servidor.

    Use a ferramenta netsh.exe para registrar certificados para o aplicativo:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: Especifica o endereço IP local para a ligação. Não use uma vinculação curinga. Use um endereço IP válido.
    • <PORT>: Especifica a porta para a ligação.
    • <THUMBPRINT>: A impressão digital do certificado X.509.
    • <GUID>: Um GUID gerado pelo desenvolvedor para representar o aplicativo para fins informativos.

    Para fins de referência, armazene o GUID no aplicativo como uma tag de pacote:

    • No Visual Studio:
      • Abra as propriedades do projeto do aplicativo clicando com o botão direito do mouse no aplicativo no Gerenciador de Soluções e selecionando Propriedades.
      • Selecione a guia Pacote .
      • Insira o GUID que você criou no campo Tags .
    • Quando não estiver usando o Visual Studio:
      • Abra o arquivo de projeto do aplicativo.

      • Adicione uma <PackageTags> propriedade a uma nova ou existente <PropertyGroup> com o GUID que você criou:

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

    No exemplo a seguir:

    • O endereço IP local do servidor é 10.0.0.4.
    • Um gerador de GUID aleatório online fornece o valor appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Quando um certificado é registrado, a ferramenta responde com SSL Certificate successfully added.

    Para excluir um registro de certificado, use o delete sslcert comando:

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

    Documentação de referência para netsh.exe:

  8. Execute o aplicativo.

    Os privilégios de administrador não são necessários para executar o aplicativo ao vincular ao localhost usando HTTP (não HTTPS) com um número de porta maior que 1024. Para outras configurações (por exemplo, usando um endereço IP local ou vinculando à porta 443), execute o aplicativo com privilégios de administrador.

    O aplicativo responde no endereço IP público do servidor. Neste exemplo, o servidor é alcançado a partir da Internet em seu endereço IP público de 104.214.79.47.

    Um certificado de desenvolvimento é usado neste exemplo. A página é carregada com segurança depois de ignorar o aviso de certificado não confiável do navegador.

    Janela do navegador mostrando a página Índice do aplicativo carregada

Cenários de servidor proxy e balanceador de carga

Para aplicativos hospedados por HTTP.sys que interagem com solicitações da Internet ou de uma rede corporativa, pode ser necessária uma configuração adicional ao hospedar atrás de servidores proxy e balanceadores de carga. Para obter mais informações, consulte Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga.

Recursos avançados de HTTP/2 para suportar gRPC

Recursos adicionais de HTTP/2 no HTTP.sys suportam gRPC, incluindo suporte para trailers de resposta e envio de quadros de redefinição.

Requisitos para executar o gRPC com HTTP.sys:

  • Windows 10, OS Build 19041.508 ou posterior
  • Conexão TLS 1.2 ou posterior

Trailers

Os trailers HTTP são semelhantes aos cabeçalhos HTTP, exceto que são enviados após o corpo da resposta ser enviado. Para o IIS e o HTTP.sys, apenas trailers de resposta HTTP/2 são suportados.

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

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

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

No código de exemplo anterior:

  • SupportsTrailers garante que os reboques são suportados para a resposta.
  • DeclareTrailer adiciona o nome do trailer fornecido ao cabeçalho de resposta Trailer. Declarar os trailers de uma resposta é opcional, mas recomendado. Se DeclareTrailer for chamado, deve ser antes que os cabeçalhos de resposta sejam enviados.
  • AppendTrailer anexa o trailer.

Reset

Reset permite que o servidor redefina uma solicitação HTTP/2 com um código de erro especificado. Um pedido de reinicialização é considerado abortado.

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

Reset no exemplo de código anterior especifica o código de erro INTERNAL_ERROR. Para obter mais informações sobre códigos de erro HTTP/2, visite a seção código de erro de especificação HTTP/2.

Recursos adicionais

HTTP.sys é um servidor web para ASP.NET Core que só é executado no Windows. HTTP.sys é uma alternativa ao Kestrel servidor e oferece alguns recursos que Kestrel não fornecem.

Important

HTTP.sys não é compatível com o ASP.NET Core Module e não pode ser usado com o IIS ou o IIS Express.

HTTP.sys suporta os seguintes recursos:

  • Autenticação do Windows
  • Partilha de portas
  • HTTPS com SNI
  • HTTP/2 sobre TLS (Windows 10 ou posterior)
  • HTTP/3 sobre TLS (Windows 11 ou posterior)
  • Transmissão direta de arquivos
  • Caching de resposta
  • WebSockets (Windows 8 ou posterior)
  • Descritores de segurança personalizáveis

Versões suportadas do Windows:

  • Windows 7 ou posterior
  • Windows Server 2008 R2 ou posterior

Visualizar ou descarregar amostra de código (como descarregar)

Quando usar HTTP.sys

HTTP.sys é útil para implantações onde:

  • Há uma necessidade de expor o servidor diretamente à Internet sem usar o IIS.

    HTTP.sys comunica diretamente com a Internet

  • Uma implantação interna requer um recurso não disponível no Kestrel. Para obter mais informações, consulte Kestrel vs. HTTP.sys

    HTTP.sys comunica diretamente com a rede interna

HTTP.sys é uma tecnologia madura que protege contra muitos tipos de ataques e fornece a robustez, segurança e escalabilidade de um servidor Web completo. O próprio IIS é executado como um ouvinte HTTP sobre HTTP.sys.

Suporte HTTP/2

HTTP/2 é habilitado para aplicativos ASP.NET Core quando os seguintes requisitos básicos são atendidos:

Se uma conexão HTTP/2 for estabelecida, HttpRequest.Protocol relata HTTP/2.

HTTP/2 é ativado por padrão. Se uma conexão HTTP/2 não for estabelecida, a conexão retornará para HTTP/1.1. Em uma versão futura do Windows, sinalizadores de configuração HTTP/2 estarão disponíveis, incluindo a capacidade de desabilitar HTTP/2 com HTTP.sys.

Suporte HTTP/3

HTTP/3 é habilitado para aplicativos ASP.NET Core quando os seguintes requisitos básicos são atendidos:

As versões anteriores do Windows 11 Build podem exigir o uso de uma compilação do Windows Insider .

HTTP/3 é descoberto como uma atualização de HTTP/1.1 ou HTTP/2 através do alt-svc cabeçalho. Isso significa que a primeira solicitação normalmente usará HTTP/1.1 ou HTTP/2 antes de mudar para HTTP/3. Http.Sys não adiciona automaticamente o alt-svc cabeçalho, ele deve ser adicionado pelo aplicativo. O código seguinte é um exemplo de middleware que adiciona o cabeçalho de resposta alt-svc.

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

Coloque o código anterior no início do pipeline de solicitação.

Http.Sys também suporta o envio de uma mensagem de protocolo AltSvc HTTP/2 em vez de um cabeçalho de resposta para notificar o cliente de que HTTP/3 está disponível. Consulte a chave de registo EnableAltSvc. Isso requer ligações netsh sslcert que usam nomes de host em vez de endereços IP.

Autenticação em modo kernel com Kerberos

HTTP.sys delega a autenticação no modo kernel com o protocolo de autenticação Kerberos. A autenticação de modo de usuário não é suportada com Kerberos e HTTP.sys. A conta da máquina deve ser usada para descriptografar o token/tíquete Kerberos obtido do Ative Directory e encaminhado pelo cliente para o servidor para autenticar o usuário. Registre o SPN (Nome da Entidade de Serviço) para o host, não para o usuário do aplicativo.

Suporte para buffer de resposta em modo kernel

Em alguns cenários, altos volumes de pequenas gravações com alta latência podem causar um impacto significativo no desempenho de HTTP.sys. Este impacto deve-se à falta de um buffer de Pipe na implementação HTTP.sys. Para melhorar o desempenho nesses cenários, o suporte para buffer de resposta está incluído no HTTP.sys. Habilite o buffer definindo HttpSysOptions.EnableKernelResponseBuffering como true. O buffer de resposta deve ser ativado por uma aplicação que faça E/S síncrona ou E/S assíncrona, com não mais de uma gravação pendente de cada vez. Nesses cenários, o buffer de resposta pode melhorar significativamente a taxa de transferência em conexões de alta latência.

Os aplicativos que usam E/S assíncrona e que podem ter mais de uma gravação pendente por vez não devem usar esse sinalizador. Ativar esse sinalizador pode resultar em maior uso de CPU e memória por HTTP.Sys.

Como usar HTTP.sys

Configurar a aplicação ASP.NET Core para usar HTTP.sys

Chame o método de extensão UseHttpSys ao criar o host, especificando qualquer HttpSysOptions necessário. O exemplo a seguir define opções para seus valores padrão:

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

A configuração HTTP.sys adicional é tratada através das definições do registo.

Para mais informações sobre as opções de HTTP.sys, consulte HttpSysOptions.

MaxRequestBodySize

O tamanho máximo permitido de qualquer corpo de solicitação em bytes. Quando definido como null, o tamanho máximo do corpo da solicitação é ilimitado. Esse limite não tem efeito sobre as conexões atualizadas, que são sempre ilimitadas.

A forma recomendada para ultrapassar o limite numa aplicação ASP.NET Core MVC para um único IActionResult é utilizar o atributo RequestSizeLimitAttribute num método de ação.

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Uma exceção será lançada se o aplicativo tentar configurar o limite em uma solicitação depois que o aplicativo começar a ler a solicitação. Uma IsReadOnly propriedade pode ser usada para indicar se a MaxRequestBodySize propriedade está em um estado somente leitura, o que significa que é tarde demais para configurar o limite.

Se o aplicativo deve substituir MaxRequestBodySize por pedido, utilize o IHttpMaxRequestBodySizeFeature.

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

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

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

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

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

    return next(context);
});

Se estiver usando o Visual Studio, verifique se o aplicativo não está configurado para executar o IIS ou o IIS Express.

No Visual Studio, o perfil de inicialização padrão é para o IIS Express. Para executar o projeto como um aplicativo de console, altere manualmente o perfil selecionado, conforme mostrado na captura de tela a seguir:

Selecionar perfil do aplicativo de console

Configurar Windows Server

  1. Determine as portas a serem abertas para o aplicativo e use o Firewall do Windows ou o cmdlet New-NetFirewallRule PowerShell para abrir portas de firewall para permitir que o tráfego alcance HTTP.sys. Nos comandos a seguir e na configuração do aplicativo, a porta 443 é usada.

  2. Ao implantar em uma VM do Azure, abra as portas no Grupo de Segurança de Rede. Nos comandos a seguir e na configuração do aplicativo, a porta 443 é usada.

  3. Obtenha e instale certificados X.509, se necessário.

    No Windows, crie certificados autoassinados usando o cmdletNew-SelfSignedCertificate PowerShell. Para obter um exemplo sem suporte, consulte UpdateIISExpressSSLForChrome.ps1.

    Instale certificados autoassinados ou assinados por CA na loja Máquina Local>Pessoal do servidor.

  4. Se a aplicação for uma implantação dependente de framework, instale o .NET, o .NET Framework ou ambos (se a aplicação for uma aplicação .NET dirigida ao .NET Framework).

    • .NET: Se o aplicativo exigir o .NET, obtenha e execute o instalador do .NET Runtime a partir de Downloads do .NET. Não instale o SDK completo no servidor.
    • .NET Framework: Se o aplicativo exigir o .NET Framework, consulte o guia de instalação do .NET Framework. Instale o .NET Framework necessário. O instalador do .NET Framework mais recente está disponível na página Downloads do .NET .

    Se o aplicativo for uma implantação independente, o aplicativo incluirá o tempo de execução em sua implantação. Nenhuma instalação de estrutura é necessária no servidor.

  5. Configure URLs e portas no aplicativo.

    Por padrão, ASP.NET Core se liga a http://localhost:5000. Para configurar prefixos e portas de URL, as opções incluem:

    • UseUrls
    • urls argumento de linha de comando
    • ASPNETCORE_URLS variável de ambiente
    • UrlPrefixes

    O exemplo de código a seguir mostra como usar UrlPrefixes com o endereço 10.0.0.4 IP local do servidor na porta 443:

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

    Uma vantagem de UrlPrefixes é que uma mensagem de erro é gerada imediatamente para prefixos formatados incorretamente.

    As configurações em UrlPrefixes substituem as configurações em UseUrls/urls/ASPNETCORE_URLS. Portanto, uma vantagem de UseUrls, urls, e a ASPNETCORE_URLS variável de ambiente é que é mais fácil alternar entre Kestrel e HTTP.sys.

    HTTP.sys reconhece dois tipos de curingas na definição de prefixos de URL.

    • * é uma ligação fraca, também conhecida como ligação de fallback. Se o prefixo da URL for http://*:5000, e algo mais estiver vinculado à porta 5000, essa associação não será usada.
    • + é uma forte vinculação. Se o prefixo da URL for http://+:5000, essa associação será usada antes de outras ligações da porta 5000.

    Para obter mais informações, consulte UrlPrefix Strings.

    Warning

    As ligações genéricas de nível superior (http://*:80/ e http://+:80) não devem ser usadas. As ligações curinga de nível superior criam vulnerabilidades na segurança da aplicação. Isso aplica-se tanto a curingas fortes como a fracos. Use nomes de host explícitos ou endereços IP em vez de curingas. A vinculação de curinga de subdomínio (por exemplo, *.mysub.com) não é um risco de segurança se você controlar todo o domínio pai (ao contrário do *.com, que é vulnerável). Para obter mais informações, consulte RFC 9110: Seção 7.2: Host e :authority.

    Aplicativos e contêineres geralmente recebem apenas uma porta para escutar, como a porta 80, sem restrições adicionais, como host ou caminho. HTTP_PORTS e HTTPS_PORTS são chaves de configuração que especificam as portas de escuta para os servidores Kestrel e HTTP.sys. Essas chaves podem ser especificadas como variáveis de ambiente definidas com os prefixos DOTNET_ ou ASPNETCORE_, ou especificadas diretamente por meio de qualquer outra entrada de configuração, como appsettings.json. Cada um é uma lista delimitada por ponto-e-vírgula de valores de porta, conforme mostrado no exemplo a seguir:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    O exemplo anterior é uma abreviação para a configuração a seguir, que especifica o esquema (HTTP ou HTTPS) e qualquer host ou IP.

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

    As chaves de configuração HTTP_PORTS e HTTPS_PORTS são de prioridade mais baixa e são substituídas por URLs ou valores fornecidos diretamente no código. Os certificados ainda precisam ser configurados separadamente por meio de mecânicas específicas do servidor para HTTPS.

    Essas chaves de configuração correspondem às associações curinga de nível superior. Eles são convenientes para cenários de desenvolvimento e contentores, mas evite o uso de curingas ao executar em uma máquina que também possa hospedar outros serviços.

  6. Pré-registrar prefixos de URL no servidor.

    A ferramenta interna para configurar HTTP.sys é netsh.exe. netsh.exe é usado para reservar prefixos de URL e atribuir certificados X.509. A ferramenta requer privilégios de administrador.

    Use a ferramenta netsh.exe para registrar URLs para o aplicativo:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: O URL (Uniform Resource Locator) totalmente qualificado. Não use uma vinculação curinga. Use um nome de host válido ou um endereço IP local. O URL deve incluir uma barra final.
    • <USER>: Especifica o nome do usuário ou grupo de usuários.

    No exemplo a seguir, o endereço IP local do servidor é 10.0.0.4:

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

    Quando um URL é registrado, a ferramenta responde com URL reservation successfully added.

    Para excluir uma URL registrada, use o delete urlacl comando:

    netsh http delete urlacl url=<URL>
    
  7. Registre certificados X.509 no servidor.

    Use a ferramenta netsh.exe para registrar certificados para o aplicativo:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: Especifica o endereço IP local para a ligação. Não use uma vinculação curinga. Use um endereço IP válido.
    • <PORT>: Especifica a porta para a ligação.
    • <THUMBPRINT>: A impressão digital do certificado X.509.
    • <GUID>: Um GUID gerado pelo desenvolvedor para representar o aplicativo para fins informativos.

    Para fins de referência, armazene o GUID no aplicativo como uma tag de pacote:

    • No Visual Studio:
      • Abra as propriedades do projeto do aplicativo clicando com o botão direito do mouse no aplicativo no Gerenciador de Soluções e selecionando Propriedades.
      • Selecione a guia Pacote .
      • Insira o GUID que você criou no campo Tags .
    • Quando não estiver usando o Visual Studio:
      • Abra o arquivo de projeto do aplicativo.

      • Adicione uma <PackageTags> propriedade a uma nova ou existente <PropertyGroup> com o GUID que você criou:

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

    No exemplo a seguir:

    • O endereço IP local do servidor é 10.0.0.4.
    • Um gerador de GUID aleatório online fornece o valor appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Quando um certificado é registrado, a ferramenta responde com SSL Certificate successfully added.

    Para excluir um registro de certificado, use o delete sslcert comando:

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

    Documentação de referência para netsh.exe:

  8. Execute o aplicativo.

    Os privilégios de administrador não são necessários para executar o aplicativo ao vincular ao localhost usando HTTP (não HTTPS) com um número de porta maior que 1024. Para outras configurações (por exemplo, usando um endereço IP local ou vinculando à porta 443), execute o aplicativo com privilégios de administrador.

    O aplicativo responde no endereço IP público do servidor. Neste exemplo, o servidor é alcançado a partir da Internet em seu endereço IP público de 104.214.79.47.

    Um certificado de desenvolvimento é usado neste exemplo. A página é carregada com segurança depois de ignorar o aviso de certificado não confiável do navegador.

    Janela do navegador mostrando a página Índice do aplicativo carregada

Cenários de servidor proxy e balanceador de carga

Para aplicativos hospedados por HTTP.sys que interagem com solicitações da Internet ou de uma rede corporativa, pode ser necessária uma configuração adicional ao hospedar atrás de servidores proxy e balanceadores de carga. Para obter mais informações, consulte Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga.

Obtenha informações detalhadas sobre o tempo com IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature fornece informações detalhadas de tempo para solicitações:

  • Os carimbos de data/hora são obtidos utilizando o QueryPerformanceCounter.
  • A frequência de carimbo de data/hora pode ser obtida através de QueryPerformanceFrequency.
  • O índice do tempo pode ser convertido para HttpSysRequestTimingType para saber o que o tempo representa.
  • O valor pode ser 0 se o tempo não estiver disponível para a solicitação atual.
  • Requer o Windows 10 versão 2004, Windows Server 2022 ou posterior.
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

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

    var timestamps = feature.Timestamps;

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

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

    return next(context);
});

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

app.Run();

IHttpSysRequestTimingFeature.TryGetTimestamp recupera o carimbo de data/hora para o tipo de tempo fornecido:

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 fornece o tempo decorrido entre dois tempos especificados:

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

Recursos avançados de HTTP/2 para suportar gRPC

Recursos adicionais de HTTP/2 no HTTP.sys suportam gRPC, incluindo suporte para trailers de resposta e envio de quadros de redefinição.

Requisitos para executar o gRPC com HTTP.sys:

  • Windows 11 Build 22000 ou posterior, Windows Server 2022 Build 20348 ou posterior.
  • Conexão TLS 1.2 ou posterior.

Trailers

Os trailers HTTP são semelhantes aos cabeçalhos HTTP, exceto que são enviados após o corpo da resposta ser enviado. Para o IIS e o HTTP.sys, apenas trailers de resposta HTTP/2 são suportados.

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

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

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

No código de exemplo anterior:

  • SupportsTrailers garante que os reboques são suportados para a resposta.
  • DeclareTrailer adiciona o nome do trailer fornecido ao cabeçalho de resposta Trailer. Declarar os trailers de uma resposta é opcional, mas recomendado. Se DeclareTrailer for chamado, deve ser antes que os cabeçalhos de resposta sejam enviados.
  • AppendTrailer anexa o trailer.

Reset

Reset permite que o servidor redefina uma solicitação HTTP/2 com um código de erro especificado. Um pedido de reinicialização é considerado abortado.

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

Reset no exemplo de código anterior especifica o código de erro INTERNAL_ERROR. Para obter mais informações sobre códigos de erro HTTP/2, visite a seção código de erro de especificação HTTP/2.

Tracing

Para obter informações sobre como obter registos de HTTP.sys, consulte HTTP.sys Cenários de Gerenciabilidade.

Recursos adicionais