Implementação do servidor Web HTTP.sys no ASP.NET Core

Observação

Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Aviso

Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Importante

Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Por Tom Dykstra e Chris Ross

O HTTP.sys é um servidor Web para ASP.NET Core executado apenas no Windows. O HTTP.sys é uma alternativa ao servidor Kestrel e oferece alguns recursos que o Kestrel não fornece.

Importante

O HTTP.sys não é compatível com o Módulo do ASP.NET Core e não pode ser usado com IIS ou IIS Express.

O HTTP.sys dá suporte aos seguintes recursos:

  • Autenticação do Windows
  • Compartilhamento de porta
  • HTTPS com SNI
  • HTTP/2 sobre TLS (Windows 10 ou posterior)
  • Transmissão direta de arquivo
  • Cache de resposta
  • WebSockets (Windows 8 ou posterior)

Versões do Windows com suporte:

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

Exibir ou baixar código de exemplo (como baixar)

Quando usar o HTTP.sys

O HTTP.sys é útil nas implantações em que:

  • É necessário expor o servidor diretamente à Internet sem usar o IIS.

    O HTTP.sys se comunica diretamente com a Internet

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

    O HTTP.sys se comunica diretamente com a rede interna

O HTTP.sys é uma tecnologia madura que protege contra vários tipos de ataques e proporciona as propriedades de robustez, segurança e escalabilidade de um servidor Web completo. O próprio IIS é executado como um ouvinte HTTP sobre o HTTP.sys.

Suporte do HTTP/2

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

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

O HTTP/2 está habilitado por padrão. Se uma conexão HTTP/2 não tiver sido estabelecida, a conexão retornará para HTTP/1.1. Em uma versão futura do Windows, os sinalizadores de configuração de HTTP/2 estarão disponíveis e contarão com a capacidade de desabilitar o HTTP/2 com HTTP.sys.

Suporte a HTTP/3

O HTTP/3 estará habilitado para aplicativos ASP.NET Core se os seguintes requisitos básicos forem atendidos:

As versões de build anteriores do Windows 11 podem exigir o uso de um build do Windows Insider.

O HTTP/3 for descoberto como uma atualização do HTTP/1.1 ou HTTP/2 por meio do cabeçalho alt-svc. Isso significa que a primeira solicitação normalmente usará HTTP/1.1 ou HTTP/2 antes de alternar para HTTP/3. Http.Sys não adiciona automaticamente o cabeçalho alt-svc; ele deve ser adicionado pelo aplicativo. O código a seguir é 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 dá suporte ao envio de uma mensagem de protocolo HTTP/2 AltSvc em vez de um cabeçalho de resposta para notificar o cliente de que HTTP/3 está disponível. Confira a chave do Registro EnableAltSvc. Isso requer associações netsh sslcert que usam nomes de host em vez de endereços IP.

Autenticação de modo kernel com Kerberos

O HTTP.sys delega à autenticação de modo kernel com o protocolo de autenticação Kerberos. Não há suporte para autenticação de modo de usuário com o Kerberos e o HTTP.sys. A conta do computador precisa ser usada para descriptografar o token/tíquete do Kerberos que é obtido do Active Directory e encaminhado pelo cliente ao servidor para autenticar o usuário. Registre o SPN (nome da entidade de serviço) do host, não do usuário do aplicativo.

Suporte para buffer de resposta no modo kernel

Em alguns cenários, grandes volumes de gravações pequenas com alta latência podem causar um impacto significativo no desempenho de HTTP.sys. Esse impacto ocorre devido à falta de um buffer 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 habilitado por um aplicativo que faz E/S síncrona ou E/S assíncrona com não mais de uma gravação pendente por vez. Nesses cenários, o buffer de resposta pode melhorar significativamente a taxa de transferência em relação a 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. Habilitar esse sinalizador pode resultar em maior uso de CPU e memória por HTTP.Sys.

Como usar o HTTP.sys

Configurar o aplicativo ASP.NET Core para usar o HTTP.sys

Chame o método de extensão UseHttpSys ao compilar o host, especificando qualquer HttpSysOptions necessária. O exemplo a seguir define as 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 adicional do HTTP.sys é tratada por meio das configurações do registro.

Para obter mais informações sobre as opções HTTP.sys, confira HttpSysOptions.

MaxRequestBodySize

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

