mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 20:30:23 +00:00
Add sendfile support to SPDY, enabling cowboy_static use
This commit is contained in:
parent
e50f7e4086
commit
1fc69977da
2 changed files with 48 additions and 4 deletions
|
@ -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}.
|
||||
|
|
|
@ -44,9 +44,13 @@ init_per_suite(Config) ->
|
|||
application:start(cowboy),
|
||||
application:start(public_key),
|
||||
application:start(ssl),
|
||||
Config.
|
||||
Dir = ?config(priv_dir, Config) ++ "/static",
|
||||
ct_helper:create_static_dir(Dir),
|
||||
[{static_dir, Dir}|Config].
|
||||
|
||||
end_per_suite(_Config) ->
|
||||
end_per_suite(Config) ->
|
||||
Dir = ?config(static_dir, Config),
|
||||
ct_helper:delete_static_dir(Dir),
|
||||
application:stop(ssl),
|
||||
application:stop(public_key),
|
||||
application:stop(cowboy),
|
||||
|
@ -69,9 +73,12 @@ end_per_group(Name, _) ->
|
|||
|
||||
%% Dispatch configuration.
|
||||
|
||||
init_dispatch(_) ->
|
||||
init_dispatch(Config) ->
|
||||
cowboy_router:compile([
|
||||
{"localhost", [
|
||||
{"/static/[...]", cowboy_static,
|
||||
[{directory, ?config(static_dir, Config)},
|
||||
{mimetypes, [{<<".css">>, [<<"text/css">>]}]}]},
|
||||
{"/chunked", http_chunked, []},
|
||||
{"/", http_handler, []}
|
||||
]}
|
||||
|
@ -152,6 +159,7 @@ check_status(Config) ->
|
|||
Tests = [
|
||||
{200, nofin, "localhost", "/"},
|
||||
{200, nofin, "localhost", "/chunked"},
|
||||
{200, nofin, "localhost", "/static/style.css"},
|
||||
{400, fin, "bad-host", "/"},
|
||||
{400, fin, "localhost", "bad-path"},
|
||||
{404, fin, "localhost", "/this/path/does/not/exist"}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue