flm01/server/api/webmachine/src/webmachine_mochiweb.erl

90 lines
3.4 KiB
Erlang

%% @author Justin Sheehy <justin@basho.com>
%% @author Andy Gross <andy@basho.com>
%% @copyright 2007-2008 Basho Technologies
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%% @doc Mochiweb interface for webmachine.
-module(webmachine_mochiweb).
-author('Justin Sheehy <justin@basho.com>').
-author('Andy Gross <andy@basho.com>').
-export([start/1, stop/0, loop/1]).
start(Options) ->
{DispatchList, Options1} = get_option(dispatch, Options),
{ErrorHandler0, Options2} = get_option(error_handler, Options1),
{EnablePerfLog, Options3} = get_option(enable_perf_logger, Options2),
ErrorHandler =
case ErrorHandler0 of
undefined ->
webmachine_error_handler;
EH -> EH
end,
{LogDir, Options4} = get_option(log_dir, Options3),
webmachine_sup:start_logger(LogDir),
case EnablePerfLog of
true ->
application:set_env(webmachine, enable_perf_logger, true),
webmachine_sup:start_perf_logger(LogDir);
_ ->
ignore
end,
application:set_env(webmachine, dispatch_list, DispatchList),
application:set_env(webmachine, error_handler, ErrorHandler),
mochiweb_http:start([{name, ?MODULE}, {loop, fun loop/1} | Options4]).
stop() ->
mochiweb_http:stop(?MODULE).
loop(MochiReq) ->
Req = webmachine:new_request(mochiweb, MochiReq),
{ok, DispatchList} = application:get_env(webmachine, dispatch_list),
Host = case host_headers(Req) of
[H|_] -> H;
[] -> []
end,
case webmachine_dispatcher:dispatch(Host, Req:path(), DispatchList) of
{no_dispatch_match, _UnmatchedHost, _UnmatchedPathTokens} ->
{ok, ErrorHandler} = application:get_env(webmachine, error_handler),
ErrorHTML = ErrorHandler:render_error(404, Req, {none, none, []}),
Req:append_to_response_body(ErrorHTML),
Req:send_response(404),
LogData = Req:log_data(),
LogModule =
case application:get_env(webmachine,webmachine_logger_module) of
{ok, Val} -> Val;
_ -> webmachine_logger
end,
spawn(LogModule, log_access, [LogData]),
Req:stop();
{Mod, ModOpts, HostTokens, Port, PathTokens, Bindings,
AppRoot, StringPath} ->
BootstrapResource = webmachine_resource:new(x,x,x,x),
{ok, Resource} = BootstrapResource:wrap(Mod, ModOpts),
Req:load_dispatch_data(Bindings,HostTokens,Port,PathTokens,
AppRoot,StringPath,Req),
Req:set_metadata('resource_module', Mod),
webmachine_decision_core:handle_request(Req, Resource)
end.
get_option(Option, Options) ->
{proplists:get_value(Option, Options), proplists:delete(Option, Options)}.
host_headers(Req) ->
[ V || V <- [Req:get_header_value(H)
|| H <- ["x-forwarded-for",
"x-forwarded-host",
"x-forwarded-server",
"host"]],
V /= undefined].