evento
19/11, 23 - 21/11, 23
Participe de sessões on-line no Microsoft Ignite criadas para expandir suas habilidades e ajudá-lo a lidar com os problemas complexos de hoje.
Registe-se agoraEste browser já não é suportado.
Atualize para o Microsoft Edge para tirar partido das mais recentes funcionalidades, atualizações de segurança e de suporte técnico.
Nota
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 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 a versão atual, consulte a versão .NET 9 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:
Versões do Windows com suporte:
Exibir ou baixar código de exemplo (como baixar)
O HTTP.sys é útil nas implantações em que:
É necessário expor o servidor diretamente à Internet sem usar o IIS.
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 é 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.
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.
O HTTP/3 estará habilitado para aplicativos ASP.NET Core se os seguintes requisitos básicos forem atendidos:
https
for usada.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.
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.
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.
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:
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.
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.
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.
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).
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.
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:
urls
ASPNETCORE_URLS
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.
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>
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:
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:
10.0.0.4
.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:
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.
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.
IHttpSysRequestTimingFeature fornece informações detalhadas de tempo para solicitações:
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();
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:
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.AppendTrailer
acrescenta o trailer.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.
Para obter informações sobre como obter rastreamentos de HTTP.sys, consulte Cenários de capacidade de gerenciamento de HTTP.sys.
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:
Versões do Windows com suporte:
Exibir ou baixar código de exemplo (como baixar)
O HTTP.sys é útil nas implantações em que:
É necessário expor o servidor diretamente à Internet sem usar o IIS.
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 é 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.
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.
O HTTP/3 estará habilitado para aplicativos ASP.NET Core se os seguintes requisitos básicos forem atendidos:
https
for usada.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.
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.
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:
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.
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.
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.
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).
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.
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:
urls
ASPNETCORE_URLS
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.
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>
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:
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:
10.0.0.4
.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:
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.
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.
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:
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.AppendTrailer
acrescenta o trailer.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.
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:
Versões do Windows com suporte:
Exibir ou baixar código de exemplo (como baixar)
O HTTP.sys é útil nas implantações em que:
É necessário expor o servidor diretamente à Internet sem usar o IIS.
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 é 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.
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.
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.
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:
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.
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.
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.
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).
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.
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:
urls
ASPNETCORE_URLS
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.
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>
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:
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:
10.0.0.4
.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:
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.
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.
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:
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.AppendTrailer
acrescenta o trailer.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.
Comentários do ASP.NET Core
O ASP.NET Core é um projeto código aberto. Selecione um link para fornecer comentários:
evento
19/11, 23 - 21/11, 23
Participe de sessões on-line no Microsoft Ignite criadas para expandir suas habilidades e ajudá-lo a lidar com os problemas complexos de hoje.
Registe-se agora