# flare.http.headers

> A module of flare_mlake's API.

HTTP header collection with case-insensitive key lookup.

Lookups use inline case-insensitive byte comparison (no pre-computed
lowercase mirror). Original casing is preserved for wire serialisation.

## Structs

### `HeaderInjectionError`

```mojo
struct HeaderInjectionError
```

Raised when a header key or value contains CR or LF bytes.

Implements: `Copyable`, `Movable`, `Writable`

Fields:

- `field: String`
- `value: String`

#### `__init__`

```mojo
def __init__(out self, field: String, value: String)
```

#### `write_to`

```mojo
def write_to[W: Writer](self, mut writer: W)
```

### `HeaderMap`

```mojo
struct HeaderMap
```

An ordered, case-insensitive HTTP header collection.

Keys are stored in their original casing. Lookups use inline
case-insensitive byte comparison -- no pre-computed lowercase list.

This type is ``Movable`` but not ``Copyable``.
Use ``copy()`` when an explicit copy is needed.

Example:
```mojo
var h = HeaderMap()
h.set("Content-Type", "application/json")
print(h.get("content-type")) # application/json
```

Implements: `Movable`, `Writable`

#### `__init__`

```mojo
def __init__(out self)
```

#### `reserve`

```mojo
def reserve(mut self, n: Int)
```

Make room for ``n`` fields without regrowing.

#### `set_unchecked`

```mojo
def set_unchecked(mut self, key: String, lk: String, value: String)
```

Set a header without injection checks.

The ``lk`` parameter is accepted for API compatibility but ignored;
lookup uses inline case-insensitive comparison on ``key``.

Args:

- `key`: Header name.
- `lk`: Ignored (kept for backward compat).
- `value`: Header value.

#### `copy`

```mojo
def copy(self) -> Self
```

Return a deep copy of this ``HeaderMap``.

#### `set`

```mojo
def set(mut self, key: String, value: String)
```

Set a header, replacing any existing value with the same key.

Args:

- `key`: Header name (case-insensitive; stored in original casing).
- `value`: Header value.

Raises: HeaderInjectionError: If ``key`` or ``value`` contains ``\r`` or ``\n``.

#### `append`

```mojo
def append(mut self, key: String, value: String)
```

Append a header without replacing existing values.

Args:

- `key`: Header name.
- `value`: Header value.

Raises: HeaderInjectionError: If ``key`` or ``value`` contains ``\r`` or ``\n``.

#### `get`

```mojo
def get(self, key: String) -> String
```

Return the first value for ``key``, or ``""`` if absent.

Args:

- `key`: Header name (case-insensitive).

#### `get_all`

```mojo
def get_all(self, key: String) -> List[String]
```

Return all values for ``key`` in insertion order.

Args:

- `key`: Header name (case-insensitive).

#### `contains`

```mojo
def contains(self, key: String) -> Bool
```

Return True if the header is present.

Args:

- `key`: Header name (case-insensitive).

#### `remove`

```mojo
def remove(mut self, key: String) -> Bool
```

Remove all entries with the given key.

Args:

- `key`: Header name (case-insensitive).

#### `len`

```mojo
def len(self) -> Int
```

Return the total number of header entries (including duplicates).

#### `name_at`

```mojo
def name_at(self, i: Int) -> ref[self._keys["element"]] String
```

The name of field ``i``, in the order the fields were added.

With :meth:`value_at` and :meth:`len`, this walks every field once,
repeated names as separate entries, without copying::

    for i in range(h.len()):
        use(h.name_at(i), h.value_at(i))

Raises: Error: If ``i`` is not in ``[0, len())``.

#### `value_at`

```mojo
def value_at(self, i: Int) -> ref[self._values["element"]] String
```

The value of field ``i``; see :meth:`name_at`.

Raises: Error: If ``i`` is not in ``[0, len())``.

#### `write_to`

```mojo
def write_to[W: Writer](self, mut writer: W)
```

#### `encode_to`

```mojo
def encode_to(self, mut buf: List[UInt8])
```

Serialise all headers as wire bytes into ``buf``.

Appends ``key: value\r\n`` for each header.

## Functions

### `trailer_field_allowed`

```mojo
def trailer_field_allowed(name: String) -> Bool
```

Whether a trailer field may be kept: not one that frames, routes, authenticates or describes the content (RFC 9110 sec 6.5.1).
