KestrelImplementação do servidor Web no ASP.NET Core

Por Tom Dykstra, Chris Ross e Stephen Halter

Kestrelé um servidor Web multiplataforma para ASP.NET Core. Kestrelé o servidor Web incluído e habilitado por padrão em ASP.NET Core modelos de projeto.

Kestrel oferece suporte aos seguintes cenários:

  • HTTPS
  • HTTP/2 (exceto no macOS†)
  • Atualização do Opaque usado para habilitar o WebSockets
  • Soquetes do UNIX para alto desempenho protegidos pelo Nginx

†HTTP/2 terá suporte no macOS em uma versão futura.

Kestrel há suporte em todas as plataformas e versões compatíveis com o .NET Core.

Introdução

ASP.NET Core modelos de projeto usam Kestrel por padrão quando não são hospedados com o IIS. No seguinte modelo gerado Program.cs, o WebApplication.CreateBuilder método chama UseKestrel internamente:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Para obter mais informações sobre como WebApplication configurar e WebApplicationBuilder, consulte a visão geral de APIs mínimas.

Certificados de cliente opcionais

Para obter informações sobre aplicativos que devem proteger um subconjunto do aplicativo com um certificado, consulte certificados de cliente opcionais.

Recursos adicionais

Observação

A partir de ASP.NET Core 5.0, Kestrelo transporte libuv está obsoleto. O transporte libuv não recebe atualizações para dar suporte a novas plataformas do sistema operacional, como o Windows ARM64, e será removido em uma versão futura. Remova todas as chamadas para o método obsoleto e use Kestrelo transporte de soquete UseLibuv padrão.

Kestrelé um servidor Web multiplataforma para ASP.NET Core. Kestrelé o servidor Web incluído e habilitado por padrão em ASP.NET Core modelos de projeto.

Kestrel oferece suporte aos seguintes cenários:

  • HTTPS
  • HTTP/2 (exceto no macOS†)
  • Atualização do Opaque usado para habilitar o WebSockets
  • Soquetes do UNIX para alto desempenho protegidos pelo Nginx

†HTTP/2 terá suporte no macOS em uma versão futura.

Kestrel há suporte em todas as plataformas e versões compatíveis com o .NET Core.

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

Introdução

ASP.NET Core modelos de projeto usam Kestrel por padrão quando não são hospedados com o IIS. In Program.cs, o ConfigureWebHostDefaults método chama UseKestrel:

public static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Para obter mais informações sobre como criar o host, consulte as seções Configurar um host e configurações de construtor padrão do Host Genérico .NET no ASP.NET Core.

Certificados de cliente opcionais

Para obter informações sobre aplicativos que devem proteger um subconjunto do aplicativo com um certificado, consulte certificados de cliente opcionais.

Recursos adicionais

Observação

A partir de ASP.NET Core 5.0, Kestrelo transporte libuv está obsoleto. O transporte libuv não recebe atualizações para dar suporte a novas plataformas do sistema operacional, como o Windows ARM64, e será removido em uma versão futura. Remova todas as chamadas para o método obsoleto e use Kestrelo transporte de soquete UseLibuv padrão.

Kestrelé um servidor Web multiplataforma para ASP.NET Core. Kestrelé o servidor Web incluído por padrão em ASP.NET Core modelos de projeto.

Kestrel oferece suporte aos seguintes cenários:

  • HTTPS
  • Atualização do Opaque usado para habilitar o WebSockets
  • Soquetes do UNIX para alto desempenho protegidos pelo Nginx
  • HTTP/2 (exceto no macOS†)

†HTTP/2 terá suporte no macOS em uma versão futura.

Kestrel há suporte em todas as plataformas e versões compatíveis com o .NET Core.

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

Suporte do HTTP/2

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

  • Sistema operacional†
    • Windows Server 2016/Windows 10 ou posterior‡
    • Linux com OpenSSL 1.0.2 ou posterior (por exemplo, Ubuntu 16.04 ou posterior)
  • Estrutura de destino: .NET Core 2.2 ou posterior
  • Conexão ALPN (Negociação de protocolo de camada de aplicativo)
  • Conexão TLS 1.2 ou posterior

†HTTP/2 terá suporte no macOS em uma versão futura. Kestrel‡ tem suporte limitado para HTTP/2 em Windows Server 2012 R2 e Windows 8.1. O suporte é limitado porque a lista de conjuntos de codificação TLS disponível nesses sistemas operacionais é limitada. Um certificado gerado usando um ECDSA (Algoritmo de Assinatura Digital Curva Elíptica) pode ser necessário para proteger conexões TLS.

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

A partir do .NET Core 3.0, HTTP/2 está habilitado por padrão. Para obter mais informações sobre configuração, consulte as opções e seções KestrelListenOptions.Protocols.

Quando usar Kestrel com um proxy reverso

Kestrel pode ser usado por si mesmo ou com um servidor proxy reverso. Um servidor proxy reverso recebe solicitações HTTP da rede e as encaminha para Kestrel. Exemplos de um servidor proxy reverso incluem:

Kestrel usado como um servidor Web de borda (voltado para a Internet):

Kestrel comunica-se diretamente com a Internet sem um servidor proxy reverso

Kestrel usado em uma configuração de proxy reverso:

Kestrel comunica-se indiretamente com a Internet por meio de um servidor proxy reverso, como IIS, Nginx ou Apache

A configuração, com ou sem um servidor proxy reverso, é uma configuração de hospedagem com suporte.

Kestrel usado como um servidor de borda sem um servidor proxy reverso não dá suporte ao compartilhamento do mesmo IP e porta entre vários processos. Quando Kestrel está configurado para escutar em uma porta, Kestrel manipula todo o tráfego para essa porta, independentemente dos cabeçalhos das Host solicitações. Um proxy reverso que pode compartilhar portas tem a capacidade de encaminhar solicitações em Kestrel um IP e porta exclusivos.

Mesmo se um servidor proxy reverso não for necessário, o uso de um servidor proxy reverso poderá ser uma boa opção.

Um proxy reverso:

  • Pode limitar a área da superfície pública exposta dos aplicativos que ele hospeda.
  • Fornece uma camada adicional de configuração e proteção.
  • Pode ser integrado melhor à infraestrutura existente.
  • Simplifica o balanceamento de carga e a configuração de comunicação segura (HTTPS). Somente o servidor proxy reverso requer um certificado X.509 e esse servidor pode se comunicar com os servidores do aplicativo na rede interna usando HTTP sem formatação.

Aviso

A hospedagem em uma configuração de proxy reverso requer a configuração de Middleware de Cabeçalhos Encaminhados.

Kestrelem aplicativos ASP.NET Core

ASP.NET Core modelos de projeto são usados Kestrel por padrão. In Program.cs, o ConfigureWebHostDefaults método chama UseKestrel:

public static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Para obter mais informações sobre como criar o host, consulte as seções Configurar um host e configurações de construtor padrão do Host Genérico .NET no ASP.NET Core.

Para fornecer configuração adicional após chamar ConfigureWebHostDefaults, use ConfigureKestrel:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

Kestrel options

O Kestrel servidor Web tem opções de configuração de restrição que são especialmente úteis em implantações voltadas para a Internet.

Defina restrições sobre a propriedade Limits da classe KestrelServerOptions. A propriedade Limits contém uma instância da classe KestrelServerLimits.

Os exemplos a seguir usam o namespace Microsoft.AspNetCore.Server.Kestrel.Core:

using Microsoft.AspNetCore.Server.Kestrel.Core;

Em exemplos mostrados posteriormente neste artigo, Kestrel as opções são configuradas no código C#. Kestrel as opções também podem ser definidas usando um provedor de configuração. Por exemplo, o Provedor de Configuração de Arquivos pode carregar Kestrel a configuração de um appsettings.json ou appsettings.{Environment}.json arquivo:

{
  "Kestrel": {
    "Limits": {
      "MaxConcurrentConnections": 100,
      "MaxConcurrentUpgradedConnections": 100
    },
    "DisableStringReuse": true
  }
}

Observação

KestrelServerOptions e a configuração de ponto de extremidade são configuráveis de provedores de configuração. A configuração restante Kestrel deve ser configurada no código C#.

