]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/ocaml-http/http_types.ml
added support for HTTP (Basic) authentication
[helm.git] / helm / DEVEL / ocaml-http / http_types.ml
1
2 (*
3   OCaml HTTP - do it yourself (fully OCaml) HTTP daemon
4
5   Copyright (C) <2002> 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 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.
11
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.
16
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
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   (** informational HTTP status, see RFC2616 *)
64 type informational_substatus =
65   [ `Continue
66   | `Switching_protocols
67   ]
68
69   (** success HTTP status, see RFC2616 *)
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   (** redirection HTTP status, see RFC2616 *)
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   (** client error HTTP status, see RFC2616 *)
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   (** server error HTTP status, see RFC2616 *)
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   (** File sources *)
144 type file_source =
145   | FileSrc of string           (** filename *)
146   | InChanSrc of in_channel     (** input channel *)
147
148   (** {2 Exceptions} *)
149
150   (** invalid header encountered *)
151 exception Invalid_header of string
152
153   (** invalid header name encountered *)
154 exception Invalid_header_name of string
155
156   (** invalid header value encountered *)
157 exception Invalid_header_value of string
158
159   (** unsupported or invalid HTTP version encountered *)
160 exception Invalid_HTTP_version of string
161
162   (** unsupported or invalid HTTP method encountered *)
163 exception Invalid_HTTP_method of string
164
165   (** invalid HTTP status code integer representation encountered *)
166 exception Invalid_code of int
167
168   (** invalid URL encountered *)
169 exception Malformed_URL of string
170
171   (** invalid query string encountered *)
172 exception Malformed_query of string
173
174   (** invalid query string part encountered, arguments are parameter name and
175   parameter value *)
176 exception Malformed_query_part of string * string
177
178   (** invalid request URI encountered *)
179 exception Malformed_request_URI of string
180
181   (** malformed request received *)
182 exception Malformed_request of string
183
184   (** malformed response received, argument is response's first line *)
185 exception Malformed_response of string
186
187   (** a parameter you were looking for was not found *)
188 exception Param_not_found of string
189
190   (** invalid HTTP status line encountered *)
191 exception Invalid_status_line of string
192
193   (** an header you were looking for was not found *)
194 exception Header_not_found of string
195
196   (** raisable by callbacks to make main daemon quit, this is the only
197   'clean' way to make start functions return *)
198 exception Quit
199
200   (** raisable by callbacks to force a 401 (unauthorized) HTTP answer.
201   * This exception should be raised _before_ sending any data over given out
202   * channel.
203   * @param realm authentication realm (usually needed to prompt user) *)
204 exception Unauthorized of string
205
206   (** {2 OO representation of HTTP messages} *)
207
208   (** HTTP generic messages. See {! Http_message.message} *)
209 class type message = object
210
211     method version: version option
212     method setVersion: version -> unit
213
214     method body: string
215     method setBody: string -> unit
216     method bodyBuf: Buffer.t
217     method setBodyBuf: Buffer.t -> unit
218     method addBody: string -> unit
219     method addBodyBuf: Buffer.t -> unit
220
221     method addHeader: name:string -> value:string -> unit
222     method addHeaders: (string * string) list -> unit
223     method replaceHeader: name:string -> value:string -> unit
224     method replaceHeaders: (string * string) list -> unit
225     method removeHeader: name:string -> unit
226     method hasHeader: name:string -> bool
227     method header: name:string -> string
228     method headers: (string * string) list
229
230     method clientSockaddr: Unix.sockaddr
231     method clientAddr: string
232     method clientPort: int
233
234     method serverSockaddr: Unix.sockaddr
235     method serverAddr: string
236     method serverPort: int
237
238     method toString: string
239     method serialize: out_channel -> unit
240
241   end
242
243   (** HTTP requests *)
244 class type request = object
245
246       (** an HTTP request is a flavour of HTTP message *)
247     inherit message
248
249       (** @return request method *)
250     method meth: meth
251
252       (** @return requested URI (including query string, fragment, ...) *)
253     method uri: string
254
255       (** @return requested path *)
256     method path: string
257
258       (** lookup a given parameter
259       @param meth if given restrict the lookup area (e.g. if meth = POST than
260       only parameters received via POST are searched), if not given both GET and
261       POST parameter are searched in an unspecified order (actually the
262       implementation prefers POST parameters but this is not granted, you've
263       been warned)
264       @param name name of the parameter to lookup
265       @return value associated to parameter name
266       @raise Param_not_found if parameter name was not found *)
267     method param: ?meth:meth -> string -> string
268
269       (** like param above but return a list of values associated to given
270       parameter (a parameter could be defined indeed more than once: passed more
271       than once in a query string or passed both insider the url (the GET way)
272       and inside message body (the POST way)) *)
273     method paramAll: ?meth:meth -> string -> string list
274
275       (** @return the list of all received parameters *)
276     method params: (string * string) list
277
278       (** @return the list of all parameters received via GET *)
279     method params_GET: (string * string) list
280
281       (** @return the list of all parameter received via POST *)
282     method params_POST: (string * string) list
283
284       (** @return authorization information, if given by the client *)
285     method authorization: auth_info option
286
287   end
288
289   (** HTTP responses *)
290 class type response = object
291
292     inherit message
293
294       (** @return response code *)
295     method code: int
296
297       (** set response code *)
298     method setCode: int -> unit
299
300       (** @return response status, see {! Http_types.status} *)
301     method status: status
302
303       (** set response status *)
304     method setStatus: status -> unit
305
306       (** @return reason string *)
307     method reason: string
308
309       (** set reason string *)
310     method setReason: string -> unit
311
312       (** @return status line *)
313     method statusLine: string
314
315       (** set status line
316       @raise Invalid_status_line if an invalid HTTP status line was passed *)
317     method setStatusLine: string -> unit
318
319       (** response is an informational one *)
320     method isInformational: bool
321
322       (** response is a success one *)
323     method isSuccess: bool
324
325       (** response is a redirection one *)
326     method isRedirection: bool
327
328       (** response is a client error one *)
329     method isClientError: bool
330
331       (** response is a server error one *)
332     method isServerError: bool
333
334       (** response is either a client error or a server error response *)
335     method isError: bool
336
337       (** add basic headers to response, see {! Http_daemon.send_basic_headers}
338       *)
339     method addBasicHeaders: unit
340
341       (** facilities to access some frequently used headers *)
342
343       (** @return Content-Type header value *)
344     method contentType: string
345
346       (** set Content-Type header value *)
347     method setContentType: string -> unit
348
349       (** @return Content-Encoding header value *)
350     method contentEncoding: string
351
352       (** set Content-Encoding header value *)
353     method setContentEncoding: string -> unit
354
355       (** @return Date header value *)
356     method date: string
357
358       (** set Date header value *)
359     method setDate: string -> unit
360
361       (** @return Expires header value *)
362     method expires: string
363
364       (** set Expires header value *)
365     method setExpires: string -> unit
366
367       (** @return Server header value *)
368     method server: string
369
370       (** set Server header value *)
371     method setServer: string -> unit
372
373   end
374
375   (** {2 OO representation of other HTTP "entities"} *)
376
377   (** an HTTP connection from a client to a server *)
378 class type connection =
379   object
380       (** @return next request object, may block if client hasn't submitted any
381       request yet, may be None if client request was ill-formed *)
382     method getRequest: request option
383
384       (** respond to client sending it a response *)
385     method respond_with: response -> unit
386
387       (** close connection to client. Warning: this object can't be used any
388       longer after this method has been called *)
389     method close: unit
390   end
391
392   (** an HTTP daemon *)
393 class type daemon =
394   object
395       (** @return a connection to a client, may block if no client has connected
396       yet *)
397     method accept: connection
398
399       (** shortcut method, blocks until a client has submit a request and
400       return a pair request * connection *)
401     method getRequest: request * connection
402   end
403