Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/from-boss'
Browse files Browse the repository at this point in the history
  • Loading branch information
choptastic committed May 30, 2012
2 parents 52da9c7 + 4aa2102 commit 736a094
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 86 deletions.
104 changes: 73 additions & 31 deletions src/misultin_bridge_modules/misultin_request_bridge.erl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@
init/1, init/1,
request_method/1, path/1, uri/1, request_method/1, path/1, uri/1,
peer_ip/1, peer_port/1, peer_ip/1, peer_port/1,
headers/1, cookies/1, headers/1, header/2, cookies/1,
query_params/1, post_params/1, request_body/1 query_params/1, post_params/1, request_body/1,
socket/1, recv_from_socket/3
]). ]).



%% @todo could not figure out how to get the socket from misultin
%% so could not implement socket/1, recv_from_socket/3 that are
%% present in other request modules

init(Req) -> init(Req) ->
Req. Req.


Expand All @@ -28,36 +24,70 @@ uri(Req) ->
Req:get(uri). Req:get(uri).


peer_ip(Req) -> peer_ip(Req) ->
Req:get(peer_addr). case Req:get(peer_addr) of
{ok, IP} -> IP;
IP -> IP
end.


peer_port(Req) -> peer_port(Req) ->
Req:get(peer_port). Req:get(peer_port).


header(connection, Req) ->
misultin_utility:get_key_value('Connection', Req:get(headers));
header(accept, Req) ->
misultin_utility:get_key_value('Accept', Req:get(headers));
header(host, Req) ->
misultin_utility:get_key_value('Host', Req:get(headers));
header(if_modified_since, Req) ->
misultin_utility:get_key_value('If-Modified-Since', Req:get(headers));
header(if_match, Req) ->
misultin_utility:get_key_value('If-Match', Req:get(headers));
header(if_none_match, Req) ->
misultin_utility:get_key_value('If-None-Match', Req:get(headers));
header(if_range, Req) ->
misultin_utility:get_key_value('If-Range', Req:get(headers));
header(if_unmodified_since, Req) ->
misultin_utility:get_key_value('If-Unmodified-Since', Req:get(headers));
header(range, Req) ->
misultin_utility:get_key_value('Range', Req:get(headers));
header(referer, Req) ->
misultin_utility:get_key_value('Referer', Req:get(headers));
header(user_agent, Req) ->
misultin_utility:get_key_value('User-Agent', Req:get(headers));
header(accept_ranges, Req) ->
misultin_utility:get_key_value('Accept-Ranges', Req:get(headers));
header(cookie, Req) ->
misultin_utility:get_key_value('Cookie', Req:get(headers));
header(keep_alive, Req) ->
misultin_utility:get_key_value('Keep-Alive', Req:get(headers));
header(location, Req) ->
misultin_utility:get_key_value('Location', Req:get(headers));
header(content_length, Req) ->
misultin_utility:get_key_value('Content-Length', Req:get(headers));
header(content_type, Req) ->
misultin_utility:get_key_value('Content-Type', Req:get(headers));
header(content_encoding, Req) ->
misultin_utility:get_key_value('Content-Encoding', Req:get(headers));
header(authorization, Req) ->
misultin_utility:get_key_value('Authorization', Req:get(headers));
header(x_forwarded_for, Req) ->
misultin_utility:get_key_value('X-Forwarded-For', Req:get(headers));
header(transfer_encoding, Req) ->
misultin_utility:get_key_value('Transfer-Encoding', Req:get(headers));
header(accept_language, Req) ->
misultin_utility:get_key_value('Accept-Language', Req:get(headers));
header(Header, Req) ->
misultin_utility:get_key_value(Header, Req:get(headers)).