Use uma das seguintes abordagens:

  • Configurar Kestrel em Startup.ConfigureServices:

    1. Injete uma instância da IConfigurationStartup classe. O exemplo a seguir pressupõe que a configuração injetada seja atribuída à Configuration propriedade.

    2. Em Startup.ConfigureServices, carregue a Kestrel seção de configuração na Kestrelconfiguração de 's:

      using Microsoft.Extensions.Configuration
      
      public class Startup
      {
          public Startup(IConfiguration configuration)
          {
              Configuration = configuration;
          }
      
          public IConfiguration Configuration { get; }
      
          public void ConfigureServices(IServiceCollection services)
          {
              services.Configure<KestrelServerOptions>(
                  Configuration.GetSection("Kestrel"));
          }
      
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              ...
          }
      }
      
  • Kestrel Configurar ao criar o host:

    Em Program.cs, carregue a Kestrel seção de configuração na Kestrelconfiguração de 's:

    // using Microsoft.Extensions.DependencyInjection;
    
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((context, services) =>
            {
                services.Configure<KestrelServerOptions>(
                    context.Configuration.GetSection("Kestrel"));
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    

Ambas as abordagens anteriores funcionam com qualquer provedor de configuração.

Tempo limite de keep-alive

KeepAliveTimeout

Obtém ou define o tempo limite de keep-alive. O padrão é de dois minutos.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Número máximo de conexões de cliente

MaxConcurrentConnections MaxConcurrentUpgradedConnections

O número máximo de conexões TCP abertas simultâneas pode ser definido para o aplicativo inteiro com o código a seguir:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Há um limite separado para conexões que foram atualizadas do HTTP ou HTTPS para outro protocolo (por exemplo, em uma solicitação do WebSockets). Depois que uma conexão é atualizada, ela não é contada em relação ao limite de MaxConcurrentConnections.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

O número máximo de conexões é ilimitado (nulo) por padrão.

Tamanho máximo do corpo da solicitação

MaxRequestBodySize

O tamanho máximo do corpo da solicitação padrão é de 30.000.000 bytes, que equivale aproximadamente a 28,6 MB.

A abordagem recomendada para substituir o limite em um aplicativo ASP.NET Core MVC é usar o atributo RequestSizeLimitAttribute em um método de ação:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Aqui está um exemplo que mostra como configurar a restrição para o aplicativo em cada solicitação:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Substitua a configuração em uma solicitação específica no middleware:

app.Run(async (context) =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>()
        .MaxRequestBodySize = 10 * 1024;

    var minRequestRateFeature = 
        context.Features.Get<IHttpMinRequestBodyDataRateFeature>();
    var minResponseRateFeature = 
        context.Features.Get<IHttpMinResponseDataRateFeature>();

    if (minRequestRateFeature != null)
    {
        minRequestRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

    if (minResponseRateFeature != null)
    {
        minResponseRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

Uma exceção será gerada se o aplicativo configurar o limite em uma solicitação depois que o aplicativo começar a ler a solicitação. Há uma propriedade IsReadOnly que indica se a propriedade MaxRequestBodySize está no estado somente leitura, o que significa que é tarde demais para configurar o limite.

Quando um aplicativo é executado fora do processo por trás do Módulo ASP.NET Core, Kestrelo limite de tamanho do corpo da solicitação é desabilitado porque o IIS já define o limite.

Taxa de dados mínima do corpo da solicitação

MinRequestBodyDataRate MinResponseDataRate

Kestrel verifica a cada segundo se os dados estão chegando à taxa especificada em bytes/segundo. Se a taxa cair abaixo do mínimo, a conexão será cronometrada. O período de carência é a quantidade de tempo que Kestrel dá ao cliente para aumentar sua taxa de envio até o mínimo; a taxa não é verificada durante esse período. O período de cortesia ajuda a evitar a remoção de conexões que inicialmente enviam dados em uma taxa baixa devido ao início lento do TCP.

A taxa mínima de padrão é de 240 bytes/segundo com um período de cortesia de 5 segundos.

Uma taxa mínima também se aplica à resposta. O código para definir o limite de solicitação e o limite de resposta é o mesmo, exceto por ter RequestBody ou Response nos nomes da propriedade e da interface.

Aqui está um exemplo que mostra como configurar as taxas de dados mínimas em Program.cs:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Substitua os limites de taxa mínima por solicitação no middleware:

app.Run(async (context) =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>()
        .MaxRequestBodySize = 10 * 1024;

    var minRequestRateFeature = 
        context.Features.Get<IHttpMinRequestBodyDataRateFeature>();
    var minResponseRateFeature = 
        context.Features.Get<IHttpMinResponseDataRateFeature>();

    if (minRequestRateFeature != null)
    {
        minRequestRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

    if (minResponseRateFeature != null)
    {
        minResponseRateFeature.MinDataRate = new MinDataRate(
            bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    }

O IHttpMinResponseDataRateFeature referenciado no exemplo anterior não está presente no HttpContext.Features para solicitações HTTP/2, porque a modificação dos limites de taxa em cada solicitação não é geralmente compatível com HTTP/2 devido ao suporte de multiplexação de solicitação do protocolo. No entanto, o IHttpMinRequestBodyDataRateFeature ainda está presente em HttpContext.Features para solicitações HTTP/2, pois o limite de taxa de leitura ainda pode ser desabilitado totalmente em cada solicitação, definindo IHttpMinRequestBodyDataRateFeature.MinDataRate para null mesmo em uma solicitação HTTP/2. Tentar ler IHttpMinRequestBodyDataRateFeature.MinDataRate ou tentar defini-lo como um valor diferente de null resultará na geração de um NotSupportedException devido a uma solicitação HTTP/2.

Os limites de taxa de todo o servidor configurados por meio de KestrelServerOptions.Limits ainda se aplicam a conexões HTTP/1.x e HTTP/2.

Tempo limite dos cabeçalhos de solicitação

RequestHeadersTimeout

Obtém ou define a quantidade máxima de tempo que o servidor gasta recebendo cabeçalhos de solicitação. O padrão é 30 segundos.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.MaxConcurrentConnections = 100;
    serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
    serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
    serverOptions.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    serverOptions.Listen(IPAddress.Loopback, 5000);
    serverOptions.Listen(IPAddress.Loopback, 5001, 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testPassword");
        });
    serverOptions.Limits.KeepAliveTimeout = 
        TimeSpan.FromMinutes(2);
    serverOptions.Limits.RequestHeadersTimeout = 
        TimeSpan.FromMinutes(1);
})

Fluxos máximos por conexão

O Http2.MaxStreamsPerConnection limita o número de fluxos de solicitações simultâneas por conexão HTTP/2. Os fluxos em excesso são recusados.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.MaxStreamsPerConnection = 100;
});

O valor padrão é 100.

Tamanho da tabela de cabeçalho

O decodificador HPACK descompacta os cabeçalhos HTTP para conexões HTTP/2. O Http2.HeaderTableSize limita o tamanho da tabela de compactação de cabeçalho usada pelo decodificador HPACK. O valor é fornecido em octetos e deve ser maior do que zero (0).

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.HeaderTableSize = 4096;
});

O valor padrão é 4096.

Tamanho máximo do quadro

Http2.MaxFrameSize indica o tamanho máximo permitido de uma carga de quadro de conexão HTTP/2 recebida ou enviada pelo servidor. O valor é fornecido em octetos e deve estar entre 2^14 (16.384) e 2^24-1 (16.777.215).

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.MaxFrameSize = 16384;
});

O valor padrão é 2^14 (16.384).

Tamanho máximo do cabeçalho de solicitação

Http2.MaxRequestHeaderFieldSize indica o tamanho máximo permitido em octetos de valores de cabeçalho de solicitação. Esse limite se aplica ao nome e ao valor em suas representações compactadas e não compactadas. O valor deve ser maior que zero (0).

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.MaxRequestHeaderFieldSize = 8192;
});

O valor padrão é 8.192.

Tamanho inicial da janela de conexão

Http2.InitialConnectionWindowSize indica os dados máximos do corpo da solicitação em bytes, que o servidor armazena em buffer ao mesmo tempo, agregados em todas as solicitações (fluxos) por conexão. As solicitações também são limitadas por Http2.InitialStreamWindowSize. O valor deve ser maior ou igual a 65.535 e menor que 2^31 (2.147.483.648).

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.InitialConnectionWindowSize = 131072;
});

