Open
Description
To reduce request size, often the body is compressed. A mechanism that supports this is currently missing from Wisp.
I am not quite sure what scope of a solution is a good fit for Wisp. A full flow will be:
- Detect compressions supported by the browser using the
accept-encoding
header - Compress non-binary bodies
- Set the
content-encoding
header to indicate the compression for responses compressed on the fly - Allow setting the header for static files that are pre-compressed
Steps 1 through 3 are fairly straightforward to do on top of wisp:
let accept_encoding =
req.headers
|> list.find_map(fn(header) {
case header.0 == "accept-encoding" {
True -> Ok(header.1)
False -> Error(Nil)
}
})
|> result.unwrap("")
|> string.split(",")
|> list.map(string.trim)
let deflate_accepted = accept_encoding |> list.contains("deflate")
case res.body, deflate_accepted {
wisp.Text(body), True ->
res
|> wisp.set_header("content-encoding", "deflate")
|> wisp.set_body(
body
|> string_builder.to_string
|> bit_array.from_string
|> gzlib.compress
|> bytes_builder.from_bit_array
|> wisp.Bytes,
)
_, _ -> res
}
But there's no clear way to achieve step 4
My current work around is to hard-code the file names:
let res =
wisp.serve_static(
req,
under: "/priv/static",
from: client_priv_static,
next: fun,
)
let compressed_statics = [ "script.mjs" ]
case compressed_statics |> list.any(string.contains(req.path, _)) {
True -> res |> wisp.set_header("content-encoding", "gzip")
False -> res
}
But even beyond the hard-coding of file name, this checks every response
Metadata
Assignees
Labels
No labels