diff --git a/src/extensions/authbasic.ml b/src/extensions/authbasic.ml index 1c8e005d7..ea2670dbd 100644 --- a/src/extensions/authbasic.ml +++ b/src/extensions/authbasic.ml @@ -111,7 +111,4 @@ let () = () (** Instruction for static linking without config file: *) -let instruction ~realm ~auth () _ _ _ = gen ~realm ~auth - -let run ?site ~realm ~auth () = - Ocsigen_server.Site.register ?site (instruction ~realm ~auth ()) +let run ~realm ~auth () _ _ _ = gen ~realm ~auth diff --git a/src/extensions/authbasic.mli b/src/extensions/authbasic.mli index 118fb5970..ea1259504 100644 --- a/src/extensions/authbasic.mli +++ b/src/extensions/authbasic.mli @@ -59,13 +59,8 @@ val register_basic_authentication_method : (Xml.xml -> auth) -> unit from the point of view of plugin developers and is totally transparent to the plugin. *) -val run : - ?site:Ocsigen_server.Site.t - -> realm:string - -> auth:auth - -> unit - -> unit -(** [run ~realm ~auth ()] makes it possible to use this extension without +val run : realm:string -> auth:auth -> unit -> Ocsigen_server.instruction +(** [run ~realm ~auth ()] makes it possible to use this extension without configuration file. *) (**/**) diff --git a/src/extensions/cors.ml b/src/extensions/cors.ml index 2de2e5d28..273f2a059 100644 --- a/src/extensions/cors.ml +++ b/src/extensions/cors.ml @@ -156,11 +156,7 @@ let () = ~fun_site:(fun _ _ _ -> parse_config) () -let instruction ?credentials ?max_age ?exposed_headers ?methods () _ _ _ = +let run ?credentials ?max_age ?exposed_headers ?methods () _ _ _ = let credentials = Ocsigen_lib.Option.get' false credentials in let exposed_headers = Ocsigen_lib.Option.get' [] exposed_headers in main {credentials; methods; max_age; exposed_headers} - -let run ?site ?credentials ?max_age ?exposed_headers ?methods () = - Ocsigen_server.Site.register ?site - (instruction ?credentials ?max_age ?exposed_headers ?methods ()) diff --git a/src/extensions/cors.mli b/src/extensions/cors.mli index a604b50e3..239eeb666 100644 --- a/src/extensions/cors.mli +++ b/src/extensions/cors.mli @@ -1,8 +1,7 @@ val run : - ?site:Ocsigen_server.Site.t - -> ?credentials:bool + ?credentials:bool -> ?max_age:int -> ?exposed_headers:string list -> ?methods:Cohttp.Code.meth list -> unit - -> unit + -> Ocsigen_server.instruction diff --git a/src/extensions/deflatemod.ml b/src/extensions/deflatemod.ml index ed7ce96e3..76fe927ba 100644 --- a/src/extensions/deflatemod.ml +++ b/src/extensions/deflatemod.ml @@ -366,7 +366,4 @@ let () = ~fun_site:(fun _ _ _ _ _ _ -> parse_config) ~init_fun:parse_global_config () -let instruction ~mode () _ _ _ = filter mode - -let run ?site ~mode () = - Ocsigen_server.Site.register ?site (instruction ~mode ()) +let run ~mode () _ _ _ = filter mode diff --git a/src/extensions/deflatemod.mli b/src/extensions/deflatemod.mli index b9e3a7db7..3fc99be6f 100644 --- a/src/extensions/deflatemod.mli +++ b/src/extensions/deflatemod.mli @@ -7,7 +7,6 @@ val set_buffer_size : int -> unit type filter = [`Type of string option * string option | `Extension of string] val run : - ?site:Ocsigen_server.Site.t - -> mode:[`All_but of filter list | `Only of filter list] - -> unit + mode:[`All_but of filter list | `Only of filter list] -> unit + -> Ocsigen_server.instruction diff --git a/src/extensions/outputfilter.ml b/src/extensions/outputfilter.ml index 30cc1c506..08167bb0d 100644 --- a/src/extensions/outputfilter.ml +++ b/src/extensions/outputfilter.ml @@ -116,8 +116,5 @@ let () = ~fun_site:(fun _ _ _ _ _ _ -> parse_config) () -let instruction ~mode () _ _ _ = +let run ~mode () _ _ _ = match mode with `Code c -> gen_code c | #header_filter as f -> gen f - -let run ?site ~mode () = - Ocsigen_server.Site.register ?site (instruction ~mode ()) diff --git a/src/extensions/outputfilter.mli b/src/extensions/outputfilter.mli index f1d4ffa40..06551ffad 100644 --- a/src/extensions/outputfilter.mli +++ b/src/extensions/outputfilter.mli @@ -1,8 +1,7 @@ val run : - ?site:Ocsigen_server.Site.t - -> mode: - [ `Rewrite of Ocsigen_header.Name.t * Re.Pcre.regexp * string - | `Add of Ocsigen_header.Name.t * string * bool option - | `Code of Cohttp.Code.status ] - -> unit + mode: + [ `Rewrite of Ocsigen_header.Name.t * Re.Pcre.regexp * string + | `Add of Ocsigen_header.Name.t * string * bool option + | `Code of Cohttp.Code.status ] -> unit + -> Ocsigen_server.instruction diff --git a/src/extensions/redirectmod.ml b/src/extensions/redirectmod.ml index 9912d61e5..1c65647fd 100644 --- a/src/extensions/redirectmod.ml +++ b/src/extensions/redirectmod.ml @@ -112,7 +112,4 @@ let () = ~fun_site:(fun _ _ _ _ _ _ -> parse_config) () -let instruction ~redirection () _ _ _ = gen redirection - -let run ?site ~redirection () = - Ocsigen_server.Site.register ?site (instruction ~redirection ()) +let run ~redirection () _ _ _ = gen redirection diff --git a/src/extensions/redirectmod.mli b/src/extensions/redirectmod.mli index 4c4b15ce9..711f4b1c1 100644 --- a/src/extensions/redirectmod.mli +++ b/src/extensions/redirectmod.mli @@ -10,4 +10,4 @@ val create_redirection : -> string -> redirection -val run : ?site:Ocsigen_server.Site.t -> redirection:redirection -> unit -> unit +val run : redirection:redirection -> unit -> Ocsigen_server.instruction diff --git a/src/extensions/revproxy.ml b/src/extensions/revproxy.ml index 79c5d3b43..3143bccd2 100644 --- a/src/extensions/revproxy.ml +++ b/src/extensions/revproxy.ml @@ -197,7 +197,4 @@ let () = when sending to extensions! *) () -let instruction ~redirection () _ _ _ = gen redirection - -let run ?site ~redirection () = - Ocsigen_server.Site.register ?site (instruction ~redirection ()) +let run ~redirection () _ _ _ = gen redirection diff --git a/src/extensions/revproxy.mli b/src/extensions/revproxy.mli index 7e2e5949b..a5c8f842a 100644 --- a/src/extensions/revproxy.mli +++ b/src/extensions/revproxy.mli @@ -11,4 +11,4 @@ val create_redirection : -> string -> redirection -val run : ?site:Ocsigen_server.Site.t -> redirection:redirection -> unit -> unit +val run : redirection:redirection -> unit -> Ocsigen_server.instruction diff --git a/src/extensions/rewritemod.ml b/src/extensions/rewritemod.ml index 073cdd36a..a8e272f82 100644 --- a/src/extensions/rewritemod.ml +++ b/src/extensions/rewritemod.ml @@ -128,16 +128,10 @@ let () = ~fun_site:(fun _ _ _ _ _ _ -> parse_config) () -let instruction ?(continue = false) ?(full_rewrite = false) ~regexp dest () _ _ - _ - = +let run ?(continue = false) ?(full_rewrite = false) ~regexp dest () _ _ _ = gen (Regexp ( Ocsigen_lib.Netstring_pcre.regexp ("^" ^ regexp ^ "$") , dest , full_rewrite )) continue - -let run ?site ?continue ?full_rewrite ~regexp dest () = - Ocsigen_server.Site.register ?site - (instruction ?continue ?full_rewrite ~regexp dest ()) diff --git a/src/extensions/rewritemod.mli b/src/extensions/rewritemod.mli index ba60ae605..7b4c52275 100644 --- a/src/extensions/rewritemod.mli +++ b/src/extensions/rewritemod.mli @@ -2,10 +2,9 @@ val section : Lwt_log_core.section (** use Lwt_log.Section.set_level in order to debug *) val run : - ?site:Ocsigen_server.Site.t - -> ?continue:bool + ?continue:bool -> ?full_rewrite:bool -> regexp:string -> string -> unit - -> unit + -> Ocsigen_server.instruction diff --git a/src/extensions/staticmod.ml b/src/extensions/staticmod.ml index a9bd94ef9..a6af87930 100644 --- a/src/extensions/staticmod.ml +++ b/src/extensions/staticmod.ml @@ -281,7 +281,7 @@ let () = (* Registration for static linking: *) let preprocess s = "^" ^ s ^ "$" -let instruction ?dir ?regexp ?dest ?code ?cache ?root () = +let run ?dir ?regexp ?dest ?code ?cache ?root () = let kind = kind dir (Ocsigen_lib.Option.map (fun x -> Pcre.regexp (preprocess x)) regexp) @@ -296,7 +296,3 @@ let instruction ?dir ?regexp ?dest ?code ?cache ?root () = root) in fun _ _ _ -> gen ~usermode:None ?cache kind - -let run ?site ?dir ?regexp ?dest ?code ?cache ?root () = - Ocsigen_server.Site.register ?site - (instruction ?dir ?regexp ?dest ?code ?cache ?root ()) diff --git a/src/extensions/staticmod.mli b/src/extensions/staticmod.mli index ac33141f0..4d202fe46 100644 --- a/src/extensions/staticmod.mli +++ b/src/extensions/staticmod.mli @@ -2,14 +2,13 @@ val section : Lwt_log_core.section (** use Lwt_log.Section.set_level in order to debug *) val run : - ?site:Ocsigen_server.Site.t - -> ?dir:string + ?dir:string -> ?regexp:string -> ?dest:string -> ?code:string -> ?cache:int -> ?root:string -> unit - -> unit + -> Ocsigen_server.instruction (** Run static mod on a specific directory. Call this if you want to run Ocsigen Server without configuration file. *) diff --git a/src/ocsigenserver.ml b/src/ocsigenserver.ml index 3727ac321..072bb9718 100644 --- a/src/ocsigenserver.ml +++ b/src/ocsigenserver.ml @@ -31,4 +31,4 @@ let () = "usage: ocsigenserver [-c configfile]" with Arg.Help s -> print_endline s; exit 0 -let () = Ocsigen_server.start ~config:(Ocsigen_parseconfig.parse_config ()) () +let () = Ocsigen_server.exec (Ocsigen_parseconfig.parse_config ()) diff --git a/src/server/ocsigen_extensions.ml b/src/server/ocsigen_extensions.ml index 4ac19f1e3..3eb0737b9 100644 --- a/src/server/ocsigen_extensions.ml +++ b/src/server/ocsigen_extensions.ml @@ -258,9 +258,9 @@ type parse_fun = Xml.xml list -> extension_composite type parse_host = | Parse_host of (Url.path -> parse_host -> parse_fun -> Xml.xml -> extension) -let hosts : (virtual_hosts * config_info * extension_composite) list ref = - ref [] +type host_config = virtual_hosts * config_info * extension_composite +let hosts : host_config list ref = ref [] let set_hosts v = hosts := v let get_hosts () = !hosts diff --git a/src/server/ocsigen_extensions.mli b/src/server/ocsigen_extensions.mli index db1e336ba..92c012819 100644 --- a/src/server/ocsigen_extensions.mli +++ b/src/server/ocsigen_extensions.mli @@ -406,7 +406,9 @@ val site_ext : -> Ocsigen_lib.Url.path -> extension -val set_hosts : (virtual_hosts * config_info * extension_composite) list -> unit +type host_config = virtual_hosts * config_info * extension_composite + +val set_hosts : host_config list -> unit val get_hosts : unit -> (virtual_hosts * config_info * extension_composite) list val compute_result : @@ -416,9 +418,9 @@ val compute_result : (** Compute the answer to be sent to the client, by trying all extensions according the configuration file. *) -val get_number_of_connected : unit -> int -(** Profiling *) +(** {3 Profiling} *) +val get_number_of_connected : unit -> int val during_initialisation : unit -> bool val start_initialisation : unit -> unit val end_initialisation : unit -> unit diff --git a/src/server/ocsigen_server.ml b/src/server/ocsigen_server.ml index 8e5983d0a..f7642e37f 100644 --- a/src/server/ocsigen_server.ml +++ b/src/server/ocsigen_server.ml @@ -122,93 +122,60 @@ let _ = in Ocsigen_command.register_command_function f -module Site = struct - type instruction = - Ocsigen_extensions.virtual_hosts - -> Ocsigen_extensions.config_info - -> Ocsigen_lib.Url.path - -> Ocsigen_extensions.extension +type instruction = + Ocsigen_extensions.virtual_hosts + -> Ocsigen_extensions.config_info + -> Ocsigen_lib.Url.path + -> Ocsigen_extensions.extension - type t = - { s_id : - [ `Host of Ocsigen_extensions.virtual_hosts - | `Attach of t * Ocsigen_lib.Url.path ] - ; s_config_info : Ocsigen_extensions.config_info - ; s_charset : Ocsigen_charset_mime.charset option - ; mutable s_children_l : - [`Instruction of Ocsigen_extensions.extension | `Child of t] list } +let default_re_string = ".*" - (** host list *) - let l = ref [] - - let default_re_string = ".*" - let default_re = Ocsigen_lib.Netstring_pcre.regexp default_re_string - - let rec path_and_hosts {s_id; _} = - match s_id with - | `Host hosts -> [], hosts - | `Attach (s, path') -> - let path, hosts = path_and_hosts s in - path @ path', hosts - - let create ?(config_info = Ocsigen_extensions.default_config_info ()) - ?(id = `Host (default_re_string, None)) ?charset () - = - let s_id = - match id with - | `Host (host_regexp, port) when host_regexp = default_re_string -> - `Host [default_re_string, default_re, port] - | `Host (host_regexp, port) -> - `Host - [host_regexp, Ocsigen_lib.Netstring_pcre.regexp host_regexp, port] - | `Attach (parent, path) -> - `Attach (parent, Ocsigen_extensions.preprocess_site_path path) - in - let s = - {s_id; s_charset = charset; s_config_info = config_info; s_children_l = []} - in - (match s_id with - | `Host _ -> l := s :: !l - | `Attach (parent, _) -> - parent.s_children_l <- `Child s :: parent.s_children_l); - s - - let default_host = create () - - let register ?(site = default_host) f = - let {s_config_info; s_children_l; _} = site in - let path, hosts = path_and_hosts site in - site.s_children_l <- - `Instruction (f hosts s_config_info path) :: s_children_l - - let rec dump_host path {s_children_l; _} = - let f = function - | `Instruction f -> f - | `Child ({s_charset; s_id = `Attach (_, path'); _} as s) -> - let path = path @ path' in - Ocsigen_extensions.site_ext (dump_host path s) s_charset path - | `Child _ -> failwith "Ocsigen_server.dump_host" - in - Ocsigen_extensions.compose (List.map f (List.rev s_children_l)) +let host ?(re = default_re_string) ?port ?default_hostname ?default_httpport + ?default_httpsport ?default_protocol_is_https ?mime_assoc ?charset_assoc + ?default_directory_index ?list_directory_content ?follow_symlinks + ?do_not_serve_404 ?do_not_serve_403 ?uploaddir ?maxuploadfilesize + instructions + = + let def = Ocsigen_extensions.default_config_info () in + let default default o = Option.value o ~default in + let config_info = + { Ocsigen_extensions.default_hostname = + default def.default_hostname default_hostname + ; default_httpport = default def.default_httpport default_httpport + ; default_httpsport = default def.default_httpsport default_httpsport + ; default_protocol_is_https = + default def.default_protocol_is_https default_protocol_is_https + ; mime_assoc = default def.mime_assoc mime_assoc + ; charset_assoc = default def.charset_assoc charset_assoc + ; default_directory_index = + default def.default_directory_index default_directory_index + ; list_directory_content = + default def.list_directory_content list_directory_content + ; follow_symlinks = default def.follow_symlinks follow_symlinks + ; do_not_serve_404 = default def.do_not_serve_404 do_not_serve_404 + ; do_not_serve_403 = default def.do_not_serve_403 do_not_serve_403 + ; uploaddir = default def.uploaddir uploaddir + ; maxuploadfilesize = default def.maxuploadfilesize maxuploadfilesize } + in + let vh = [re, Ocsigen_lib.Netstring_pcre.regexp re, port] in + ( vh + , config_info + , Ocsigen_extensions.compose + (List.map (fun i -> i vh config_info []) instructions) ) - let dump () = - let f acc = function - | {s_config_info; s_id = `Host l; s_children_l = _ :: _; _} as s -> - (l, s_config_info, dump_host [] s) :: acc - | _ -> acc - in - Ocsigen_extensions.set_hosts (List.fold_left f [] !l) -end +let site ?charset path instructions vh config_info parent_path = + let path = parent_path @ Ocsigen_extensions.preprocess_site_path path in + let composite = + Ocsigen_extensions.compose + (List.map (fun i -> i vh config_info path) instructions) + in + Ocsigen_extensions.site_ext composite charset path -let start ?config () = +let main config = try (* initialization functions for modules (Ocsigen extensions or application code) loaded from now on will be executed directly. *) Ocsigen_loader.set_init_on_load true; - (match config with - | Some (_ :: _ :: _) -> - Lwt_log.ign_warning ~section "Multiple servers not supported anymore" - | _ -> ()); let ask_for_passwd sslports _ = print_string "Please enter the password for the HTTPS server listening on port(s) "; @@ -231,7 +198,7 @@ let start ?config () = raise exn in let extensions_connector = Ocsigen_extensions.compute_result in - let run s = + let run () = let user = Ocsigen_config.get_user () and group = Ocsigen_config.get_group () in Lwt_main.run (Ocsigen_messages.open_files ~user ~group ()); @@ -319,19 +286,8 @@ let start ?config () = match e with | Unix.Unix_error (Unix.EPIPE, _, _) -> () | _ -> Lwt_log.ign_error ~section ~exn:e "Uncaught Exception"); - (match s with - | Some s -> - (* Now I can load the modules *) - Dynlink_wrapper.allow_unsafe_modules true; - Ocsigen_extensions.start_initialisation (); - Ocsigen_parseconfig.later_pass s; - (* As libraries are reloaded each time the config file is - read, we do not allow to register extensions in - libraries. Seems it does not work :-/ *) - Dynlink_wrapper.prohibit ["Ocsigen_extensions.R"] - | None -> - Ocsigen_extensions.start_initialisation (); - Site.dump ()); + (* Now apply host configuration: *) + config (); if Ocsigen_config.get_silent () then ( (* Close stderr, stdout stdin if silent *) @@ -421,31 +377,46 @@ let start ?config () = ignore (Unix.write_substring f spid 0 len); Unix.close f in - let launch h = - Ocsigen_lib.Option.iter Ocsigen_parseconfig.first_pass h; - (* set_passwd_if_needed sslinfo; *) - if Ocsigen_config.get_daemon () - then - let pid = Unix.fork () in - if pid = 0 - then run h - else ( - Ocsigen_messages.console (fun () -> - "Process " ^ string_of_int pid ^ " detached"); - write_pid pid) + (* set_passwd_if_needed sslinfo; *) + if Ocsigen_config.get_daemon () + then + let pid = Unix.fork () in + if pid = 0 + then run () else ( - write_pid (Unix.getpid ()); - run h) - in - let launch = function - | Some [] -> () - | Some [h] -> launch (Some h) - | None -> launch None - | Some (_ :: _ :: _) -> () - (* Multiple servers not supported any more *) - in - launch config + Ocsigen_messages.console (fun () -> + "Process " ^ string_of_int pid ^ " detached"); + write_pid pid) + else ( + write_pid (Unix.getpid ()); + run ()) with e -> let msg, errno = errmsg e in Ocsigen_messages.errlog msg; exit errno + +let exec = function + | [] -> () + | [h] -> + (try Ocsigen_parseconfig.first_pass h + with e -> + let msg, errno = errmsg e in + Ocsigen_messages.errlog msg; + exit errno); + main (fun () -> + (* Now I can load the modules *) + Dynlink_wrapper.allow_unsafe_modules true; + Ocsigen_extensions.start_initialisation (); + Ocsigen_parseconfig.later_pass h; + (* As libraries are reloaded each time the config file is + read, we do not allow to register extensions in + libraries. Seems it does not work :-/ *) + Dynlink_wrapper.prohibit ["Ocsigen_extensions.R"]) + | _ :: _ :: _ -> + Lwt_log.ign_warning ~section "Multiple servers not supported anymore" +(* Multiple servers not supported any more *) + +let start instructions = + main (fun () -> + Ocsigen_extensions.start_initialisation (); + Ocsigen_extensions.set_hosts instructions) diff --git a/src/server/ocsigen_server.mli b/src/server/ocsigen_server.mli index c57e04a9d..6be7709a6 100644 --- a/src/server/ocsigen_server.mli +++ b/src/server/ocsigen_server.mli @@ -26,38 +26,39 @@ val reload : ?file:string -> unit -> unit [?file] may be used to read the configuration from another file. *) -val start : ?config:Xml.xml list list -> unit -> unit -(** Start the server. Never returns. *) +val exec : Xml.xml list list -> unit +(** Start the server with a configuration file. Never returns. *) -(** Use this to create an extension that can be linked statically, - and used without configuration file. *) -module Site : sig - type t +val start : Ocsigen_extensions.host_config list -> unit +(** Start the server with some instructions. Never returns. *) - val create : - ?config_info:Ocsigen_extensions.config_info - -> ?id:[`Attach of t * Ocsigen_lib.Url.path | `Host of string * int option] - -> ?charset:Ocsigen_charset_mime.charset - -> unit - -> t - (** [create ?config_info ?id ?charset ()] - creates a subsite. - This is equivalent to the [] or [] config file options. - *) +type instruction = + Ocsigen_extensions.virtual_hosts + -> Ocsigen_extensions.config_info + -> Ocsigen_lib.Url.path + -> Ocsigen_extensions.extension - val default_host : t - (** Defaut host. Any hostname, any port. - Will be used if you don not specify [?site]. *) +val host : + ?re:string + -> ?port:int + -> ?default_hostname:string + -> ?default_httpport:int + -> ?default_httpsport:int + -> ?default_protocol_is_https:bool + -> ?mime_assoc:Ocsigen_charset_mime.mime_assoc + -> ?charset_assoc:Ocsigen_charset_mime.charset_assoc + -> ?default_directory_index:string list + -> ?list_directory_content:bool + -> ?follow_symlinks:[`Always | `No | `Owner_match] + -> ?do_not_serve_404:Ocsigen_extensions.do_not_serve + -> ?do_not_serve_403:Ocsigen_extensions.do_not_serve + -> ?uploaddir:string option + -> ?maxuploadfilesize:int64 option + -> instruction list + -> Ocsigen_extensions.host_config - type instruction = - Ocsigen_extensions.virtual_hosts - -> Ocsigen_extensions.config_info - -> Ocsigen_lib.Url.path - -> Ocsigen_extensions.extension - (** Instructions are defined by extensions, and correspond to the - configuration file options defined by extensions ( ...)*) - - val register : ?site:t -> instruction -> unit - (** [register ~site:s e] registers instruction [e] to be run inside site [s]. - Use this if you want to create an extension yourself. *) -end +val site : + ?charset:string + -> Ocsigen_lib.Url.path + -> instruction list + -> instruction