Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support of wildcards and relative paths to load sub-config files.

Now, subconfig and subconfigdir targets accept relative paths, searched
relatively to the configuration location. So for the configuration
"/etc/yaws/yaws.conf", all relative files and directories will be searched from
"/etc/yaws". Of course, absolute paths are always supported.

furthermore, the subconfig target can take Unix-style wildcard strings to
include several files at once. See filelib:wildcard/1 for details.

Last, hidden files, starting by a dot, will be ignored in any cases.
  • Loading branch information...
commit e81c94adf128173698a49ec3e2fcfe59653458aa 1 parent 90e36db
@capflam capflam authored
View
1  configure.ac
@@ -510,6 +510,7 @@ AC_CONFIG_FILES([
src/yaws_charset.hrl
src/yaws_appdeps.hrl
+ test/eunit//subconfig_DATA/yaws_absolute.conf
test/support/yaws.conf
test/t1/yaws.conf
test/t2/yaws.conf
View
22 doc/yaws.tex
@@ -2419,10 +2419,28 @@ \section{Global Part}
\verb+infinity+ is legal but not recommended.
\item \verb+subconfig = File+ ---
- Load specified config file.
+ Load specified config file. Absolute paths or relative ones to
+ the configuration location are allowed. Unix-style wildcard
+ strings can be used to include several files at once. See
+ \verb+filelib:wildcard/1+ for details. Hidden files, starting by a
+ dot, will be ignored. For example:
+
+\begin{verbatim}
+ subconfig = /etc/yaws/global.conf
+ subconfig = /etc/yaws/vhosts/*.conf
+\end{verbatim}
+
+ Or, relatively to the configuration localtion:
+
+\begin{verbatim}
+ subconfig = global.conf
+ subconfig = vhosts/*.conf
+\end{verbatim}
\item \verb+subconfigdir = Directory+ ---
- Load all config files in specified directory.
+ Load all config files found in the specified directory. The given
+ Directory can be an absolute path or relative to the configuration
+ location. Hidden files, starting by a dot, will be ignored.
\item \verb+x_forwarded_for_log_proxy_whitelist = ListOfUpstreamProxyServerIps+ ---
\textit{This target is deprecated and will be ignored}.
View
22 man/yaws.conf.5
@@ -263,11 +263,29 @@ but not recommended.
.TP
\fBsubconfig = File\fR
-Load specified config file.
+Load specified config file. Absolute paths or relative ones to the configuration
+location are allowed. Unix-style wildcard strings can be used to include several
+files at once. See \fIfilelib:wildcard/1\fR for details. Hidden files, starting
+by a dot, will be ignored. For example:
+
+.nf
+ subconfig = /etc/yaws/global.conf
+ subconfig = /etc/yaws/vhosts/*.conf
+.fi
+
+Or, relatively to the configuration localtion:
+
+.nf
+ subconfig = global.conf
+ subconfig = vhosts/*.conf
+.fi
+
.TP
\fBsubconfigdir = Directory\fR
-Load all config file in specified directory.
+Load all config files found in the specified directory. The given Directory can
+be an absolute path or relative to the configuration location. Hidden files,
+starting by a dot, will be ignored.
.TP
\fBx_forwarded_for_log_proxy_whitelist = ListOfUpstreamProxyServerIps\fR
View
115 src/yaws_config.erl
@@ -695,45 +695,44 @@ fload(FD, globals, GC, C, Cs, Lno, Chars) ->
fload(FD, globals, GC, C, Cs, Lno+1, Next);
["subconfig", '=', Name] ->
- File = filename:absname(Name),
- case is_file(File) of
- true ->
- error_logger:info_msg(
- "Yaws: Using subconfig file ~s~n", [File]),
- case file:open(File, [read]) of
- {ok, FD1} ->
- R = (catch fload(FD1, globals, GC, undefined,
- Cs, 1, io:get_line(FD1, ''))),
- ?Debug("FLOAD: ~p", [R]),
- case R of
- {ok, GC1, Cs1} ->
- fload(FD, globals, GC1, C, Cs1, Lno+1,Next);
- Err ->
- Err
- end;
+ {ok, Config} = file:pid2name(FD),
+ ConfPath = filename:dirname(filename:absname(Config)),
+ File = filename:absname(Name, ConfPath),
+ case {is_file(File), is_wildcard(Name)} of
+ {true,_} ->
+ case subconfigfile(File, GC, Cs) of
+ {ok, GC1, Cs1} ->
+ fload(FD, globals, GC1, C, Cs1, Lno+1,Next);
Err ->
- {error, ?F("Can't open config file ~s:~p",
- [File,Err])}
+ Err
end;
- false ->
- {error, ?F("Expect filename at line ~w", [Lno])}
+ {false,true} ->
+ Names = filelib:wildcard(Name, ConfPath),
+ Files = [filename:absname(N, ConfPath)
+ || N <- lists:sort(Names)],
+ case subconfigfiles(Files, GC, Cs) of
+ {ok, GC1, Cs1} ->
+ fload(FD, globals, GC1, C, Cs1,
+ Lno+1, Next);
+ Err ->
+ Err
+ end;
+ {false,false} ->
+ {error, ?F("Expect filename or wildcard at line ~w"
+ " [subconfig: ~s]", [Lno, Name])}
end;
["subconfigdir", '=', Name] ->
- Dir = filename:absname(Name),
+ {ok, Config} = file:pid2name(FD),
+ ConfPath = filename:dirname(filename:absname(Config)),
+ Dir = filename:absname(Name, ConfPath),
case is_dir(Dir) of
true ->
case file:list_dir(Dir) of
{ok, Names} ->
- Sorted = lists:sort(Names),
- Paths = lists:map(
- fun(N) ->
- filename:absname(N, Dir)
- end, Sorted),
- Fold = lists:foldl(
- fun subconfigdir_fold/2,
- {ok, GC, Cs}, Paths),
- case Fold of
+ Files = [filename:absname(N, Dir)
+ || N <- lists:sort(Names)],
+ case subconfigfiles(Files, GC, Cs) of
{ok, GC1, Cs1} ->
fload(FD, globals, GC1, C, Cs1,
Lno+1, Next);
@@ -2228,6 +2227,12 @@ is_file(Val) ->
false
end.
+is_wildcard(Val) ->
+ (lists:member($*, Val) orelse
+ lists:member($?, Val) orelse
+ (lists:member($[, Val) andalso lists:member($], Val)) orelse
+ (lists:member(${, Val) andalso lists:member($}, Val))).
+
%% tokenizer
toks(Lno, Chars) ->
@@ -3031,31 +3036,35 @@ parse_auth_ips([Str|Rest], Result) ->
end.
-subconfigdir_fold(_File, {error, _Err}=Acc) ->
- Acc;
-subconfigdir_fold(File, {ok, GCp, Csp}=Acc) ->
- case is_file(File) of
- true ->
- error_logger:info_msg("Yaws: Using subconfig file ~s~n", [File]),
- case file:open(File, [read]) of
- {ok, FD1} ->
- R = (catch fload(FD1,
- globals,
- GCp,
- undefined,
- Csp,
- 1,
- io:get_line(FD1, ''))),
- ?Debug("FLOAD: ~p", [R]),
- R;
- _ ->
- {error, "Can't open config file " ++ File}
- end;
- false ->
- %% Ignore subdirectories
- Acc
+
+subconfigfiles([], GC, Cs) ->
+ {ok, GC, Cs};
+subconfigfiles([File|Files], GC, Cs) ->
+ case filename:basename(File) of
+ [$.|_] ->
+ error_logger:info_msg("Yaws: Ignore subconfig file ~s~n", [File]),
+ subconfigfiles(Files, GC, Cs);
+ _ ->
+ case subconfigfile(File, GC, Cs) of
+ {ok, GC1, Cs1} -> subconfigfiles(Files, GC1, Cs1);
+ Err -> Err
+ end
+ end.
+
+subconfigfile(File, GC, Cs) ->
+ error_logger:info_msg("Yaws: Using subconfig file ~s~n", [File]),
+ case file:open(File, [read]) of
+ {ok, FD} ->
+ R = (catch fload(FD, globals, GC, undefined,
+ Cs, 1, io:get_line(FD, ''))),
+ ?Debug("FLOAD: ~p", [R]),
+ R;
+ Err ->
+ {error, ?F("Can't open config file ~s: ~p", [File,Err])}
end.
+
+
str2term(Str0) ->
Str=Str0++".",
{ok,Tokens,_EndLine} = erl_scan:string(Str),
View
5 test/eunit/Makefile.am
@@ -9,9 +9,10 @@ MODULES = multipart_post_parsing.erl \
gconf.erl \
sconf.erl \
yaws_rpc_test.erl \
- proc_cleanup.erl
+ proc_cleanup.erl \
+ subconfig.erl
-EXTRA_DIST = $(MODULES) cookies.dump setcookies.dump
+EXTRA_DIST = $(MODULES) cookies.dump setcookies.dump subconfig_DATA
EBIN_FILES=$(MODULES:%.erl=%.beam)
View
30 test/eunit/subconfig.erl
@@ -0,0 +1,30 @@
+-module(subconfig).
+-compile(export_all).
+-include_lib("eunit/include/eunit.hrl").
+
+-include("yaws.hrl").
+-include("tftest.hrl").
+
+absolute_subconfig_test() ->
+ Env = #env{debug = false,
+ conf = {file, ?builddir++"/subconfig_DATA/yaws_absolute.conf"}},
+
+ {ok, _GC, SCs} = yaws_config:load(Env),
+ check_sconfs(lists:flatten(SCs)).
+
+relative_subconfig_test() ->
+ Env = #env{debug = false,
+ conf = {file, ?srcdir++"/subconfig_DATA/yaws_relative.conf"}},
+
+ {ok, _GC, SCs} = yaws_config:load(Env),
+ check_sconfs(lists:flatten(SCs)).
+
+check_sconfs(SCs) ->
+ ?assertEqual(5, length(SCs)),
+ ?assert(lists:keymember(80, #sconf.port, SCs)),
+ ?assert(lists:keymember(8001, #sconf.port, SCs)),
+ ?assert(lists:keymember(8002, #sconf.port, SCs)),
+ ?assert(lists:keymember(8003, #sconf.port, SCs)),
+ ?assert(lists:keymember(8004, #sconf.port, SCs)),
+ ok.
+
View
5 test/eunit/subconfig_DATA/subconfig.conf
@@ -0,0 +1,5 @@
+<server vhost_subconfig>
+ port = 80
+ listen = 0.0.0.0
+ docroot = /tmp
+</server>
View
1  test/eunit/subconfig_DATA/subconfig.d/.hidden.conf
@@ -0,0 +1 @@
+invalid_param = error
View
1  test/eunit/subconfig_DATA/subconfig.d/ignored
@@ -0,0 +1 @@
+invalid_param = error
View
5 test/eunit/subconfig_DATA/subconfig.d/subconfig1.conf
@@ -0,0 +1,5 @@
+<server vhost_subconfigdir1>
+ port = 8001
+ listen = 0.0.0.0
+ docroot = /tmp
+</server>
View
5 test/eunit/subconfig_DATA/subconfig.d/subconfig2.conf
@@ -0,0 +1,5 @@
+<server vhost_subconfigdir2>
+ port = 8002
+ listen = 0.0.0.0
+ docroot = /tmp
+</server>
View
1  test/eunit/subconfig_DATA/subconfigdir.d/.hidden.conf
@@ -0,0 +1 @@
+invalid_param = error
View
5 test/eunit/subconfig_DATA/subconfigdir.d/subconfigdir1.conf
@@ -0,0 +1,5 @@
+<server vhost_subconfigdir1>
+ port = 8003
+ listen = 0.0.0.0
+ docroot = /tmp
+</server>
View
5 test/eunit/subconfig_DATA/subconfigdir.d/subconfigdir2.conf
@@ -0,0 +1,5 @@
+<server vhost_subconfigdir2>
+ port = 8004
+ listen = 0.0.0.0
+ docroot = /tmp
+</server>
View
3  test/eunit/subconfig_DATA/yaws_absolute.conf.in
@@ -0,0 +1,3 @@
+subconfigdir = @abs_srcdir@/subconfigdir.d
+subconfig = @abs_srcdir@/subconfig.conf
+subconfig = @abs_srcdir@/subconfig.d/*.conf
View
3  test/eunit/subconfig_DATA/yaws_relative.conf
@@ -0,0 +1,3 @@
+subconfigdir = subconfigdir.d
+subconfig = subconfig.conf
+subconfig = subconfig.d/*.conf
Please sign in to comment.
Something went wrong with that request. Please try again.