(* $Id: netcgi_env.mli 1016 2006-10-02 13:58:45Z gerd $
* ----------------------------------------------------------------------
*
*)
(** Access to the environment for CGI and related protocols *)
type input_mode =
[ `Standard (* | `Direct *) ]
(** Determines how to read the request:
* - [`Standard]: Only the request body is read from the input
* channel (CGI standard)
* - Not yet implemented: [`Direct]: Both header and body of the
* request are read from the input channel
*)
type input_state =
[ `Start |
`Receiving_header | `Received_header |
`Receiving_body | `Received_body
]
(** The input processing state:
* - [`Start]: Input data have not yet been received
* - [`Receiving_header]: The request header is currently being
* received
* - [`Received_header]: The request header has been completely
* received, and nothing of the request body has yet been
* received
* - [`Receiving_body]: The request body is currently being
* received
* - [`Received_body]: The request body has been completely
* received
*
* Transition diagram:
* {[
* `Start ->
* `Receiving_header ->
* `Received_header ->
* `Receiving_body ->
* `Received_body ]}
*)
type output_mode =
[ `Standard (* | `Direct *) ]
(** Determines how to deliver the response:
* - [`Standard]: The format of the response header has CGI format,
* followed by the response body
* - Not yet implemented: [`Direct]: The format of the response
* header has HTTP format, followed by the response body. This
* is also known as "non-parsed header" format.
*)
type output_state =
[ `Start |
`Sending_header | `Sent_header |
`Sending_body | `Sent_body |
`Sending_part_header | `Sent_part_header |
`Sending_part_body | `Sent_part_body |
`End
]
(** The output processing state:
* - [`Start]: Output has not yet been sent
* - [`Sending_header]: The response header is currently being sent
* - [`Sent_header]: The response header has been completely sent,
* and nothing of the body has yet been sent
* - [`Sending_body]: The response body is currently being sent
* - [`Sent_body]: The response body has been sent up to a
* check point
* - [`End]: The response has been completely sent
*
* Transition diagram:
* {[
* `Start ->
* `Sending_header ->
* `Sent_header ->
* +-> `Sending_body
* | |
* | V
* +-- `Sent_body
* |
* V
* `End ]}
*
* The state [`Sent_body] is reached when the output data are
* committed. It is possible to continue with another transaction,
* which would mean to go back to [`Sending_body], or to finish
* the body completely, by going to [`End].
*
* Extension for multi-part response messages (e.g. needed for
* server push, not yet implemented):
* - [`Sending_part_header]: The header of a message part is being
* sent
* - [`Sent_part_header]: The header of a message part has been
* completely sent
* - [`Sending_part_body]: The body of a message part is being
* sent
* - [`Sent_part_body]: The body of a message part has been sent
* up to a check point
*)
type protocol_version = Nethttp.protocol_version
(** Now defined in [Nethttp] *)
type protocol_attribute = Nethttp.protocol_attribute
(** Now defined in [Nethttp] *)
type protocol = Nethttp.protocol
(** Now defined in [Nethttp] *)
type workaround =
[ `Work_around_MSIE_Content_type_bug
| `Work_around_backslash_bug
]
(** Indicates special behaviour:
* - [`Work_around_MSIE_Content_type_bug]: Versions of the Internet
* Explorer send illegal content types. This workaround extracts
* the right data from the malformed data field
* - [`Work_around_backslash_bug]: Almost all browsers send illegal
* backslash sequences when backslashes occur in filenames.
* This workaround accepts such sequences.
*)
type cgi_config =
{ (* System: *)
tmp_directory : string;
(** The directory where to create temporary files. This should be
* an absolute path name
*)
tmp_prefix : string;
(** The name prefix for temporary files. This must be a non-empty
* string. It must not contain '/'.
*)
(* Limits: *)
permitted_http_methods : string list;
(** The list of accepted HTTP methods (uppercase letters) *)
permitted_input_content_types : string list;
(** The list of accepted content types in requests.
* Content type parameters (like "charset") are ignored.
* If the list is empty, all content types are allowed.
*)
input_content_length_limit : int;
(** The maximum size of the request *)
workarounds : workaround list;
(** The list of enabled workarounds *)
}
val default_config : cgi_config
(** The default configuration is:
* - [tmp_directory]: one of /var/tmp, /tmp, C:\temp, .
* - [tmp_prefix]: "netstring"
* - [permitted_http_methods]: ["GET"], ["POST"]
* - [permitted_input_content_types]: ["multipart/form-data"],
* ["application/x-www-form-urlencoded"]
* - [input_content_length_limit]: [maxint]
* - [workarounds]: all
*
* To create a custom configuration, it is suggested to use this
* syntax:
* {[ let custom_config =
* { default_config with tmp_prefix = "my_prefix" }
* ]}
*)
(* DISCUSS: Is the configuration part of cgi_environment or cgi_activation?
*)
(** The class type cgi_environment contains the resources by which
* the CGI activation is connected to the "outer world". In particular,
* the following applies:
*
* - CGI properties: These are the global properties of the CGI request
* such as the HTTP method, which HTTP server serves the request, and
* which client sent the request.
* For a classic CGI environment, the properties are the environment
* variables not beginning with ["HTTP_"], and neither ["CONTENT_LENGTH"]
* nor ["CONTENT_TYPE"].
* - Input header: The header of the HTTP request.
* For a classic CGI environment, the input header can be extracted
* from the process environment. It consists of all variables beginning
* with ["HTTP_"] and the variables ["CONTENT_LENGTH"] and ["CONTENT_TYPE"].
* - Input channel: Over the input channel the HTTP request can be read in.
* The input state tracks which parts of the request have already be
* read.
* For a classic CGI environment, the input channel contains only the
* body of the request, and the (required) header field content-length
* specifies the length of the body in bytes.
* - Output header: The header of the HTTP response.
* - Output channel: Over the output channel the HTTP response is sent.
* The output state tracks which parts of the response have already been
* sent.
*
* The CGI environment cannot only be used for classic CGI but also for
* non-standard ways of communication with the HTTP server. By design,
* the header and the body of both the request and the response are
* separated, and because of this every of these message parts can be
* processed independently of the other parts.
*
* There is a certain protocol between the environment and the
* [cgi_activation] objects.
* - The [cgi_activation] object expects that the input state of the
* environment is at least [`Received_header] when it starts to
* process the request. This means that it is the task of the
* environment to read the request header in.
* - The [cgi_activation] object reads the request body from
* [input_ch], and modifies the input state as it reads the body
* - The [cgi_activation] object sets the response header in the
* environment, and calls [send_output_header] when the right
* moment for sending the output header is reached. It does not
* write the response header to [output_ch] itself. This is the
* sole task of the [send_output_header] method of the environment.
* - After the output header is sent, the [cgi_activation] object
* writes the response body to [output_ch]. The output state is
* modified by this object.
*)
class type cgi_environment =
object
(* Configuration: *)
method config : cgi_config
(** The CGI configuration *)
(** Standard properties
*
* The following properties are standardised by CGI. The methods
* return [""] or [None] (in the case of the port number) when
* the property is not available.
*)
method cgi_gateway_interface : string
method cgi_server_software : string
method cgi_server_name : string
method cgi_server_protocol : string
method cgi_server_port : int option
method cgi_request_method : string
method cgi_path_info : string
method cgi_path_translated : string
method cgi_script_name : string
method cgi_query_string : string
method cgi_remote_host : string
method cgi_remote_addr : string
method cgi_auth_type : string
method cgi_remote_user : string
method cgi_remote_ident : string
(** Non-standard properties *)
method cgi_property : ?default:string -> string -> string
(** Returns a (possibly non-standard) environment property. If the property
* is not set, [Not_found] will be raised unless the [default] argument is
* passed. The [default] argument determines the result of the function in