Esvaziamento de solicitação com o servidor Web Kestrel do ASP.NET Core

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, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Importante

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

Para a versão atual, consulte a versão .NET 9 deste artigo.

Abrir conexões HTTP é algo demorado. Para HTTPS, o uso de recursos também é intensivo. Portanto, o 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 solicitações HTTP POST em que o servidor retorna um redirecionamento ou uma resposta 404. No caso de redirecionamento HTTP POST:

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

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

  • O esvaziamento 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 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 gravar a resposta. Por exemplo, os clientes podem ter limites de dados restritivos. 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 para 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.
    • Chame apenas Abort quando um problema específico precisar ser resolvido. Por exemplo, chame Abort se clientes mal-intencionados estão tentando postar dados ou quando há um bug no código do cliente que causa várias solicitações ou solicitações grandes.
    • Não chame Abort para 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 drenagem de cinco segundos não se aplica. Se houver dados do corpo da solicitação não lidos após a conclusão de uma resposta, o servidor enviará um quadro HTTP/2 RST. Quadros de dados do corpo da solicitação adicionais são ignorados.

Se possível, é melhor que os clientes usem o cabeçalho de solicitação Expect: 100-continue e aguardem até que o servidor responda 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.