%%% BEGIN openflax/app.erl %%% %%% %%% openflax - Open Source web server for Erlang/OTP %%% Copyright (c)2004 Cat's Eye Technologies. All rights reserved. %%% %%% Redistribution and use in source and binary forms, with or without %%% modification, are permitted provided that the following conditions %%% are met: %%% %%% Redistributions of source code must retain the above copyright %%% notice, this list of conditions and the following disclaimer. %%% %%% Redistributions in binary form must reproduce the above copyright %%% notice, this list of conditions and the following disclaimer in %%% the documentation and/or other materials provided with the %%% distribution. %%% %%% Neither the name of Cat's Eye Technologies nor the names of its %%% contributors may be used to endorse or promote products derived %%% from this software without specific prior written permission. %%% %%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND %%% CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, %%% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF %%% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE %%% DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE %%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, %%% OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, %%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, %%% OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON %%% ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, %%% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY %%% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE %%% POSSIBILITY OF SUCH DAMAGE. %% @doc OpenFlax web server main module. %% %%

OpenFlax is an open-source (BSD license) web server written %% in Erlang. For more information on OpenFlax, please refer %% to the full documentation.

%% %%

The purpose of this module is to provide an entry point for %% starting up the webserver, generally from the command line.

%% %% @end -module(openflax.app). -vsn('$Id: app.erl 31 2004-04-23 07:00:11Z catseye $'). -author('catseye@catseye.mb.ca'). -copyright('Copyright (c)2004 Cat`s Eye Technologies. All rights reserved.'). -export([start/1, wait/0, version/0, debug/2]). % module imports -import(erlang). -import(dict). -import(os). -import(io). %% @spec start(ConfigModuleNames::[string()]) -> ok %% @doc Starts the OpenFlax web server. %% This function loads all modules and starts all processes %% required to run the web server. All configuration information is %% read from the given file or files. OpenFlax will refuse to start if it %% notices that it is being run as root. start(ConfigModuleNames) -> % First, try to make sure we're not running as root case os:getenv("USER") of "root" -> erlang:fault(shant_run_as_root); _ -> start0(ConfigModuleNames) end. start0(ConfigModuleNames) -> % Read the configuration file(s). MasterDict = openflax.conf:load(ConfigModuleNames), % Find the global conf (the 'openflax' section of the config file(s)). {ok, Conf} = dict:find(openflax, MasterDict), % Start all handlers Conf0 = openflax.handler:start_all(Conf, MasterDict), % Start the HTTP interface, which will spawn openflax.app:connect/1 % each time an incoming request is accepted on our TCP port Interface = case openflax.conf:get_value(cfg_openflax_iface, Conf0) of {ok, String} when is_list(String) -> String; {ok, IP={_,_,_,_}} -> IP; _ -> undefined end, {ok, Port} = openflax.conf:get_value(cfg_openflax_port, Conf0), {ok, MaxConn} = openflax.conf:get_value(cfg_openflax_max_conn, Conf0), openflax.http.interface:start(fun(Http, RemoteAddress) -> Conf1 = openflax.conf:put_value(cfg_openflax_http, Http, Conf0), Conf2 = openflax.conf:put_value(sreq_remote_address, RemoteAddress, Conf1), connect(Http, Conf2, MasterDict) end, Interface, Port, MaxConn). wait() -> receive after infinity -> ok end. %% connect(http(), conf(), master_dict()) -> exit() %% Used by start/1 to handle each socket connection. %% Its purpose is to accept the user agent's HTTP request and to %% generate an appropriate HTTP response. connect(Http, Conf, MasterDict) -> % debug(collecting, {self(), Http, openflax.conf:dump(Conf)}), % Accept and interpret the HTTP request - the information from % the HTTP headers is placed into a new conf() for us. case openflax.http.request:collect(Http, Conf, MasterDict) of {ok, Conf0} -> % request was ok, so serve the selected resource % which, incidentally, will accept (or not) the request-body % debug(request_ok, openflax.conf:dump(Conf0)), Conf1 = openflax.serve:serve(Http, Conf0, MasterDict), case openflax.conf:get_value(sres_keep_alive, Conf1) of {ok, true} -> connect(Http, Conf, MasterDict); % note: Conf, NOT Conf1 :) _ -> % We're now finished accepting HTTP requests - clean up & exit Http ! {self(), close} end; {error, {Response, Conf0}} -> % the request was bogus in some way. openflax.serve:handle_response(Response, Conf0, Http, MasterDict), Http ! {self(), close} end. % exit(normal) is implied after this function finishes. version() -> '2004.0129'. debug(Where, What) -> io:fwrite("Debug: ~p: ~p~n", [Where, What]). %%% END of openflax/app.erl %%%