Module Extensions


module Extensions: sig .. end
Writing extensions for Ocsigen

exception Ocsigen_http_error of 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
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; (*Where the file is stored on the server*)
   filesize : int64; (*Size, in bytes*)
   original_filename : string; (*Original file name*)
}
The files sent in the request

Note that the files are cancelled once the request has been fulfilled


type request_info = {
   ri_url_string : string; (*full URL*)
   ri_url : Neturl.url;
   ri_method : Http_frame.Http_header.http_method; (*GET, POST, HEAD...*)
   ri_protocol : Http_frame.Http_header.proto; (*HTTP protocol used by client*)
   ri_path_string : string; (*path of the URL*)
   ri_full_path : string list; (*full path of the URL*)
   ri_sub_path : string list; (*path of the URL (only part concerning the site)*)
   ri_sub_path_string : string Lazy.t; (*path of the URL (only part concerning the site)*)
   ri_get_params_string : string option; (*string containing GET parameters*)
   ri_host : string option; (*Host field of the request (if any)*)
   ri_get_params : (string * string) list Lazy.t; (*Association list of get parameters*)
   ri_post_params : (string * string) list Lwt.t Lazy.t; (*Association list of post parameters*)
   ri_files : (string * file_info) list Lwt.t Lazy.t; (*Files sent in the request*)
   ri_inet_addr : Unix.inet_addr; (*IP of the client*)
   ri_ip : string; (*IP of the client*)
   ri_ip32 : int32 Lazy.t; (*IP of the client, as a 32 bits integer*)
   ri_remote_port : int; (*Port used by the client*)
   ri_port : int; (*Port of the request (server)*)
   ri_user_agent : string; (*User_agent of the browser*)
   ri_cookies_string : string option Lazy.t; (*Cookies sent by the browser*)
   ri_cookies : string Http_frame.Cookievalues.t Lazy.t; (*Cookies sent by the browser*)
   ri_ifmodifiedsince : float option; (*if-modified-since field*)
   ri_ifunmodifiedsince : float option; (*if-unmodified-since field*)
   ri_ifnonematch : string list; (*if-none-match field ( * and weak entity tags not implemented)*)
   ri_ifmatch : string list option; (*if-match field ( * not implemented)*)
   ri_content_type : string option; (*Content-Type HTTP header*)
   ri_content_length : int64 option; (*Content-Length HTTP header*)
   ri_referer : string option Lazy.t; (*Referer HTTP header*)
   ri_accept : ((string option * string option) * float option * (string * string) list)
list Lazy.t
;
(*Accept HTTP header. For example (Some "text", None) means "text/*". The float is the "quality" value, if any. The last association list is for other extensions.*)
   ri_accept_charset : (string option * float option) list Lazy.t; (*Accept-Charset HTTP header. None for the first value means "*". The float is the "quality" value, if any.*)
   ri_accept_encoding : (string option * float option) list Lazy.t; (*Accept-Encoding HTTP header. None for the first value means "*". The float is the "quality" value, if any.*)
   ri_accept_language : (string * float option) list Lazy.t; (*Accept-Language HTTP header. The float is the "quality" value, if any.*)
   ri_http_frame : Http_frame.t; (*The full http_frame*)
   ri_extension_info : exn list; (*Use this to put anything you want, for example, information for subsequent extensions*)
}
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 =
| Ext_found of Http_frame.result (*OK stop! I found the page.*)
| Ext_not_found of int (*Page not found. Try next extension. The integer is the HTTP error code. It is usally 404, but may be for ex 403 (forbidden) if you want another extension to try after a 403*)
| Ext_stop of int (*Error. Do not try next extension, but try next site. If you do not want to try next site send an Ext_found with an error code. The integer is the HTTP error code, usally 403.*)
| Ext_continue_with of request_info * Http_frame.cookieset * int (*Used to modify the request before giving it to next extension. The extension returns the request_info (possibly modified) and a set of cookies if it wants to set or cookies (!Http_frame.Cookies.empty for no cookies). You must add these cookies yourself in request_info if you want them to be seen by subsequent extensions, for example using Http_frame.compute_new_ri_cookies. The integer is usually equal to the error code received from preceding extension (but you may want to modify it).*)
| Ext_retry_with of request_info * Http_frame.cookieset (*Used to retry all the extensions with a new request_info. The extension returns the request_info (possibly modified) and a set of cookies if it wants to set or cookies (!Http_frame.Cookies.empty for no cookies). You must add these cookies yourself in request_info if you want them to be seen by subsequent extensions, for example using Http_frame.compute_new_ri_cookies.*)

type extension =
| Page_gen of (int -> string -> request_info -> answer Lwt.t)
| Filter of (string ->
request_info -> Http_frame.result -> answer Lwt.t)
(*For each <site> tag in the configuration file, you can set the extensions you want. They take the error code received from preceding extensions (not for filters, the default is 404), the charset (type string), a request_info. If it is a filter, it takes the result of the previous extension. And they both return an answer.*)
val register_extension : (virtual_hosts ->
url_path ->
string option -> Simplexmlparser.xml -> extension) *
(unit -> unit) * (unit -> unit) * (exn -> string) -> unit
For each extension generating pages, we register four functions:
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)