1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
include Http.Header
let media_type_re =
let re = Re.Emacs.re ~case:true "[ \t]*\\([^ \t;]+\\)" in
Re.(compile (seq [ start; re ]))
let get_first_match _re s =
try
let subs = Re.exec ~pos:0 media_type_re s in
let start, stop = Re.Group.offset subs 1 in
Some (String.sub s start (stop - start))
with Not_found -> None
let get_media_type =
match get headers "content-type" with
| Some s -> get_first_match media_type_re s
| None -> None
let get_acceptable_media_ranges =
Accept.media_ranges (get_multi_concat ~list_value_only:true headers "accept")
let get_acceptable_charsets =
Accept.charsets
(get_multi_concat ~list_value_only:true headers "accept-charset")
let get_acceptable_encodings =
Accept.encodings
(get_multi_concat ~list_value_only:true headers "accept-encoding")
let get_acceptable_languages =
Accept.languages
(get_multi_concat ~list_value_only:true headers "accept-language")
let get_transfer_encoding =
match get_multi_concat ~list_value_only:true headers "transfer-encoding" with
| Some "chunked" -> Transfer.Chunked
| Some _ | None -> (
match get_content_range headers with
| Some len -> Transfer.Fixed len
| None -> Transfer.Unknown)
let add_transfer_encoding enc =
let open Transfer in
match (get_transfer_encoding headers, enc) with
| Fixed _, _ | Chunked, _
->
headers
| Unknown, Chunked -> add headers "transfer-encoding" "chunked"
| Unknown, Fixed len -> add headers "content-length" (Int64.to_string len)
| Unknown, Unknown -> headers
let add_authorization_req challenge =
add headers "www-authenticate" (Auth.string_of_challenge challenge)
let add_authorization cred =
add headers "authorization" (Auth.string_of_credential cred)
let get_authorization =
match get headers "authorization" with
| None -> None
| Some v -> Some (Auth.credential_of_string v)
let is_form =
get_media_type headers = Some "application/x-www-form-urlencoded"
let get_location =
match get_location headers with
| None -> None
| Some u -> Some (Uri.of_string u)
let get_links =
List.rev
(List.fold_left
(fun list link_s -> List.rev_append (Link.of_string link_s) list)
[] (get_multi headers "link"))
let add_links links =
add_multi headers "link" (List.map Link.to_string links)
let user_agent = Printf.sprintf "ocaml-cohttp/%s" Conf.version
let prepend_user_agent user_agent =
let k = "user-agent" in
match get headers k with
| Some ua -> replace headers k (user_agent ^ " " ^ ua)
| None -> add headers k user_agent
let connection h =
match get h "connection" with
| Some v when v = "keep-alive" -> Some `Keep_alive
| Some v when v = "close" -> Some `Close
| Some x -> Some (`Unknown x)
| _ -> None
open Sexplib0.Sexp_conv
let sexp_of_t t =
sexp_of_list (sexp_of_pair sexp_of_string sexp_of_string) (to_list t)
let t_of_sexp s =
of_list (list_of_sexp (pair_of_sexp string_of_sexp string_of_sexp) s)
let pp_hum ppf h =
Format.fprintf ppf "%s" (h |> sexp_of_t |> Sexplib0.Sexp.to_string_hum)