%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
%%
%%
%%----------------------------------------------------------------------
%% Purpose: The top supervisor for an instance of the http server. (You may
%% have several instances running on the same machine.) Hangs under
%% httpd_sup.
%%----------------------------------------------------------------------
-module(httpd_instance_sup).
-behaviour(supervisor).
%% Internal application API
-export([start_link/3, start_link/4]).
%% Supervisor callbacks
-export([init/1]).
%%%=========================================================================
%%% Internal Application API
%%%=========================================================================
start_link([{_, _}| _] = Config, AcceptTimeout, Debug) ->
case httpd_conf:validate_properties(Config) of
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
Name = make_name(Address, Port),
SupName = {local, Name},
supervisor:start_link(SupName, ?MODULE,
[undefined, Config2, AcceptTimeout,
Debug, Address, Port]);
{error, Reason} ->
error_logger:error_report(Reason),
{stop, Reason}
end;
start_link(ConfigFile, AcceptTimeout, Debug) ->
case file_2_config(ConfigFile) of
{ok, ConfigList, Address, Port} ->
Name = make_name(Address, Port),
SupName = {local, Name},
supervisor:start_link(SupName, ?MODULE,
[ConfigFile, ConfigList, AcceptTimeout,
Debug, Address, Port]);
{error, Reason} ->
error_logger:error_report(Reason),
{stop, Reason}
end.
start_link([{_, _}| _] = Config, AcceptTimeout, ListenInfo, Debug) ->
case httpd_conf:validate_properties(Config) of
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
Name = make_name(Address, Port),
SupName = {local, Name},
supervisor:start_link(SupName, ?MODULE,
[undefined, Config2, AcceptTimeout,
Debug, Address, Port, ListenInfo]);
{error, Reason} ->
error_logger:error_report(Reason),
{stop, Reason}
end;
start_link(ConfigFile, AcceptTimeout, ListenInfo, Debug) ->
case file_2_config(ConfigFile) of
{ok, ConfigList, Address, Port} ->
Name = make_name(Address, Port),
SupName = {local, Name},
supervisor:start_link(SupName, ?MODULE,
[ConfigFile, ConfigList, AcceptTimeout,
Debug, Address, Port, ListenInfo]);
{error, Reason} ->
error_logger:error_report(Reason),
{stop, Reason}
end.
%%%=========================================================================
%%% Supervisor callback
%%%=========================================================================
init([ConfigFile, ConfigList, AcceptTimeout, _Debug, Address, Port]) ->
Flags = {one_for_one, 0, 1},
Children = [sup_spec(httpd_acceptor_sup, Address, Port),
sup_spec(httpd_misc_sup, Address, Port),
worker_spec(httpd_manager, Address, Port,
ConfigFile, ConfigList,AcceptTimeout)],
{ok, {Flags, Children}};
init([ConfigFile, ConfigList, AcceptTimeout, _Debug, Address, Port, ListenInfo]) ->
Flags = {one_for_one, 0, 1},
Children = [sup_spec(httpd_acceptor_sup, Address, Port),
sup_spec(httpd_misc_sup, Address, Port),
worker_spec(httpd_manager, Address, Port, ListenInfo,
ConfigFile, ConfigList, AcceptTimeout)],
{ok, {Flags, Children}}.
%%%=========================================================================
%%% Internal functions
%%%=========================================================================
sup_spec(SupModule, Address, Port) ->
Name = {SupModule, Address, Port},
StartFunc = {SupModule, start_link, [Address, Port]},
Restart = permanent,
Shutdown = infinity,
Modules = [SupModule],
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
worker_spec(WorkerModule, Address, Port, ConfigFile,
ConfigList, AcceptTimeout) ->
Name = {WorkerModule, Address, Port},
StartFunc = {WorkerModule, start_link,
[ConfigFile, ConfigList, AcceptTimeout]},
Restart = permanent,
Shutdown = 4000,
Modules = [WorkerModule],
Type = worker,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
worker_spec(WorkerModule, Address, Port, ListenInfo, ConfigFile,
ConfigList, AcceptTimeout) ->
Name = {WorkerModule, Address, Port},
StartFunc = {WorkerModule, start_link,
[ConfigFile, ConfigList, AcceptTimeout, ListenInfo]},
Restart = permanent,
Shutdown = 4000,
Modules = [WorkerModule],
Type = worker,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
make_name(Address,Port) ->
httpd_util:make_name("httpd_instance_sup", Address, Port).
file_2_config(ConfigFile) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
case httpd_conf:validate_properties(ConfigList) of
{ok, Config} ->
Address = proplists:get_value(bind_address, ConfigList),
Port = proplists:get_value(port, ConfigList),
{ok, Config, Address, Port};
Error ->
Error
end;
Error ->
Error
end.