aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ranch.erl27
-rw-r--r--test/acceptor_SUITE.erl17
-rw-r--r--test/check_tcp_options.erl15
3 files changed, 49 insertions, 10 deletions
diff --git a/src/ranch.erl b/src/ranch.erl
index 17d24d2..c7e9727 100644
--- a/src/ranch.erl
+++ b/src/ranch.erl
@@ -120,18 +120,27 @@ set_protocol_options(Ref, Opts) ->
-spec filter_options([{atom(), any()} | {raw, any(), any(), any()}],
[atom()], Acc) -> Acc when Acc :: [any()].
-filter_options([], _, Acc) ->
- Acc;
-filter_options([Opt = {Key, _}|Tail], AllowedKeys, Acc) ->
+filter_options(UserOptions, AllowedKeys, DefaultOptions) ->
+ AllowedOptions = filter_user_options(UserOptions, AllowedKeys),
+ lists:foldl(fun merge_options/2, DefaultOptions, AllowedOptions).
+
+filter_user_options([Opt = {Key, _}|Tail], AllowedKeys) ->
case lists:member(Key, AllowedKeys) of
- true -> filter_options(Tail, AllowedKeys, [Opt|Acc]);
- false -> filter_options(Tail, AllowedKeys, Acc)
+ true -> [Opt|filter_user_options(Tail, AllowedKeys)];
+ false -> filter_user_options(Tail, AllowedKeys)
end;
-filter_options([Opt = {raw, _, _, _}|Tail], AllowedKeys, Acc) ->
+filter_user_options([Opt = {raw, _, _, _}|Tail], AllowedKeys) ->
case lists:member(raw, AllowedKeys) of
- true -> filter_options(Tail, AllowedKeys, [Opt|Acc]);
- false -> filter_options(Tail, AllowedKeys, Acc)
- end.
+ true -> [Opt|filter_user_options(Tail, AllowedKeys)];
+ false -> filter_user_options(Tail, AllowedKeys)
+ end;
+filter_user_options([], _) ->
+ [].
+
+merge_options({Key, _} = Option, OptionList) ->
+ lists:keystore(Key, 1, OptionList, Option);
+merge_options(Option, OptionList) ->
+ [Option|OptionList].
-spec set_option_default(Opts, atom(), any())
-> Opts when Opts :: [{atom(), any()}].
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl
index f4789c8..6325055 100644
--- a/test/acceptor_SUITE.erl
+++ b/test/acceptor_SUITE.erl
@@ -37,6 +37,7 @@
-export([tcp_accept_socket/1]).
-export([tcp_active_echo/1]).
-export([tcp_echo/1]).
+-export([tcp_inherit_options/1]).
-export([tcp_max_connections/1]).
-export([tcp_max_connections_and_beyond/1]).
-export([tcp_set_max_connections/1]).
@@ -66,7 +67,8 @@ groups() ->
tcp_max_connections_and_beyond,
tcp_set_max_connections,
tcp_clean_set_max_connections,
- tcp_upgrade
+ tcp_upgrade,
+ tcp_inherit_options
]}, {ssl, [
ssl_accept_error,
ssl_accept_socket,
@@ -370,6 +372,19 @@ tcp_upgrade(_) ->
receive upgraded -> ok after 1000 -> error(timeout) end,
ranch:stop_listener(Name).
+tcp_inherit_options(_) ->
+ Name = tcp_inherit_options,
+ TcpOptions = [{nodelay, false}, {send_timeout_close, false}],
+ {ok, _} = ranch:start_listener(Name, 4, ranch_tcp,
+ [{port, 0} | TcpOptions],
+ check_tcp_options, [{pid, self()} | TcpOptions]),
+ Port = ranch:get_port(Name),
+ {ok, Socket} = gen_tcp:connect("localhost", Port,
+ [binary, {active, true}, {packet, raw}]),
+ receive checked -> ok after 1000 -> error(timeout) end,
+ ok = gen_tcp:close(Socket),
+ ranch:stop_listener(Name).
+
%% Supervisor tests
supervisor_clean_restart(_) ->
diff --git a/test/check_tcp_options.erl b/test/check_tcp_options.erl
new file mode 100644
index 0000000..18432ac
--- /dev/null
+++ b/test/check_tcp_options.erl
@@ -0,0 +1,15 @@
+-module(check_tcp_options).
+-behaviour(ranch_protocol).
+
+-export([start_link/4]).
+-export([init/3]).
+
+start_link(_, Socket, _, [{pid, TestPid}|TcpOptions]) ->
+ {ok, RealTcpOptions} =
+ inet:getopts(Socket, [Key || {Key, _} <- TcpOptions]),
+ Pid = spawn_link(?MODULE, init, [TestPid, RealTcpOptions, TcpOptions]),
+ {ok, Pid}.
+
+init(Pid, TcpOptions, TcpOptions) ->
+ Pid ! checked,
+ receive after 2500 -> ok end.