Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ doc/*
!doc/img
!doc/img/*
!doc/img/logo.png
*.lock
.vscode
3 changes: 2 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

{deps, [
{zotonic_stdlib, "~> 1.6"},
{cowboy, "2.9.0"}
{cowlib, "~> 2.16"},
{cowboy, "~> 2.14"}
]}.

{profiles, [
Expand Down
28 changes: 28 additions & 0 deletions rebar.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{"1.2.0",
[{<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},0},
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.16.0">>},0},
{<<"qdate_localtime">>,{pkg,<<"qdate_localtime">>,<<"1.2.1">>},1},
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},1},
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.7">>},2},
{<<"tls_certificate_check">>,
{pkg,<<"tls_certificate_check">>,<<"1.29.0">>},
1},
{<<"zotonic_stdlib">>,{pkg,<<"zotonic_stdlib">>,<<"1.24.0">>},0}]}.
[
{pkg_hash,[
{<<"cowboy">>, <<"865DD8B6607E14CF03282E10E934023A1BD8BE6F6BACF921A7E2A96D800CD452">>},
{<<"cowlib">>, <<"54592074EBBBB92EE4746C8A8846E5605052F29309D3A873468D76CDF932076F">>},
{<<"qdate_localtime">>, <<"72E1034DC6B7FEE8F588281EDDD0BD0DC5260005D758052F50634D265D382C18">>},
{<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>},
{<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>},
{<<"tls_certificate_check">>, <<"4473005EB0BBDAD215D7083A230E2E076F538D9EA472C8009FD22006A4CFC5F6">>},
{<<"zotonic_stdlib">>, <<"31456B4C25B41043B83E539C25FF387C5594BE8542906242DC4E07FAE1B81844">>}]},
{pkg_hash_ext,[
{<<"cowboy">>, <<"2C729F934B4E1AA149AFF882F57C6372C15399A20D54F65C8D67BEF583021BDE">>},
{<<"cowlib">>, <<"7F478D80D66B747344F0EA7708C187645CFCC08B11AA424632F78E25BF05DB51">>},
{<<"qdate_localtime">>, <<"1109958D205C65C595C8C5694CB83EBAF2DBE770CF902E4DCE8AFB2C4123764D">>},
{<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>},
{<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>},
{<<"tls_certificate_check">>, <<"5B0D0E5CB0F928BC4F210DF667304ED91C5BFF2A391CE6BDEDFBFE70A8F096C5">>},
{<<"zotonic_stdlib">>, <<"BC626DE1E5884E4695DA91A1169A0797D13F8EE933FE1C5452B9C10EFABADA03">>}]}
].
29 changes: 24 additions & 5 deletions src/cowmachine_response.erl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
]).

-define(FILE_CHUNK_LENGTH, 16#80000). % 512KB
-define(DEFAULT_IDLE_TIMEOUT, 60000).

%% @doc Returns server header.
-spec server_header() -> Result when
Expand Down Expand Up @@ -116,8 +117,6 @@ send_response_code(Code, Parts, Context) ->
Parts :: cowmachine_req:parts(),
Context :: cowmachine_req:context(),
Result :: cowmachine_req:context().
% send_response_bodyfun(undefined, Code, Parts, Context) ->
% send_response_bodyfun(<<>>, Code, Parts, Context);
send_response_bodyfun({device, IO}, Code, Parts, Context) ->
Length = iodevice_size(IO),
send_response_bodyfun({device, Length, IO}, Code, Parts, Context);
Expand Down Expand Up @@ -191,11 +190,14 @@ send_response_bodyfun(Body, Code, all, Context) ->
Req1 = cowboy_req:reply(Code, Headers, Body, Req),
cowmachine_req:set_req(Req1, Context);
send_response_bodyfun(Body, Code, Parts, Context) ->
set_idle_timeout(infinity, Context),
Headers = response_headers(Context),
Req = cowmachine_req:req(Context),
Req1 = cowboy_req:stream_reply(Code, Headers, Req),
Context1 = cowmachine_req:set_req(Req1, Context),
send_parts(Context1, Parts, iolist_to_binary(Body)).
Result = send_parts(Context1, Parts, iolist_to_binary(Body)),
set_idle_timeout(?DEFAULT_IDLE_TIMEOUT, Context),
Result.

-spec start_response_stream(Code, Length, InitialStream, Parts, Context) -> Result when
Code :: integer(),
Expand All @@ -205,6 +207,7 @@ send_response_bodyfun(Body, Code, Parts, Context) ->
Context :: cowmachine_req:context(),
Result :: cowmachine_req:context().
start_response_stream(Code, Length, InitialStream, Parts, Context) ->
set_idle_timeout(infinity, Context),
{Code1, Context1, Parts1} = case is_streaming_range(InitialStream) of
false when Parts =/= all ->
% Drop range response header
Expand All @@ -227,7 +230,9 @@ start_response_stream(Code, Length, InitialStream, Parts, Context) ->
InitialFun ->
stream_initial_fun(InitialFun, Parts1)
end,
send_stream_body(FirstHunk, Context2).
Result = send_stream_body(FirstHunk, Context2),
set_idle_timeout(?DEFAULT_IDLE_TIMEOUT, Result),
Result.

-spec stream_initial_fun(Fun, Parts) -> Result when
Fun :: function(),
Expand All @@ -240,6 +245,17 @@ stream_initial_fun(F, _Parts) when is_function(F) ->
stream_initial_fun(done, _Parts) ->
done.

%% @doc Set the idle timeout for the connection. This will reset the idle timeout
%% timer for HTTP/1.x connections. During streaming we do not want a timeout.
%% The default is 60 seconds.
-spec set_idle_timeout(Timeout, Context) -> ok when
Timeout :: pos_integer() | infinity,
Context :: cowmachine_req:context().
set_idle_timeout(Timeout, Context) ->
Req = cowmachine_req:req(Context),
cowboy_req:cast({set_options, #{
idle_timeout => Timeout
}}, Req).

%% @doc Check if we support ranges on the data stream (body or function)
-spec is_streaming_range(Stream) -> Result when
Expand Down Expand Up @@ -406,7 +422,10 @@ send_file_body_parts(Context, Parts, Filename) ->
Bin :: binary(),
Result :: cowmachine_req:context().
send_parts(Context, {[{From,Length}], _Size, _Boundary, _ContentType}, Bin) ->
send_chunk(Context, binary:part(Bin,From,Length), fin);
set_idle_timeout(infinity, Context),
Result = send_chunk(Context, binary:part(Bin,From,Length), fin),
set_idle_timeout(?DEFAULT_IDLE_TIMEOUT, Context),
Result;
send_parts(Context, {Parts, Size, Boundary, ContentType}, Bin) ->
lists:foreach(
fun({From,Length}) ->
Expand Down
Loading