%%% BEGIN openflax/dispatch.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 Dispatching logic for OpenFlax.
%%
%% @end
-module(openflax.dispatch).
-vsn('$Id: dispatch.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([resolve_request/4]). % External interface
-import(lists).
-import(regexp).
%% @spec resolve_request([dispatch()], Resource::string(), Args::string(),
%% RemoteAddress::ip()) -> {response(), conf()}
%% dispatch() = {resource_pattern(), args_pattern(),
%% response(), conf_list(), allowed_ips()}
%% resource_pattern() = regexp()
%% args_pattern() = regexp()
%% conf_list() = [{atom(), term()}]
%% allowed_ips() = [ip()]
%% regexp() = string()
%% ip() = string()
%% @doc Returns the response() from the first entry in
%% the given dispatch rules which pattern-matches the given basic resource
%% and arguments of a URI and which is set to allow the given
%% IP address of the client. Additional configuation settings may be
%% specified in a list in the dispatch (they will override existing ones.)
resolve_request([], _Resource, _Args, _RemoteIP) ->
{not_found, openflax.conf:new()};
resolve_request([{ResPat, ArgsPat, Response, ConfList, AllowedIPs} | Tail],
Resource, Args, RemoteIP) ->
% determine whether the client is allowed to access this resource
case lists:member(RemoteIP, AllowedIPs) of
true ->
resolve_request([{ResPat, ArgsPat, Response, ConfList} | Tail],
Resource, Args, RemoteIP);
false ->
resolve_request(Tail, Resource, Args, RemoteIP)
end;
resolve_request([{ResPat, ArgsPat, Response, ConfList} | Tail],
Resource, Args, RemoteIP) ->
case regexp:first_match(Resource, regexp:sh_to_awk(ResPat)) of
{match, _, _} ->
% The following is a total hack to make up for a limitation
% in the regexp modules (can't match null strings!)
case case Args of
"" ->
case ArgsPat of
"*" ->
{match, [true]};
_ ->
{match, []}
end;
_ ->
regexp:matches(Args, regexp:sh_to_awk(ArgsPat))
end of
{match, [_FirstMatch | _OtherMatches]} ->
{Response, openflax.conf:new(ConfList)};
_ ->
resolve_request(Tail, Resource, Args, RemoteIP)
end;
_ ->
resolve_request(Tail, Resource, Args, RemoteIP)
end;
resolve_request([{ResPat, ArgsPat, Response} | Tail],
Resource, Args, RemoteIP) ->
resolve_request([{ResPat, ArgsPat, Response, []} | Tail],
Resource, Args, RemoteIP).
%%% END of openflax/dispatch.erl %%%