headers(Req) -> headers(Req) ->
Headers = Req:get(headers), Headers1 = [ connection, accept, host, if_modified_since,
F = fun(Header) -> proplists:get_value(Header, Headers) end, if_match, if_none_match, if_range, if_unmodified_since,
Headers1 = [ range, referer, user_agent, accept_language, accept_ranges, cookie,
{connection, F('Connection')}, keep_alive, location, content_length, content_type,
{accept, F('Accept')}, content_encoding, authorization, x_forwarded_for, transfer_encoding
{host, F('Host')},
{if_modified_since, F('If-Modified-Since')},
{if_match, F('If-Match')},
{if_none_match, F('If-Range')},
{if_unmodified_since, F('If-Unmodified-Since')},
{range, F('Range')},
{referer, F('Referer')},
{user_agent, F('User-Agent')},
{accept_ranges, F('Accept-Ranges')},
{cookie, F('Cookie')},
{keep_alive, F('Keep-Alive')},
{location, F('Location')},
{content_length, F('Content-Length')},
{content_type, F('Content-Type')},
{content_encoding, F('Content-Encoding')},
{authorization, F('Authorization')},
{transfer_encoding, F('Transfer-Encoding')}
], ],
[{K, V} || {K, V} <- Headers1, V /= undefined]. Headers2 = lists:map(fun(H) -> {H, header(H, Req)} end, Headers1),
[{K, V} || {K, V} <- Headers2, V /= undefined].


cookies(Req) -> cookies(Req) ->
Headers = headers(Req), Headers = headers(Req),
Expand All @@ -81,3 +111,15 @@ post_params(Req) ->


request_body(Req) -> request_body(Req) ->
Req:get(body). Req:get(body).

socket(Req) ->
Req:get(socket).

recv_from_socket(Length, Timeout, Req) ->
Socket = socket(Req),
case gen_tcp:recv(Socket, Length, Timeout) of
{ok, Data} ->
Data;
_Other ->
exit(normal)
end.
9 changes: 6 additions & 3 deletions src/misultin_bridge_modules/misultin_response_bridge.erl
Original file line number Original file line Diff line number Diff line change
@@ -1,9 +1,12 @@
-module (misultin_response_bridge). -module (misultin_response_bridge).
-behaviour (simple_bridge_response). -behaviour (simple_bridge_response).
-include_lib ("simple_bridge.hrl"). -include_lib ("simple_bridge.hrl").
-export ([build_response/2]). -export ([build_response/2,init/1]).


build_response(Req, Res) -> init({Req,DocRoot}) ->
{Req,DocRoot}.

build_response({Req, DocRoot}, Res) ->
% Some values... % Some values...
Code = Res#response.statuscode, Code = Res#response.statuscode,
case Res#response.data of case Res#response.data of
Expand All @@ -18,7 +21,7 @@ build_response(Req, Res) ->
% Send the misultin response... % Send the misultin response...
Req:respond(Code, Headers, Body); Req:respond(Code, Headers, Body);
{file, Path} -> {file, Path} ->
Req:file([Path]) Req:file([DocRoot, Path])
end. end.


create_cookie_header(Cookie) -> create_cookie_header(Cookie) ->
Expand Down
132 changes: 87 additions & 45 deletions src/mochiweb_bridge_modules/mochiweb_request_bridge.erl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -9,81 +9,123 @@
init/1, init/1,
request_method/1, path/1, uri/1, request_method/1, path/1, uri/1,
peer_ip/1, peer_port/1, peer_ip/1, peer_port/1,
headers/1, cookies/1, headers/1, header/2, cookies/1,
query_params/1, post_params/1, request_body/1, query_params/1, post_params/1, request_body/1,
socket/1, recv_from_socket/3 socket/1, recv_from_socket/3
]). ]).


%% Mochiweb's max request size is 1MB, let's updated it to 1GB %% Max Body of 10MB by default
-define(MAX_BODY_SIZE, (1024*1024*1024)). -define(MAX_RECV_BODY,(1024*1024*10)).


init({Req, DocRoot}) -> init(Req) ->
{Req, DocRoot}. Req.


