Поделиться через


Очистка запросов с помощью веб-сервера Kestrel для ASP.NET Core

Открытие HTTP-соединений занимает много времени. Для протокола HTTPS это также требует больших ресурсов. Поэтому Kestrel пытается повторно использовать подключения по протоколу HTTP/1.1. Чтобы разрешить повторное использование соединения, текст запроса должен быть полностью использован. Приложение не всегда использует текст запроса, например запросы HTTP POST, в которых сервер возвращает ответ перенаправления или 404. В случае перенаправления HTTP POST:

  • Возможно, клиент уже отправил часть данных POST.
  • Сервер записывает ответ 301.
  • Соединение нельзя использовать для нового запроса, пока не будут полностью прочитаны данные POST из предыдущего текста запроса.
  • Kestrel пытается очистить текст запроса. Очистка текста запроса означает чтение и отмену данных без их обработки.

Процесс очистки позволяет найти баланс между возможностью повторного использования соединения и временем, которое требуется для очистки оставшихся данных:

  • Время ожидания очистки составляет 5 секунд. Этот параметр нельзя изменить.
  • Если все данные, указанные в заголовке Content-Length или Transfer-Encoding, не были считаны до истечения времени ожидания, соединение закрывается.

Иногда может потребоваться немедленно завершить запрос до или после записи ответа. Например, клиенты могут иметь строгие ограничения на данные. При этом приоритетным требованием может быть ограничение передаваемых данных. В таких случаях для завершения запроса вызовите HttpContext.Abort из контроллера, страницы Razor или ПО промежуточного слоя.

Вызов Abort имеет определенные недостатки.

  • Создание новых подключений может выполняться очень медленно и требовать много ресурсов.
  • Нет никакой гарантии, что клиент прочитал ответ перед закрытием соединения.
  • Вызов Abort следует использовать редко и только для серьезных, а не распространенных ошибок.
    • Вызывайте Abort, только когда нужно решить конкретную проблему. Например, вызовите Abort, если вредоносные клиенты пытаются выполнить операцию POST с данными или если в клиентском коде есть ошибка, вызывающая большие или многочисленные запросы.
    • Не вызывайте Abort для распространенных ошибок, таких как HTTP 404 (не найдено).

Вызов HttpResponse.CompleteAsync перед вызовом Abort гарантирует, что сервер завершит запись ответа. Однако поведение клиента не предсказуемо. Он может не считать ответ, прежде чем подключение будет прервано.

Этот процесс отличается для HTTP/2, так как протокол поддерживает прерывание отдельных потоков запросов без закрытия соединения. 5-секундное время ожидания очистки не применяется. Если после завершения ответа сервер содержит непрочтенные данные текста запроса, он отправляет кадр HTTP/2 RST. Дополнительные кадры данных текста запроса игнорируются.

По возможности клиенты лучше использовать заголовок запроса :100-continue и ждать ответа сервера перед началом отправки текста запроса. Это дает клиенту возможность проверить ответ и прервать операцию перед отправкой ненужных данных.