Skip to content


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.
-behaviour (simple_bridge_response).
-include_lib ("simple_bridge.hrl").
-export ([build_response/2,init/1]).
init(_Arg) ->
build_response(_Arg, Res) ->
% Get vars...
Code = Res#response.statuscode,
%% Assemble headers...
Headers = assemble_headers(Res),
case of
{data, Body} ->
%% Get the content type...
ContentType = get_content_type(Res),
% Send the yaws response...
{status, Code},
{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} ->
{ok,Bin} ->
{status, Code},
[{header, {"Expires", ExpireDate}} | Headers],
{content, ContentType, Bin}
assemble_headers(Res) ->
[{header, {, X#header.value}} || X <- Res#response.headers],
[create_cookie(X) || X <- Res#response.cookies]
get_content_type(Res) ->
kvl3(content_type, Res#response.headers),
kvl3("content-type", Res#response.headers),
kvl3("Content-Type", Res#response.headers),
kvl3("CONTENT-TYPE", Res#response.headers),
kvl3(Key,L) ->
case lists:keysearch(Key,2,L) of
{value, {_,_,Val}} -> Val;
_ -> undefined
coalesce([]) -> undefined;
coalesce([undefined|T]) -> coalesce(T);
coalesce([H|_T]) -> H.
create_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),
Jump to Line
Something went wrong with that request. Please try again.