O valor padrão é 128 KB (131.072).

Tamanho inicial da janela de fluxo

Http2.InitialStreamWindowSize indica o máximo de dados do corpo da solicitação, em bytes, que o servidor armazena em buffer ao mesmo tempo, por solicitação (fluxo). As solicitações também são limitadas por Http2.InitialConnectionWindowSize. O valor deve ser maior ou igual a 65.535 e menor que 2^31 (2.147.483.648).

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Limits.Http2.InitialStreamWindowSize = 98304;
});

O valor padrão é 96 KB (98.304).

Trailers

Os trailers HTTP são semelhantes aos Cabeçalhos HTTP, exceto que são enviados depois que o corpo da resposta é 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 têm suporte para a resposta.
  • DeclareTrailer adiciona o nome do trailer fornecido ao cabeçalho de Trailer resposta. 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 acrescenta o trailer.

Redefinir

A redefinição 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 INTERNAL_ERROR código de erro. 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.

E/S Síncrona

AllowSynchronousIO controla se a E/S síncrona é permitida para a solicitação e a resposta. O valor padrão é false.

Aviso

Um grande número de operações de E/S síncronas de bloqueio pode levar à fome do pool de threads, o que torna o aplicativo sem resposta. Habilitar AllowSynchronousIO somente ao usar uma biblioteca que não dá suporte a E/S assíncrona.

O exemplo a seguir habilita a E/S síncrona:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.AllowSynchronousIO = true;
})

Para obter informações sobre outras Kestrel opções e limites, consulte:

Configuração de ponto de extremidade

Por padrão, o ASP.NET Core associa a:

  • http://localhost:5000
  • https://localhost:5001 (quando um certificado de desenvolvimento local está presente)

Especificar URLs usando:

  • A variável de ambiente ASPNETCORE_URLS.
  • O argumento de linha de comando --urls.
  • A chave de configuração do host urls.
  • O método de extensão UseUrls.

O valor fornecido usando essas abordagens pode ser um ou mais pontos de extremidade HTTP e HTTPS (HTTPS se houver um certificado padrão). Configure o valor como uma lista separada por ponto e vírgula (por exemplo, "Urls": "http://localhost:8000;http://localhost:8001").

Veja mais informações sobre essas abordagens em URLs de servidor e Substituir configuração.

Um certificado de desenvolvimento é criado:

Alguns navegadores exigem a concessão de permissão explícita para confiar no certificado de desenvolvimento local.

Os modelos de projeto configuram aplicativos para serem executados em HTTPS por padrão e incluem o redirecionamento HTTPS e o suporte ao HSTS.

Chamar Listen ou ListenUnixSocket métodos KestrelServerOptions para configurar prefixos de URL e portas para Kestrel.

UseUrls, o argumento de linha de comando --urls, a chave de configuração de host urls e a variável de ambiente ASPNETCORE_URLS também funcionam mas têm limitações que serão indicadas mais adiante nesta seção (um certificado padrão precisa estar disponível para a configuração do ponto de extremidade HTTPS).

KestrelServerOptions configuração:

ConfigureEndpointDefaults(Action<ListenOptions>)

Especifica uma Action de configuração a ser executada para cada ponto de extremidade especificado. Chamar ConfigureEndpointDefaults várias vezes substitui as Actions pela última Action especificada.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });
});

Observação

Os pontos de extremidade criados pela chamada Listenantes da chamada ConfigureEndpointDefaults não terão os padrões aplicados.

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)

Especifica uma Action de configuração a ser executada para cada ponto de extremidade HTTPS. Chamar ConfigureHttpsDefaults várias vezes substitui as Actions pela última Action especificada.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // certificate is an X509Certificate2
        listenOptions.ServerCertificate = certificate;
    });
});

Observação

Os pontos de extremidade criados pela chamada Listenantes da chamada ConfigureHttpsDefaults não terão os padrões aplicados.

Configure(IConfiguration)

Cria um carregador de configuração para configurar Kestrel que usa uma IConfiguration entrada como. A configuração deve ter o escopo da seção de configuração para Kestrel.

ListenOptions.UseHttps

Configure Kestrel para usar HTTPS.

Extensões ListenOptions.UseHttps:

  • UseHttps: configure Kestrel para usar HTTPS com o certificado padrão. Gera uma exceção quando não há nenhum certificado padrão configurado.
  • UseHttps(string fileName)
  • UseHttps(string fileName, string password)
  • UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(StoreName storeName, string subject)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)
  • UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(X509Certificate2 serverCertificate)
  • UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)
  • UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)

Parâmetros de ListenOptions.UseHttps:

  • filename é o caminho e o nome do arquivo de um arquivo de certificado, relativo ao diretório que contém os arquivos de conteúdo do aplicativo.
  • password é a senha necessária para acessar os dados do certificado X.509 .
  • configureOptions é uma Action para configurar as HttpsConnectionAdapterOptions. Retorna o ListenOptions.
  • storeName é o repositório de certificados do qual o certificado deve ser carregado.
  • subject é o nome da entidade do certificado.
  • allowInvalid indica se certificados inválidos devem ser considerados, como os certificados autoassinados.
  • location é o local do repositório do qual o certificado deve ser carregado.
  • serverCertificate é o certificado X.509.

Em produção, HTTPS precisa ser configurado explicitamente. No mínimo, um certificado padrão precisa ser fornecido.

Configurações com suporte descritas a seguir:

  • Nenhuma configuração
  • Substituir o certificado padrão da configuração
  • Alterar os padrões no código

Nenhuma configuração

