Жизненный цикл запроса
Эта страница переведена с английского автоматически. Читать оригинал
Ниже объясняется весь жизненный цикл запроса на примере HTTP‑запроса.
- Получение запроса: каждый запрос создает 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 (по умолчанию 100 МБ), если он больше нуля.
- Если запрос отправляет
Content-Length, превышающий настроенный, клиенту возвращается ответ 413 Payload Too Large, а в HTTP‑контекст записывается статусHttpServerExecutionStatus = ContentTooLarge.
- Если запрос отправляет
- Событие
OnHttpRequestOpenвызывается для всех настроенных обработчиков HTTP‑сервера.
- Внешняя проверка запроса: проверка HttpServerConfiguration.RemoteRequestsAction выполняется для запроса.
- Маршрутизация действия: сервер вызывает роутер для полученного запроса.
- Если роутер не находит маршрут, соответствующий запросу:
- Если свойство 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.
- Если роутер не находит маршрут, соответствующий запросу:
- Обработка ответа: когда ответ готов, сервер подготавливает его к отправке клиенту.
- Заголовки политики Cross-Origin Resource Sharing (CORS) добавляются в ответ в соответствии с настройкой текущего ListeningHost.CrossOriginResourceSharingPolicy.
- Код состояния и заголовки ответа отправляются клиенту.
- Содержимое ответа отправляется клиенту:
- Если содержимое ответа является наследником ByteArrayContent, байты ответа копируются напрямую в поток вывода ответа.
- Если предыдущее условие не выполнено, ответ сериализуется в поток и копируется в поток вывода ответа.
- Потоки закрываются, а содержимое ответа отбрасывается.
- Если включено HttpServerConfiguration.DisposeDisposableContextValues, все объекты, определённые в контексте запроса и наследующие IDisposable, отбрасываются.
- Событие
OnHttpRequestCloseвызывается для всех настроенных обработчиков HTTP‑сервера. - Если на сервере было выброшено исключение, событие
OnExceptionвызывается для всех настроенных обработчиков HTTP‑сервера. - Если маршрут разрешает ведение журнала доступа и HttpServerConfiguration.AccessLogsStream не равен null, в вывод журнала записывается строка.
- Если маршрут разрешает ведение журнала ошибок, возникло исключение и HttpServerConfiguration.ErrorsLogsStream не равен null, в вывод журнала ошибок записывается строка.
- Если сервер ожидает запрос через HttpServer.WaitNext, мьютекс освобождается, и контекст становится доступным пользователю.