(* $Id: nethttpd_plex.mli 1488 2010-09-30 22:10:06Z gerd $ *) (** {1 Netplex support} *) (** The important function is [nethttpd_factory], see below. The other functions are only needed for special effects. An example is explained here: {!Netplex_intro.webserver} *) type config_log_error = Nethttpd_types.request_info -> string -> unit type config_log_access = Nethttpd_types.full_info -> unit type config_error_response = Nethttpd_types.error_response_params -> string (** Three type abbreviations for logging functions *) val std_log_error : Netplex_types.container -> config_log_error (** Returns a function that logs errors using the [log_subch] method of the passed container *) val std_log_access : ?debug:bool -> Netplex_types.container -> config_log_access (** Returns a function that logs accesses using the [log_subch] method of the passed container If [debug] is set, additional debug log messages are printed that dump the whole access (incl. header and all available information) *) val std_error_response : config_error_response (** A sample error response function *) val restrict_file_service_config : Netplex_types.config_file -> Netplex_types.address -> unit (** Restricts the subsections and paremeters in the [service] configuration section of type "file" to the allowed ones. *) val read_file_service_config : Netplex_types.config_file -> Netplex_types.address -> string -> Nethttpd_services.file_service (** [read_file_service_config cfg addr uri_path]: Reads the [service] configuration section of type "file" from config file [cfg] at address [addr]. [uri_path] is the default value put into the [file_uri] component of the returned record if no "uri" configuration parameter exists. (In other words, this is the path of the enclosing "uri" section, or "/" if there is only a "host" section.) All other parameters are only taken from the configuration section. See below at [nethttpd_factory] how a file service needs to be configured. *) val restrict_dynamic_service_config : Netplex_types.config_file -> Netplex_types.address -> unit (** Restricts the subsections and paremeters in the [service] configuration section of type "dynamic" to the allowed ones. *) val read_dynamic_service_config : (string * (Netplex_types.config_file -> Netplex_types.address -> string -> 'a Nethttpd_services.dynamic_service ) ) list -> Netplex_types.config_file -> Netplex_types.address -> string -> 'a Nethttpd_services.dynamic_service (** [read_dynamic_service_config handlers cfg addr uri_path]: Reads the [service] configuration section of type "dynamic" from config file [cfg] at address [addr]. The alist [handlers] defines the available handlers. Every handler [h] is called like [h cfg addr uri_path]. [uri_path] is like in [read_file_service_config], i.e. the path of the enclosing "uri" section, or "/" by default. The [h] function has to return the dynamic service to use, which is also returned by [read_dynamic_service_config]. See below at [nethttpd_factory] how a dynamic service needs to be configured. *) type encap = [ `Reactor | `Engine ] val nethttpd_processor : ?hooks:Netplex_types.processor_hooks -> ?encap:encap -> (Netplex_types.container -> #Nethttpd_reactor.http_reactor_config) -> 'a Nethttpd_types.http_service -> Netplex_types.processor (** [netplex_processor mk_config http_service]: Creates a Netplex processor * for Nethttpd. * * [mk_config] determines the nethttpd config for a container. * This is especially useful for setting the logging functions. * * The resulting processor must be turned into a full Netplex service * by [Netplex_sockserv.create_socket_service] which can then be added * by calling the controller's method [add_service]. * * [hooks]: One can pass a Netplex hook object to set the hooks of the * processor. * * [encap]: Selects the encapsulation, [`Reactor] or [`Engine]. * The default is [`Reactor]. Each encapsulation has specific strengths * and weaknesses: * - [`Reactor] is simpler code. Also, the request and response bodies * need not to be buffered up, and are directly connected with the * underlying socket (low memory requirement). The disadvantage is * that a reactor processes TCP connections serially (important to know * when there is only a single Unix process) * - [`Engine]: The request body needs to be completely buffered up. * If pipelining is enabled, the response bodies are also buffered * (FIXME). * The advantage of this encapsulation is that the engine can * process multiple TCP connections simultaneously, even in a * single process/thread. *) type ('a,'b) service_factory = (string * 'a Nethttpd_services.dynamic_service) list -> Netplex_types.config_file -> Netplex_types.address -> string -> 'b Nethttpd_types.http_service constraint 'b = [ `Dynamic_service of 'a Nethttpd_services.dynamic_service | `File_service of Nethttpd_services.file_service ] (** The service factory function is called when a [service] configuration section of a certain type needs to be read. The function has args [handlers], [cfg], [addr], and [uri_path]. It needs to return the [http_service]. Such a function is usually [read_file_service_config], or [read_dynamic_service_config], or a derivative, whose return value is turned into a [http_service]. This can be done with {!Nethttpd_services.file_service} and {!Nethttpd_services.dynamic_service}. *) val default_services : (string * ('a,'b) service_factory) list (** The default services *) type httpd_factory = { httpd_factory : 'a . (Netplex_types.container -> Nethttpd_reactor.http_reactor_config) -> 'a Nethttpd_types.http_service -> Netplex_types.processor } (** The type of the [nethttpd_processor] function *) val nethttpd_factory : ?name:string -> ?hooks:Netplex_types.processor_hooks -> ?encap:encap -> ?config_cgi:Netcgi.config -> ?handlers:(string * 'a Nethttpd_services.dynamic_service) list -> ?services:(string * ('a,'b) service_factory) list -> ?log_error:(Netplex_types.container -> config_log_error) -> ?log_access:(?debug:bool -> Netplex_types.container -> config_log_access) -> ?error_response:config_error_response -> ?processor_factory:httpd_factory -> unit -> Netplex_types.processor_factory (** Factory for a web server component. * * {b Configuration file.} Reads a configuration section like * {[ * processor { * type = "nethttpd"; (* or what is passed as "name" arg *) * timeout = 300.0; * timeout_next_request = 15.0; * access_log = "enabled"; * suppress_broken_pipe = true; * host { * pref_name = "myhost"; (* optional *) * pref_port = 80; (* optional *) * names = "myhost:80 yourhost:81"; (* use *:0 for any name *) * uri { * path = "/the/path"; * method { * allow = "GET POST"; * (* or: deny = "..." *) * service { * type = "..."; * ... * } * } * } * uri { * ... * } * } * host { * ... * } * } * ]} * * The [access_log] parameter can be set to [off], [enabled], or [debug]. * The default is [off]. Access messages go to the "access" subchannel * of the component logger. If [enabled], one line is printed with the * most important data. If [debug] is set, all access data are printed. * * If [suppress_broken_pipe] the error "Broken pipe" is not logged * in the error log. This error occurs frequently, and may be regarded * as a normal condition. * * The sections [host], [uri] and [method] can be nested to any depth. * However, on every nesting level only one of these section types must be * used. For example, if a [host] section already contains [uri] * subsections, it is not allowed to add [method] subsections. * Furthermore, the outermost section must be [host]. * * The [service] section may be one of (at least if the [services] * parameter is not overridden): * * {[ * service { * type = "file"; * docroot = "/a/path/in/the/filesystem"; * uri = "/the/uri/prefix/corresponding/to/docroot"; * media_types_file = "/etc/mime.types"; * media_type { * type = "application/foo"; * suffix = "foo" * } * default_media_type = "text/plain"; * enable_gzip = true; (* see doc in nethttpd_services.mli *) * index_files = "index.html"; * enable_listings = true; * hide_from_listings = "README"; (* list of PCRE regexps *) * } * ]} * * Note that [uri] is taken from the surrounding [uri] section (or * assumed to be "/" if there is none) if omitted. * * {[ * service { * type = "dynamic"; * handler = "name_of_handler"; * } * ]} * * Binds the passed handler here. * * Any of [host], [uri], and [method] sections may contain one or several * [access] sections (which are AND-connected): * * {[ * access { * type = "host"; * allow = "host1 host2 ..."; * (* or deny = "host1 host2 ..."; *) * } * ]} * * Other access control methods are not yet available. * * The [services] optional argument can be used to change the service * types understood. If not passed, it defaults to [default_services]. * The default includes "file" and "dynamic". * * {b Arguments.} * * - [name]: The processor name. Defaults to "nethttpd". This name can * be referenced by the "type" parameters in the [processor] section * of the config file. * - [hooks]: One can pass a Netplex hook object to set the hooks of the * processor. (This argument is ignored if a [processor_factory] is * passed to this function.) * - [encap]: See {!Nethttpd_plex.nethttpd_processor}. (This argument is * ignored if a [processor_factory] is * passed to this function.) * - [config_cgi]: The CGI configuration to use * - [handlers]: a list of handler function. These functions can be * referenced from a [service] section in the config file where * [type="dynamic"] (see example above). Defaults to the empty list. * - [services]: A list of service handlers that can be used * by [service] sections in the config files. Defaults to * {!Nethttpd_plex.default_services} which defines "file" and "dynamic". * - [log_error]: The error logger. Defaults to * {!Nethttpd_plex.std_log_error}. * - [log_access]: The access logger. Defaults to * {!Nethttpd_plex.std_log_access}. * - [error_response]: a handler which is invoked to generate error * responses. Defaults to {!Nethttpd_plex.std_error_response}. * - [processor_factory]: the function creating the processor. * Default is [nethttpd_processor]. *)