Kestrelhttp://localhost:5000 escuta e https://localhost:5001 (se um certificado padrão estiver disponível).

Substituir o certificado padrão da configuração

CreateDefaultBuilder chamadas Configure(context.Configuration.GetSection("Kestrel")) por padrão para carregar Kestrel a configuração. Um esquema de configuração de configuração de aplicativo HTTPS padrão está disponível para Kestrel. Configure vários pontos de extremidade, incluindo URLs e os certificados a serem usados, por meio de um arquivo no disco ou de um repositório de certificados.

No exemplo a seguir appsettings.json :

  • Defina AllowInvalid como true para permitir o uso de certificados inválidos (por exemplo, os certificados autoassinados).
  • Todo ponto de extremidade HTTPS que não especificar um certificado (HttpsDefaultCert no exemplo a seguir) será revertido para o certificado definido em Certificados>Padrão ou para o certificado de desenvolvimento.
{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5003"
      },
      "Https": {
        "Url": "https://*:5004",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "<certificate password>"
      }
    }
  }
}

Uma alternativa ao uso de Caminho e Senha para qualquer nó de certificado é especificar o certificado usando campos de repositório de certificados. Por exemplo, o certificadoPadrãode Certificados> pode ser especificado como:

"Default": {
  "Subject": "<subject; required>",
  "Store": "<cert store; required>",
  "Location": "<location; defaults to CurrentUser>",
  "AllowInvalid": "<true or false; defaults to false>"
}

Observações do esquema:

  • Os nomes de pontos de extremidade diferenciam maiúsculas de minúsculas. Por exemplo, HTTPS e Https são válidos.
  • O parâmetro Url é necessário para cada ponto de extremidade. O formato desse parâmetro é o mesmo que o do parâmetro de configuração de Urls de nível superior, exceto que ele é limitado a um único valor.
  • Esses pontos de extremidade substituem aqueles definidos na configuração de Urls de nível superior em vez de serem adicionados a eles. Os pontos de extremidade definidos no código por meio de Listen são acumulados com os pontos de extremidade definidos na seção de configuração.
  • A seção Certificate é opcional. Se a seção Certificate não for especificada, os padrões definidos nos cenários anteriores serão usados. Se não houver nenhum padrão disponível, o servidor gerará uma exceção e não poderá ser iniciado.
  • A Certificate seção dá suporte a certificados PathPassword e Subject-Store.
  • Qualquer número de pontos de extremidade pode ser definido dessa forma, contanto que eles não causem conflitos de porta.
  • options.Configure(context.Configuration.GetSection("{SECTION}")) retorna um KestrelConfigurationLoader com um método .Endpoint(string name, listenOptions => { }) que pode ser usado para complementar as definições de um ponto de extremidade configurado:
webBuilder.UseKestrel((context, serverOptions) =>
{
    serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
        .Endpoint("HTTPS", listenOptions =>
        {
            listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
        });
});

KestrelServerOptions.ConfigurationLoader pode ser acessado diretamente para continuar iterando no carregador existente, como aquele fornecido por CreateDefaultBuilder.

  • A seção de configuração para cada ponto de extremidade está disponível nas opções no método para que as Endpoint configurações personalizadas possam ser lidas.
  • Várias configurações podem ser carregadas chamando options.Configure(context.Configuration.GetSection("{SECTION}")) novamente com outra seção. Somente a última configuração será usada, a menos que Load seja chamado explicitamente nas instâncias anteriores. O metapacote não chama Load, portanto, sua seção de configuração padrão pode ser substituída.
  • O KestrelConfigurationLoader espelha a família de APIs Listen de KestrelServerOptions como sobrecargas de Endpoint, portanto, os pontos de extremidade de código e de configuração podem ser configurados no mesmo local. Essas sobrecargas não usam nomes e consomem somente as definições padrão da configuração.

Alterar os padrões no código

ConfigureEndpointDefaults e ConfigureHttpsDefaults podem ser usados para alterar as configurações padrão de ListenOptions e HttpsConnectionAdapterOptions, incluindo a substituição do certificado padrão especificado no cenário anterior. ConfigureEndpointDefaults e ConfigureHttpsDefaults devem ser chamados antes que qualquer ponto de extremidade seja configurado.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls12;
    });
});

Kestrel suporte para SNI

A SNI (Indicação de Nome de Servidor) pode ser usada para hospedar vários domínios no mesmo endereço IP e na mesma porta. Para que a SNI funcione, o cliente envia o nome do host da sessão segura para o servidor durante o handshake TLS para que o servidor possa fornecer o certificado correto. O cliente usa o certificado fornecido para a comunicação criptografada com o servidor durante a sessão segura que segue o handshake TLS.

Kestrel dá suporte ao SNI por meio do ServerCertificateSelector retorno de chamada. O retorno de chamada é invocado uma vez por conexão para permitir que o aplicativo inspecione o nome do host e selecione o certificado apropriado.

O suporte para SNI requer:

  • Em execução na estrutura de destino netcoreapp2.1 ou posterior. Ativado net461 ou posterior, o retorno de chamada é invocado, mas o name é sempre null. O name também será null se o cliente não fornecer o parâmetro de nome do host no handshake TLS.
  • Todos os sites são executados na mesma Kestrel instância. Kestrel não dá suporte ao compartilhamento de um endereço IP e uma porta em várias instâncias sem um proxy reverso.
webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(5005, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            var localhostCert = CertificateLoader.LoadFromStoreCert(
                "localhost", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var exampleCert = CertificateLoader.LoadFromStoreCert(
                "example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var subExampleCert = CertificateLoader.LoadFromStoreCert(
                "sub.example.com", "My", StoreLocation.CurrentUser,
                allowInvalid: true);
            var certs = new Dictionary<string, X509Certificate2>(
                StringComparer.OrdinalIgnoreCase);
            certs["localhost"] = localhostCert;
            certs["example.com"] = exampleCert;
            certs["sub.example.com"] = subExampleCert;

            httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
            {
                if (name != null && certs.TryGetValue(name, out var cert))
                {
                    return cert;
                }

                return exampleCert;
            };
        });
    });
});

Log de conexão

Chame UseConnectionLogging para emitir logs de nível de depuração para comunicação em nível de byte em uma conexão. O log de conexões é útil para solucionar problemas na comunicação de baixo nível, como durante a criptografia TLS e por trás de proxies. Se UseConnectionLogging for colocado antes UseHttps, o tráfego criptografado será registrado. Se UseConnectionLogging for colocado depois UseHttps, o tráfego descriptografado será registrado.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseConnectionLogging();
    });
});

Associar a um soquete TCP

O método Listen é associado a um soquete TCP, e um lambda de opções permite a configuração do certificado X.509:

public static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                serverOptions.Listen(IPAddress.Loopback, 5000);
                serverOptions.Listen(IPAddress.Loopback, 5001, 
                    listenOptions =>
                    {
                        listenOptions.UseHttps("testCert.pfx", 
                            "testPassword");
                    });
            })
            .UseStartup<Startup>();
        });

O exemplo configura o HTTPS de um ponto de extremidade com ListenOptions. Use a mesma API para definir outras Kestrel configurações para pontos de extremidade específicos.

No Windows, certificados autoassinados podem ser criados usando o cmdlet doNew-SelfSignedCertificate PowerShell. Para obter um exemplo sem suporte, consulte UpdateIISExpressSSLForChrome.ps1.

Nas plataformas macOS, Linux e Windows, é possível criar certificados usando o OpenSSL.

Associar a um soquete do UNIX

Escute em um soquete do UNIX com ListenUnixSocket para um melhor desempenho com o Nginx, conforme mostrado neste exemplo:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
    serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock", 
        listenOptions =>
        {
            listenOptions.UseHttps("testCert.pfx", 
                "testpassword");
        });
})
  • No arquivo de configuração Nginx, defina a server>proxy_pass>locationentrada como .http://unix:/tmp/{KESTREL SOCKET}:/; {KESTREL SOCKET} é o nome do soquete fornecido ListenUnixSocket (por exemplo, kestrel-test.sock no exemplo anterior).
  • Verifique se o soquete é gravável por Nginx (por exemplo, chmod go+w /tmp/kestrel-test.sock).

Porta 0

Quando o número 0 da porta é especificado, Kestrel associa-se dinamicamente a uma porta disponível. O exemplo a seguir mostra como determinar qual porta Kestrel realmente vinculada em runtime:

public void Configure(IApplicationBuilder app)
{
    var serverAddressesFeature = 
        app.ServerFeatures.Get<IServerAddressesFeature>();

    app.UseStaticFiles();

    app.Run(async (context) =>
    {
        context.Response.ContentType = "text/html";
        await context.Response
            .WriteAsync("<!DOCTYPE html><html lang=\"en\"><head>" +
                "<title></title></head><body><p>Hosted by Kestrel</p>");

        if (serverAddressesFeature != null)
        {
            await context.Response
                .WriteAsync("<p>Listening on the following addresses: " +
                    string.Join(", ", serverAddressesFeature.Addresses) +
                    "</p>");
        }

        await context.Response.WriteAsync("<p>Request URL: " +
            $"{context.Request.GetDisplayUrl()}<p>");
    });
}

Quando o aplicativo é executado, a saída da janela do console indica a porta dinâmica na qual o aplicativo pode ser acessado:

Listening on the following addresses: http://127.0.0.1:48508

Limitações

Configure pontos de extremidade com as seguintes abordagens:

  • UseUrls
  • O argumento de linha de comando --urls
  • A chave de configuração do host urls
  • A variável de ambiente ASPNETCORE_URLS

Esses métodos são úteis para fazer o código funcionar com servidores diferentes de Kestrel. No entanto, esteja ciente das seguintes limitações:

  • O protocolo HTTPS não pode ser usado com essas abordagens, a menos que um certificado padrão seja fornecido na configuração do ponto de extremidade HTTPS (por exemplo, usando a configuração KestrelServerOptions ou um arquivo de configuração, como já foi mostrado neste tópico).
  • Quando ambas as abordagens, Listen e UseUrls, são usadas ao mesmo tempo, os pontos de extremidade de Listen substituem os pontos de extremidade de UseUrls.

Configuração de ponto de extremidade do IIS

Ao usar o IIS, as associações de URL para IIS substituem as associações definidas por Listen ou UseUrls. Para obter mais informações, confira o tópico Módulo do ASP.NET Core.

ListenOptions.Protocols

A propriedade Protocols estabelece os protocolos HTTP (HttpProtocols) habilitados em um ponto de extremidade de conexão ou para o servidor. Atribua um valor à propriedade Protocols com base na enumeração HttpProtocols.

Valor de enumeração HttpProtocols Protocolo de conexão permitido
Http1 HTTP/1.1 apenas. Pode ser usado com ou sem TLS.
Http2 HTTP/2 apenas. Poderá ser usado sem TLS apenas se o cliente for compatível com um Modo de conhecimento prévio.
Http1AndHttp2 HTTP/1.1 e HTTP/2. HTTP/2 requer que o cliente selecione HTTP/2 no handshake da ALPN (Negociação de Protocolo de Camada de Aplicativo) TLS; caso contrário, a conexão é padrão para HTTP/1.1.

