Жизненный цикл запроса
Эта страница переведена с английского автоматически. Читать оригинал
Ниже объясняется весь жизненный цикл запроса на примере HTTP‑запроса.
- Receiving the request: каждый запрос создает HTTP‑контекст между самим запросом и ответом, который будет доставлен клиенту. Этот контекст создаётся встроенным слушателем в Sisk, которым может быть HttpListener, Kestrel или Cadente.
- Валидация внешних запросов: проверяется значение HttpServerConfiguration.RemoteRequestsAction для запроса.
- Если запрос внешний и свойство имеет значение
Drop, соединение закрывается без ответа клиенту сHttpServerExecutionStatus = RemoteRequestDropped.
- Если запрос внешний и свойство имеет значение
- Конфигурация Forwarding Resolver: если настроен ForwardingResolver, он вызовет метод OnResolveRequestHost на оригинальном хосте запроса.
- Сопоставление DNS: после разрешения хоста и при наличии более одного настроенного ListeningHost сервер ищет соответствующий хост для запроса.
- Если ни один ListeningHost не подходит, клиенту возвращается ответ 400 Bad Request, а в HTTP‑контекст записывается статус
HttpServerExecutionStatus = DnsUnknownHost. - Если найден ListeningHost, но его Router ещё не инициализирован, клиенту возвращается ответ 503 Service Unavailable, а в HTTP‑контекст записывается статус
HttpServerExecutionStatus = ListeningHostNotReady.
- Если ни один ListeningHost не подходит, клиенту возвращается ответ 400 Bad Request, а в HTTP‑контекст записывается статус
- Привязка роутера: роутер соответствующего ListeningHost связывается с полученным HTTP‑сервером.
- Если роутер уже связан с другим HTTP‑сервером, что недопустимо, поскольку роутер активно использует ресурсы конфигурации сервера, выбрасывается
InvalidOperationException. Это происходит только при инициализации HTTP‑сервера, а не при создании HTTP‑контекста.
- Если роутер уже связан с другим HTTP‑сервером, что недопустимо, поскольку роутер активно использует ресурсы конфигурации сервера, выбрасывается
- Предопределение заголовков:
- Если настроено, в ответе предварительно задаётся заголовок
X-Request-Id. - Если настроено, в ответе предварительно задаётся заголовок
X-Powered-By.
- Если настроено, в ответе предварительно задаётся заголовок
- Валидация размера содержимого: проверяется, что размер содержимого запроса меньше HttpServerConfiguration.MaximumContentLength только если он больше нуля.
- Если запрос отправляет
Content-Length, превышающий настроенный, клиенту возвращается ответ 413 Payload Too Large, а в HTTP‑контекст записывается статусHttpServerExecutionStatus = ContentTooLarge.
- Если запрос отправляет
- Событие
OnHttpRequestOpenвызывается для всех настроенных обработчиков HTTP‑сервера.
- Валидация внешних запросов: проверяется значение HttpServerConfiguration.RemoteRequestsAction для запроса.
- Routing the action: сервер вызывает роутер для полученного запроса.
- Если роутер не находит маршрут, соответствующий запросу:
- Если свойство Router.NotFoundErrorHandler настроено, вызывается действие, и его ответ пересылается HTTP‑клиенту.
- Если предыдущее свойство равно
null, клиенту возвращается стандартный ответ 404 Not Found.
- Если роутер находит подходящий маршрут, но метод маршрута не совпадает с методом запроса:
- Если свойство Router.MethodNotAllowedErrorHandler настроено, вызывается действие, и его ответ пересылается HTTP‑клиенту.
- Если предыдущее свойство равно
null, клиенту возвращается стандартный ответ 405 Method Not Allowed.
- Если запрос имеет метод
OPTIONS:- Роутер возвращает клиенту ответ 200 Ok только если ни один маршрут не соответствует методу запроса (метод маршрута явно не указан как RouteMethod.Options).
- Если свойство HttpServerConfiguration.ForceTrailingSlash включено, найденный маршрут не является регулярным выражением, путь запроса не заканчивается символом
/, а метод запроса —GET:- Клиенту возвращается HTTP‑ответ 307 Temporary Redirect с заголовком
Location, указывающим путь и запрос к тому же месту, но с завершающим/.
- Клиенту возвращается HTTP‑ответ 307 Temporary Redirect с заголовком
- Событие
OnContextBagCreatedвызывается для всех настроенных обработчиков HTTP‑сервера. - Все глобальные экземпляры IRequestHandler с флагом
BeforeResponseвыполняются.- Если любой обработчик возвращает ненулевой ответ, он пересылается HTTP‑клиенту, и контекст закрывается.
- Если на этом этапе выбрасывается ошибка и HttpServerConfiguration.ThrowExceptions отключено:
- Если свойство Router.CallbackErrorHandler включено, оно вызывается, и полученный ответ возвращается клиенту.
- Если предыдущее свойство не определено, сервер получает пустой ответ и пересылает ответ в зависимости от типа выброшенного исключения, обычно это 500 Internal Server Error.
- Все экземпляры IRequestHandler, определённые в маршруте и с флагом
BeforeResponse, выполняются.- Если любой обработчик возвращает ненулевой ответ, он пересылается HTTP‑клиенту, и контекст закрывается.
- Если на этом этапе выбрасывается ошибка и HttpServerConfiguration.ThrowExceptions отключено:
- Если свойство Router.CallbackErrorHandler включено, оно вызывается, и полученный ответ возвращается клиенту.
- Если предыдущее свойство не определено, сервер получает пустой ответ и пересылает ответ в зависимости от типа выброшенного исключения, обычно это 500 Internal Server Error.
- Действие роутера вызывается и преобразуется в HTTP‑ответ.
- Если на этом этапе выбрасывается ошибка и HttpServerConfiguration.ThrowExceptions отключено:
- Если свойство Router.CallbackErrorHandler включено, оно вызывается, и полученный ответ возвращается клиенту.
- Если предыдущее свойство не определено, сервер получает пустой ответ и пересылает ответ в зависимости от типа выброшенного исключения, обычно это 500 Internal Server Error.
- Если на этом этапе выбрасывается ошибка и HttpServerConfiguration.ThrowExceptions отключено:
- Все глобальные экземпляры IRequestHandler с флагом
AfterResponseвыполняются.- Если любой обработчик возвращает ненулевой ответ, ответ обработчика заменяет предыдущий и немедленно пересылается HTTP‑клиенту.
- Если на этом этапе выбрасывается ошибка и HttpServerConfiguration.ThrowExceptions отключено:
- Если свойство Router.CallbackErrorHandler включено, оно вызывается, и полученный ответ возвращается клиенту.
- Если предыдущее свойство не определено, сервер получает пустой ответ и пересылает ответ в зависимости от типа выброшенного исключения, обычно это 500 Internal Server Error.
- Все экземпляры IRequestHandler, определённые в маршруте и с флагом
AfterResponse, выполняются.- Если любой обработчик возвращает ненулевой ответ, ответ обработчика заменяет предыдущий и немедленно пересылается HTTP‑клиенту.
- Если на этом этапе выбрасывается ошибка и HttpServerConfiguration.ThrowExceptions отключено:
- Если свойство Router.CallbackErrorHandler включено, оно вызывается, и полученный ответ возвращается клиенту.
- Если предыдущее свойство не определено, сервер получает пустой ответ и пересылает ответ в зависимости от типа выброшенного исключения, обычно это 500 Internal Server Error.
- Если роутер не находит маршрут, соответствующий запросу:
- Processing the response: когда ответ готов, сервер подготавливает его к отправке клиенту.
- Заголовки политики Cross-Origin Resource Sharing (CORS) задаются в ответе в соответствии с настройкой текущего ListeningHost.CrossOriginResourceSharingPolicy.
- Код статуса и заголовки ответа отправляются клиенту.
- Содержимое ответа отправляется клиенту:
- Если содержимое ответа является наследником ByteArrayContent, байты ответа копируются напрямую в поток вывода ответа.
- Если предыдущее условие не выполнено, ответ сериализуется в поток и копируется в поток вывода ответа.
- Потоки закрываются, а содержимое ответа отбрасывается.
- Если включено HttpServerConfiguration.DisposeDisposableContextValues, все объекты, определённые в контексте запроса и наследующие IDisposable, отбрасываются.
- Событие
OnHttpRequestCloseвызывается для всех настроенных обработчиков HTTP‑сервера. - Если на сервере было выброшено исключение, событие
OnExceptionвызывается для всех настроенных обработчиков HTTP‑сервера. - Если маршрут разрешает логирование доступа и HttpServerConfiguration.AccessLogsStream не
null, в вывод логов записывается строка. - Если маршрут разрешает логирование ошибок, возникло исключение и HttpServerConfiguration.ErrorsLogsStream не
null, в вывод журнала ошибок записывается строка. - Если сервер ожидает запрос через HttpServer.WaitNext, мьютекс освобождается, и контекст становится доступным пользователю.