From 06e36b435676498b570b4e3591a52be726a42fe4 Mon Sep 17 00:00:00 2001
From: Luca Padovani " ^ String.concat "" (List.map (fun s -> "
") outchan
+ | "/createprofile" ->
+ let cmd = sprintf "createprofile %s,%s,%s,%s,%s,%s,%s"
+ (string_of_param_option req "id")
+ (string_of_param_option req "orig")
+ (string_of_param_option req "origpassword")
+ (string_of_param_option req "readperm")
+ (string_of_param_option req "writeperm")
+ (string_of_param_option req "adminperm")
+ (string_of_param_option req "password")
+ in
+ short_circuit_grandfather_and_client ~cmd ~cmd_pipe ~res_pipe outchan
+ | "/removeprofile" ->
+ let cmd = sprintf "removeprofile %s,%s"
+ (req#param "id")
+ (string_of_param_option req "password")
+ in
+ short_circuit_grandfather_and_client ~cmd ~cmd_pipe ~res_pipe outchan
+ | "/setprofileparam" ->
+ let cmd = sprintf "setprofileparam %s,%s,%s,%s"
+ (string_of_param_option req "id")
+ (string_of_param_option req "password")
+ (req#param "key")
+ (string_of_param_option req "value")
+ in
+ short_circuit_grandfather_and_client ~cmd ~cmd_pipe ~res_pipe outchan
+ | "/setpassword" ->
+ let cmd = sprintf "setpassword %s,%s,%s"
+ (req#param "id")
+ (string_of_param_option req "password")
+ (string_of_param_option req "oldpassword")
+ in
+ short_circuit_grandfather_and_client ~cmd ~cmd_pipe ~res_pipe outchan
+ | "/setpermission" ->
+ begin
+ match req#param "for" with
+ "read"
+ | "write"
+ | "admin" as forwhat ->
+ let cmd = sprintf "setpermission %s,%s,%s,%s"
+ (req#param "id")
+ (string_of_param_option req "password")
+ forwhat
+ (req#param "value")
+ in
+ short_circuit_grandfather_and_client ~cmd ~cmd_pipe ~res_pipe outchan
+ | _ -> Http_daemon.respond_error ~code:(`Status (`Client_error `Bad_request)) outchan
+ end
+ | "/getparams" ->
+ let pid = req#param "id" in
+ let password = try Some (req#param "password") with _ -> None in
+ let res = Uwobo_profiles.get_params pid ?password () in
+ respond_html
+ ("" ^
+ String.concat "" (List.map (fun k,v -> "
") outchan
+ | "/getparam" ->
+ let pid = req#param "id" in
+ let password = try Some (req#param "password") with _ -> None in
+ let key = req#param "key" in
+ let value = Uwobo_profiles.get_param pid ?password ~key () in
+ respond_html ("" ^ value ^ "") outchan
+ | "/getpermission" ->
+ let pid = req#param "id" in
+ let password = try Some (req#param "password") with _ -> None in
+ let forwhat =
+ match req#param "for" with
+ "read" -> Some `Read
+ | "write" -> Some `Write
+ | "admin" -> Some `Admin
+ | _ -> None
+ in
+ begin
+ match forwhat with
+ Some forwhat ->
+ let value = Uwobo_profiles.get_permission pid ?password forwhat in
+ respond_html ("" ^ (if value then "true" else "false") ^ "") outchan
+ | None -> Http_daemon.respond_error ~code:(`Status (`Client_error `Bad_request)) outchan ;
+ end
| "/apply" ->
let logger = new Uwobo_logger.processingLogger () in
veillogger#clearMsgs;
+ let profile = try Some (req#param "profile") with _ -> None in
+ let password = try Some (req#param "password") with _ -> None in
let xmluri = req#param "xmluri" in
let keys = Pcre.split ~pat:"," (req#param "keys") in
(* notation: "local" parameters are those defined on a per-stylesheet
pasis (i.e. param.key.param=value), "global" parameters are those
defined for all stylesheets (i.e. param.param=value) *)
- let (params, props) = parse_apply_params req#params in
+ let (user_params, props) = parse_apply_params req#params in
+ let profile_params =
+ match profile with
+ None -> []
+ | Some profile -> Uwobo_profiles.get_params profile ?password () in
+ let params =
+ (* user provided parameters override the profile parameters *)
+ let is_global_param x = Pcre.pmatch ~pat:"^(\\.[^.]+){1}$" ("." ^ x) in
+ let is_local_param x = Pcre.pmatch ~pat:"^(\\.[^.]+){2}$" ("." ^ x) in
+ let add key value params =
+ if List.mem_assoc key params then params else params @ [key,value]
+ in
+ List.fold_left
+ (fun old_params (name, value) ->
+ match name with
+ | name when is_global_param name ->
+ (fun x -> add name value (old_params x))
+ | name when is_local_param name ->
+ let pieces = Pcre.extract ~pat:"^([^.]+)\\.(.*)" name in
+ let (key, name) = (pieces.(1), pieces.(2)) in
+ (function
+ | x when x = key -> add name value (old_params x)
+ | x -> old_params x)
+ | _ -> assert false)
+ user_params profile_params
+ in
let (libxslt_errormode, libxslt_debugmode) =
parse_libxslt_msgs_mode req
in
@@ -371,7 +493,7 @@ let callback
syslogger#log `Debug
(sprintf "sending output to client (Content-Type: %s)...."
content_type);
- Http_daemon.send_basic_headers ~code:200 outchan;
+ Http_daemon.send_basic_headers ~code:(`Code 200) outchan;
Http_daemon.send_header "Content-Type" content_type outchan;
Http_daemon.send_CRLF outchan;
write_result outchan
@@ -384,7 +506,7 @@ let callback
outchan)
| "/help" -> respond_html usage_string outchan
| invalid_request ->
- Http_daemon.respond_error ~status:(`Client_error `Bad_request) outchan);
+ Http_daemon.respond_error ~code:(`Status (`Client_error `Bad_request)) outchan);
syslogger#log `Debug (sprintf "%s done!" req#path);
with
| Http_types.Param_not_found attr_name ->
@@ -503,13 +625,98 @@ let main () =
"reloading";
output_string res_pipe (logger#asHtml);
raise Restart_HTTP_daemon
+ | line when Pcre.pmatch ~rex:createprofile_cmd_RE line -> (* /createprofile *)
+ stop_http_daemon ();
+ let params =
+ List.map string_option_of_string (Pcre.split ~pat:"," (Pcre.replace ~rex:createprofile_cmd_RE line))
+ in
+ begin
+ match params with
+ [id; clone; clone_password; read_perm; write_perm; admin_perm; password] ->
+ let bool_option_of_string_option =
+ function
+ Some "true" -> Some true
+ | Some _ -> Some false
+ | None -> None
+ in
+ let pid =
+ Uwobo_profiles.create
+ ?id
+ ?clone
+ ?clone_password
+ ?read_perm:(bool_option_of_string_option read_perm)
+ ?write_perm:(bool_option_of_string_option write_perm)
+ ?admin_perm:(bool_option_of_string_option admin_perm)
+ ?password
+ ()
+ in
+ output_string res_pipe ("Profile " ^ pid ^ " created. Hi " ^ pid) ;
+ raise Restart_HTTP_daemon
+ | _ -> assert false
+ end
+ | line when Pcre.pmatch ~rex:removeprofile_cmd_RE line -> (* /removeprofile *)
+ stop_http_daemon ();
+ let pid, password =
+ match Pcre.split ~pat:"," (Pcre.replace ~rex:removeprofile_cmd_RE line) with
+ [pid; password] -> pid, (string_option_of_string password)
+ | _ -> assert false
+ in
+ Uwobo_profiles.remove pid ?password () ;
+ output_string res_pipe "Done" ;
+ raise Restart_HTTP_daemon
+ | line when Pcre.pmatch ~rex:setprofileparam_cmd_RE line -> (* /setprofileparam *)
+ stop_http_daemon ();
+ let pid, password, key, value =
+ match Pcre.split ~pat:"," (Pcre.replace ~rex:setprofileparam_cmd_RE line) with
+ [pid; password; key; value] ->
+ pid, (string_option_of_string password), key, (string_option_of_string value)
+ | _ -> assert false
+ in
+ Uwobo_profiles.set_param pid ?password ~key ~value () ;
+ output_string res_pipe "Done" ;
+ raise Restart_HTTP_daemon
+ | line when Pcre.pmatch ~rex:setpassword_cmd_RE line -> (* /setpassword *)
+ stop_http_daemon ();
+ let pid, old_password, password =
+ match Pcre.split ~pat:"," (Pcre.replace ~rex:setpassword_cmd_RE line) with
+ [pid; old_password; password] ->
+ pid, (string_option_of_string old_password), (string_option_of_string password)
+ | _ -> assert false
+ in
+ Uwobo_profiles.set_password pid ?old_password password ;
+ output_string res_pipe "Done" ;
+ raise Restart_HTTP_daemon
+ | line when Pcre.pmatch ~rex:setpermission_cmd_RE line -> (* /setpermission *)
+ stop_http_daemon ();
+ let permission_of_string =
+ function
+ "read" -> `Read
+ | "write" -> `Write
+ | "admin" -> `Admin
+ | _ -> assert false
+ and bool_of_string s = "true" = s
+ in
+ let pid, password, forwhat, value =
+ match Pcre.split ~pat:"," (Pcre.replace ~rex:setpermission_cmd_RE line) with
+ [pid; password; forwhat; value] ->
+ pid, (string_option_of_string password), (permission_of_string forwhat), (bool_of_string value)
+ | _ -> assert false
+ in
+ Uwobo_profiles.set_permission pid ?password forwhat value ;
+ output_string res_pipe "Done" ;
+ raise Restart_HTTP_daemon
| cmd -> (* invalid interprocess command received *)
syslogger#log `Warning
(sprintf "Ignoring invalid interprocess command: '%s'" cmd))
done
- with Restart_HTTP_daemon ->
- close_in cmd_pipe; (* these calls close also fds *)
- close_out res_pipe;)
+ with
+ Restart_HTTP_daemon ->
+ close_in cmd_pipe; (* these calls close also fds *)
+ close_out res_pipe
+ | e -> (* Should we return a 404 error here? Maybe... (how?) *)
+ output_string res_pipe (Printexc.to_string e);
+ close_in cmd_pipe; (* these calls close also fds *)
+ close_out res_pipe)
| 0 -> (* (5) child: serve http requests *)
Unix.close cmd_pipe_exit;
Unix.close res_pipe_entrance;
diff --git a/helm/uwobo/uwobo_common.ml b/helm/uwobo/uwobo_common.ml
index b4a910f9d..bdb455bc7 100644
--- a/helm/uwobo/uwobo_common.ml
+++ b/helm/uwobo/uwobo_common.ml
@@ -100,7 +100,7 @@ let usage_string =
return a list of loaded stylesheets
- apply?xmluri=uri&keys=key1,key2,...[&errormode={ignore|comment|embed}][&debugmode={ignore|comment|embed}][¶m.name=value[¶m.name=value[&...]]][¶m.key.name=value[¶m.key.name=value[&...]]][&prop.name[=value][&prop.name[=value][&...]]]
+ apply?xmluri=uri&keys=key1,key2,...[&errormode={ignore|comment|embed}][&debugmode={ignore|comment|embed}][&profile=id][&password=password][¶m.name=value[¶m.name=value[&...]]][¶m.key.name=value[¶m.key.name=value[&...]]][&prop.name[=value][&prop.name[=value][&...]]]
apply a chain of stylesheets, specified by key1, key2, ..., to an
input document, specified by uri.
Error and debugging modes could be ste to three different values.
@@ -114,11 +114,62 @@ let usage_string =
param.name=value syntax, per stylesheet parameters are set using
param.key.name=value where key is the key of a loaded
stylesheet.
+ Moreover, it is possible to specify a profile that is searched for
+ additional global and local parameters. The parameters stored in the profile
+ have lower precedence with respect to those provided in the URL. A
+ password for the profile must be provided if the read permission
+ of the profile is set to false.
Properties of the final chain output can be set too: valueless properties
can be set using prop.name syntax, others can be set using
prop.name=value syntax.
Current supported properties are: %s.
+ listprofiles
+ return the list of profiles available
+
+ createprofile?[id=id][&orig=orig][&origpassword=origpassword][&readperm={true|false}][&writeperm={true|false}][&adminperm={true|false}][&password=password]
+ creates a new profile. The id of the created profile is id (if provided); otherwise it is a fresh id.
+ The parameters are inherited from the profile orig, if provided. origpassword is the password of the
+ profile being copied in case the read permission of that profile is set to false. The defaults for
+ password and readper,writeperm,adminperm are respectively true, true, true and no password.
+
+ removeprofile?id=id[&password=password]
+ completely removes the profile id. The password is required if the profile administrative permission
+ is set to false.
+
+ setprofileparam?id=id[&password=password]&key=key[&value=value]
+ sets the property key to value, if value is provided; otherwise
+ the parameter is unset. The password is required if the profile writing permission is set to
+ false.
+
+ setpassword?id=id[&oldpassword=oldpassword][&password=password]
+ changes or unset the password. The old password is required if it was set.
+
+ setpermission?id=id[&password=password]&permission={read|write|admin}&value={true|false}
+ changes the permission permission. The password is required if the administrative permission
+ is set to false.
+
+ getparams?id=id[&password=password]
+ returns all the params of the profile id. The password is required if the read permission
+ is set to false.
+
+ getparam?id=id[&password=password]&key=key
+ returns the value of the param key of the profile id. The password is required if the read permission
+ is set to false.
+
+ getpermission?id=id[&password=password]&for={read|write|admin}
+ returns the value of the permission key of the profile id. The password is required if the administrative
+ permission is set to false.
+