module Ocsigen_extensions: sig
.. end
Writing extensions for Ocsigen
exception Ocsigen_http_error of (Ocsigen_http_frame.cookieset * int)
exception Ocsigen_Is_a_directory
exception Ocsigen_malformed_url
exception Ocsigen_Internal_Error of string
exception Bad_config_tag_for_extension of string
Try next extension
exception Error_in_config_file of string
Stop with an error message
val badconfig : ('a, unit, string, 'b) Pervasives.format4 -> 'a
Convenient function for raising Error_in_config_file exceptions with
a sprintf-formatted argument.
type
url_path = string list
The type of URL paths. ["plop";"plip"]
corresponds to plop/plip
.
val string_of_url_path : url_path -> string
type
virtual_host_part =
| |
Text of string * int |
| |
Wildcard |
type
virtual_hosts = (virtual_host_part list * int option) list
type
file_info = {
|
tmp_filename : string ; |
|
filesize : int64 ; |
|
raw_original_filename : string ; |
|
original_basename : string ; |
}
The files sent in the request
Note that the files are cancelled once the request has been fulfilled
Only IE is known to make raw_original_filename
and
original_basename
differ, as it sends the full original path
of uploaded files. In all cases, original_basename
is the
basename of the file. More precisely, it is the part of the
filename after the last /
or \
, if any, or "none"
if one of
these characters is the last one. You should probably never use
raw_original_filename
.
type
client
A value of this type represents the client who did the request.
val client_id : client -> int
Returns the id number of the connection
val client_connection : client -> Ocsigen_http_com.connection
Returns the connection
type
request_info = {
|
ri_url_string : string ; |
|
ri_url : Neturl.url ; |
|
ri_method : Ocsigen_http_frame.Http_header.http_method ; |
|
ri_protocol : Ocsigen_http_frame.Http_header.proto ; |
|
ri_ssl : bool ; |
|
ri_full_path_string : string ; |
|
ri_full_path : string list ; |
|
ri_sub_path : string list ; |
|
ri_sub_path_string : string ; |
|
ri_get_params_string : string option ; |
|
ri_host : string option ; |
|
ri_get_params : (string * string) list Lazy.t ; |
|
ri_initial_get_params : (string * string) list Lazy.t ; |
|
ri_post_params : (string * string) list Lwt.t Lazy.t ; |
|
ri_files : (string * file_info) list Lwt.t Lazy.t ; |
|
ri_remote_inet_addr : Unix.inet_addr ; |
|
ri_remote_ip : string ; |
|
ri_remote_ip_parsed : Ocsigen_lib.ip_address Lazy.t ; |
|
ri_remote_port : int ; |
|
ri_server_port : int ; |
|
ri_user_agent : string ; |
|
ri_cookies_string : string option Lazy.t ; |
|
ri_cookies : string Ocsigen_http_frame.Cookievalues.t Lazy.t ; |
|
ri_ifmodifiedsince : float option ; |
|
ri_ifunmodifiedsince : float option ; |
|
ri_ifnonematch : string list ; |
|
ri_ifmatch : string list option ; |
|
ri_content_type : ((string * string) * (string * string) list) option ; |
|
ri_content_type_string : string option ; |
|
ri_content_length : int64 option ; |
|
ri_referer : string option Lazy.t ; |
|
ri_accept : ((string option * string option) * float option * (string * string) list) list Lazy.t ; |
|
ri_accept_charset : (string option * float option) list Lazy.t ; |
|
ri_accept_encoding : (string option * float option) list Lazy.t ; |
|
ri_accept_language : (string * float option) list Lazy.t ; |
|
ri_http_frame : Ocsigen_http_frame.t ; |
|
ri_extension_info : exn list ; |
|
ri_client : client ; |
}
The request
If you force ri_files
or ri_post_params
, the request is fully read,
so it is not possible any more to read it from ri_http_frame
(and vice versa).
type
answer =
type
request_state =
type
extension2 = (unit -> unit) ->
Ocsigen_http_frame.cookieset ->
request_state ->
(answer * Ocsigen_http_frame.cookieset) Lwt.t
type
extension = request_state -> answer Lwt.t
For each <site> tag in the configuration file,
you can set the extensions you want.
Each extension is implemented as a function, taking
the charset found in configuration file,
the current state of the request,
and returning an answer.
If no page has been generated so far (Req_not_found
), it receive
the error code given by the previous extension (default 404),
and the request information.
If a page has been generated by previous extensions (case Req_found
),
the extension may want to modify the result (filters).
type
parse_fun = Simplexmlparser.xml list -> extension2
type
parse_host
val register_extension : ?respect_pipeline:bool ->
(virtual_hosts ->
url_path ->
string * string * int * int ->
parse_host ->
parse_fun ->
Simplexmlparser.xml -> extension) ->
(virtual_hosts ->
url_path ->
string * string * int * int ->
parse_host ->
parse_fun ->
Simplexmlparser.xml -> extension) ->
(unit -> unit) -> (unit -> unit) -> (exn -> string) -> unit
For each extension generating pages, we register four functions:
- a function taking
- the name of the virtual <host>
that will be called for each <host>,
and that will generate a function taking:
- the path attribute of a <site> tag
that will be called for each <site>,
and that will generate a function taking:
- an item of the config file
that will be called on each tag inside <site> and:
- raise
Bad_config_tag_for_extension
if it does not recognize that tag
- return something of type
extension
(filter or page generator)
- a function of same type, that will be called every time user configuration
files are parsed (if userconf is enabled).
It must define only safe options, for example it is not
safe to allow such options to load a cmo specified by a user, or to
execute a program, as this program will be executed by ocsigen's user.
Note that function will be called for every request, whereas the first one
is called only when starting or reloading the server.
If you do not want to allow users to use your extension,
use the predefined function
void_extension
(defines no option).
- a function that will be called at the beginning
of the initialisation phase (each time the config file is reloaded)
(Note that the extensions are not reloaded)
- a function that will be called at the end of the initialisation phase
of the server
- a function that will create an error message from the exceptions
that may be raised during the initialisation phase, and raise again
all other exceptions
If the optional parameter
?respect_pipeline
is
true
, the extension
will ask the server to respect the order of the pipeline. That means that
it will wait to be sure that the previous request from the same connection
has been taken by an extension before giving a request to an extension.
Use this to write proxies extensions, when you want to be able to pipeline
the requests you to another server. It is false by default.
val void_extension : virtual_hosts ->
url_path ->
string * string * int * int ->
parse_host ->
parse_fun ->
Simplexmlparser.xml -> extension
val get_config : unit -> Simplexmlparser.xml list
While loading an extension,
get the configuration tree between <dynlink></dynlink>
val ri_of_url : string -> request_info -> request_info
Parsing URLs.
This allows to modify the URL in the request_info.
(to be used for example with Ext_retry_with or Ext_continue_with)
User directories
type
ud_string
The type for string that may contain a $u(...)
val parse_user_dir : string -> ud_string
val replace_user_dir : Netstring_pcre.regexp -> ud_string -> string -> string
raises Not_found
is the directory does not exist