Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 6db59ccb55
Fetching contributors…

Cannot retrieve contributors at this time

107 lines (87 sloc) 3.814 kb
% vim: sw=4 ts=4 et
% Simple Bridge
% Copyright (c) 2008-2010 Rusty Klophaus
% See MIT-LICENSE for licensing information.
-module(yaws_response_bridge).
-behaviour (simple_bridge_response).
-include_lib ("simple_bridge.hrl").
-export ([build_response/2,init/1]).
init(_Arg) ->
_Arg.
build_response(_Arg, Res) ->
% Get vars...
Code = Res#response.statuscode,
%% Assemble headers...
Headers = assemble_headers(Res),
case Res#response.data of
{data, Body} ->
%% Get the content type...
ContentType = get_content_type(Res),
% Send the yaws response...
lists:flatten([
{status, Code},
Headers,
{content, ContentType, Body}
]);
{file, Path} ->
%% Note: This section should only be entered in the event that a static file is
%% requested that isn't found in the 'appmod' section of the yaws.conf file.
%% I've not found a way to "pass the buck" back to yaws and say "even though this
%% directory isn't found in the appmod, I want you to serve it anyway". This
%% means that with the current implementation, you don't want to be serving files
%% big files that aren't covered in the appmod section, primarily because this little
%% snippet loads the entire file into memory then passes it off to yaws to be served,
%% rather than streaming it. I'll need to look further into to either 1) Pass the buck
%% completely back to Yaws, or 2) how the streamcontent return types work as define in
%% yaws_server:handle_out_reply
ExpireDate = simple_bridge_util:expires(years, 10),
%% Docroot needed to find file in Path
Docroot = yaws_api:arg_docroot(_Arg),
FullPath = [Docroot,Path],
%% Get the content type as defined by yaws
ContentType = yaws_api:mime_type(Path),
%% Get the file content
FullResponse = case file:read_file(FullPath) of
{error,enoent} ->
yaws_outmod:out404(_Arg);
{ok,Bin} ->
[
{status, Code},
[{header, {"Expires", ExpireDate}} | Headers],
{content, ContentType, Bin}
]
end,
lists:flatten(FullResponse)
end.
assemble_headers(Res) ->
lists:flatten([
[{header, {X#header.name, X#header.value}} || X <- Res#response.headers],
[create_cookie(X) || X <- Res#response.cookies]
]).
get_content_type(Res) ->
coalesce([
kvl3(content_type, Res#response.headers),
kvl3("content-type", Res#response.headers),
kvl3("Content-Type", Res#response.headers),
kvl3("CONTENT-TYPE", Res#response.headers),
"text/html"
]).
kvl3(Key,L) ->
case lists:keysearch(Key,2,L) of
{value, {_,_,Val}} -> Val;
_ -> undefined
end.
coalesce([]) -> undefined;
coalesce([undefined|T]) -> coalesce(T);
coalesce([H|_T]) -> H.
create_cookie(Cookie) ->
Name = Cookie#cookie.name,
Value = Cookie#cookie.value,
Path = Cookie#cookie.path,
SecondsToLive = Cookie#cookie.minutes_to_live * 60,
Expire = to_cookie_expire(SecondsToLive),
yaws_api:setcookie(Name, Value, Path, Expire).
to_cookie_expire(SecondsToLive) ->
Seconds = calendar:datetime_to_gregorian_seconds(calendar:local_time()),
DateTime = calendar:gregorian_seconds_to_datetime(Seconds + SecondsToLive),
httpd_util:rfc1123_date(DateTime).
Jump to Line
Something went wrong with that request. Please try again.