]> matita.cs.unibo.it Git - helm.git/blob - DEVEL/ocaml-http/http_message.ml
- added some documentation on the fwd tatcic
[helm.git] / DEVEL / ocaml-http / http_message.ml
1
2 (*
3   OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
4
5   Copyright (C) <2002-2005> Stefano Zacchiroli <zack@cs.unibo.it>
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU Library General Public License as
9   published by the Free Software Foundation, version 2.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU Library General Public License for more details.
15
16   You should have received a copy of the GNU Library General Public
17   License along with this program; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
19   USA
20 *)
21
22 open Http_common;;
23 open Http_constants;;
24 open Http_types;;
25 open Printf;;
26
27   (* remove all bindings of 'name' from hashtbl 'tbl' *)
28 let rec hashtbl_remove_all tbl name =
29   if not (Hashtbl.mem tbl name) then
30     raise (Header_not_found name);
31   Hashtbl.remove tbl name;
32   if Hashtbl.mem tbl name then hashtbl_remove_all tbl name
33 ;;
34
35 class virtual message ~body ~headers ~version ~clisockaddr ~srvsockaddr =
36
37   let ((cliaddr, cliport), (srvaddr, srvport)) =
38     (Http_misc.explode_sockaddr clisockaddr,
39      Http_misc.explode_sockaddr srvsockaddr)
40   in
41
42   object (self)
43
44     val _contentsBuf = Buffer.create 1024
45     val _headers = Hashtbl.create 11
46     val mutable _version: version option = version
47
48     initializer
49       self#setBody body;
50       self#addHeaders headers
51
52     method version = _version
53     method setVersion v = _version <- Some v
54
55     method body = Buffer.contents _contentsBuf
56     method setBody c =
57       Buffer.clear _contentsBuf;
58       Buffer.add_string _contentsBuf c
59     method bodyBuf = _contentsBuf
60     method setBodyBuf b =
61       Buffer.clear _contentsBuf;
62       Buffer.add_buffer _contentsBuf b
63     method addBody s = Buffer.add_string _contentsBuf s
64     method addBodyBuf b = Buffer.add_buffer _contentsBuf b
65
66     method addHeader ~name ~value =
67       let name = String.lowercase name in
68       Http_parser_sanity.heal_header (name, value);
69       Hashtbl.add _headers name value
70     method addHeaders =
71       List.iter (fun (name, value) -> self#addHeader ~name ~value)
72     method replaceHeader ~name ~value =
73       let name = String.lowercase name in
74       Http_parser_sanity.heal_header (name, value);
75       Hashtbl.replace _headers name value
76     method replaceHeaders =
77       List.iter (fun (name, value) -> self#replaceHeader ~name ~value)
78     method removeHeader ~name =
79       let name = String.lowercase name in
80       hashtbl_remove_all _headers name
81     method hasHeader ~name =
82       let name = String.lowercase name in
83       Hashtbl.mem _headers name
84     method header ~name =
85       if not (self#hasHeader name) then raise (Header_not_found name);
86       let name = String.lowercase name in
87       String.concat ", " (List.rev (Hashtbl.find_all _headers name))
88     method headers =
89       List.rev
90         (Hashtbl.fold
91           (fun name _ headers -> (name, self#header ~name)::headers)
92           _headers
93           [])
94
95     method clientSockaddr = clisockaddr
96     method clientAddr = cliaddr
97     method clientPort = cliport
98
99     method serverSockaddr = srvsockaddr
100     method serverAddr = srvaddr
101     method serverPort = srvport
102
103     method private virtual fstLineToString: string
104     method toString =
105       self#fstLineToString ^  (* {request,status} line *)
106       crlf ^
107       (String.concat  (* headers, crlf terminated *)
108         ""
109         (List.map (fun (h,v) -> h ^ ": " ^ v ^ crlf) self#headers)) ^
110       (sprintf "Content-Length: %d" (String.length self#body)) ^ crlf ^
111       crlf ^
112       self#body (* body *)
113     method serialize outchan =
114       output_string outchan self#toString;
115       flush outchan
116
117   end
118