# Request-Lebenszyklus

Source: https://docs.sisk-framework.org/de/docs/advanced/request-lifecycle.html

Im Folgenden wird der gesamte Lebenszyklus einer Anfrage anhand eines Beispiels einer HTTP‑Anfrage erklärt.

- **Empfangen der Anfrage:** Jede Anfrage erzeugt einen HTTP‑Kontext zwischen der eigentlichen Anfrage und der Antwort, die dem Client zugestellt wird. Dieser Kontext stammt vom integrierten Listener in Sisk, der entweder [HttpListener](https://learn.microsoft.com/en-us/dotnet/api/system.net.httplistener?view=net-9.0), [Kestrel](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-9.0) oder [Cadente](https://blog.sisk-framework.org/posts/2025-01-29-cadente-experiment/) sein kann.
    - Externe Anfragenvalidierung: Die Validierung von [HttpServerConfiguration.RemoteRequestsAction](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.RemoteRequestsAction.md) wird für die Anfrage durchgeführt.
        - Ist die Anfrage extern und ist die Eigenschaft `Drop`, wird die Verbindung ohne Antwort an den Client geschlossen mit einem `HttpServerExecutionStatus = RemoteRequestDropped`.
    - Forwarding‑Resolver‑Konfiguration: Ist ein [ForwardingResolver](https://docs.sisk-framework.org/de/docs/advanced/forwarding-resolvers.md) konfiguriert, ruft er die Methode [OnResolveRequestHost](https://docs.sisk-framework.org/api/Sisk.Core.Http.ForwardingResolver.OnResolveRequestHost.md) auf dem ursprünglichen Host der Anfrage auf.
    - DNS‑Abgleich: Nachdem der Host aufgelöst wurde und mehr als ein [ListeningHost](https://docs.sisk-framework.org/api/Sisk.Core.Http.ListeningHost.md) konfiguriert ist, sucht der Server nach dem entsprechenden Host für die Anfrage.
        - Falls kein ListeningHost passt, wird dem Client eine 400 Bad Request‑Antwort zurückgegeben und dem HTTP‑Kontext der Status `HttpServerExecutionStatus = DnsUnknownHost` übermittelt.
        - Passt ein ListeningHost, dessen [Router](https://docs.sisk-framework.org/api/Sisk.Core.Http.ListeningHost.Router.md) jedoch noch nicht initialisiert ist, wird dem Client eine 503 Service Unavailable‑Antwort zurückgegeben und dem HTTP‑Kontext der Status `HttpServerExecutionStatus = ListeningHostNotReady` übermittelt.
    - Router‑Bindung: Der Router des entsprechenden ListeningHost wird dem empfangenen HTTP‑Server zugeordnet.
        - Ist der Router bereits einem anderen HTTP‑Server zugeordnet, was nicht zulässig ist, weil der Router aktiv die Konfigurationsressourcen des Servers nutzt, wird eine `InvalidOperationException` ausgelöst. Dies geschieht nur während der Initialisierung des HTTP‑Servers, nicht bei der Erstellung des HTTP‑Kontexts.
    - Vordefinition von Headern:
        - Definiert den Header `X-Request-Id` in der Antwort vor, falls dies konfiguriert ist.
        - Definiert den Header `X-Powered-By` in der Antwort vor, falls dies konfiguriert ist.
    - Validierung der Inhaltsgröße: Prüft, ob der Anfrageninhalt kleiner ist als [HttpServerConfiguration.MaximumContentLength](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.MaximumContentLength.md) (standardmäßig 100 MB), sofern er größer als null ist.
        - Sendet die Anfrage ein `Content-Length`, das größer ist als das konfigurierte, wird dem Client eine 413 Payload Too Large‑Antwort zurückgegeben und dem HTTP‑Kontext der Status `HttpServerExecutionStatus = ContentTooLarge` übermittelt.
    - Das Ereignis `OnHttpRequestOpen` wird für alle konfigurierten HTTP‑Server‑Handler aufgerufen.
- **Routing der Aktion:** Der Server ruft den Router für die empfangene Anfrage auf.
    - Findet der Router keine Route, die zur Anfrage passt:
        - Ist die Eigenschaft [Router.NotFoundErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.NotFoundErrorHandler.md) konfiguriert, wird die Aktion aufgerufen und die Antwort der Aktion an den HTTP‑Client weitergeleitet.
        - Ist die vorherige Eigenschaft null, wird dem Client eine standardmäßige 404 Not Found‑Antwort zurückgegeben.
    - Findet der Router eine passende Route, aber die Methode der Route stimmt nicht mit der Methode der Anfrage überein:
        - Ist die Eigenschaft [Router.MethodNotAllowedErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.MethodNotAllowedErrorHandler.md) konfiguriert, wird die Aktion aufgerufen und die Antwort der Aktion an den HTTP‑Client weitergeleitet.
        - Ist die vorherige Eigenschaft null, wird dem Client eine standardmäßige 405 Method Not Allowed‑Antwort zurückgegeben.
    - Ist die Anfrage von der Methode `OPTIONS`:
        - Gibt der Router nur dann eine 200 Ok‑Antwort an den Client zurück, wenn keine Route mit der Anfragemethode übereinstimmt (die Methode der Route ist nicht explizit [RouteMethod.Options](https://docs.sisk-framework.org/api/Sisk.Core.Routing.RouteMethod.md)).
    - Ist die Eigenschaft [HttpServerConfiguration.ForceTrailingSlash](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ForceTrailingSlash.md) aktiviert, die gefundene Route kein Regex ist, der Anforderungspfad nicht mit `/` endet und die Anfragemethode `GET` ist:
        - Wird dem Client eine 307 Temporary Redirect‑HTTP‑Antwort mit dem `Location`‑Header zurückgegeben, der Pfad und Abfrage zur gleichen Adresse mit einem abschließenden `/` enthält.
    - Das Ereignis `OnContextBagCreated` wird für alle konfigurierten HTTP‑Server‑Handler aufgerufen.
    - Alle globalen [IRequestHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.IRequestHandler.md)-Instanzen mit dem Flag `BeforeResponse` werden ausgeführt.
        - Gibt ein Handler eine nicht‑null‑Antwort zurück, wird diese Antwort an den HTTP‑Client weitergeleitet und der Kontext geschlossen.
        - Wird in diesem Schritt ein Fehler ausgelöst und ist [HttpServerConfiguration.ThrowExceptions](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ThrowExceptions.md) deaktiviert:
            - Ist die Eigenschaft [Router.CallbackErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.CallbackErrorHandler.md) aktiviert, wird sie aufgerufen und die resultierende Antwort dem Client zurückgegeben.
            - Ist die vorherige Eigenschaft nicht definiert, wird eine leere Antwort an den Server zurückgegeben, der dann eine Antwort basierend auf dem Typ der ausgelösten Ausnahme weiterleitet, üblicherweise 500 Internal Server Error.
    - Alle [IRequestHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.IRequestHandler.md)-Instanzen, die in der Route definiert sind und das Flag `BeforeResponse` besitzen, werden ausgeführt.
        - Gibt ein Handler eine nicht‑null‑Antwort zurück, wird diese Antwort an den HTTP‑Client weitergeleitet und der Kontext geschlossen.
        - Wird in diesem Schritt ein Fehler ausgelöst und ist [HttpServerConfiguration.ThrowExceptions](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ThrowExceptions.md) deaktiviert:
            - Ist die Eigenschaft [Router.CallbackErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.CallbackErrorHandler.md) aktiviert, wird sie aufgerufen und die resultierende Antwort dem Client zurückgegeben.
            - Ist die vorherige Eigenschaft nicht definiert, wird eine leere Antwort an den Server zurückgegeben, der dann eine Antwort basierend auf dem Typ der ausgelösten Ausnahme weiterleitet, üblicherweise 500 Internal Server Error.
    - Die Aktion des Routers wird aufgerufen und in eine HTTP‑Antwort umgewandelt.
        - Wird in diesem Schritt ein Fehler ausgelöst und ist [HttpServerConfiguration.ThrowExceptions](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ThrowExceptions.md) deaktiviert:
            - Ist die Eigenschaft [Router.CallbackErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.CallbackErrorHandler.md) aktiviert, wird sie aufgerufen und die resultierende Antwort dem Client zurückgegeben.
            - Ist die vorherige Eigenschaft nicht definiert, wird eine leere Antwort an den Server zurückgegeben, der dann eine Antwort basierend auf dem Typ der ausgelösten Ausnahme weiterleitet, üblicherweise 500 Internal Server Error.
    - Alle globalen [IRequestHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.IRequestHandler.md)-Instanzen mit dem Flag `AfterResponse` werden ausgeführt.
        - Gibt ein Handler eine nicht‑null‑Antwort zurück, ersetzt die Antwort des Handlers die vorherige Antwort und wird sofort an den HTTP‑Client weitergeleitet.
        - Wird in diesem Schritt ein Fehler ausgelöst und ist [HttpServerConfiguration.ThrowExceptions](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ThrowExceptions.md) deaktiviert:
            - Ist die Eigenschaft [Router.CallbackErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.CallbackErrorHandler.md) aktiviert, wird sie aufgerufen und die resultierende Antwort dem Client zurückgegeben.
            - Ist die vorherige Eigenschaft nicht definiert, wird eine leere Antwort an den Server zurückgegeben, der dann eine Antwort basierend auf dem Typ der ausgelösten Ausnahme weiterleitet, üblicherweise 500 Internal Server Error.
    - Alle [IRequestHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.IRequestHandler.md)-Instanzen, die in der Route definiert sind und das Flag `AfterResponse` besitzen, werden ausgeführt.
        - Gibt ein Handler eine nicht‑null‑Antwort zurück, ersetzt die Antwort des Handlers die vorherige Antwort und wird sofort an den HTTP‑Client weitergeleitet.
        - Wird in diesem Schritt ein Fehler ausgelöst und ist [HttpServerConfiguration.ThrowExceptions](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ThrowExceptions.md) deaktiviert:
            - Ist die Eigenschaft [Router.CallbackErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.CallbackErrorHandler.md) aktiviert, wird sie aufgerufen und die resultierende Antwort dem Client zurückgegeben.
            - Ist die vorherige Eigenschaft nicht definiert, wird eine leere Antwort an den Server zurückgegeben, der dann eine Antwort basierend auf dem Typ der ausgelösten Ausnahme weiterleitet, üblicherweise 500 Internal Server Error.
- **Verarbeiten der Antwort:** Sobald die Antwort bereit ist, bereitet der Server sie für das Senden an den Client vor.
    - Die Header der Cross‑Origin Resource Sharing‑Policy (CORS) werden in der Antwort gemäß der im aktuellen [ListeningHost.CrossOriginResourceSharingPolicy](https://docs.sisk-framework.org/api/Sisk.Core.Http.ListeningHost.CrossOriginResourceSharingPolicy.md) konfigurierten Richtlinie festgelegt.
    - Der Statuscode und die Header der Antwort werden an den Client gesendet.
    - Der Antwortinhalt wird an den Client gesendet:
        - Ist der Antwortinhalt ein Nachfolger von [ByteArrayContent](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.bytearraycontent), werden die Antwortbytes direkt in den Ausgabestream der Antwort kopiert.
        - Wird die vorherige Bedingung nicht erfüllt, wird die Antwort in einen Stream serialisiert und in den Ausgabestream der Antwort kopiert.
    - Die Streams werden geschlossen und der Antwortinhalt verworfen.
    - Ist [HttpServerConfiguration.DisposeDisposableContextValues](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.DisposeDisposableContextValues.md) aktiviert, werden alle im Anforderungskontext definierten Objekte, die von [IDisposable](https://learn.microsoft.com/en-us/dotnet/api/system.idisposable) erben, verworfen.
    - Das Ereignis `OnHttpRequestClose` wird für alle konfigurierten HTTP‑Server‑Handler aufgerufen.
    - Wurde auf dem Server eine Ausnahme ausgelöst, wird das Ereignis `OnException` für alle konfigurierten HTTP‑Server‑Handler aufgerufen.
    - Erlaubt die Route Zugriffs‑Logging und ist [HttpServerConfiguration.AccessLogsStream](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.AccessLogsStream.md) nicht null, wird eine Log‑Zeile in die Log‑Ausgabe geschrieben.
    - Erlaubt die Route Fehler‑Logging, liegt eine Ausnahme vor und ist [HttpServerConfiguration.ErrorsLogsStream](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ErrorsLogsStream.md) nicht null, wird eine Log‑Zeile in die Fehler‑Log‑Ausgabe geschrieben.
    - Wartet der Server über [HttpServer.WaitNext](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServer.WaitNext.md) auf eine Anfrage, wird das Mutex freigegeben und der Kontext dem Benutzer zur Verfügung gestellt.
