import gleam/bytes_tree import gleam/http/response import gleam/int import gleam/list /// Encodes an HTTP response into bytes. /// pub fn encode_response( response: response.Response(BitArray), ) -> bytes_tree.BytesTree { bytes_tree.new() |> bytes_tree.append(encode_status_line(response.status)) |> bytes_tree.append(encode_headers(response.headers)) |> bytes_tree.append(response.body) } /// Encodes the HTTP status line and headers of an HTTP response. /// pub fn encode_response_partially( response: response.Response(a), ) -> bytes_tree.BytesTree { bytes_tree.new() |> bytes_tree.append(encode_status_line(response.status)) |> bytes_tree.append(encode_headers(response.headers)) } /// Encodes the HTTP status line. /// fn encode_status_line(status: Int) -> BitArray { let status_name = status_to_bit_array(status) let status = int.to_string(status) <<"HTTP/1.1 ", status:utf8, " ", status_name:bits, "\r\n">> } /// Encodes HTTP headers into bytes. /// fn encode_headers(headers: List(#(String, String))) -> BitArray { let headers = list.fold(headers, <<>>, fn(acc, headers) { let #(key, value) = headers <> }) <> } /// Maps HTTP status codes to their text descriptions. /// fn status_to_bit_array(status: Int) -> BitArray { case status { 100 -> <<"Continue">> 101 -> <<"Switching Protocols">> 102 -> <<"Processing">> 103 -> <<"Early Hints">> 200 -> <<"OK">> 201 -> <<"Created">> 202 -> <<"Accepted">> 203 -> <<"Non-Authoritative Information">> 204 -> <<"No Content">> 205 -> <<"Reset Content">> 206 -> <<"Partial Content">> 207 -> <<"Multi-Status">> 208 -> <<"Already Reported">> 226 -> <<"IM Used">> 300 -> <<"Multiple Choices">> 301 -> <<"Moved Permanently">> 302 -> <<"Found">> 303 -> <<"See Other">> 304 -> <<"Not Modified">> 307 -> <<"Temporary Redirect">> 308 -> <<"Permanent Redirect">> 400 -> <<"Bad Request">> 401 -> <<"Unauthorized">> 403 -> <<"Forbidden">> 404 -> <<"Not Found">> 405 -> <<"Method Not Allowed">> 406 -> <<"Not Acceptable">> 407 -> <<"Proxy Authentication Required">> 408 -> <<"Request Timeout">> 409 -> <<"Conflict">> 410 -> <<"Gone">> 411 -> <<"Length Required">> 412 -> <<"Precondition Failed">> 413 -> <<"Payload Too Large">> 414 -> <<"URI Too Long">> 415 -> <<"Unsupported Media Type">> 416 -> <<"Range Not Satisfiable">> 417 -> <<"Expectation Failed">> 418 -> <<"I'm a teapot">> 421 -> <<"Misdirected Request">> 422 -> <<"Unprocessable Entity">> 423 -> <<"Locked">> 424 -> <<"Failed Dependency">> 425 -> <<"Too Early">> 426 -> <<"Upgrade Required">> 428 -> <<"Precondition Required">> 429 -> <<"Too Many Requests">> 431 -> <<"Request Header Fields Too Large">> 451 -> <<"Unavailable For Legal Reasons">> 500 -> <<"Internal Server Error">> 501 -> <<"Not Implemented">> 502 -> <<"Bad Gateway">> 503 -> <<"Service Unavailable">> 504 -> <<"Gateway Timeout">> 505 -> <<"HTTP Version Not Supported">> 506 -> <<"Variant Also Negotiates">> 507 -> <<"Insufficient Storage">> 508 -> <<"Loop Detected">> 510 -> <<"Not Extended">> 511 -> <<"Network Authentication Required">> _ -> <<"Unknown HTTP Status">> } }