mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Add an option to disable sendfile for a listener
This commit is contained in:
parent
571719a164
commit
be09711687
5 changed files with 48 additions and 8 deletions
|
@ -32,6 +32,7 @@ opts() :: #{
|
|||
max_skip_body_length => non_neg_integer(),
|
||||
middlewares => [module()],
|
||||
request_timeout => timeout(),
|
||||
sendfile => boolean(),
|
||||
shutdown_timeout => timeout(),
|
||||
stream_handlers => [module()]
|
||||
}
|
||||
|
@ -96,6 +97,11 @@ middlewares ([cowboy_router, cowboy_handler])::
|
|||
request_timeout (5000)::
|
||||
Time in ms with no requests before Cowboy closes the connection.
|
||||
|
||||
sendfile (true)::
|
||||
Whether the sendfile syscall may be used. It can be useful to disable
|
||||
it on systems where the syscall has a buggy implementation, for example
|
||||
under VirtualBox when using shared folders.
|
||||
|
||||
shutdown_timeout (5000)::
|
||||
Time in ms Cowboy will wait for child processes to shut down before killing them.
|
||||
|
||||
|
@ -104,6 +110,7 @@ stream_handlers ([cowboy_stream_h])::
|
|||
|
||||
== Changelog
|
||||
|
||||
* *2.6*: The `sendfile` option was added.
|
||||
* *2.5*: The `linger_timeout` option was added.
|
||||
* *2.2*: The `max_skip_body_length` option was added.
|
||||
* *2.0*: The `timeout` option was renamed `request_timeout`.
|
||||
|
|
|
@ -30,6 +30,7 @@ opts() :: #{
|
|||
max_frame_size_sent => 16384..16777215 | infinity,
|
||||
middlewares => [module()],
|
||||
preface_timeout => timeout(),
|
||||
sendfile => boolean(),
|
||||
settings_timeout => timeout(),
|
||||
shutdown_timeout => timeout(),
|
||||
stream_handlers => [module()]
|
||||
|
@ -119,6 +120,12 @@ preface_timeout (5000)::
|
|||
|
||||
Time in ms Cowboy is willing to wait for the connection preface.
|
||||
|
||||
sendfile (true)::
|
||||
|
||||
Whether the sendfile syscall may be used. It can be useful to disable
|
||||
it on systems where the syscall has a buggy implementation, for example
|
||||
under VirtualBox when using shared folders.
|
||||
|
||||
settings_timeout (5000)::
|
||||
|
||||
Time in ms Cowboy is willing to wait for a SETTINGS ack.
|
||||
|
@ -133,6 +140,7 @@ Ordered list of stream handlers that will handle all stream events.
|
|||
|
||||
== Changelog
|
||||
|
||||
* *2.6*: The `sendfile` option was added.
|
||||
* *2.4*: Add the options `initial_connection_window_size`,
|
||||
`initial_stream_window_size`, `max_concurrent_streams`,
|
||||
`max_decode_table_size`, `max_encode_table_size`,
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
middlewares => [module()],
|
||||
proxy_header => boolean(),
|
||||
request_timeout => timeout(),
|
||||
sendfile => boolean(),
|
||||
shutdown_timeout => timeout(),
|
||||
stream_handlers => [module()],
|
||||
tracer_callback => cowboy_tracer_h:tracer_callback(),
|
||||
|
@ -1050,7 +1051,7 @@ commands(State=#state{socket=Socket, transport=Transport, streams=Streams, out_s
|
|||
end,
|
||||
commands(State#state{out_state=done}, StreamID, Tail);
|
||||
%% Send a file.
|
||||
commands(State0=#state{socket=Socket, transport=Transport}, StreamID,
|
||||
commands(State0=#state{socket=Socket, transport=Transport, opts=Opts}, StreamID,
|
||||
[{sendfile, IsFin, Offset, Bytes, Path}|Tail]) ->
|
||||
%% @todo exit with response_body_too_large if we exceed content-length
|
||||
%% We wrap the sendfile call into a try/catch because on OTP-20
|
||||
|
@ -1066,7 +1067,11 @@ commands(State0=#state{socket=Socket, transport=Transport}, StreamID,
|
|||
%% This try/catch prevents some noisy logs to be written
|
||||
%% when these errors occur.
|
||||
try
|
||||
Transport:sendfile(Socket, Path, Offset, Bytes),
|
||||
%% When sendfile is disabled we explicitly use the fallback.
|
||||
_ = case maps:get(sendfile, Opts, true) of
|
||||
true -> Transport:sendfile(Socket, Path, Offset, Bytes);
|
||||
false -> ranch_transport:sendfile(Transport, Socket, Path, Offset, Bytes, [])
|
||||
end,
|
||||
State = case IsFin of
|
||||
fin -> State0#state{out_state=done}
|
||||
%% @todo Add the sendfile command.
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
middlewares => [module()],
|
||||
preface_timeout => timeout(),
|
||||
proxy_header => boolean(),
|
||||
sendfile => boolean(),
|
||||
settings_timeout => timeout(),
|
||||
shutdown_timeout => timeout(),
|
||||
stream_handlers => [module()],
|
||||
|
@ -650,10 +651,14 @@ send_data_frame(State=#state{socket=Socket, transport=Transport},
|
|||
StreamID, IsFin, {data, Data}) ->
|
||||
Transport:send(Socket, cow_http2:data(StreamID, IsFin, Data)),
|
||||
State;
|
||||
send_data_frame(State=#state{socket=Socket, transport=Transport},
|
||||
send_data_frame(State=#state{socket=Socket, transport=Transport, opts=Opts},
|
||||
StreamID, IsFin, {sendfile, Offset, Bytes, Path}) ->
|
||||
Transport:send(Socket, cow_http2:data_header(StreamID, IsFin, Bytes)),
|
||||
Transport:sendfile(Socket, Path, Offset, Bytes),
|
||||
%% When sendfile is disabled we explicitly use the fallback.
|
||||
_ = case maps:get(sendfile, Opts, true) of
|
||||
true -> Transport:sendfile(Socket, Path, Offset, Bytes);
|
||||
false -> ranch_transport:sendfile(Transport, Socket, Path, Offset, Bytes, [])
|
||||
end,
|
||||
State;
|
||||
%% The stream is terminated in cow_http2_machine:prepare_trailers.
|
||||
send_data_frame(State=#state{socket=Socket, transport=Transport,
|
||||
|
|
|
@ -23,7 +23,10 @@
|
|||
%% ct.
|
||||
|
||||
all() ->
|
||||
cowboy_test:common_all().
|
||||
cowboy_test:common_all() ++ [
|
||||
{group, http_no_sendfile},
|
||||
{group, h2c_no_sendfile}
|
||||
].
|
||||
|
||||
groups() ->
|
||||
AllTests = ct_helper:all(?MODULE),
|
||||
|
@ -44,7 +47,10 @@ groups() ->
|
|||
{http_compress, [parallel], GroupTests},
|
||||
{https_compress, [parallel], GroupTests},
|
||||
{h2_compress, [parallel], GroupTests},
|
||||
{h2c_compress, [parallel], GroupTests}
|
||||
{h2c_compress, [parallel], GroupTests},
|
||||
%% No real need to test sendfile disabled against https or h2.
|
||||
{http_no_sendfile, [parallel], GroupTests},
|
||||
{h2c_no_sendfile, [parallel], GroupTests}
|
||||
].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
|
@ -94,8 +100,17 @@ init_per_group(dir, Config) ->
|
|||
[{prefix, "/dir"}|Config];
|
||||
init_per_group(priv_dir, Config) ->
|
||||
[{prefix, "/priv_dir"}|Config];
|
||||
init_per_group(tttt, Config) ->
|
||||
Config;
|
||||
init_per_group(Name=http_no_sendfile, Config) ->
|
||||
cowboy_test:init_http(Name, #{
|
||||
env => #{dispatch => init_dispatch(Config)},
|
||||
sendfile => false
|
||||
}, [{flavor, vanilla}|Config]);
|
||||
init_per_group(Name=h2c_no_sendfile, Config) ->
|
||||
Config1 = cowboy_test:init_http(Name, #{
|
||||
env => #{dispatch => init_dispatch(Config)},
|
||||
sendfile => false
|
||||
}, [{flavor, vanilla}|Config]),
|
||||
lists:keyreplace(protocol, 1, Config1, {protocol, http2});
|
||||
init_per_group(Name, Config) ->
|
||||
cowboy_test:init_common_groups(Name, Config, ?MODULE).
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue