0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-15 12:40:25 +00:00

Add sendfile support to SPDY, enabling cowboy_static use

This commit is contained in:
Loïc Hoguin 2013-06-03 19:10:03 +02:00
parent e50f7e4086
commit 1fc69977da
2 changed files with 48 additions and 4 deletions

View file

@ -42,6 +42,7 @@
%% Internal transport functions.
-export([name/0]).
-export([send/2]).
-export([sendfile/2]).
-record(child, {
streamid :: non_neg_integer(),
@ -174,6 +175,14 @@ loop(State=#state{parent=Parent, socket=Socket, transport=Transport,
Children2 = lists:keyreplace(StreamID,
#child.streamid, Children, Child#child{output=fin}),
loop(State#state{children=Children2});
{sendfile, {Pid, StreamID}, Filepath}
when Pid =:= self() ->
Child = #child{output=nofin} = lists:keyfind(StreamID,
#child.streamid, Children),
data_from_file(State, StreamID, Filepath),
Children2 = lists:keyreplace(StreamID,
#child.streamid, Children, Child#child{output=fin}),
loop(State#state{children=Children2});
{'EXIT', Parent, Reason} ->
exit(Reason);
{'EXIT', Pid, _} ->
@ -430,6 +439,27 @@ data(#state{socket=Socket, transport=Transport}, IsFin, StreamID, Data) ->
<< 0:1, StreamID:31, Flags:8, Len:24 >>,
Data]).
data_from_file(#state{socket=Socket, transport=Transport},
StreamID, Filepath) ->
{ok, IoDevice} = file:open(Filepath, [read, binary, raw]),
data_from_file(Socket, Transport, StreamID, IoDevice).
data_from_file(Socket, Transport, StreamID, IoDevice) ->
case file:read(IoDevice, 16#1fff) of
eof ->
_ = Transport:send(Socket, << 0:1, StreamID:31, 1:8, 0:24 >>),
ok;
{ok, Data} ->
Len = byte_size(Data),
Data2 = [<< 0:1, StreamID:31, 0:8, Len:24 >>, Data],
case Transport:send(Socket, Data2) of
ok ->
data_from_file(Socket, Transport, StreamID, IoDevice);
{error, _} ->
ok
end
end.
%% Request process.
request_init(Parent, StreamID, Peer,
@ -535,10 +565,16 @@ stream_close(Socket = {Pid, _}) ->
ok.
%% Internal transport functions.
%% @todo recv, sendfile
%% @todo recv
name() ->
spdy.
send(Socket, Data) ->
stream_data(Socket, Data).
%% We don't wait for the result of the actual sendfile call,
%% therefore we can't know how much was actually sent.
sendfile(Socket = {Pid, _}, Filepath) ->
_ = Pid ! {sendfile, Socket, Filepath},
{ok, undefined}.