Sisk

Жизненный цикл запроса

Эта страница переведена с английского автоматически. Читать оригинал

Ниже объясняется весь жизненный цикл запроса на примере 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 связывается с полученным HTTP‑сервером.
      • Если роутер уже связан с другим HTTP‑сервером, что недопустимо, поскольку роутер активно использует ресурсы конфигурации сервера, выбрасывается InvalidOperationException. Это происходит только при инициализации HTTP‑сервера, а не при создании HTTP‑контекста.
    • Предопределение заголовков:
      • Если настроено, в ответе предварительно задаётся заголовок X-Request-Id.
      • Если настроено, в ответе предварительно задаётся заголовок X-Powered-By.
    • Валидация размера содержимого: проверяется, что размер содержимого запроса меньше HttpServerConfiguration.MaximumContentLength только если он больше нуля.
      • Если запрос отправляет Content-Length, превышающий настроенный, клиенту возвращается ответ 413 Payload Too Large, а в HTTP‑контекст записывается статус HttpServerExecutionStatus = ContentTooLarge.
    • Событие OnHttpRequestOpen вызывается для всех настроенных обработчиков HTTP‑сервера.
  • 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, указывающим путь и запрос к тому же месту, но с завершающим /.
    • Событие 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.
    • Все глобальные экземпляры 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, мьютекс освобождается, и контекст становится доступным пользователю.

Начните вводить, чтобы искать по документации и справочнику API.