-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhttp_response.ml
101 lines (84 loc) · 3.41 KB
/
http_response.ml
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
(*
OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
Copyright (C) <2002-2005> Stefano Zacchiroli <[email protected]>
Copyright (C) <2009> Anil Madhavapeddy <[email protected]>
Copyright (C) <2009> David Sheets <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as
published by the Free Software Foundation, version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
*)
open Http_types
open Http_constants
open Http_common
open Printf
open Lwt
let status_line_RE = Pcre.regexp "^(HTTP/\\d\\.\\d) (\\d{3}) (.*)$"
let anyize = function
| Some addr -> addr
| None -> Unix.ADDR_INET (Unix.inet_addr_any, -1)
type response = {
r_msg: Http_message.message;
mutable r_code: int;
mutable r_reason: string option;
}
let add_basic_headers r =
Http_message.add_header r.r_msg ~name:"Date" ~value:(Http_misc.date_822 ());
Http_message.add_header r.r_msg ~name:"Server" ~value:server_string
let init
?(body = [`String ""]) ?(headers = []) ?(version = default_version)
?(status=`Code 200) ?reason ?clisockaddr ?srvsockaddr ()
=
let (clisockaddr, srvsockaddr) = (anyize clisockaddr, anyize srvsockaddr) in
let r = { r_msg = Http_message.init ~body ~headers ~version ~clisockaddr ~srvsockaddr;
r_code = begin match status with
| `Code c -> c
| `Status s -> code_of_status s
end;
r_reason = reason } in
let () = add_basic_headers r in r
let version_string r = string_of_version (Http_message.version r.r_msg)
let code r = r.r_code
let set_code r c =
ignore (status_of_code c); (* sanity check on c *)
r.r_code <- c
let status r = status_of_code (code r)
let set_status r (s: Http_types.status) = r.r_code <- code_of_status s
let reason r =
match r.r_reason with
| None -> Http_misc.reason_phrase_of_code r.r_code
| Some r -> r
let set_reason r rs = r.r_reason <- Some rs
let status_line r =
String.concat " "
[version_string r; string_of_int (code r); reason r ]
let is_informational r = Http_common.is_informational r.r_code
let is_success r = Http_common.is_success r.r_code
let is_redirection r = Http_common.is_redirection r.r_code
let is_client_error r = Http_common.is_client_error r.r_code
let is_server_error r = Http_common.is_server_error r.r_code
let is_error r = Http_common.is_error r.r_code
let gh name r =
match Http_message.header r.r_msg ~name with [] -> None | x :: _ -> Some x
let rh name r = Http_message.replace_header r.r_msg ~name
let content_type = gh "Content-Type"
let set_content_type = rh "Content-Type"
let content_encoding = gh "Content-Encoding"
let set_content_encoding = rh "Content-Encoding"
let date = gh "Date"
let set_date = rh "Date"
let expires = gh "Expires"
let set_expires = rh "Expires"
let server = gh "Server"
let set_server = rh "Server"
let serialize r outchan =
let fstLineToString =
sprintf "%s %d %s" (version_string r) (code r) (reason r) in
Http_message.serialize r.r_msg outchan ~fstLineToString