O método recomendado para substituir o limite em um aplicativo ASP.NET Core MVC para um único IActionResult é usar o atributo RequestSizeLimitAttribute em um método de ação:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Uma exceção é gerada quando o aplicativo tenta configurar o limite de uma solicitação, depois que o aplicativo inicia a leitura da solicitação. É possível usar uma propriedade IsReadOnly para indicar se a propriedade MaxRequestBodySize está no estado somente leitura, o que significa que é tarde demais para configurar o limite.

Se o aplicativo precisar substituir MaxRequestBodySize mediante solicitação, use 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);
});

Quando usar o Visual Studio, verifique se que o aplicativo está configurado para executar o IIS ou IIS Express.

No Visual Studio, o perfil de inicialização padrão destina-se ao 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 o perfil do aplicativo de console

Configurar o Windows Server

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

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

  3. Obtenha e instale os certificados X.509, se precisar.

    No Windows, crie certificados autoassinados, usando o cmdlet do PowerShell New-SelfSignedCertificate. Para ver um exemplo sem suporte, confira UpdateIISExpressSSLForChrome.ps1.

    Instale certificados autoassinados ou assinados pela AC no repositório Computador Local>Pessoal do servidor.

  4. Se o aplicativo for uma implantação dependente de estrutura, instale o .NET Core, o .NET Framework ou ambos (caso o aplicativo .NET Core seja direcionado ao .NET Framework).

    • .NET Core: se o aplicativo exigir o .NET Core, obtenha e execute o instalador do .NET Core Runtime em Downloads do .NET Core. Não instale o SDK completo no servidor.
    • .NET Framework: se o aplicativo exigir o .NET Framework, confira 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 Core.

    Se o aplicativo for uma implantação autocontida, ele incluirá o runtime em sua implantação. Nenhuma instalação do framework é necessária no servidor.

  5. Configure URLs e portas no aplicativo.

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

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

    O exemplo de código a seguir mostra como usar UrlPrefixes com o endereço IP local do servidor 10.0.0.4 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 usar UrlPrefixes é que uma mensagem de erro é gerada imediatamente no caso de prefixos formatados de forma incorreta.

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

    O HTTP.sys reconhece dois tipos de curingas em prefixos de URL:

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

    Para obter mais informações, consulte Cadeias de caracteres UrlPrefix.

    Aviso

    Associações de curinga de nível superior (http://*:80/ e http://+:80) não devem ser usadas. Associações de curinga de nível superior criam vulnerabilidades de segurança no aplicativo. Isso se aplica a curingas fortes e fracos. Use nomes de host explícitos ou endereços IP em vez de curingas. Associações de curinga de subdomínio (por exemplo, *.mysub.com) não serão um risco à segurança se você controlar todo o domínio pai (ao contrário de *.com, o qual é vulnerável). Para obter mais informações, confira RFC 9110: Seção 7.2: Host e :authority.

    Aplicativos e contêineres geralmente recebem apenas uma porta para escutar, por exemplo, 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 HTTP.sys e Kestrel. Essas chaves podem ser especificadas como variáveis de ambiente definidas com os prefixos DOTNET_ ou ASPNETCORE_, ou especificadas diretamente por meio de outra entrada de configuração, como appsettings.json. Cada uma delas é uma lista delimitada por ponto e vírgula de valores de porta, conforme mostrado no exemplo abaixo:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    O exemplo anterior é uma abreviação da 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 menor prioridade 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ânica específica do servidor para HTTPS.

    Essas chaves de configuração são equivalentes a associações curinga de nível superior. Elas são convenientes para cenários de desenvolvimento e contêiner, mas evitam caracteres curinga quando executadas em um computador que também pode hospedar outros serviços.

  6. Pré-registre os prefixos de URL no servidor.

    O netsh.exe é a ferramenta interna destinada a configurar o HTTP.sys. Com o netsh.exe, é possível reservar prefixos de URL e atribuir certificados X.509. A ferramenta exige privilégios de administrador.

    Use a ferramenta netsh.exe para registrar as URLs do aplicativo:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: a URL (Uniform Resource Locator) totalmente qualificada. Não use uma associação de curinga. Use um nome de host válido ou o endereço IP local. A URL deve incluir uma barra à direita.
    • <USER>: especifica o nome de usuário ou do 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 uma URL é registrada, a ferramenta responde com URL reservation successfully added.

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

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

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

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: especifica o endereço IP local para a associação. Não use uma associação de curinga. Use um endereço IP válido.
    • <PORT>: especifica a porta para a associação.
    • <THUMBPRINT>: a impressão digital do certificado de cliente 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 marca 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 Marcas.
    • Quando não estiver usando o Visual Studio:
      • Abra o arquivo de projeto do aplicativo.

      • Adicione uma propriedade <PackageTags> a um <PropertyGroup> novo ou existente 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 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 comando delete sslcert:

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

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

  8. Execute o aplicativo.

    Não é necessário ter privilégios de administrador para executar o aplicativo ao associar ao localhost usando HTTP (não HTTPS) com um número de porta maior do que 1024. Para outras configurações (por exemplo, usar um endereço IP local ou associação à 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 é acessado pela Internet como 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 após ignorar o aviso de certificado não confiável do navegador.

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

Servidor proxy e cenários de balanceador de carga

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

Obter informações detalhadas de tempo com IHttpSysRequestTimingFeature

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

  • Os carimbos de data/hora são obtidos por meio deQueryPerformanceCounter.
  • A frequência de carimbo de data/hora pode ser obtida por meio de QueryPerformanceFrequency.
  • O índice do tempo pode ser convertido em HttpSysRequestTimingType para saber o que o tempo representa.
  • O valor poderá ser 0 se o tempo não estiver disponível para a solicitação atual.
  • Exige 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 dá o tempo decorrido entre dois intervalos 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 HTTP/2 avançados para dar suporte a gRPC

Os recursos HTTP/2 adicionais em HTTP.sys dão suporte a 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 por serem enviados após o corpo da resposta ser enviado. Para IIS e HTTP.sys, há suporte apenas para trailers de resposta HTTP/2.

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 trailers sejam compatíveis com 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, deverá ser antes que os cabeçalhos de resposta sejam enviados.
  • O AppendTrailer acrescenta o trailer.

Redefinir

A opção Redefinir permite que o servidor redefina uma solicitação HTTP/2 com um código de erro especificado. Uma solicitação de redefinição é considerada anulada.

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 de código de erro de especificação HTTP/2.

Rastreamento

Para obter informações sobre como obter rastreamentos de HTTP.sys, consulte Cenários de capacidade de gerenciamento de HTTP.sys.

Recursos adicionais

O HTTP.sys é um servidor Web para ASP.NET Core executado apenas no Windows. O HTTP.sys é uma alternativa ao servidor Kestrel e oferece alguns recursos que o Kestrel não fornece.

Importante

O HTTP.sys não é compatível com o Módulo do ASP.NET Core e não pode ser usado com IIS ou IIS Express.

O HTTP.sys dá suporte aos seguintes recursos:

  • Autenticação do Windows
  • Compartilhamento de porta
  • HTTPS com SNI
  • HTTP/2 sobre TLS (Windows 10 ou posterior)
  • Transmissão direta de arquivo
  • Cache de resposta
  • WebSockets (Windows 8 ou posterior)

Versões do Windows com suporte:

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

Exibir ou baixar código de exemplo (como baixar)

Quando usar o HTTP.sys

O HTTP.sys é útil nas implantações em que:

  • É necessário expor o servidor diretamente à Internet sem usar o IIS.

    O HTTP.sys se comunica diretamente com a Internet

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

    O HTTP.sys se comunica diretamente com a rede interna

O HTTP.sys é uma tecnologia madura que protege contra vários tipos de ataques e proporciona as propriedades de robustez, segurança e escalabilidade de um servidor Web completo. O próprio IIS é executado como um ouvinte HTTP sobre o HTTP.sys.

Suporte do HTTP/2

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

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

O HTTP/2 está habilitado por padrão. Se uma conexão HTTP/2 não tiver sido estabelecida, a conexão retornará para HTTP/1.1. Em uma versão futura do Windows, os sinalizadores de configuração de HTTP/2 estarão disponíveis e contarão com a capacidade de desabilitar o HTTP/2 com HTTP.sys.

Suporte a HTTP/3

O HTTP/3 estará habilitado para aplicativos ASP.NET Core se os seguintes requisitos básicos forem atendidos:

As versões de build anteriores do Windows 11 podem exigir o uso de um build do Windows Insider.

O HTTP/3 for descoberto como uma atualização do HTTP/1.1 ou HTTP/2 por meio do cabeçalho alt-svc. Isso significa que a primeira solicitação normalmente usará HTTP/1.1 ou HTTP/2 antes de alternar para HTTP/3. Http.Sys não adiciona automaticamente o cabeçalho alt-svc; ele deve ser adicionado pelo aplicativo. O código a seguir é 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 dá suporte ao envio de uma mensagem de protocolo HTTP/2 AltSvc em vez de um cabeçalho de resposta para notificar o cliente de que HTTP/3 está disponível. Confira a chave do Registro EnableAltSvc. Isso requer associações netsh sslcert que usam nomes de host em vez de endereços IP.

Autenticação de modo kernel com Kerberos

O HTTP.sys delega à autenticação de modo kernel com o protocolo de autenticação Kerberos. Não há suporte para autenticação de modo de usuário com o Kerberos e o HTTP.sys. A conta do computador precisa ser usada para descriptografar o token/tíquete do Kerberos que é obtido do Active Directory e encaminhado pelo cliente ao servidor para autenticar o usuário. Registre o SPN (nome da entidade de serviço) do host, não do usuário do aplicativo.

Como usar o HTTP.sys

Configurar o aplicativo ASP.NET Core para usar o HTTP.sys

Chame o método de extensão UseHttpSys ao compilar o host, especificando qualquer HttpSysOptions necessária. O exemplo a seguir define as 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 adicional do HTTP.sys é tratada por meio das configurações do registro.

Para obter mais informações sobre as opções HTTP.sys, confira HttpSysOptions.

MaxRequestBodySize

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

O método recomendado para substituir o limite em um aplicativo ASP.NET Core MVC para um único IActionResult é usar o atributo RequestSizeLimitAttribute em um método de ação:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Uma exceção é gerada quando o aplicativo tenta configurar o limite de uma solicitação, depois que o aplicativo inicia a leitura da solicitação. É possível usar uma propriedade IsReadOnly para indicar se a propriedade MaxRequestBodySize está no estado somente leitura, o que significa que é tarde demais para configurar o limite.

Se o aplicativo precisar substituir MaxRequestBodySize mediante solicitação, use 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();
    });
}

