]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/ocaml-http/http_types.mli
ocaml 3.09 transition
[helm.git] / helm / DEVEL / ocaml-http / http_types.mli
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 (** Type definitions *)
23
24   (** HTTP version, actually only 1.0 and 1.1 are supported. Note that
25   'supported' here means only 'accepted inside a HTTP request line', no
26   different behaviours are actually implemented depending on HTTP version *)
27 type version =
28   [ `HTTP_1_0
29   | `HTTP_1_1
30   ]
31
32   (** HTTP method, actually only GET and POST methods are supported *)
33 type meth =
34   [ `GET
35   | `POST
36   ]
37
38   (** Daemon behaviour wrt request handling. `Single mode use a single process
39   to handle all requests, no request is served until a previous one has been
40   fully served. `Fork mode fork a new process for each request, the new process
41   will execute the callback function and then exit. `Thread mode create a new
42   thread for each request, the new thread will execute the callback function and
43   then exit, threads can communicate using standard OCaml Thread library. *)
44 type daemon_mode = [ `Single | `Fork | `Thread ]
45
46   (** A TCP server is a function taking an address on which bind and listen for
47   connections, an optional timeout after which abort client connections and a
48   callback function which in turn takes an input and an output channel as
49   arguments. After receiving this argument a TCP server sits and waits for
50   connection, on each connection it apply the callback function to channels
51   connected to client. *)
52 type tcp_server =
53   sockaddr:Unix.sockaddr -> timeout:int option ->
54   (in_channel -> out_channel -> unit) ->
55     unit
56
57   (** authentication information *)
58 type auth_info =
59   [ `Basic of string * string (* username, password *)
60 (*   | `Digest of ...  (* TODO digest authentication *) *)
61   ]
62
63   (** @see "RFC2616" informational HTTP status *)
64 type informational_substatus =
65   [ `Continue
66   | `Switching_protocols
67   ]
68
69   (** @see "RFC2616" success HTTP status *)
70 type success_substatus =
71   [ `OK
72   | `Created
73   | `Accepted
74   | `Non_authoritative_information
75   | `No_content
76   | `Reset_content
77   | `Partial_content
78   ]
79
80   (** @see "RFC2616" redirection HTTP status *)
81 type redirection_substatus =
82   [ `Multiple_choices
83   | `Moved_permanently
84   | `Found
85   | `See_other
86   | `Not_modified
87   | `Use_proxy
88   | `Temporary_redirect
89   ]
90
91   (** @see "RFC2616" client error HTTP status *)
92 type client_error_substatus =
93   [ `Bad_request
94   | `Unauthorized
95   | `Payment_required
96   | `Forbidden
97   | `Not_found
98   | `Method_not_allowed
99   | `Not_acceptable
100   | `Proxy_authentication_required
101   | `Request_time_out
102   | `Conflict
103   | `Gone
104   | `Length_required
105   | `Precondition_failed
106   | `Request_entity_too_large
107   | `Request_URI_too_large
108   | `Unsupported_media_type
109   | `Requested_range_not_satisfiable
110   | `Expectation_failed
111   ]
112
113   (** @see "RFC2616" server error HTTP status *)
114 type server_error_substatus =
115   [ `Internal_server_error
116   | `Not_implemented
117   | `Bad_gateway
118   | `Service_unavailable
119   | `Gateway_time_out
120   | `HTTP_version_not_supported
121   ]
122
123 type informational_status = [ `Informational of informational_substatus ]
124 type success_status = [ `Success of success_substatus ]
125 type redirection_status = [ `Redirection of redirection_substatus ]
126 type client_error_status = [ `Client_error of client_error_substatus ]
127 type server_error_status = [ `Server_error of server_error_substatus ]
128
129 type error_status =
130   [ client_error_status
131   | server_error_status
132   ]
133
134   (** HTTP status *)
135 type status =
136   [ informational_status
137   | success_status
138   | redirection_status
139   | client_error_status
140   | server_error_status
141   ]
142
143 type status_code = [ `Code of int | `Status of status ]
144
145   (** File sources *)
146 type file_source =
147   | FileSrc of string           (** filename *)
148   | InChanSrc of in_channel     (** input channel *)
149
150   (** {2 Exceptions} *)
151
152   (** invalid header encountered *)
153 exception Invalid_header of string
154
155   (** invalid header name encountered *)
156 exception Invalid_header_name of string
157
158   (** invalid header value encountered *)
159 exception Invalid_header_value of string
160
161   (** unsupported or invalid HTTP version encountered *)
162 exception Invalid_HTTP_version of string
163
164   (** unsupported or invalid HTTP method encountered *)
165 exception Invalid_HTTP_method of string
166
167   (** invalid HTTP status code integer representation encountered *)
168 exception Invalid_code of int
169
170   (** invalid URL encountered *)
171 exception Malformed_URL of string
172
173   (** invalid query string encountered *)
174 exception Malformed_query of string
175
176   (** invalid query string part encountered, arguments are parameter name and
177   parameter value *)
178 exception Malformed_query_part of string * string
179
180   (** invalid request URI encountered *)
181 exception Malformed_request_URI of string
182
183   (** malformed request received *)
184 exception Malformed_request of string
185
186   (** malformed response received, argument is response's first line *)
187 exception Malformed_response of string
188
189   (** a parameter you were looking for was not found *)
190 exception Param_not_found of string
191
192   (** invalid HTTP status line encountered *)
193 exception Invalid_status_line of string
194
195   (** an header you were looking for was not found *)
196 exception Header_not_found of string
197
198   (** raisable by callbacks to make main daemon quit, this is the only
199   * 'clean' way to make start functions return *)
200 exception Quit
201
202   (** raisable by callbacks to force a 401 (unauthorized) HTTP answer.
203   * This exception should be raised _before_ sending any data over given out
204   * channel.
205   * @param realm authentication realm (usually needed to prompt user) *)
206 exception Unauthorized of string
207
208   (** {2 OO representation of HTTP messages} *)
209
210   (** HTTP generic messages. See {! Http_message.message} *)
211 class type message = object
212
213     method version: version option
214     method setVersion: version -> unit
215
216     method body: string
217     method setBody: string -> unit
218     method bodyBuf: Buffer.t
219     method setBodyBuf: Buffer.t -> unit
220     method addBody: string -> unit
221     method addBodyBuf: Buffer.t -> unit
222
223     method addHeader: name:string -> value:string -> unit
224     method addHeaders: (string * string) list -> unit
225     method replaceHeader: name:string -> value:string -> unit
226     method replaceHeaders: (string * string) list -> unit
227     method removeHeader: name:string -> unit
228     method hasHeader: name:string -> bool
229     method header: name:string -> string
230     method headers: (string * string) list
231
232     method clientSockaddr: Unix.sockaddr
233     method clientAddr: string
234     method clientPort: int
235
236     method serverSockaddr: Unix.sockaddr
237     method serverAddr: string
238     method serverPort: int
239
240     method toString: string
241     method serialize: out_channel -> unit
242
243   end
244
245   (** HTTP requests *)
246 class type request = object
247
248       (** an HTTP request is a flavour of HTTP message *)
249     inherit message
250
251       (** @return request method *)
252     method meth: meth
253
254       (** @return requested URI (including query string, fragment, ...) *)
255     method uri: string
256
257       (** @return requested path *)
258     method path: string
259
260       (** lookup a given parameter
261       @param meth if given restrict the lookup area (e.g. if meth = POST than
262         only parameters received via POST are searched), if not given both GET
263         and POST parameter are searched in an unspecified order (actually the
264         implementation prefers POST parameters but this is not granted, you've
265         been warned)
266       @param default if provided, this value will be returned in case no
267         parameter of that name is available instead of raising Param_not_found
268       @param name name of the parameter to lookup
269       @return value associated to parameter name
270       @raise Param_not_found if parameter name was not found *)
271     method param: ?meth:meth -> ?default:string -> string -> string
272
273       (** like param above but return a list of values associated to given
274       parameter (a parameter could be defined indeed more than once: passed more
275       than once in a query string or passed both insider the url (the GET way)
276       and inside message body (the POST way)) *)
277     method paramAll: ?meth:meth -> string -> string list
278
279       (** @return the list of all received parameters *)
280     method params: (string * string) list
281
282       (** @return the list of all parameters received via GET *)
283     method params_GET: (string * string) list
284
285       (** @return the list of all parameter received via POST *)
286     method params_POST: (string * string) list
287
288       (** @return authorization information, if given by the client *)
289     method authorization: auth_info option
290
291   end
292
293   (** HTTP responses *)
294 class type response = object
295
296     inherit message
297
298       (** @return response code *)
299     method code: int
300
301       (** set response code *)
302     method setCode: int -> unit
303
304       (** @return response status *)
305     method status: status
306
307       (** set response status *)
308     method setStatus: status -> unit
309
310       (** @return reason string *)
311     method reason: string
312
313       (** set reason string *)
314     method setReason: string -> unit
315
316       (** @return status line *)
317     method statusLine: string
318
319       (** set status line
320       @raise Invalid_status_line if an invalid HTTP status line was passed *)
321     method setStatusLine: string -> unit
322
323       (** response is an informational one *)
324     method isInformational: bool
325
326       (** response is a success one *)
327     method isSuccess: bool
328
329       (** response is a redirection one *)
330     method isRedirection: bool
331
332       (** response is a client error one *)
333     method isClientError: bool
334
335       (** response is a server error one *)
336     method isServerError: bool
337
338       (** response is either a client error or a server error response *)
339     method isError: bool
340
341       (** add basic headers to response, see {!Http_daemon.send_basic_headers}
342       *)
343     method addBasicHeaders: unit
344
345       (** facilities to access some frequently used headers *)
346
347       (** @return Content-Type header value *)
348     method contentType: string
349
350       (** set Content-Type header value *)
351     method setContentType: string -> unit
352
353       (** @return Content-Encoding header value *)
354     method contentEncoding: string
355
356       (** set Content-Encoding header value *)
357     method setContentEncoding: string -> unit
358
359       (** @return Date header value *)
360     method date: string
361
362       (** set Date header value *)
363     method setDate: string -> unit
364
365       (** @return Expires header value *)
366     method expires: string
367
368       (** set Expires header value *)
369     method setExpires: string -> unit
370
371       (** @return Server header value *)
372     method server: string
373
374       (** set Server header value *)
375     method setServer: string -> unit
376
377   end
378
379   (** {2 Daemon specification} *)
380
381   (** daemon specification, describe the behaviour of an HTTP daemon.
382   *
383   * The default daemon specification is {!Http_daemon.default_spec}
384   *)
385 type daemon_spec = {
386   address: string;
387     (** @param address adress on which daemon will be listening, can be both a
388     * numeric address (e.g. "127.0.0.1") and an hostname (e.g. "localhost") *)
389   auth: (string * auth_info) option;
390     (** authentication requirements (currently only basic authentication is
391     * supported). If set to None no authentication is required. If set to Some
392     * ("realm", `Basic ("foo", "bar")), only clients authenticated with baisc
393     * authentication, for realm "realm", providing username "foo" and password
394     * "bar" are accepted; others are rejected with a 401 response code *)
395   callback: request -> out_channel -> unit;
396     (** function which will be called each time a correct HTTP request will be
397     * received. 1st callback argument is an Http_types.request object
398     * corresponding to the request received; 2nd argument is an output channel
399     * corresponding to the socket connected to the client *)
400   mode: daemon_mode;
401     (** requests handling mode, it can have three different values:
402     * - `Single -> all requests will be handled by the same process,
403     * - `Fork   -> each request will be handled by a child process,
404     * - `Thread -> each request will be handled by a (new) thread *)
405   port: int;  (** TCP port on which the daemon will be listening *)
406   root_dir: string option;
407     (** directory to which ocaml http will chdir before starting handling
408     * requests; if None, no chdir will be performed (i.e. stay in the current
409     * working directory) *)
410   exn_handler: (exn -> out_channel -> unit) option;
411     (** what to do when executing callback raises an exception.  If None, the
412     * exception will be re-raised: in `Fork/`Thread mode the current
413     * process/thread will be terminated. in `Single mode the exception is
414     * ignored and the client socket closed. If Some callback, the callback will
415     * be executed before acting as per None; the callback is meant to perform
416     * some clean up actions, like releasing global mutexes in `Thread mode *)
417   timeout: int option;
418     (** timeout in seconds after which an incoming HTTP request will be
419     * terminated closing the corresponding TCP connection; None disable the
420     * timeout *)
421 }
422
423   (** {2 OO representation of other HTTP entities} *)
424
425   (** an HTTP connection from a client to a server *)
426 class type connection =
427   object
428       (** @return next request object, may block if client hasn't submitted any
429       request yet, may be None if client request was ill-formed *)
430     method getRequest: request option
431
432       (** respond to client sending it a response *)
433     method respond_with: response -> unit
434
435       (** close connection to client. Warning: this object can't be used any
436       longer after this method has been called *)
437     method close: unit
438   end
439
440   (** an HTTP daemon *)
441 class type daemon =
442   object
443       (** @return a connection to a client, may block if no client has connected
444       yet *)
445     method accept: connection
446
447       (** shortcut method, blocks until a client has submit a request and
448       return a pair request * connection *)
449     method getRequest: request * connection
450   end
451