request_method({Req, _DocRoot}) -> request_method(Req) ->
Req:get(method). Req:get(method).


path({Req, _DocRoot}) -> path(Req) ->
RawPath = Req:get(raw_path), RawPath = Req:get(raw_path),
{Path, _, _} = mochiweb_util:urlsplit_path(RawPath), {Path, _, _} = mochiweb_util:urlsplit_path(RawPath),
Path. Path.


uri({Req, _DocRoot}) -> uri(Req) ->
Req:get(raw_path). Req:get(raw_path).


peer_ip({Req, _DocRoot}) -> peer_ip(Req) ->
Socket = Req:get(socket), case Req:get(socket) of
{ok, {IP, _Port}} = inet:peername(Socket), false -> {127, 0, 0, 1};
IP. Socket ->
{ok, {IP, _Port}} = mochiweb_socket:peername(Socket),
IP
end.


peer_port({Req, _DocRoot}) -> peer_port(Req) ->
Socket = Req:get(socket), Socket = Req:get(socket),
{ok, {_IP, Port}} = inet:peername(Socket), {ok, {_IP, Port}} = mochiweb_socket:peername(Socket),
Port. Port.

header(connection, Req) ->
Req:get_header_value("connection");
header(accept, Req) ->
Req:get_header_value("accept");
header(host, Req) ->
Req:get_header_value("host");
header(if_modified_since, Req) ->
Req:get_header_value("if-modified-since");
header(if_match, Req) ->
Req:get_header_value("if-match");
header(if_none_match, Req) ->
Req:get_header_value("if-none-match");
header(if_unmodified_since, Req) ->
Req:get_header_value("if-unmodified-since");
header(if_range, Req) ->
Req:get_header_value("if-range");
header(range, Req) ->
Req:get_header_value("range");
header(user_agent, Req) ->
Req:get_header_value("user-agent");
header(accept_language, Req) ->
Req:get_header_value("accept-language");
header(accept_ranges, Req) ->
Req:get_header_value("accept-ranges");
header(cookie, Req) ->
Req:get_header_value("cookie");
header(keep_alive, Req) ->
Req:get_header_value("keep-alive");
header(location, Req) ->
Req:get_header_value("location");
header(content_length, Req) ->
Req:get_header_value("content-length");
header(content_type, Req) ->
Req:get_header_value("content-type");
header(content_encoding, Req) ->
Req:get_header_value("content-encoding");
header(authorization, Req) ->
Req:get_header_value("authorization");
header(x_forwarded_for, Req) ->
Req:get_header_value("x-forwarded-for");
header(transfer_encoding, Req) ->
Req:get_header_value("transfer-encoding");
header(Header, Req) ->
Req:get_header_value(Header).


headers({Req, _DocRoot}) -> headers(Req) ->
F = fun(Header) -> Req:get_header_value(Header) end, Headers = [connection, accept, host, if_modified_since,
Headers1 = [ connection, accept, host, if_modified_since, if_match,
{connection, F("connection")}, if_none_match, if_unmodified_since, if_range, range,
{accept, F("accept")}, referer, user_agent, accept_language, accept_ranges,
{host, F("host")}, cookie, keep_alive, location, content_length, content_type,
{if_modified_since, F("if-modified-since")}, content_encoding, authorization, x_forwarded_for, transfer_encoding
{if_match, F("if-match")},
{if_none_match, F("if-range")},
{if_unmodified_since, F("if-unmodified-since")},
{range, F("range")},
{referer, F("referer")},
{user_agent, F("user-agent")},
{accept_ranges, F("accept-ranges")},
{cookie, F("cookie")},
{keep_alive, F("keep-alive")},
{location, F("location")},
{content_length, F("content-length")},
{content_type, F("content-type")},
{content_encoding, F("content-encoding")},
{authorization, F("authorization")},
{x_forwarded_for, F("x-forwarded-for")},
{transfer_encoding, F("transfer-encoding")}
], ],
Headers1 = lists:map(fun(H) -> {H, header(H, Req)} end, Headers),
[{K, V} || {K, V} <- Headers1, V /= undefined]. [{K, V} || {K, V} <- Headers1, V /= undefined].


