3 OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
5 Copyright (C) <2002-2004> Stefano Zacchiroli <zack@cs.unibo.it>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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
35 class virtual message ~body ~headers ~version ~clisockaddr ~srvsockaddr =
37 let ((cliaddr, cliport), (srvaddr, srvport)) =
38 (Http_misc.explode_sockaddr clisockaddr,
39 Http_misc.explode_sockaddr srvsockaddr)
44 val _contentsBuf = Buffer.create 1024
45 val _headers = Hashtbl.create 11
46 val mutable _version: version option = version
50 self#addHeaders headers
52 method version = _version
53 method setVersion v = _version <- Some v
55 method body = Buffer.contents _contentsBuf
57 Buffer.clear _contentsBuf;
58 Buffer.add_string _contentsBuf c
59 method bodyBuf = _contentsBuf
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
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
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
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))
91 (fun name _ headers -> (name, self#header ~name)::headers)
95 method clientSockaddr = clisockaddr
96 method clientAddr = cliaddr
97 method clientPort = cliport
99 method serverSockaddr = srvsockaddr
100 method serverAddr = srvaddr
101 method serverPort = srvport
103 method private virtual fstLineToString: string
105 self#fstLineToString ^ (* {request,status} line *)
107 (String.concat (* headers, crlf terminated *)
109 (List.map (fun (h,v) -> h ^ ": " ^ v ^ crlf) self#headers)) ^
110 (sprintf "Content-Length: %d" (String.length self#body)) ^ crlf ^
113 method serialize outchan =
114 output_string outchan self#toString;