3 OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
5 Copyright (C) <2002> 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
22 (** HTTP version, actually only 1.0 and 1.1 are supported. Note that
23 'supported' here means only 'accepted inside a HTTP request line', no
24 different behaviours are actually implemented depending on HTTP version *)
30 (** HTTP method, actually only GET and POST methods are supported *)
36 (** Daemon behaviour wrt request handling. `Single mode use a single process
37 to handle all requests, no request is served until a previous one has been
38 fully served. `Fork mode fork a new process for each request, the new process
39 will execute the callback function and then exit. `Thread mode create a new
40 thread for each request, the new thread will execute the callback function and
41 then exit, threads can communicate using standard OCaml Thread library. *)
42 type daemon_mode = [ `Single | `Fork | `Thread ]
45 sockaddr:Unix.sockaddr -> timeout:int option ->
46 (in_channel -> out_channel -> unit) ->
49 type informational_substatus =
51 | `Switching_protocols
54 type success_substatus =
58 | `Non_authoritative_information
64 type redirection_substatus =
74 type client_error_substatus =
82 | `Proxy_authentication_required
87 | `Precondition_failed
88 | `Request_entity_too_large
89 | `Request_URI_too_large
90 | `Unsupported_media_type
91 | `Requested_range_not_satisfiable
95 type server_error_substatus =
96 [ `Internal_server_error
99 | `Service_unavailable
101 | `HTTP_version_not_supported
104 type informational_status = [ `Informational of informational_substatus ]
105 type success_status = [ `Success of success_substatus ]
106 type redirection_status = [ `Redirection of redirection_substatus ]
107 type client_error_status = [ `Client_error of client_error_substatus ]
108 type server_error_status = [ `Server_error of server_error_substatus ]
111 [ client_error_status
112 | server_error_status
116 [ informational_status
119 | client_error_status
120 | server_error_status
123 exception Invalid_header of string
124 exception Invalid_header_name of string
125 exception Invalid_header_value of string
126 exception Invalid_HTTP_version of string
127 exception Invalid_HTTP_method of string
128 exception Invalid_code of int
129 exception Invalid_status of status
131 exception Malformed_URL of string
132 exception Malformed_query of string
133 exception Malformed_query_part of string * string
134 exception Unsupported_method of string
135 exception Unsupported_HTTP_version of string
136 exception Malformed_request_URI of string
137 exception Malformed_request of string
139 exception Param_not_found of string
141 exception Invalid_status_line of string
142 exception Header_not_found of string
144 (** raisable by callback functions to make main daemon quit, this is the only
145 'clean' way to make start functions return *)
148 class type message = object
150 method version: version option
151 method setVersion: version -> unit
154 method setBody: string -> unit
155 method bodyBuf: Buffer.t
156 method setBodyBuf: Buffer.t -> unit
157 method addBody: string -> unit
158 method addBodyBuf: Buffer.t -> unit
160 (** header name comparison are performed in a case-insensitive manner as
161 required by RFC2616, actually the implementation works converting all header
162 names in lowercase *)
164 method addHeader: name:string -> value:string -> unit
165 method addHeaders: (string * string) list -> unit
166 method replaceHeader: name:string -> value:string -> unit
167 method replaceHeaders: (string * string) list -> unit
168 method removeHeader: name:string -> unit
169 method hasHeader: name:string -> bool
170 method header: name:string -> string
171 method headers: (string * string) list
173 method clientSockaddr: Unix.sockaddr
174 method clientAddr: string
175 method clientPort: int
177 method serverSockaddr: Unix.sockaddr
178 method serverAddr: string
179 method serverPort: int
181 method toString: string
182 method serialize: out_channel -> unit
186 class type request = object
193 method param: ?meth:meth -> string -> string
194 method paramAll: ?meth:meth -> string -> string list
195 method params: (string * string) list
196 method params_GET: (string * string) list
197 method params_POST: (string * string) list
201 class type response = object
206 method setCode: int -> unit
207 method status: status
208 method setStatus: status -> unit
209 method reason: string
210 method setReason: string -> unit
211 method statusLine: string
212 method setStatusLine: string -> unit
214 method isInformational: bool
215 method isSuccess: bool
216 method isRedirection: bool
217 method isClientError: bool
218 method isServerError: bool
221 method addBasicHeaders: unit
222 method contentType: string
223 method setContentType: string -> unit
224 method contentEncoding: string
225 method setContentEncoding: string -> unit
227 method setDate: string -> unit
228 method expires: string
229 method setExpires: string -> unit
230 method server: string
231 method setServer: string -> unit
235 class type connection =
237 method getRequest: request option
238 method respond_with: response -> unit
244 method accept: connection
245 method getRequest: request * connection