module Ocsigen_extensions: sig
.. end
Writing extensions for Ocsigen
exception Ocsigen_http_error of (Ocsigen_http_frame.cookieset * int)
exception Bad_config_tag_for_extension of string
Xml tag not recognized by an extension (usually not a real error)
exception Error_in_config_file of string
Error in a <site> tag inside the main ocsigen.conf file
exception Error_in_user_config_file of string
Option incorrect in a userconf file
val badconfig : ('a, unit, string, 'b) Pervasives.format4 -> 'a
Convenient function for raising Error_in_config_file exceptions with
a sprintf-formatted argument.
type
virtual_hosts = (string * Netstring_pcre.regexp * int option) list
Type of the result of parsing the field hostfiler
in the configuration
file. Inside the list, the first argument is the host itself
(which is a glob-like pattern that can contains *
), a regexp
parsing this pattern, and optionnaly a port.
val hash_virtual_hosts : virtual_hosts -> int
val equal_virtual_hosts : virtual_hosts -> virtual_hosts -> bool
val host_match : virtual_hosts:virtual_hosts ->
host:string option -> port:int -> bool
type
do_not_serve = {
|
do_not_serve_regexps : string list ; |
|
do_not_serve_files : string list ; |
|
do_not_serve_extensions : string list ; |
}
Configuration to hide/forbid local files
exception IncorrectRegexpes of do_not_serve
val do_not_serve_to_regexp : do_not_serve -> Netstring_pcre.regexp
Compile a do_not_serve structure into a regexp. Raises
IncorrectRegexpes
if the compilation fails. The result is
memoized for subsequent calls with the same argument
val join_do_not_serve : do_not_serve ->
do_not_serve -> do_not_serve
type
config_info = {
}
Configuration options, passed to (and modified by) extensions
type
follow_symlink =
| |
DoNotFollowSymlinks |
| |
FollowSymlinksIfOwnerMatch |
| |
AlwaysFollowSymlinks |
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
ifrange =
| |
IR_No |
| |
IR_Ifunmodsince of float |
| |
IR_ifmatch of string |
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_original_full_path_string : string ; |
|
ri_original_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_port_from_host_field : int option ; |
|
ri_get_params : (string * string) list Lazy.t ; |
|
ri_initial_get_params : (string * string) list Lazy.t ; |
|
ri_post_params : config_info -> (string * string) list Lwt.t ; |
|
ri_files : config_info -> (string * Ocsigen_lib.file_info) list Lwt.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_lib.String_Table.t Lazy.t ; |
|
ri_ifmodifiedsince : float option ; |
|
ri_ifunmodifiedsince : float option ; |
|
ri_ifnonematch : string list option ; |
|
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 ; |
|
mutable ri_request_cache : Polytables.t ; |
|
ri_client : client ; |
|
ri_range : ((int64 * int64) list * int64 option * ifrange) option Lazy.t ; |
|
mutable ri_nb_tries : int ; |
}
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
request = {
}
exception Ocsigen_Is_a_directory of request
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
Type of the functions parsing the content of a <host> tag
type
userconf_info = {
|
localfiles_root : string ; |
}
Information received by extensions accepting userconf files.
The parameter localfiles_root
is an absolute path to the
directory that the user is allowed to serve. This is used
by staticmod, to disallow the user from allowing access to
outside of this directory
type
parse_config = virtual_hosts -> parse_config_aux
parse_config
is the type of the functions parsing a <site> tag
(and returning an extension). Those are functions 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)
parse_config_user
is the type of functions parsing a site tag
inside an userconf file. They take one more parameter, of type userconf_info
type
parse_config_user = userconf_info -> parse_config
type
parse_config_aux = Ocsigen_lib.url_path ->
parse_host ->
parse_fun ->
Simplexmlparser.xml -> extension
val register_extension : name:string ->
?fun_site:parse_config ->
?user_fun_site:parse_config_user ->
?begin_init:(unit -> unit) ->
?end_init:(unit -> unit) ->
?init_fun:(Simplexmlparser.xml list -> unit) ->
?exn_handler:(exn -> string) -> ?respect_pipeline:bool -> unit -> unit
For each extension generating pages, we register its name and six functions:
- a function
fun_site
of type parse_config
. This function
will be responsible for handling the options of the configuration
files that are recognized by the extension, and potentially generating
a page.
- a function
user_fun_site
of type parse_user_config
which has the
same role as fun_site
, but inside userconf files. Specify nothing
if your extension is disallowed in userconf files. Otherwise, compared
to fun_site
, you can selectively disallow some options,
as user_fun_site
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 user_fun_site
will be called for every request, whereas the
fun_site
is called only when starting or reloading the server.
- a function
begin_init
that will be called at the beginning
of the initialisation phase of each site, and each time the config file is
reloaded.
- a function
end_init
that will be called at the end of the initialisation
phase of each site
- a function
init_fun
that will be called just before registering the
extension, taking as parameter the configuration options between
<extension>
and </extension>
. This allows to give configuration options
to extensions. If no function is supplied, the extension is supposed to
accept no option (and loading will fail if an option is supplied)
- a function
exn_handler
that will create an error message from the
exceptions that may be raised during the initialisation phase, and raise again
all other exceptions
Moreover, 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 get_hostname : request -> string
Returns the hostname to be used for absolute links or redirections.
It is either the Host header or the hostname set in
the configuration file.
val get_port : request -> int
Returns the port to be used for absolute links or redirections.
It is either the port the server is listening at or the default port set in
the configuration file.
val ri_of_url : ?full_rewrite:bool ->
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
Exception raised when an non-existing user is found
exception NoSuchUser
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
exception Not_concerned
Regular expressions for redirections
val find_redirection : Netstring_pcre.regexp ->
bool ->
string ->
bool -> string option -> int -> string option -> string -> string -> string
exception Unknown_command
Extending server commands
val register_command_function : ?prefix:string -> (string -> string list -> unit) -> unit
Use a prefix for all your cammands when you want to create
extension specific commands.
For example if the prefix is "myextension" and the commande "blah",
the actual command to be written by the user is "myextension:blah".
Give as parameter the function that will parse the command and do an action.
Its first parameter is the full comand as a string.
The second one is the command without prefix, split by word.
It must raise ocsigen_extensions.Unknown_command
if it does
not recognize the command.