Skip to content

Commit 83d9c9e

Browse files
committed
http: move first and move_to_first to Private
1 parent efd4ec0 commit 83d9c9e

File tree

4 files changed

+66
-63
lines changed

4 files changed

+66
-63
lines changed

cohttp-eio/src/client.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ let write_request writer request body =
3232
(Http.Request.headers request)
3333
body
3434
in
35+
let headers = Http.Header.Private.move_to_front headers "Host" in
3536
let meth = Http.Method.to_string @@ Http.Request.meth request in
3637
let version = Http.Version.to_string @@ Http.Request.version request in
3738
Buf_write.string writer meth;
@@ -72,16 +73,15 @@ let response buf_read =
7273

7374
let call ?meth ?version ?(headers = Http.Header.init ()) ?(body = Body.Empty)
7475
~conn host resource_path =
75-
let host_hdr = "Host" in
7676
let headers =
77-
if not (Http.Header.mem headers host_hdr) then
77+
if not (Http.Header.mem headers "Host") then
7878
let host =
7979
match host with
8080
| host, Some port -> host ^ ":" ^ string_of_int port
8181
| host, None -> host
8282
in
83-
Http.Header.add headers host_hdr host
84-
else Http.Header.move_to_front headers host_hdr
83+
Http.Header.add headers "Host" host
84+
else headers
8585
in
8686
let request = Http.Request.make ?meth ?version ~headers resource_path in
8787
Buf_write.with_flow ~initial_size:0x1000 conn (fun writer ->

http/src/http.ml

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,56 +14,51 @@ module Transfer = struct
1414
end
1515

1616
module Header = struct
17-
module Private = struct
18-
external string_unsafe_get64 : string -> int -> int64
19-
= "%caml_string_get64u"
17+
external string_unsafe_get64 : string -> int -> int64 = "%caml_string_get64u"
2018

21-
(* [caseless_equal a b] must be equivalent to
22-
[String.equal (String.lowercase_ascii a) (String.lowercase_ascii b)]. *)
23-
let caseless_equal a b =
24-
if a == b then true
25-
else
26-
let len = String.length a in
27-
len = String.length b
28-
(* Note: at this point we konw that [a] and [b] have the same length. *)
29-
&&
30-
(* [word_loop a b i len] compares strings [a] and [b] from
31-
offsets [i] (included) to [len] (excluded), one word at a time.
32-
[i] is a world-aligned index into the strings.
33-
*)
34-
let rec word_loop a b i len =
35-
if i = len then true
19+
(* [caseless_equal a b] must be equivalent to
20+
[String.equal (String.lowercase_ascii a) (String.lowercase_ascii b)]. *)
21+
let caseless_equal a b =
22+
if a == b then true
23+
else
24+
let len = String.length a in
25+
len = String.length b
26+
(* Note: at this point we konw that [a] and [b] have the same length. *)
27+
&&
28+
(* [word_loop a b i len] compares strings [a] and [b] from
29+
offsets [i] (included) to [len] (excluded), one word at a time.
30+
[i] is a world-aligned index into the strings.
31+
*)
32+
let rec word_loop a b i len =
33+
if i = len then true
34+
else
35+
let i' = i + 8 in
36+
(* If [i' > len], what remains to be compared is strictly
37+
less than a word long, use byte-per-byte comparison. *)
38+
if i' > len then byte_loop a b i len
39+
else if string_unsafe_get64 a i = string_unsafe_get64 b i then
40+
word_loop a b i' len
3641
else
37-
let i' = i + 8 in
38-
(* If [i' > len], what remains to be compared is strictly
39-
less than a word long, use byte-per-byte comparison. *)
40-
if i' > len then byte_loop a b i len
41-
else if string_unsafe_get64 a i = string_unsafe_get64 b i then
42-
word_loop a b i' len
43-
else
44-
(* If the words at [i] differ, it may due to a case
45-
difference; we check the individual bytes of this
46-
work, and then we continue checking the other
47-
words. *)
48-
byte_loop a b i i' && word_loop a b i' len
49-
(* [byte_loop a b i len] compares the strings [a] and [b] from
50-
offsets [i] (included) to [len] (excluded), one byte at
51-
a time.
52-
53-
This function assumes that [i < len] holds -- its only called
54-
by [word_loop] when this is known to hold. *)
55-
and byte_loop a b i len =
56-
let c1 = String.unsafe_get a i in
57-
let c2 = String.unsafe_get b i in
58-
Char.lowercase_ascii c1 = Char.lowercase_ascii c2
59-
&&
60-
let i' = i + 1 in
61-
i' = len || byte_loop a b i' len
62-
in
63-
word_loop a b 0 len
64-
end
65-
66-
let caseless_equal = Private.caseless_equal
42+
(* If the words at [i] differ, it may due to a case
43+
difference; we check the individual bytes of this
44+
work, and then we continue checking the other
45+
words. *)
46+
byte_loop a b i i' && word_loop a b i' len
47+
(* [byte_loop a b i len] compares the strings [a] and [b] from
48+
offsets [i] (included) to [len] (excluded), one byte at
49+
a time.
50+
51+
This function assumes that [i < len] holds -- its only called
52+
by [word_loop] when this is known to hold. *)
53+
and byte_loop a b i len =
54+
let c1 = String.unsafe_get a i in
55+
let c2 = String.unsafe_get b i in
56+
Char.lowercase_ascii c1 = Char.lowercase_ascii c2
57+
&&
58+
let i' = i + 1 in
59+
i' = len || byte_loop a b i' len
60+
in
61+
word_loop a b 0 len
6762

6863
type t = (string * string) list
6964

@@ -351,6 +346,12 @@ module Header = struct
351346
| Some v when v = "close" -> Some `Close
352347
| Some x -> Some (`Unknown x)
353348
| _ -> None
349+
350+
module Private = struct
351+
let caseless_equal = caseless_equal
352+
let first = first
353+
let move_to_front = move_to_front
354+
end
354355
end
355356

356357
module Status = struct

http/src/http.mli

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,6 @@ module Header : sig
256256
(** [get h k] returns [Some v] where [v] is the last added value associated
257257
with [k] in [h] if it exists and [None] otherwise *)
258258

259-
val first : t -> (string * string) option
260-
(** [first t] is [Some (hdr_name, hdr_value)], which represents the first
261-
header in headers list [t]. It is [None] if [t] is empty. *)
262-
263259
val get_multi : t -> string -> string list
264260
(** [get_multi h k] returns a list of all values associated with [k] in [h] in
265261
order they appear in it. *)
@@ -307,11 +303,6 @@ module Header : sig
307303
- If [k] was already associated in [h] to a list that is equal to [vs],
308304
[h] is returned unchanged. *)
309305

310-
val move_to_front : t -> string -> t
311-
(** [move_to_front t hdr_name] is [t] with header name [hdr_name] moved to the
312-
front of the headers list [t]. If the header doesn't exist in [t] or the
313-
header is already at the front, then [t] is unchanged. *)
314-
315306
val iter : (string -> string -> unit) -> t -> unit
316307
val map : (string -> string -> string) -> t -> t
317308
val fold : (string -> string -> 'a -> 'a) -> t -> 'a -> 'a
@@ -375,6 +366,15 @@ module Header : sig
375366
val caseless_equal : string -> string -> bool
376367
(** [caseless_equal a b] must be equivalent to
377368
[String.equal (String.lowercase_ascii a) (String.lowercase_ascii b)]. *)
369+
370+
val first : t -> (string * string) option
371+
(** [first t] is [Some (hdr_name, hdr_value)], which represents the first
372+
header in headers list [t]. It is [None] if [t] is empty. *)
373+
374+
val move_to_front : t -> string -> t
375+
(** [move_to_front t hdr_name] is [t] with header name [hdr_name] moved to
376+
the front of the headers list [t]. If the header doesn't exist in [t] or
377+
the header is already at the front, then [t] is unchanged. *)
378378
end
379379
end
380380

http/test/test_header.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,13 @@ let move_to_front_tests () =
175175
]
176176
in
177177
aeso {|move_to_front h "Host"|} (Some "Host")
178-
(H.(move_to_front (H.of_list headers1) "Host") |> H.first |> function
178+
(H.(Private.move_to_front (H.of_list headers1) "Host" |> Private.first)
179+
|> function
179180
| Some (k, _) -> Some k
180181
| None -> Some "");
181182
aeso {|move_to_front h "Host"|} (Some "Host")
182-
(H.(move_to_front (H.of_list headers2) "Host") |> H.first |> function
183+
(H.(Private.move_to_front (H.of_list headers2) "Host" |> Private.first)
184+
|> function
183185
| Some (k, _) -> Some k
184186
| None -> Some "")
185187

0 commit comments

Comments
 (0)