30
30
open Ocsigen_extensions
33
34
(*****************************************************************************)
37
let gen hostpattern sitepath charset (regexp, conf, url, prefix) req_state =
39
| Ocsigen_extensions.Req_found (_, r) -> Lwt.return (Ocsigen_extensions.Ext_found r)
40
(*VVV not possible to set a filter for now *)
41
| Ocsigen_extensions.Req_not_found (previous_extension_err, ri) ->
42
let path = ri.ri_sub_path_string in
37
Ocsigen_extensions.Ext_stop_site (Ocsigen_http_frame.Cookies.empty, 500)
40
(* Catch invalid userconf files and report an error *)
41
let handle_parsing_error req = function
42
| Ocsigen_extensions.Error_in_config_file s ->
43
Ocsigen_messages.errlog (Printf.sprintf
44
"Syntax error in userconf configuration file for url %s: %s"
45
req.request_info.ri_url_string s);
48
| Ocsigen_extensions.Error_in_user_config_file s ->
49
Ocsigen_messages.errlog (Printf.sprintf
50
"Unauthorized option in user configuration for url %s: %s"
51
req.request_info.ri_url_string s);
57
(* Answer returned by userconf when the url matches *)
58
let subresult new_req user_parse_site conf previous_err req req_state =
60
(fun awake cookies_to_set rs ->
61
(* XXX why is rs above never used ?? *)
64
user_parse_site conf awake cookies_to_set
65
(Ocsigen_extensions.Req_not_found (previous_err, new_req))
66
>>= fun (answer, cookies) ->
67
(* If the request is not satisfied by userconf, the changes
68
in configuration (in request_config) are preserved for the
69
remainder of the enclosing <site> (in the Ext_continue
70
and Ext_found_continue cases below) *)
71
let rec aux ((answer, cts) as r) = match answer with
72
| Ext_sub_result sr ->
73
(* XXX Are these the good cookies ?? *)
74
sr awake cookies_to_set req_state
76
| Ext_continue_with (newreq, cookies, err) ->
79
({req with request_config = newreq.request_config },
81
| Ext_found_continue_with r ->
82
(* We keep config information outside userconf! *)
84
(Ext_found_continue_with
86
r () >>= fun (r, newreq) -> Lwt.return
88
{ req with request_config = newreq.request_config })
91
in aux (answer, cookies)
94
handle_parsing_error req e >>=
96
Lwt.return (answer, Ocsigen_http_frame.Cookies.empty))
100
let conf_to_xml conf =
101
try Simplexmlparser.xmlparser_file conf
103
| Sys_error _ -> raise NoConfFile
104
| Simplexmlparser.Xml_parser_error s ->
105
raise (Ocsigen_extensions.Error_in_config_file s)
108
let gen hostpattern sitepath (regexp, conf, url, prefix, localpath) = function
110
(* We do not allow setting filters through userconf files right now *)
111
Lwt.return Ext_do_nothing
113
| Req_not_found (previous_err, req) as req_state->
114
let path = req.request_info.ri_sub_path_string in
43
115
match Netstring_pcre.string_match regexp path 0 with
44
| None -> Lwt.return (Ext_next previous_extension_err)
45
| Some _ -> (* Matching regexp found! *)
116
| None -> Lwt.return (Ext_next previous_err)
47
119
Ocsigen_messages.debug2 "--Userconf: Using user configuration";
50
Ocsigen_extensions.replace_user_dir regexp conf path
51
with Not_found -> raise Failed_404
53
let url = Netstring_pcre.global_replace regexp url path in
54
let prefix = Netstring_pcre.global_replace regexp prefix path in
55
ignore (Unix.stat conf);
56
let user_parse_host = Ocsigen_extensions.parse_user_site_item hostpattern in
58
Ocsigen_extensions.make_parse_site
59
(sitepath@[prefix]) charset user_parse_host
61
let xmllist = Simplexmlparser.xmlparser_file conf in
120
let conf = Ocsigen_extensions.replace_user_dir regexp conf path in
121
let url = Netstring_pcre.global_replace regexp url path
122
and prefix = Netstring_pcre.global_replace regexp prefix path
123
and userconf_options = {
124
Ocsigen_extensions.localfiles_root =
125
Ocsigen_extensions.replace_user_dir regexp localpath path }
126
and conf = conf_to_xml conf
128
let user_parse_host = Ocsigen_extensions.parse_user_site_item
129
userconf_options hostpattern in
130
(* Inside userconf, we create a new virtual site starting
131
after [prefix], and use a request modified accordingly*)
132
let user_parse_site = Ocsigen_extensions.make_parse_config
133
(sitepath@[prefix]) user_parse_host
135
Ocsigen_lib.remove_slash_at_beginning
136
(Ocsigen_lib.remove_dotdot (Neturl.split_path url))
139
{ req with request_info =
140
{ req.request_info with
141
ri_sub_path = path; ri_sub_path_string = url}}
64
(fun awake cookies_to_set rs ->
66
Ocsigen_lib.remove_slash_at_end
67
(Ocsigen_lib.remove_slash_at_beginning
68
(Ocsigen_lib.remove_dotdot (Neturl.split_path url)))
74
(Ocsigen_extensions.Req_not_found
75
(previous_extension_err,
78
ri_sub_path_string = url}))
79
(*VVV We do not want to continue to search if the page has not been found *)
80
(*VVV Filters won't be applied. Is it the right behaviour? *)
83
let rec aux ((answer, cts) as r) =
87
| Ext_retry_with _ -> Lwt.return r
90
(Ext_stop_all (Ocsigen_http_frame.Cookies.empty, err),
92
| Ext_continue_with (_, cts2, err)
93
| Ext_stop_site (cts2, err)
94
| Ext_stop_host (cts2, err) ->
95
Lwt.return (Ext_stop_all (cts2, err), cts)
96
| Ext_sub_result sr ->
97
sr awake cookies_to_set req_state
144
(subresult new_req user_parse_site conf previous_err req req_state)
147
| Ocsigen_extensions.NoSuchUser
104
149
| Unix.Unix_error (Unix.EACCES,_,_)
105
150
| Unix.Unix_error (Unix.ENOENT, _, _) ->
106
Lwt.return (Ocsigen_extensions.Ext_next previous_extension_err)
108
Lwt.return (Ocsigen_extensions.Ext_next 404)
151
Lwt.return (Ocsigen_extensions.Ext_next previous_err)
152
| e -> handle_parsing_error req e
113
157
(** Parsing of config file *)
114
158
open Simplexmlparser
116
let parse_config hostpattern path charset =
118
let rec parse_attrs_local ((regexp, conf, url, prefix) as res) = function
120
| ("regexp", s)::l when regexp = None ->
123
(Some (Netstring_pcre.regexp ("^"^s^"$")), conf, url, prefix)
126
raise (Error_in_config_file "Bad regexp in <userconf regexp=\"...\" />"))
127
| ("conf", s)::l when conf = None ->
129
(regexp, Some (Ocsigen_extensions.parse_user_dir s), url, prefix)
131
| ("url", s)::l when url = None ->
133
(regexp, conf, Some s, prefix)
135
| ("prefix", s)::l when prefix = None ->
137
(regexp, conf, url, Some s)
139
| _ -> raise (Error_in_config_file "Wrong attribute for <userconf>")
142
| Element ("userconf", atts, []) ->
144
match parse_attrs_local (None, None, None, None) atts with
145
| (Some r, Some t, Some u, Some p) -> (r, t, u, p)
146
| _ -> raise (Error_in_config_file
147
"Missing attributes for <userconf>")
149
gen hostpattern path charset info
150
| Element (t, _, _) -> raise (Bad_config_tag_for_extension t)
151
| _ -> raise (Error_in_config_file "(userconf extension) Bad data")
154
(*****************************************************************************)
155
(** Function to be called at the beginning of the initialisation phase *)
159
(** Function to be called at the end of the initialisation phase *)
160
let parse_config hostpattern path = fun _ _ ->
161
let rec parse_attrs_local l ((regexp, conf, url, prefix, path) as r) =
164
| ("regexp", s)::l when regexp = None ->
165
(try parse_attrs_local l
166
(Some (Netstring_pcre.regexp ("^"^s^"$")), conf, url, prefix, path)
168
badconfig "Bad regexp '%s' in <userconf regexp=\"...\" />" s)
169
| ("conf", s)::l when conf = None ->
171
(regexp, Some (Ocsigen_extensions.parse_user_dir s), url, prefix, path)
172
| ("url", s)::l when url = None ->
173
parse_attrs_local l (regexp, conf, Some s, prefix, path)
174
| ("prefix", s)::l when prefix = None ->
175
parse_attrs_local l (regexp, conf, url, Some s, path)
176
| ("localpath", s) :: l when path = None ->
178
(regexp, conf, url, prefix, Some (Ocsigen_extensions.parse_user_dir s))
180
badconfig "Wrong or duplicate attribute %s for <userconf>" a
183
| Element ("userconf", atts, []) ->
185
match parse_attrs_local atts (None, None, None, None, None) with
186
| (Some r, Some t, Some u, Some p, Some p') -> (r, t, u, p, p')
187
| _ -> badconfig "Missing attributes for <userconf>"
189
gen hostpattern path info
190
| Element ("userconf", _, _ :: _) ->
191
badconfig "Incorrect (useless) data inside <userconf>"
192
| Element (t, _, _) -> raise (Bad_config_tag_for_extension t)
193
| _ -> badconfig "Bad data in conf file"
165
196
(*****************************************************************************)
166
197
(** extension registration *)
167
let _ = register_extension
169
Ocsigen_extensions.void_extension
171
parse_config (Ocsigen_extensions.parse_user_site_item hostpattern)*)
198
let () = register_extension
200
~fun_site:parse_config