Quando usar o Visual Studio, verifique se que o aplicativo está configurado para executar o IIS ou IIS Express.

No Visual Studio, o perfil de inicialização padrão destina-se ao 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 o perfil do aplicativo de console

Configurar o Windows Server

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

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

  3. Obtenha e instale os certificados X.509, se precisar.

    No Windows, crie certificados autoassinados, usando o cmdlet do PowerShell New-SelfSignedCertificate. Para ver um exemplo sem suporte, confira UpdateIISExpressSSLForChrome.ps1.

    Instale certificados autoassinados ou assinados pela AC no repositório Computador Local>Pessoal do servidor.

  4. Se o aplicativo for uma implantação dependente de estrutura, instale o .NET Core, o .NET Framework ou ambos (caso o aplicativo .NET Core seja direcionado ao .NET Framework).

    • .NET Core: se o aplicativo exigir o .NET Core, obtenha e execute o instalador do .NET Core Runtime em Downloads do .NET Core. Não instale o SDK completo no servidor.
    • .NET Framework: se o aplicativo exigir o .NET Framework, confira 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 Core.

    Se o aplicativo for uma implantação autocontida, ele incluirá o runtime em sua implantação. Nenhuma instalação do framework é necessária no servidor.

  5. Configure URLs e portas no aplicativo.

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

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

    O exemplo de código a seguir mostra como usar UrlPrefixes com o endereço IP local do servidor 10.0.0.4 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 usar UrlPrefixes é que uma mensagem de erro é gerada imediatamente no caso de prefixos formatados de forma incorreta.

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

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

    Aviso

    Associações de curinga de nível superior (http://*:80/ e http://+:80) não devem ser usadas. Associações de curinga de nível superior criam vulnerabilidades de segurança no aplicativo. Isso se aplica a curingas fortes e fracos. Use nomes de host explícitos ou endereços IP em vez de curingas. Associações de curinga de subdomínio (por exemplo, *.mysub.com) não serão um risco à segurança se você controlar todo o domínio pai (ao contrário de *.com, o qual é vulnerável). Para obter mais informações, confira RFC 9110: Seção 7.2: Host e :authority.

  6. Pré-registre os prefixos de URL no servidor.

    O netsh.exe é a ferramenta interna destinada a configurar o HTTP.sys. Com o netsh.exe, é possível reservar prefixos de URL e atribuir certificados X.509. A ferramenta exige privilégios de administrador.

    Use a ferramenta netsh.exe para registrar as URLs do aplicativo:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: a URL (Uniform Resource Locator) totalmente qualificada. Não use uma associação de curinga. Use um nome de host válido ou o endereço IP local. A URL deve incluir uma barra à direita.
    • <USER>: especifica o nome de usuário ou do 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 uma URL é registrada, a ferramenta responde com URL reservation successfully added.

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

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

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

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: especifica o endereço IP local para a associação. Não use uma associação de curinga. Use um endereço IP válido.
    • <PORT>: especifica a porta para a associação.
    • <THUMBPRINT>: a impressão digital do certificado de cliente 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 marca 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 Marcas.
    • Quando não estiver usando o Visual Studio:
      • Abra o arquivo de projeto do aplicativo.

      • Adicione uma propriedade <PackageTags> a um <PropertyGroup> novo ou existente 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 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 comando delete sslcert:

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

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

  8. Execute o aplicativo.

    Não é necessário ter privilégios de administrador para executar o aplicativo ao associar ao localhost usando HTTP (não HTTPS) com um número de porta maior do que 1024. Para outras configurações (por exemplo, usar um endereço IP local ou associação à 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 é acessado pela Internet como 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 após ignorar o aviso de certificado não confiável do navegador.

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

Servidor proxy e cenários de balanceador de carga

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

Recursos HTTP/2 avançados para dar suporte a gRPC

Os recursos HTTP/2 adicionais em HTTP.sys dão suporte a 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 por serem enviados após o corpo da resposta ser enviado. Para IIS e HTTP.sys, há suporte apenas para trailers de resposta HTTP/2.

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 trailers sejam compatíveis com 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, deverá ser antes que os cabeçalhos de resposta sejam enviados.
  • O AppendTrailer acrescenta o trailer.

Redefinir

A opção Redefinir permite que o servidor redefina uma solicitação HTTP/2 com um código de erro especificado. Uma solicitação de redefinição é considerada anulada.

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 de código de erro de especificação HTTP/2.

Recursos adicionais

O HTTP.sys é um servidor Web para ASP.NET Core executado apenas no Windows. O HTTP.sys é uma alternativa ao servidor Kestrel e oferece alguns recursos que o Kestrel não fornece.

Importante

O HTTP.sys não é compatível com o Módulo do ASP.NET Core e não pode ser usado com IIS ou IIS Express.

O HTTP.sys dá suporte aos seguintes recursos:

  • Autenticação do Windows
  • Compartilhamento de porta
  • HTTPS com SNI
  • HTTP/2 sobre TLS (Windows 10 ou posterior)
  • Transmissão direta de arquivo
  • Cache de resposta
  • WebSockets (Windows 8 ou posterior)

Versões do Windows com suporte:

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

Exibir ou baixar código de exemplo (como baixar)

Quando usar o HTTP.sys

O HTTP.sys é útil nas implantações em que:

  • É necessário expor o servidor diretamente à Internet sem usar o IIS.

    O HTTP.sys se comunica diretamente com a Internet

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

    O HTTP.sys se comunica diretamente com a rede interna

O HTTP.sys é uma tecnologia madura que protege contra vários tipos de ataques e proporciona as propriedades de robustez, segurança e escalabilidade de um servidor Web completo. O próprio IIS é executado como um ouvinte HTTP sobre o HTTP.sys.

Suporte do HTTP/2

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

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

O HTTP/2 está habilitado por padrão. Se uma conexão HTTP/2 não tiver sido estabelecida, a conexão retornará para HTTP/1.1. Em uma versão futura do Windows, os sinalizadores de configuração de HTTP/2 estarão disponíveis e contarão com a capacidade de desabilitar o HTTP/2 com HTTP.sys.

Autenticação de modo kernel com Kerberos

O HTTP.sys delega à autenticação de modo kernel com o protocolo de autenticação Kerberos. Não há suporte para autenticação de modo de usuário com o Kerberos e o HTTP.sys. A conta do computador precisa ser usada para descriptografar o token/tíquete do Kerberos que é obtido do Active Directory e encaminhado pelo cliente ao servidor para autenticar o usuário. Registre o SPN (nome da entidade de serviço) do host, não do usuário do aplicativo.

Como usar o HTTP.sys

Configurar o aplicativo ASP.NET Core para usar o HTTP.sys

Chame o método de extensão UseHttpSys ao compilar o host, especificando qualquer HttpSysOptions necessária. O exemplo a seguir define as 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 adicional do HTTP.sys é tratada por meio das configurações do registro.

Opções do HTTP.sys

Propriedade Descrição Padrão
AllowSynchronousIO Controlar quando a Entrada/Saída síncrona deve ser permitida para HttpContext.Request.Body e HttpContext.Response.Body. false
Authentication.AllowAnonymous Permitir solicitações anônimas. true
Authentication.Schemes Especificar os esquemas de autenticação permitidos. É possível modificar a qualquer momento antes de descartar o ouvinte. Os valores são fornecidos pela enumeração AuthenticationSchemes: Basic, Kerberos, Negotiate, None e NTLM. None
EnableResponseCaching Tentativa de cache do modo kernel para obtenção de respostas com cabeçalhos qualificados. A resposta pode não incluir Set-Cookie, Vary ou cabeçalhos Pragma. Ela deve incluir um cabeçalho Cache-Control que seja public e um valor shared-max-age ou max-age, ou um cabeçalho Expires. true
Http503Verbosity O comportamento do HTTP.sys ao rejeitar solicitações devido a condições de limitação. Http503VerbosityLevel.
Básico
MaxAccepts O número máximo de aceitações simultâneas. 5 × ambiente de .
ProcessorCount
MaxConnections O número máximo de conexões simultâneas a serem aceitas. Usar -1 como infinito. Usar null a fim de usar a configuração que abranja toda máquina do registro. null
(configuração
de todo o computador)
MaxRequestBodySize Confira a seção MaxRequestBodySize. 30.000.000 de bytes
(28,6 MB)
RequestQueueLimit O número máximo de solicitações que podem ser colocadas na fila. 1000
RequestQueueMode Isso indica se o servidor é responsável por criar e configurar a fila de solicitações ou se deve ser anexado a uma fila existente.
A maioria das opções de configuração existentes não se aplica ao processo de se anexar a uma fila existente.
RequestQueueMode.Create
RequestQueueName O nome da fila de solicitação HTTP.sys. null (Fila anônima)
ThrowWriteExceptions Indica se as gravações do corpo da resposta que falham quando o cliente se desconecta devem gerar exceções ou serem concluídas normalmente. false
(concluir normalmente)
Timeouts Expor a configuração TimeoutManager do HTTP.sys, que também pode ser configurado no Registro. Siga os links de API para saber mais sobre cada configuração, inclusive os valores padrão:
UrlPrefixes Especifique o UrlPrefixCollection para registrar com o HTTP.sys. A mais útil é UrlPrefixCollection.Add, que é usada para adicionar um prefixo à coleção. É possível modificá-las a qualquer momento antes de descartar o ouvinte.

MaxRequestBodySize

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

O método recomendado para substituir o limite em um aplicativo ASP.NET Core MVC para um único IActionResult é usar o atributo RequestSizeLimitAttribute em um método de ação:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Uma exceção é gerada quando o aplicativo tenta configurar o limite de uma solicitação, depois que o aplicativo inicia a leitura da solicitação. É possível usar uma propriedade IsReadOnly para indicar se a propriedade MaxRequestBodySize está no estado somente leitura, o que significa que é tarde demais para configurar o limite.

Se o aplicativo precisar substituir MaxRequestBodySize mediante solicitação, use 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();
    });
}

