@@ -4,24 +4,38 @@ type t = (string * string) list
44
55let empty = []
66
7+ (* [Char.lowercase_ascii] but easier to inline *)
8+ let [@ inline] lower_char_ = function
9+ | 'A' .. 'Z' as c -> Char. unsafe_chr (Char. code c + 32 )
10+ | c -> c
11+
12+ (* * Are these two header names equal? This is case insensitive *)
13+ let equal_name_ (s1 : string ) (s2 : string ) : bool =
14+ String. length s1 = String. length s2
15+ &&
16+ try
17+ for i = 0 to String. length s1 - 1 do
18+ let c1 = String. unsafe_get s1 i |> lower_char_ in
19+ let c2 = String. unsafe_get s2 i |> lower_char_ in
20+ if c1 <> c2 then raise_notrace Exit
21+ done ;
22+ true
23+ with Exit -> false
24+
725let contains name headers =
8- let name' = String. lowercase_ascii name in
9- List. exists (fun (n , _ ) -> name' = n) headers
26+ List. exists (fun (n , _ ) -> equal_name_ name n) headers
1027
11- let get_exn ?(f = fun x -> x) x h =
12- let x' = String. lowercase_ascii x in
13- List. assoc x' h |> f
28+ let rec get_exn ?(f = fun x -> x) x h =
29+ match h with
30+ | [] -> raise Not_found
31+ | (k , v ) :: _ when equal_name_ x k -> f v
32+ | _ :: tl -> get_exn ~f x tl
1433
1534let get ?(f = fun x -> x) x h =
1635 try Some (get_exn ~f x h) with Not_found -> None
1736
18- let remove x h =
19- let x' = String. lowercase_ascii x in
20- List. filter (fun (k , _ ) -> k <> x') h
21-
22- let set x y h =
23- let x' = String. lowercase_ascii x in
24- (x', y) :: List. filter (fun (k , _ ) -> k <> x') h
37+ let remove x h = List. filter (fun (k , _ ) -> not (equal_name_ k x)) h
38+ let set x y h = (x, y) :: List. filter (fun (k , _ ) -> not (equal_name_ k x)) h
2539
2640let pp out l =
2741 let pp_pair out (k , v ) = Format. fprintf out " @[<h>%s: %s@]" k v in
@@ -76,6 +90,6 @@ let parse_ ~(buf : Buf.t) (bs : IO.Input.t) : t =
7690 | Error msg ->
7791 bad_reqf 400 " invalid header line: %s\n line is: %S" msg line
7892 in
79- loop ((String. lowercase_ascii k, v) :: acc)
93+ loop ((k, v) :: acc)
8094 in
8195 loop []
0 commit comments