mirror of
https://github.com/c-cube/tiny_httpd.git
synced 2025-12-07 03:35:34 -05:00
70 lines
2 KiB
OCaml
70 lines
2 KiB
OCaml
open Common_
|
|
|
|
type t = (string * string) list
|
|
|
|
let empty = []
|
|
|
|
let contains name headers =
|
|
let name' = String.lowercase_ascii name in
|
|
List.exists (fun (n, _) -> name' = n) headers
|
|
|
|
let get_exn ?(f = fun x -> x) x h =
|
|
let x' = String.lowercase_ascii x in
|
|
List.assoc x' h |> f
|
|
|
|
let get ?(f = fun x -> x) x h =
|
|
try Some (get_exn ~f x h) with Not_found -> None
|
|
|
|
let remove x h =
|
|
let x' = String.lowercase_ascii x in
|
|
List.filter (fun (k, _) -> k <> x') h
|
|
|
|
let set x y h =
|
|
let x' = String.lowercase_ascii x in
|
|
(x', y) :: List.filter (fun (k, _) -> k <> x') h
|
|
|
|
let pp out l =
|
|
let pp_pair out (k, v) = Format.fprintf out "@[<h>%s: %s@]" k v in
|
|
Format.fprintf out "@[<v>%a@]" (Format.pp_print_list pp_pair) l
|
|
|
|
(* token = 1*tchar
|
|
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_"
|
|
/ "`" / "|" / "~" / DIGIT / ALPHA ; any VCHAR, except delimiters
|
|
Reference: https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 *)
|
|
let is_tchar = function
|
|
| '0' .. '9'
|
|
| 'a' .. 'z'
|
|
| 'A' .. 'Z'
|
|
| '!' | '#' | '$' | '%' | '&' | '\'' | '*' | '+' | '-' | '.' | '^' | '_' | '`'
|
|
| '|' | '~' ->
|
|
true
|
|
| _ -> false
|
|
|
|
let for_all pred s =
|
|
try
|
|
String.iter (fun c -> if not (pred c) then raise Exit) s;
|
|
true
|
|
with Exit -> false
|
|
|
|
let parse_ ~(buf : Buf.t) (bs : IO.Input.t) : t =
|
|
let rec loop acc =
|
|
match IO.Input.read_line_using_opt ~buf bs with
|
|
| None -> raise End_of_file
|
|
| Some "\r" -> acc
|
|
| Some line ->
|
|
Log.debug (fun k -> k "parsed header line %S" line);
|
|
let k, v =
|
|
try
|
|
let i = String.index line ':' in
|
|
let k = String.sub line 0 i in
|
|
if not (for_all is_tchar k) then
|
|
invalid_arg (Printf.sprintf "Invalid header key: %S" k);
|
|
let v =
|
|
String.sub line (i + 1) (String.length line - i - 1) |> String.trim
|
|
in
|
|
k, v
|
|
with _ -> bad_reqf 400 "invalid header line: %S" line
|
|
in
|
|
loop ((String.lowercase_ascii k, v) :: acc)
|
|
in
|
|
loop []
|