Quando usar o Visual Studio, verifique se que o aplicativo está configurado para executar o IIS ou IIS Express.

No Visual Studio, o perfil de inicialização padrão destina-se ao 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 o perfil do aplicativo de console

Configurar o Windows Server

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

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

  3. Obtenha e instale os certificados X.509, se precisar.

    No Windows, crie certificados autoassinados, usando o cmdlet do PowerShell New-SelfSignedCertificate. Para ver um exemplo sem suporte, confira UpdateIISExpressSSLForChrome.ps1.

    Instale certificados autoassinados ou assinados pela AC no repositório Computador Local>Pessoal do servidor.

  4. Se o aplicativo for uma implantação dependente de estrutura, instale o .NET Core, o .NET Framework ou ambos (caso o aplicativo .NET Core seja direcionado ao .NET Framework).

    • .NET Core: se o aplicativo exigir o .NET Core, obtenha e execute o instalador do .NET Core Runtime em Downloads do .NET Core. Não instale o SDK completo no servidor.
    • .NET Framework: se o aplicativo exigir o .NET Framework, confira 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 Core.

    Se o aplicativo for uma implantação autocontida, ele incluirá o runtime em sua implantação. Nenhuma instalação do framework é necessária no servidor.

  5. Configure URLs e portas no aplicativo.

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

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

    O exemplo de código a seguir mostra como usar UrlPrefixes com o endereço IP local do servidor 10.0.0.4 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 usar UrlPrefixes é que uma mensagem de erro é gerada imediatamente no caso de prefixos formatados de forma incorreta.

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

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

    Aviso

    Associações de curinga de nível superior (http://*:80/ e http://+:80) não devem ser usadas. Associações de curinga de nível superior criam vulnerabilidades de segurança no aplicativo. Isso se aplica a curingas fortes e fracos. Use nomes de host explícitos ou endereços IP em vez de curingas. Associações de curinga de subdomínio (por exemplo, *.mysub.com) não serão um risco à segurança se você controlar todo o domínio pai (ao contrário de *.com, o qual é vulnerável). Para obter mais informações, confira RFC 9110: Seção 7.2: Host e :authority.

  6. Pré-registre os prefixos de URL no servidor.

    O netsh.exe é a ferramenta interna destinada a configurar o HTTP.sys. Com o netsh.exe, é possível reservar prefixos de URL e atribuir certificados X.509. A ferramenta exige privilégios de administrador.

    Use a ferramenta netsh.exe para registrar as URLs do aplicativo:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: a URL (Uniform Resource Locator) totalmente qualificada. Não use uma associação de curinga. Use um nome de host válido ou o endereço IP local. A URL deve incluir uma barra à direita.
    • <USER>: especifica o nome de usuário ou do 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 uma URL é registrada, a ferramenta responde com URL reservation successfully added.

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

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

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

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: especifica o endereço IP local para a associação. Não use uma associação de curinga. Use um endereço IP válido.
    • <PORT>: especifica a porta para a associação.
    • <THUMBPRINT>: a impressão digital do certificado de cliente 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 marca 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 Marcas.
    • Quando não estiver usando o Visual Studio:
      • Abra o arquivo de projeto do aplicativo.

      • Adicione uma propriedade <PackageTags> a um <PropertyGroup> novo ou existente 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 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 comando delete sslcert:

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

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

  8. Execute o aplicativo.

    Não é necessário ter privilégios de administrador para executar o aplicativo ao associar ao localhost usando HTTP (não HTTPS) com um número de porta maior do que 1024. Para outras configurações (por exemplo, usar um endereço IP local ou associação à 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 é acessado pela Internet como 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 após ignorar o aviso de certificado não confiável do navegador.

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

Servidor proxy e cenários de balanceador de carga

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

Recursos HTTP/2 avançados para dar suporte a gRPC

Os recursos HTTP/2 adicionais em HTTP.sys dão suporte a gRPC, incluindo suporte para trailers de resposta e envio de quadros de redefinição.

Requisitos para executar o gRPC com HTTP.sys:

  • Windows 10, build do sistema operacional 19041.508 ou posterior
  • Conexão TLS 1.2 ou posterior

Trailers

Os trailers HTTP são semelhantes aos cabeçalhos HTTP, exceto por serem enviados após o corpo da resposta ser enviado. Para IIS e HTTP.sys, há suporte apenas para trailers de resposta HTTP/2.

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 trailers sejam compatíveis com 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, deverá ser antes que os cabeçalhos de resposta sejam enviados.
  • O AppendTrailer acrescenta o trailer.

Redefinir

A opção Redefinir permite que o servidor redefina uma solicitação HTTP/2 com um código de erro especificado. Uma solicitação de redefinição é considerada anulada.

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 de código de erro de especificação HTTP/2.

Recursos adicionais