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 : config
tmp_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'a
connection_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