Skip to content

Commit

Permalink
added support for config changes without stopping the running systems…
Browse files Browse the repository at this point in the history
…, virt servers can be added, removed anc changed without conflicting with traffic

git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/yaws@804 9fbdc01b-0d2c-0410-bfb7-fb27d70d8b52
  • Loading branch information
Claes Wikstrom committed Dec 15, 2004
1 parent 2ca4bda commit 9199a36
Show file tree
Hide file tree
Showing 7 changed files with 729 additions and 255 deletions.
3 changes: 3 additions & 0 deletions include/yaws.hrl
Expand Up @@ -150,6 +150,9 @@
revproxy = []
}).

%% we cannot compare sconfs directly due to the ets
%% field in #sconf{} use yaws_config:eq_sconfs/2


% Auth conf - from server conf and .yaws_auth
-record(auth,
Expand Down
54 changes: 53 additions & 1 deletion src/yaws.erl
Expand Up @@ -34,7 +34,6 @@ hup(Sock) ->
end).

dohup(Sock) ->
io:format("in dohup~n", []),
{Debug, Trace, TraceOut, Conf, _RunMod, _Embed} =
yaws_sup:get_app_args(),
Res = (catch case yaws_config:load(Conf, Trace, TraceOut, Debug) of
Expand Down Expand Up @@ -2075,3 +2074,56 @@ deepmap(_Fun, []) ->
[].


sconf_to_srvstr(SC) ->
redirect_scheme(SC) ++
redirect_host(SC,undefined) ++
redirect_port(SC).

redirect_scheme(SC) ->
case {SC#sconf.ssl,SC#sconf.rmethod} of
{_, Method} when list(Method) ->
Method++"://";
{undefined,_} ->
"http://";
{_SSl,_} ->
"https://"
end.

redirect_host(SC, HostHdr) ->
case SC#sconf.rhost of
undefined ->
if HostHdr == undefined ->
ServerName = SC#sconf.servername,
SnameNoPort =
case string:chr(ServerName, $:) of
0 ->
ServerName;
N ->
lists:sublist(ServerName, N-1)
end,
SnameNoPort ++ redirect_port(SC);
true ->
HostHdr
end;
_ ->
SC#sconf.rhost
end.

redirect_port(SC) ->
case {SC#sconf.rmethod, SC#sconf.ssl, SC#sconf.port} of
{"https", _, 443} -> "";
{"http", _, 80} -> "";
{_, undefined, 80} -> "";
{_, undefined, Port} ->
[$:|integer_to_list(Port)];
{_, _SSL, 443} ->
"";
{_, _SSL, Port} ->
[$:|integer_to_list(Port)]
end.

redirect_scheme_port(SC) ->
Scheme = redirect_scheme(SC),
PortPart = redirect_port(SC),
{Scheme, PortPart}.

103 changes: 33 additions & 70 deletions src/yaws_api.erl
Expand Up @@ -39,7 +39,11 @@
cookieval_to_opaque/1, request_url/1,
print_cookie_sessions/0,
replace_cookie_session/2, delete_cookie_session/1]).
-export([getconf/0, setconf/2, set_status_code/1, reformat_header/1,

-export([getconf/0,
setconf/2]).

-export([set_status_code/1, reformat_header/1,
reformat_request/1, reformat_response/1, reformat_url/1]).

-export([set_trace/1,
Expand Down Expand Up @@ -868,71 +872,6 @@ delete_cookie_session(Cookie) ->
yaws_session_server:delete_session(Cookie).


%% to be used in embedded mode, make it possible
%% to pass a config to yaws from another data source
%% than /etc/yaws.conf, for example from a database

setconf(GC, Groups0) when record(GC, gconf) ->
case is_groups(Groups0) of
true ->
%% embeded code may give appmods as a list of strings
%% So the above is for backwards compatibility
%% appmods should be {StringPathElem, ModAtom} tuples
Groups = yaws:deepmap(
fun(SC) ->
SC#sconf{appmods =
lists:map(
fun({PE, Mod}) ->
{PE, Mod};
(AM) when list(AM) ->
{AM,list_to_atom(AM)};
(AM) when atom(AM) ->
{atom_to_list(AM), AM}
end,
SC#sconf.appmods)}
end, Groups0),

case gen_server:call(yaws_server,{setconf, GC, Groups},infinity) of
ok ->
yaws_log:setdir(GC, Groups),
case GC#gconf.trace of
false ->
ok;
{true, What} ->
yaws_log:open_trace(What)
end;
E ->
E
end;
false ->
exit({badarg, {badgroups, Groups0}})
end.

%% verify args to setconf
is_groups([H|T]) ->
case is_list_of_scs(H) of
true ->
is_groups(T);
false ->
false
end;
is_groups([]) ->
true.

is_list_of_scs([H|T]) when record(H, sconf) ->
is_list_of_scs(T);
is_list_of_scs([]) ->
true;
is_list_of_scs(_) ->
false.



%% return {ok, GC, Groups}.
getconf() ->
gen_server:call(yaws_server, getconf).


lmap(F, [H|T]) ->
[lists:map(F, H) | lmap(F, T)];
lmap(_, []) ->
Expand Down Expand Up @@ -1742,19 +1681,43 @@ request_url(ARG) ->






%% remove sick characters

sanitize_file_name(".." ++ T) ->
sanitize_file_name([$.|T]);
sanitize_file_name([H|T]) ->
case lists:member(H, " &;'!\\?<>\"()$") of
case lists:member(H, " &;'`{}!\\?<>\"()$") of
true ->
sanitize_file_name(T);
false ->
[H|sanitize_file_name(T)]
end;
sanitize_file_name([]) ->
[].



%% to be used in embedded mode, make it possible
%% to pass a config to yaws from another data source
%% than /etc/yaws.conf, for example from a database
%% this code is also called by the server -h hup code
setconf(GC0, Groups0) ->
{GC, Groups} = yaws_config:verify_upgrade_args(GC0, Groups0),
{ok, OLDGC, OldGroups} = yaws_api:getconf(),
case {yaws_config:can_hard_gc(GC, OLDGC),
yaws_config:can_soft_setconf(GC, Groups, OLDGC, OldGroups)} of
{true, true} ->
yaws_config:soft_setconf(GC, Groups, OLDGC, OldGroups);
{true, false} when OLDGC#gconf.username == undefined ->
yaws_config:hard_setconf(GC, Groups);
_ ->
{error, need_restart}
end.




%% return {ok, GC, Groups}.
getconf() ->
gen_server:call(yaws_server, getconf, infinity).

0 comments on commit 9199a36

Please sign in to comment.