You can add appmods at runtime by first retrieving the current configuration, using it to create a new configuration containing your new appmods, and then setting the new configuration.
- Call
yaws_api:getconf/0
to get a 3-tuple {ok, GlobalConf, ServerConfs}
where GlobalConf
is the global Yaws configuration and ServerConfs
is a list of lists of Yaws server configurations. The global conf is a record type named gconf
, and the server conf is a record type named sconf
; both of these record types are defined in the yaws.hrl
header file.
- Work through the server configurations to find the one containing the appmods you want to change. This is slightly tricky because you're dealing with a list of lists, and you need to keep the shape of the overall data structure unchanged.
- Once you find the
sconf
, create a new sconf
instance from it by adding your new appmod to its current list of appmods. Each element of the appmod list is a tuple consisting of a URL path for the appmod and the name of the appmod module. An appmod tuple can also optionally contain a third field consisting of a list of paths under the first path to be excluded; see the description of exclude_paths
in the Yaws appmod documentation for more details.
- Replace the existing
sconf
value in ServerConfs
with your new value.
- Call
yaws_api:setconf/2
to set the new configuration, passing the existing GlobalConf
as the first argument and the new ServerConfs
containing your new sconf
as the second argument.
The am_extend
module below shows how to do this. It exports an add/1
function that takes a function that can identify and augment the appmods in the particular server you care about.
-module(am_extend).
-export([add/1]).
add(AppmodAdder) ->
{ok, GlobalConf, ServerConfs} = yaws_api:getconf(),
NewServerConfs = add_appmod(ServerConfs, AppmodAdder),
yaws_api:setconf(GlobalConf, NewServerConfs).
add_appmod(ServerConfs, AppmodAdder) ->
lists:foldl(fun(Val, Acc) ->
Acc ++ [AppmodAdder(A) || A <- Val]
end, [], ServerConfs).
An example of using this code is to pass the function below as the AppmodAdder
argument for am_extend:add/1
. For this example, we're looking for a server that has an appmod path "/sse"
so we can add another appmod to that server for the path "/sse2"
. Any server conf we don't care about is just returned unchanged.
-include_lib("yaws/include/yaws.hrl").
add_sse2(#sconf{appmods=AM}=SC) ->
case lists:keyfind("/sse", 1, AM) of
false ->
SC;
_ ->
SC#sconf{appmods=[{"/sse2", my_sse_module}|AM]}
end.
Note that our add_sse2/1
function must be compiled with yaws.hrl
included so it has the definition for the sconf
record available.