Skip to content

Commit

Permalink
Make sendfile behaviour switchable. Defaults to using the sendfile fr…
Browse files Browse the repository at this point in the history
  • Loading branch information
mworrell committed Jan 16, 2014
1 parent 1d9adea commit f31b966
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
5 changes: 5 additions & 0 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
{erl_opts, [warnings_as_errors]}.
{cover_enabled, true}.
{edoc_opts, [{preprocess, true}]}.

{deps,
[
{sendfile, ".*", {git, "git://github.com/tuncer/sendfile.git", {branch, "master"}}}
]}.
50 changes: 43 additions & 7 deletions src/webmachine_request.erl
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
get_qs_value/2,
get_qs_value/3,
range/1,
log_data/1
log_data/1,
use_sendfile/0
]).

-include("webmachine_logger.hrl").
Expand Down Expand Up @@ -252,6 +253,7 @@ counter_process_loop(N) ->
From ! {total, N}
end.


send_device_body(Socket, Length, IO) ->
send_file_body_loop(Socket, 0, Length, IO).

Expand All @@ -261,13 +263,16 @@ send_file_body(Socket, Length, Filename) ->
send_file_body(ssl, Socket, Length, Filename) ->
send_file_body_read(Socket, Length, Filename);
send_file_body(plain, Socket, Length, Filename) ->
case erlang:function_exported(file, sendfile, 5) of
true ->
case use_sendfile() of
erlang ->
{ok, FD} = file:open(Filename, [raw,binary]),
{ok, Bytes} = file:sendfile(FD, Socket, 0, Length, []),
file:close(FD),
Bytes;
false ->
yaws ->
{ok, Bytes} = sendfile:send(Socket, Filename, 0, Length),
Bytes;
disable ->
send_file_body_read(Socket, Length, Filename)
end.

Expand Down Expand Up @@ -313,10 +318,12 @@ send_file_body_parts(Socket, Parts, Filename) ->
send_file_body_parts(ssl, Socket, Parts, Filename) ->
send_file_body_parts_read(Socket, Parts, Filename);
send_file_body_parts(plain, Socket, Parts, Filename) ->
case erlang:function_exported(file, sendfile, 5) of
true ->
case use_sendfile() of
erlang ->
send_file_body_parts_sendfile(Socket, Parts, Filename);
false ->
yaws ->
send_file_body_parts_sendfile_yaws(Socket, Parts, Filename);
disable ->
send_file_body_parts_read(Socket, Parts, Filename)
end.

Expand All @@ -340,6 +347,23 @@ send_file_body_parts_sendfile(Socket, {Parts, Size, Boundary, ContentType}, File
file:close(FD),
lists:sum(Bytes).


send_file_body_parts_sendfile_yaws(Socket, {[{From,Length}], _Size, _Boundary, _ContentType}, Filename) ->
{ok, Bytes} = sendfile:send(Socket, Filename, From, Length),
Bytes;
send_file_body_parts_sendfile_yaws(Socket, {Parts, Size, Boundary, ContentType}, Filename) ->
Bytes = [
begin
send(Socket, part_preamble(Boundary, ContentType, From, Length, Size)),
{ok, B} = sendfile:send(Socket, Filename, From, Length),
send(Socket, <<"\r\n">>),
B
end
|| {From,Length} <- Parts
],
send(Socket, end_boundary(Boundary)),
lists:sum(Bytes).

send_file_body_parts_read(Socket, Parts, Filename) ->
{ok, FD} = file:open(Filename, [raw,binary]),
Bytes = send_device_body_parts(Socket, Parts, FD),
Expand Down Expand Up @@ -794,3 +818,15 @@ load_dispatch_data(Bindings, HostTokens, Port, PathTokens, AppRoot, DispPath, Re

log_data(#wm_reqdata{log_data=LogData, metadata=MetaData}) ->
LogData#wm_log_data{metadata=MetaData}.

use_sendfile() ->
case application:get_env(webzmachine, use_sendfile) of
undefined -> disable;
{ok, disable} -> disable;
{ok, erlang} -> erlang;
{ok, yaws} ->
case sendfile:enabled() of
true -> yaws;
false -> disable
end
end.
4 changes: 2 additions & 2 deletions src/webzmachine.app.src
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
%% -*- mode: erlang -*-
{application, webzmachine,
[{description, "webzmachine"},
{vsn, "1.8.1"},
{vsn, "2.0.0"},
{modules,
[]},
{registered, []},
{mod, {webmachine_app, []}},
{env, [{node_id, 1}]},
{applications, [kernel, stdlib, crypto, mochiweb]}]}.
{applications, [kernel, stdlib, crypto, mochiweb, sendfile]}]}.

0 comments on commit f31b966

Please sign in to comment.