module Netcgi:Common data-structures for CGI-like connectors.sig..end
This library tries to minimize the use of unsafe practices. It cannot be bullet proof however and you should read about security.
REMARK: It happens frequently that hard to predict random numbers
are needed in Web applications. The previous version of this
library used to include some facilities for that (in the
Netcgi_jserv module). They have been dropped in favor of
Cryptokit.
class type cgi_argument =object..end
module Argument:sig..end
class type rw_cgi_argument =object..end
class simple_argument :?ro:bool -> string -> string ->rw_cgi_argument
class mime_argument :?work_around_backslash_bug:bool -> string -> Netmime.mime_message ->rw_cgi_argument
module Cookie:sig..end
typeconfig =Netcgi_common.config= {
|
tmp_directory : |
(* | The directory where to create temporary files. This should be an absolute path name. | *) |
|
tmp_prefix : |
(* | The name prefix for temporary files. This must be a non-empty string. It must not contain '/'. | *) |
|
permitted_http_methods : |
(* | The list of accepted HTTP methods | *) |
|
permitted_input_content_types : |
(* | 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 : |
(* | The maximum size of the request, in bytes. | *) |
|
workarounds : |
(* | The list of enabled workarounds.
`Work_around_MSIE_Content_type_bug and
`Work_around_backslash_bug are deprecated versions of,
respectively, `MSIE_Content_type_bug and `Backslash_bug. | *) |
val default_config : configtmp_directory: one of /var/tmp, /tmp, C:\temp, current directory.tmp_prefix: "netcgi"permitted_http_methods: `GET, `HEAD, `POST.permitted_input_content_types: "multipart/form-data",
"application/x-www-form-urlencoded".input_content_length_limit: maxint (i.e., no limit).workarounds: all of them. let custom_config = { default_config with tmp_prefix = "my_prefix" }
(This syntax is also robust w.r.t. the possible addition of new
config flields.)class type cgi_environment =object..end
typeother_url_spec =[ `Env | `None | `This of string ]
`Env: Take the value from the environment.`This v: Use this value v. It must already be URL-encoded.`None: Do not include this part into the URL.typequery_string_spec =[ `Args of rw_cgi_argument list
| `Env
| `None
| `This of cgi_argument list ]
`Env: The query string of the current request.`This l: The query string is created from the specified
argument list l.`None: The query string is omitted.`Args: deprecated, use `This
(left for backward compatibility).typecache_control =[ `Max_age of int | `No_cache | `Unspecified ]
`No_cache: Caches are disabled. The following headers are
sent: Cache-control: no-cache, Pragma: no-cache, Expires:
(now - 1 second)`Max_age n: Caches are allowed to store a copy of the
response for n seconds. After that, the response must be
revalidated. The following headers are sent: Cache-control:
max-age n, Cache-control: must-revalidate, Expires: (now +
n seconds)`Unspecified: No cache control header is added to the
response.Pragma and Expires
headers are sent, too. These fields are not interpreted by
HTTP/1.1 clients because Cache-control has higher precedence.class type cgi =object..end
typeoutput_type =[ `Direct of string
| `Transactional of
config ->
Netchannels.out_obj_channel -> Netchannels.trans_out_obj_channel ]
`Direct sep: Data written to the output channel of the
activation object is not collected in a transaction buffer, but
directly sent to the browser (the normal I/O buffering is still
active, however, so call #flush to ensure that data is really
sent). The method #commit_work of the output channel is the
same as #flush. The method #rollback_work causes that the
string sep is sent, meant as a separator between the already
generated output, and the now following error message.`Transactional f: A transactional channel tc is created
from the real output channel ch by calling f cfg ch (here,
cfg is the CGI configuration). The channel tc is propagated
as the output channel of the activation object. This means that
the methods commit_work and rollback_work are implemented by
tc, and the intended behaviour is that data is buffered in a
special transaction buffer until commit_work is called. This
invocation forces the buffered data to be sent to the
browser. If, however, rollback_work is called, the buffer is
cleared.`Transactional are: let buffered _ ch = new Netchannels.buffered_trans_channel ch in
`Transactional buffered
`Transactional(fun _ ch -> new Netchannels.tempfile_output_channel ch)
typearg_store =cgi_environment ->
string ->
Netmime.mime_header_ro ->
[ `Automatic
| `Automatic_max of float
| `Discard
| `File
| `File_max of float
| `Memory
| `Memory_max of float ]
arg_store so that arg_store env
name header tells whether to `Discard the argument or to
store it into a `File or in `Memory. The parameters passed
to arg_store are as follows:
env is the CGI environment. Thus, for example, you can have
different policies for different cgi_path_info.name is the name of the argument.header is the MIME header of the argument (if any).arg_store will be treated like if it
returned `Discard. Note that the `File will be treated
like `Memory except for `POST "multipart/form-data" and
`PUT queries.
`Automatic means to store it into a file if the header
contains a file name and otherwise in memory (strictly
speaking `Automatic is not necessary since arg_store can
check the header but is provided for your convenience).
`Memory_max (resp. `File_max, resp. `Automatic_max) is
the same as `Memory (resp. `File, resp. `Automatic)
except that the parameter indicates the maximum size in kB of
the argument value. If the size is bigger, the
Netcgi.cgi_argument methods #value and #open_value_rd
methods will raise Netcgi.Argument.Oversized.
Remark: this allows for fine grained size constraints while
Netcgi.config.input_content_length_limit option is a
limit on the size of the entire request.
typeexn_handler =cgi_environment -> (unit -> unit) -> unit
exn_handler allows to define a custom
handler of uncaught exceptions raised by the unit -> unit
parameter. A typical example of exn_handler is as follows:
let exn_handler env f =
try f()
with
| Exn1 -> (* generate error page *)
env#set_output_header_fields [...];
env#send_output_header();
env#out_channel#output_string "...";
env#out_channel#close_out()
| ...
class type['a]container =object..end
type'aconnection_handler ='a container -> (cgi -> unit) -> unit
typebinding =(url_filter * action) list
typeurl_filter =string -> bool
typeaction =cgi -> unit
Netcgi_cgi: classical CGI.Netcgi_fcgi: FastCGI protocol.Netcgi_ajp: AJP 1.3 connector (JSERV protocol).Netcgi_mod: connector binding to Apache API.Netcgi_scgi: SCGI connector.Netcgi_test: special "connector" to test your code. open Netcgi
let main (cgi:cgi) =
let arg = cgi#argument_value "name" in
...
cgi#out_channel#commit_work()
let () =
let buffered _ ch = new Netchannels.buffered_trans_channel ch in
Netcgi_cgi.run ~output_type:(`Transactional buffered) main