Skip to content

Commit e78a105

Browse files
committed
feat(headers): use case insensitive comparison
1 parent 08b8e1e commit e78a105

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

src/core/headers.ml

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,38 @@ type t = (string * string) list
44

55
let 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+
725
let 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
1534
let 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
2640
let 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\nline is: %S" msg line
7892
in
79-
loop ((String.lowercase_ascii k, v) :: acc)
93+
loop ((k, v) :: acc)
8094
in
8195
loop []

src/core/headers.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ val contains : string -> t -> bool
3232
val pp : Format.formatter -> t -> unit
3333
(** Pretty print the headers. *)
3434

35-
val parse_ : buf:Buf.t -> IO.Input.t -> t
3635
(**/*)
3736

37+
val parse_ : buf:Buf.t -> IO.Input.t -> t
3838
val parse_line_ : string -> (string * string, string) result
39+
3940
(**/*)

0 commit comments

Comments
 (0)