# `Sofa.Cushion`
[🔗](https://github.com/skunkwerks/sofa/blob/0.5.1/lib/sofa/cushion.ex#L1)

Internal Helpers for Sofa, with a vanity naming convention.

> If the only tool you have is CouchDB, everything is very
> uncomfortable without a Cushion.

# `headers`

```elixir
@type headers() :: %{optional(binary()) =&gt; [binary()]} | [{binary(), binary()}]
```

# `path`

```elixir
@spec path([String.t()]) :: String.t()
```

Joins path segments into a request path, URL-encoding each one.

Database names may contain `/` and `+`, document ids spaces and anything
else, and attachment names must be URL encoded per the CouchDB docs. The
`_design/` and `_local/` prefixes of special document ids keep their
slash, as CouchDB routes on them.

    iex> Sofa.Cushion.path(["recipes", "Spaghetti With Meatballs", "photo 1.jpg"])
    "recipes/Spaghetti%20With%20Meatballs/photo%201.jpg"

    iex> Sofa.Cushion.path(["my/db", "_design/app"])
    "my%2Fdb/_design/app"

# `untaint_headers`

```elixir
@spec untaint_headers(headers()) :: map()
```

Sanitise HTTP headers into ones we trust and format, and drop the rest.
This is necessary because proxies, clients, HTTP1* and HTTP2 all disagree
about whether headers should be upper, lower, camel, snake, or wtf case.

    Server : CouchDB/3.1.1 (Erlang OTP/22)
    X-Couch-Request-Id : f5b74b7038
    X-Couchdb-Body-Time : 0
    Cache-Control : must-revalidate
    Content-Length : 443
    Content-Type : application/json
    Date : Sun, 25 Apr 2021 18:43:36 GMT
    Etag : "4-322add00c33cab838bf9d7909f18d4f5"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