O valor padrão ListenOptions.Protocols para qualquer ponto de extremidade é HttpProtocols.Http1AndHttp2.

Restrições TLS para HTTP/2:

  • Versão TLS 1.2 ou posterior
  • Renegociação desabilitada
  • Compactação desabilitada
  • Tamanhos mínimos de troca de chaves efêmera:
    • Curva elíptica Diffie-Hellman (ECDHE) [RFC4492]: mínimo de 224 bits
    • Campo finito Diffie-Hellman (DHE) [TLS12]: mínimo de 2048 bits
  • Pacote de criptografia não proibido.

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] com a curva elíptica P-256 [FIPS186] tem suporte por padrão.

O exemplo a seguir permite conexões HTTP/1.1 e HTTP/2 na porta 8000. As conexões são protegidas pela TLS com um certificado fornecido:

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

Use o Middleware de Conexão para filtrar handshakes TLS por conexão para criptografias específicas, se necessário.

O exemplo a seguir gera NotSupportedException qualquer algoritmo de criptografia que o aplicativo não dá suporte. Como alternativa, defina e compare ITlsHandshakeFeature.CipherAlgorithm com uma lista de pacotes de criptografia aceitáveis.

Nenhuma criptografia é usada com um algoritmo de criptografia CipherAlgorithmType.Null .

// using System.Net;
// using Microsoft.AspNetCore.Connections;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.UseTlsFilter();
    });
});
using System;
using System.Security.Authentication;
using Microsoft.AspNetCore.Connections.Features;

namespace Microsoft.AspNetCore.Connections
{
    public static class TlsFilterConnectionMiddlewareExtensions
    {
        public static IConnectionBuilder UseTlsFilter(
            this IConnectionBuilder builder)
        {
            return builder.Use((connection, next) =>
            {
                var tlsFeature = connection.Features.Get<ITlsHandshakeFeature>();

                if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
                {
                    throw new NotSupportedException("Prohibited cipher: " +
                        tlsFeature.CipherAlgorithm);
                }

                return next();
            });
        }
    }
}

A filtragem de conexão também pode ser configurada por meio de um IConnectionBuilder lambda:

// using System;
// using System.Net;
// using System.Security.Authentication;
// using Microsoft.AspNetCore.Connections;
// using Microsoft.AspNetCore.Connections.Features;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
        listenOptions.Use((context, next) =>
        {
            var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();

            if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
            {
                throw new NotSupportedException(
                    $"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
            }

            return next();
        });
    });
});

No Linux, CipherSuitesPolicy pode ser usado para filtrar handshakes TLS por conexão:

// using System.Net.Security;
// using Microsoft.AspNetCore.Hosting;
// using Microsoft.AspNetCore.Server.Kestrel.Core;
// using Microsoft.Extensions.DependencyInjection;
// using Microsoft.Extensions.Hosting;

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.OnAuthenticate = (context, sslOptions) =>
        {
            sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
                new[]
                {
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                    TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                    // ...
                });
        };
    });
});

Definir o protocolo com base na configuração

CreateDefaultBuilder chamadas serverOptions.Configure(context.Configuration.GetSection("Kestrel")) por padrão para carregar Kestrel a configuração.

O exemplo a seguir appsettings.json estabelece HTTP/1.1 como o protocolo de conexão padrão para todos os pontos de extremidade:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1"
    }
  }
}

O exemplo a seguir appsettings.json estabelece o protocolo de conexão HTTP/1.1 para um ponto de extremidade específico:

{
  "Kestrel": {
    "Endpoints": {
      "HttpsDefaultCert": {
        "Url": "https://localhost:5001",
        "Protocols": "Http1"
      }
    }
  }
}

Os protocolos especificados no código substituem os valores definidos pela configuração.

Prefixos de URL

Ao usar UseUrls, o argumento de linha de comando --urls, a chave de configuração de host urls ou a variável de ambiente ASPNETCORE_URLS, os prefixos de URL podem estar em um dos formatos a seguir.

Somente os prefixos de URL HTTP são válidos. Kestrel não dá suporte a HTTPS ao configurar associações de URL usando UseUrls.

  • Endereço IPv4 com o número da porta

    http://65.55.39.10:80/
    

    0.0.0.0 é um caso especial que associa a todos os endereços IPv4.

  • Endereço IPv6 com número da porta

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::] é o equivalente do IPv6 ao IPv4 0.0.0.0.

  • Nome do host com o número da porta

    http://contoso.com:80/
    http://*:80/
    

    Os nomes de host * e + não são especiais. Tudo o que não é reconhecido como um endereço IP ou um localhost válido é associado a todos os IPs IPv6 e IPv4. Para associar nomes de host diferentes a diferentes aplicativos ASP.NET Core na mesma porta, use o HTTP.sys ou um servidor proxy reverso, como o IIS, o Nginx ou o Apache.

    Aviso

    A hospedagem em uma configuração de proxy reverso requer a configuração do Middleware cabeçalhos encaminhados.

  • Nome do localhost do host com o número da porta ou o IP de loopback com o número da porta

    http://localhost:5000/
    http://127.0.0.1:5000/
    http://[::1]:5000/
    

    Quando localhost é especificado, Kestrel tenta associar a interfaces de loopback IPv4 e IPv6. Se a porta solicitada estiver em uso por outro serviço em qualquer interface de loopback, Kestrel não será iniciada. Se uma das interfaces de loopback não estiver disponível por qualquer outro motivo (geralmente porque o IPv6 não tem suporte), Kestrel registra um aviso em log.