cookies({Req, _DocRoot}) -> cookies(Req) ->
Req:parse_cookie(). Req:parse_cookie().


query_params({Req, _DocRoot}) -> query_params(Req) ->
Req:parse_qs(). Req:parse_qs().


post_params({Req, _DocRoot}) -> post_params(Req) ->
Req:parse_post(). Req:parse_post().


request_body({Req, _DocRoot}) -> request_body(Req) ->
Req:recv_body(?MAX_BODY_SIZE). MaxBody = case application:get_env(mochiweb,max_request_size) of
undefined ->
?MAX_RECV_BODY;
Max when is_integer(Max) ->
Max;
Other ->
error_logger:warning_msg("Mochiweb Simple Bridge Configuration Error! Unknown value for 'mochiweb' application variable 'max_request_size': ~p. Expected: integer() or undefined. Using Default of ~p~n",[Other,?MAX_RECV_BODY]),
?MAX_RECV_BODY
end,
Req:recv_body(MaxBody).


socket({Req, _DocRoot}) -> socket(Req) ->
Req:get(socket). Req:get(socket).


recv_from_socket(Length, Timeout, {Req, DocRoot}) -> recv_from_socket(Length, Timeout, Req) ->
Socket = socket({Req, DocRoot}), Socket = socket(Req),
case gen_tcp:recv(Socket, Length, Timeout) of case gen_tcp:recv(Socket, Length, Timeout) of
{ok, Data} -> {ok, Data} ->
put(mochiweb_request_recv, true), put(mochiweb_request_recv, true),
Expand Down
14 changes: 8 additions & 6 deletions src/mochiweb_bridge_modules/mochiweb_response_bridge.erl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ build_response({Req, DocRoot}, Res) ->
[create_cookie_header(X) || X <- Res#response.cookies] [create_cookie_header(X) || X <- Res#response.cookies]
]), ]),


% Ensure content type... %
% Ensure content type...
F = fun(Key) -> lists:keymember(Key, 1, Headers) end, F = fun(Key) -> lists:keymember(Key, 1, Headers) end,
HasContentType = lists:any(F, ["content-type", "Content-Type", "CONTENT-TYPE"]), HasContentType = lists:any(F, ["content-type", "Content-Type", "CONTENT-TYPE"]),
Headers2 = case HasContentType of Headers2 = case HasContentType of
Expand All @@ -34,13 +35,14 @@ build_response({Req, DocRoot}, Res) ->
Req:respond({Code, Headers2, Body}); Req:respond({Code, Headers2, Body});
{file, Path} -> {file, Path} ->
%% Calculate expire date far into future... %% Calculate expire date far into future...
Seconds = calendar:datetime_to_gregorian_seconds(calendar:local_time()), %% This method copied from Evan Miller's implementation
TenYears = 10 * 365 * 24 * 60 * 60, {{Y, _, _}, _} = calendar:local_time(),
Seconds1 = calendar:gregorian_seconds_to_datetime(Seconds + TenYears),
ExpireDate = httpd_util:rfc1123_date(Seconds1), ExpireDate = httpd_util:rfc1123_date(),
ExpireDate1 = re:replace(ExpireDate, " \\d\\d\\d\\d ", io_lib:format(" ~4.4.0w ", [Y + 10])),


%% Create the response telling Mochiweb to serve the file... %% Create the response telling Mochiweb to serve the file...
Headers = [{"Expires", ExpireDate}], Headers = [{"Expires", ExpireDate1}],
Req:serve_file(tl(Path), DocRoot, Headers) Req:serve_file(tl(Path), DocRoot, Headers)
end. end.


Expand Down
Loading

0 comments on commit 736a094

Please sign in to comment.