# Anfragelebenszyklus

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 Anfrage selbst und der Antwort, die dem Client zugestellt wird. Dieser Kontext stammt vom integrierten Listener in Sisk, der [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 Anforderungsvalidierung: Die Validierung von [HttpServerConfiguration.RemoteRequestsAction](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.RemoteRequestsAction.md) wird für die Anfrage durchgeführt.
        - Wenn die Anfrage extern ist und die Eigenschaft `Drop` ist, wird die Verbindung ohne Antwort an den Client geschlossen mit einem `HttpServerExecutionStatus = RemoteRequestDropped`.
    - Forwarding‑Resolver‑Konfiguration: Wenn ein [ForwardingResolver](https://docs.sisk-framework.org/de/docs/advanced/forwarding-resolvers.md) konfiguriert ist, 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: Mit dem aufgelösten Host und mehr als einem konfigurierten [ListeningHost](https://docs.sisk-framework.org/api/Sisk.Core.Http.ListeningHost.md) sucht der Server nach dem entsprechenden Host für die Anfrage.
        - Wenn kein ListeningHost passt, wird eine 400 Bad Request‑Antwort an den Client zurückgegeben und ein `HttpServerExecutionStatus = DnsUnknownHost`‑Status an den HTTP‑Kontext zurückgegeben.
        - Wenn ein ListeningHost passt, dessen [Router](https://docs.sisk-framework.org/api/Sisk.Core.Http.ListeningHost.Router.md) jedoch noch nicht initialisiert ist, wird eine 503 Service Unavailable‑Antwort an den Client zurückgegeben und ein `HttpServerExecutionStatus = ListeningHostNotReady`‑Status an den HTTP‑Kontext zurückgegeben.
    - Router‑Bindung: Der Router des entsprechenden ListeningHost wird dem empfangenen HTTP‑Server zugeordnet.
        - Wenn der Router bereits einem anderen HTTP‑Server zugeordnet ist (was nicht erlaubt 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 während der Erstellung des HTTP‑Kontexts.
    - Vordefinition von Headern:
        - Definiert den Header `X-Request-Id` in der Antwort, wenn dies konfiguriert ist.
        - Definiert den Header `X-Powered-By` in der Antwort, wenn dies konfiguriert ist.
    - Inhaltsgrößen‑Validierung: Prüft, ob der Anforderungsinhalt kleiner ist als [HttpServerConfiguration.MaximumContentLength](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.MaximumContentLength.md), sofern dieser Wert größer als null ist.
        - Wenn die Anfrage einen `Content-Length`‑Wert sendet, der größer ist als der konfigurierte, wird eine 413 Payload Too Large‑Antwort an den Client zurückgegeben und ein `HttpServerExecutionStatus = ContentTooLarge`‑Status an den HTTP‑Kontext zurückgegeben.
    - 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.
    - Wenn der Router keine Route findet, die zur Anfrage passt:
        - Wenn die Eigenschaft [Router.NotFoundErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.NotFoundErrorHandler.md) konfiguriert ist, wird die Aktion aufgerufen und die Antwort der Aktion an den HTTP‑Client weitergeleitet.
        - Wenn die vorherige Eigenschaft null ist, wird eine standardmäßige 404 Not Found‑Antwort an den Client zurückgegeben.
    - Wenn der Router eine passende Route findet, die Methode der Route jedoch nicht mit der Methode der Anfrage übereinstimmt:
        - Wenn die Eigenschaft [Router.MethodNotAllowedErrorHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.MethodNotAllowedErrorHandler.md) konfiguriert ist, wird die Aktion aufgerufen und die Antwort der Aktion an den HTTP‑Client weitergeleitet.
        - Wenn die vorherige Eigenschaft null ist, wird eine standardmäßige 405 Method Not Allowed‑Antwort an den Client zurückgegeben.
    - Wenn die Anfrage die Methode `OPTIONS` hat:
        - Gibt der Router nur dann eine 200 Ok‑Antwort an den Client zurück, wenn keine Route die Anfragemethode (die Route‑Methode ist nicht explizit [RouteMethod.Options](https://docs.sisk-framework.org/api/Sisk.Core.Routing.RouteMethod.md)) erfüllt.
    - Wenn die Eigenschaft [HttpServerConfiguration.ForceTrailingSlash](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ForceTrailingSlash.md) aktiviert ist, die gefundene Route kein Regex ist, der Anforderungspfad nicht mit `/` endet und die Anfragemethode `GET` ist:
        - Wird eine 307 Temporary Redirect‑HTTP‑Antwort mit dem `Location`‑Header, der Pfad und Query zur gleichen Adresse mit einem abschließenden `/` enthält, an den Client zurückgegeben.
    - 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 an den Client zurückgegeben.
            - Wenn die vorherige Eigenschaft nicht definiert ist, wird eine leere Antwort an den Server zurückgegeben, der dann je nach Art der ausgelösten Ausnahme eine Antwort (meist 500 Internal Server Error) weiterleitet.
    - Alle [IRequestHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.IRequestHandler.md)‑Instanzen, die in der Route definiert und mit dem Flag `BeforeResponse` versehen sind, 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 an den Client zurückgegeben.
            - Wenn die vorherige Eigenschaft nicht definiert ist, wird eine leere Antwort an den Server zurückgegeben, der dann je nach Art der ausgelösten Ausnahme eine Antwort (meist 500 Internal Server Error) weiterleitet.
    - 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 an den Client zurückgegeben.
            - Wenn die vorherige Eigenschaft nicht definiert ist, wird eine leere Antwort an den Server zurückgegeben, der dann je nach Art der ausgelösten Ausnahme eine Antwort (meist 500 Internal Server Error) weiterleitet.
    - 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 an den Client zurückgegeben.
            - Wenn die vorherige Eigenschaft nicht definiert ist, wird eine leere Antwort an den Server zurückgegeben, der dann je nach Art der ausgelösten Ausnahme eine Antwort (meist 500 Internal Server Error) weiterleitet.
    - Alle [IRequestHandler](https://docs.sisk-framework.org/api/Sisk.Core.Routing.IRequestHandler.md)‑Instanzen, die in der Route definiert und mit dem Flag `AfterResponse` versehen sind, 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 an den Client zurückgegeben.
            - Wenn die vorherige Eigenschaft nicht definiert ist, wird eine leere Antwort an den Server zurückgegeben, der dann je nach Art der ausgelösten Ausnahme eine Antwort (meist 500 Internal Server Error) weiterleitet.
- **Verarbeitung der Antwort:** Sobald die Antwort fertig ist, bereitet der Server sie für den Versand an den Client vor.
    - Die Cross‑Origin Resource Sharing‑Policy (CORS)‑Header werden in der Antwort gemäß der im aktuellen [ListeningHost.CrossOriginResourceSharingPolicy](https://docs.sisk-framework.org/api/Sisk.Core.Http.ListeningHost.CrossOriginResourceSharingPolicy.md) konfigurierten Richtlinie definiert.
    - 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 Antwort‑Bytes 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.
    - Wird auf dem Server eine Ausnahme ausgelöst, wird das Ereignis `OnException` für alle konfigurierten HTTP‑Server‑Handler aufgerufen.
    - Erlaubt die Route das 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 das 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 wieder zur Verfügung gestellt.