Filtragem de host

Embora dê Kestrel suporte à configuração com base em prefixos como http://example.com:5000, Kestrel em grande parte ignora o nome do host. O host localhost é um caso especial usado para a associação a endereços de loopback. Todo host que não for um endereço IP explícito será associado a todos os endereços IP públicos. Cabeçalhos Host não são validados.

Como uma solução alternativa, use o Middleware de Filtragem de Host. O Middleware de Filtragem de Host é fornecido pelo pacote Microsoft.AspNetCore.HostFiltering, que é fornecido implicitamente para aplicativos ASP.NET Core. O middleware é adicionado pelo CreateDefaultBuilder, que chama AddHostFiltering:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

Middleware de Filtragem de Host está desabilitado por padrão. Para habilitar o middleware, defina uma AllowedHosts chave em/appsettings.jsonappsettings.{Environment}.json . O valor dessa chave é uma lista separada por ponto e vírgula de nomes de host sem números de porta:

appsettings.json:

{
  "AllowedHosts": "example.com;localhost"
}

Observação

Middleware de Cabeçalhos Encaminhados também tem uma opção AllowedHosts. Middleware de Cabeçalhos Encaminhados e Middleware de filtragem de Host têm funcionalidades semelhantes para cenários diferentes. A definição de AllowedHosts com Middleware de Cabeçalhos Encaminhados é apropriada quando o cabeçalho Host não é preservado ao encaminhar solicitações com um servidor proxy reverso ou um balanceador de carga. A configuração AllowedHosts com o Middleware de Filtragem de Host é apropriada quando Kestrel é usada como um servidor de borda voltado para o público ou quando o Host cabeçalho é encaminhado diretamente.

Para obter mais informações sobre Middleware de Cabeçalhos Encaminhados, veja Configurar o ASP.NET Core para funcionar com servidores proxy e balanceadores de carga.

Configuração de transporte libuv

Para projetos que exigem o uso do Libuv (UseLibuv):

  • Adicione uma dependência para o Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv pacote ao arquivo de projeto do aplicativo:

    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv"
                      Version="{VERSION}" />
    
  • Chamada UseLibuv no IWebHostBuilder:

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseLibuv();
                    webBuilder.UseStartup<Startup>();
                });
    }
    

Esvaziamento de solicitações HTTP/1.1

Abrir conexões HTTP é demorado. Para HTTPS, também é intensivo em recursos. Portanto, Kestrel tenta reutilizar conexões de acordo com o protocolo HTTP/1.1. Um corpo da solicitação deve ser totalmente consumido para permitir que a conexão seja reutilizado. O aplicativo nem sempre consome o corpo da solicitação, como uma POST solicitação em que o servidor retorna um redirecionamento ou uma resposta 404. POSTNo caso de redirecionamento:

  • O cliente pode já ter enviado parte dos POST dados.
  • O servidor grava a resposta 301.
  • A conexão não pode ser usada para uma nova solicitação até que os POST dados do corpo da solicitação anterior sejam totalmente lidos.
  • Kestrel tenta drenar o corpo da solicitação. Esvaziar o corpo da solicitação significa ler e descartar os dados sem processá-los.

O processo de drenagem faz uma compensação entre permitir que a conexão seja reutilizado e o tempo necessário para drenar os dados restantes:

  • A drenagem tem um tempo limite de cinco segundos, o que não é configurável.
  • Se todos os dados especificados pelo Content-Length cabeçalho ou Transfer-Encoding o cabeçalho não tiverem sido lidos antes do tempo limite, a conexão será fechada.

Às vezes, talvez você queira encerrar a solicitação imediatamente, antes ou depois de escrever a resposta. Por exemplo, os clientes podem ter limites de dados restritivos, portanto, limitar dados carregados pode ser uma prioridade. Nesses casos, para encerrar uma solicitação, chame HttpContext.Abort de um controlador, Razor página ou middleware.

Há ressalvas em chamar Abort:

  • A criação de novas conexões pode ser lenta e cara.
  • Não há garantia de que o cliente tenha lido a resposta antes do fechamento da conexão.
  • A chamada Abort deve ser rara e reservada para casos de erro graves, não erros comuns.
    • Abort Chame somente quando um problema específico precisar ser resolvido. Por exemplo, chame Abort se clientes mal-intencionados estão tentando dados POST ou quando há um bug no código do cliente que causa solicitações grandes ou inúmeras.
    • Não chame Abort situações de erro comuns, como HTTP 404 (Não Encontrado).

Chamar HttpResponse.CompleteAsync antes de chamar Abort garante que o servidor tenha concluído a gravação da resposta. No entanto, o comportamento do cliente não é previsível e eles podem não ler a resposta antes que a conexão seja anulada.

Esse processo é diferente para HTTP/2 porque o protocolo dá suporte à anulação de fluxos de solicitação individuais sem fechar a conexão. O tempo limite de 5 segundos não se aplica. Se houver algum dado do corpo da solicitação não lida após a conclusão de uma resposta, o servidor enviará um quadro HTTP/2 RST. Quadros de dados adicionais do corpo da solicitação são ignorados.

Se possível, é melhor que os clientes utilizem o cabeçalho de solicitação Esperar: 100 continuações e aguardem a resposta do servidor antes de começar a enviar o corpo da solicitação. Isso dá ao cliente a oportunidade de examinar a resposta e anular antes de enviar dados desnecessários.

Recursos adicionais