# flare.http.cache.middleware

> A module of flare_mlake's API.

HTTP cache middleware (RFC 9111).

``Cache[Inner, S]`` wraps an inner :class:`~flare.http.Handler` with
an RFC 9111-shaped HTTP cache backed by a pluggable
:class:`CacheStore`. On a request the middleware:

1. Computes the cache key from the request method + effective
   request URI, expanded by any prior ``Vary`` selection.
2. Looks the key up in the store. If hit + still fresh per
   :func:`is_fresh`, serves the stored response directly (no
   call into the inner handler, no parser run, no allocation
   beyond the response copy).
3. On miss or stale, calls the inner handler. If the response
   is cacheable (status code on the RFC 9111 §3 allow-list, no
   ``Cache-Control: no-store``, no ``Set-Cookie``), stores it
   with the parsed ``CacheControl`` + ``Vary`` carried alongside.

The middleware is generic over the store so callers can swap the
in-memory bounded store for a filesystem-backed or external
adapter without touching the handler graph. ``S`` only needs to
satisfy the :class:`CacheStore` trait.

The middleware intentionally does *not* drive conditional
revalidation (``If-None-Match`` / ``If-Modified-Since``) on its
own -- that surface lives in :class:`flare.http.Conditional`, and
users compose the two as ``Cache[Conditional[Inner], S]`` when
they want both. The split keeps each concern testable.

The cache is request-scoped: only ``GET`` and ``HEAD`` requests
hit the cache. ``POST`` / ``PUT`` / ``DELETE`` / ``PATCH`` /
``CONNECT`` / ``OPTIONS`` / ``TRACE`` invalidate any stored entry
for the same key on completion of a successful response, but
do not themselves consult the cache (RFC 9111 §4 + §4.4).

References:
- RFC 9111 §3 (storing responses).
- RFC 9111 §4 (constructing responses from caches).
- RFC 9111 §4.4 (invalidating stored responses).
- RFC 9110 §15.1 (status code semantics).

## Structs

### `Cache`

```mojo
struct Cache[Inner: Handler & Copyable, S: CacheStore & Deinitable]
```

RFC 9111 HTTP cache middleware.

The middleware composes on top of any :class:`CacheStore`
implementation. The default :class:`InMemoryCacheStore` is a
bounded FIFO; callers that want stricter LRU eviction or an
external store (Redis / memcached) swap the store without
touching the rest of the chain.

The store lives on the heap (via :class:`flare.runtime.Pool`)
and the middleware holds the address as an ``Int``; copies of
the middleware therefore share the same store, which matches
the per-worker singleton shape that ``Logger`` /
:class:`flare.http.Metrics` already use. The cell is leaked
at process exit (worker pthreads live the lifetime of the
server, so nothing meaningful to free); a future
``ArcPointer`` upgrade can swap the leak for ref-counting.

Example::

    from flare.http.cache import (
        Cache,
        InMemoryCacheStore,
    )
    var server = HttpServer(
        Cache[MyHandler, InMemoryCacheStore](
            inner=MyHandler(),
            store=InMemoryCacheStore.with_capacity(1024),
        )
    )

Parameters:

- `Inner`: The inner handler.
- `S`: The cache store; must satisfy the :class:`CacheStore`
   trait.

Implements: `Copyable`, `Handler`, `Movable`

Fields:

- `inner: Inner`: The wrapped handler.
- `store_addr: Int`: Heap address of the shared :class:`CacheStore` cell. Allocated in ``__init__``; intentionally leaked at process exit (see struct doc).

#### `BodyType`

```mojo
comptime BodyType = InlineBody
```

The ``Body`` impl this handler authors its response with.

Defaults to :struct:`InlineBody` so plain handlers that return
``Response`` conform without declaring it. Override in a handler that
returns a typed ``ResponseImpl[SomeBody]``.

#### `__init__`

```mojo
def __init__(out self, var inner: Inner, var store: S)
```

#### `serve`

```mojo
def serve(self, req: Request) -> Response
```
