(* $Id: nethttpd_types.mli 1063 2006-12-17 20:54:34Z gerd $
*
*)
(*
* Copyright 2005 Baretta s.r.l. and Gerd Stolpmann
*
* This file is part of Nethttpd.
*
* Nethttpd is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Nethttpd is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WDialog; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)
(** Type definitions for the HTTP daemon
*
* {b Contents}
*
* - {!Nethttpd_types.exceptions}
* - {!Nethttpd_types.environment}
* - {!Nethttpd_types.service}
* - {!Nethttpd_types.helpers}
*)
(** Many types can also be found in the [Nethttp] module (part of netstring).
* Furthermore, [Netcgi_env] and [Netcgi_types] are of interest (part of cgi).
*)
(** {1:exceptions Exceptions} *)
open Nethttp
exception Standard_response of http_status * http_header option * string option
(** Some HTTP containers allow you to raise this exception. The standard
* response corresponding to [http_status] is sent back to the client.
* If the third argument exists, an entry into the error log
* is written.
*)
(**********************************************************************)
(** {1:environment Environment} *)
(** An extension of [cgi_environment] for use with the daemon. The methods
* retrieve the socket addresses are virtual.
*)
class type virtual v_extended_environment =
object
inherit Netcgi1_compat.Netcgi_env.cgi_environment
method virtual server_socket_addr : Unix.sockaddr
method virtual remote_socket_addr : Unix.sockaddr
(** These are always the physical IP addresses and ports of the two endpoints
* of the current connection.
*)
method send_file : Unix.file_descr -> int64 -> unit
(** Sends the output header with a file as body. The file must already be open,
* and positioned where the transmission begins. The number is the length
* of the transmission.
*
* This method may return immediately when it is possible to open the file, and
* to set the kernel up for file transmission. Otherwise a [Unix_error] is
* raised. It is also allowed that this method blocks until the file is actually
* transmitted.
*
* It is not allowed to print to the output channel and to call [send_file].
* Only one transmission method must be invoked.
*)
end
(** Same as [v_extended_environment], but no virtual methods
*)
class type extended_environment =
object
inherit v_extended_environment
method server_socket_addr : Unix.sockaddr
method remote_socket_addr : Unix.sockaddr
end
(** {2 Construction of environments} *)
class virtual empty_environment :
object
inherit v_extended_environment
val mutable config : Netcgi1_compat.Netcgi_env.cgi_config
val mutable in_state : Netcgi1_compat.Netcgi_env.input_state
val mutable out_state : Netcgi1_compat.Netcgi_env.output_state
val mutable protocol : Netcgi1_compat.Netcgi_env.protocol
val mutable in_header : http_header
val mutable out_header : http_header
val mutable properties : (string * string) list
val mutable in_channel : Netchannels.in_obj_channel
val mutable out_channel : Netchannels.out_obj_channel
end
(** This class implements an environment with defined internal containers.
* These containers are empty, but fully functional.
* The following methods are empty and should be redefined:
* - [send_output_header]
* - [send_file]
* - [log_error]
*
* The virtual methods, of course, must be defined!
*)
class redirected_environment :
?in_state : Netcgi1_compat.Netcgi_env.input_state ->
?in_header : http_header ->
?properties : (string * string) list ->
?in_channel : Netchannels.in_obj_channel ->
extended_environment ->
extended_environment
(** This class overlays the input-side containers of an existing environment.
* The output-side containers ([out_state], [out_header], and [out_channel])
* are physically identical with the existing environment.
*
* If one of the argument is not passed on class instantiation, the corresponding
* overlay container is initialized with the current value of the passed
* environment. As exception of this rule, the input channel is initialized with
* an empty input channel.
*)
(** {2 Auxiliary Functions for Environments} *)
val output_static_response : #extended_environment ->
http_status -> http_header option -> string -> unit
(** Outputs the string argument as response body, together with the given status and
* the header (optional). Response header fields are set as follows:
* - The [Content-Length] is set to the length of the string.
* - The [Content-Type] is set to "text/html" unless given by the header.
*
* If the header is not passed, the header of the environment is taken. If the header
* argument exists, however, it overrides the header of the environment.
*)
val output_file_response : #extended_environment ->
http_status -> http_header option ->
string -> int64 -> int64 -> unit
(** Outputs the contents of a file as response body, together with the given status and
* the header (optional). The string is the file name. The first int64 number is
* the position in the file where to start, and the second number is the length
* of the body. Response header fields are set as follows:
* - The [Content-Length] is set to the length of the string.
* - The [Content-Type] is set to "text/html" unless given by the header.
*
* Note that [Content-Range] is not set automatically, even if the file is only
* partially transferred.
*
* If the header is not passed, the header of the environment is taken. If the header
* argument exists, however, it overrides the header of the environment.
*
* The function raises [Sys_error] when the file cannot be read.
*)
class type min_config =
object
method config_error_response : int -> string
method config_log_error :
Unix.sockaddr option -> Unix.sockaddr option -> http_method option -> http_header option -> string -> unit
end
(** Minimal configuration needed for [output_std_response] *)
val output_std_response : #min_config -> #extended_environment ->
http_status -> http_header option -> string option -> unit
(** Outputs a "standard response" for the [http_status]. The string argument
* is an optional entry into the error log.
*
* If the header is not passed, an empty header is taken. If the header argument
* exists, this header is taken. The header of the environment is never taken.
*)
(**********************************************************************)
(** {1:service Service Providers}
*
* Service providers are defined using the three class types:
* - [http_service]: The service provider as such. When a HTTP header has been
* received, and the service provider is invoked, it returns an object
* fitting to the next class type, [http_service_receiver]. This object
* is tagged with [`Accept_body]; at this point there are also alternate ways
* of processing, see below.
* - [http_service_receiver]: The task of this object is to receive the request
* body. When the body has been completely received, the object is notified,
* and returns a third object of type [http_service_generator].
* - [http_service_generator]: The task of this object is to generate the
* response.
*
* An implementor is free to define only one class that satisfies all three
* class types at once. However, this is only an option.
*
* The three objects reflect three stages of HTTP processing. The stages have
* made explicit to allow the implementor of services to intercept the points
* in time when the processing of the next stage begins. Furthermore, in multi-threaded
* environments it is allowed that the stages are performed in the contexts of
* different threads.
*
* In addition to the three-stage model there also several faster paths of
* processing:
* - [`Reject_body] can be used to refuse the acceptance of the request body when
* it is already clear that an error response is sent back. This path skips
* the stage [http_service_receiver].
* - [`Static] can be used to send a constant string back (only to be used
* when the string needs not to be computed)
* - [`File] can be used to send the contents of a file back (only to be used
* when the file already exists)
*)
exception Redirect_request of string * http_header
(** The "early" redirect is only allowed in stage 1 of HTTP processing.
* The string argument is the new URI path of the request. The header can also
* be exchanged except the fields that are needed to decode the request
* body. It is not possible to change the method.
*)
exception Redirect_response of string * http_header
(** The "late" redirect is only allowed in stage 3 of HTTP processing.
* The string argument is the new URI path of the request. The header can also
* be exchanged except the fields that are needed to decode the request
* body. {b The method is always changed to [GET].}
*)
class type http_service_generator =
object
method generate_response : extended_environment -> unit
(** Third stage of HTTP processing:
* This method is called when the HTTP request has been completely received,
* and the response is going to be generated. This method can again be called
* from a different thread than the previous stages. It is allowed to spend