aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjuhlig <[email protected]>2019-06-17 16:45:00 +0200
committerLoïc Hoguin <[email protected]>2019-06-19 13:58:28 +0200
commitb3695e08787679dfd7dbccbfd5cc407a6751dc2a (patch)
tree8a8388185fb0d3f9ef51e126931237348efab864
parentb27dd725854dd016c05e2075f8ae99933a2903d8 (diff)
downloadranch-b3695e08787679dfd7dbccbfd5cc407a6751dc2a.tar.gz
ranch-b3695e08787679dfd7dbccbfd5cc407a6751dc2a.tar.bz2
ranch-b3695e08787679dfd7dbccbfd5cc407a6751dc2a.zip
Validate transport options
-rw-r--r--src/ranch.erl59
-rw-r--r--test/acceptor_SUITE.erl6
2 files changed, 57 insertions, 8 deletions
diff --git a/src/ranch.erl b/src/ranch.erl
index 0580d5b..b26f3a6 100644
--- a/src/ranch.erl
+++ b/src/ranch.erl
@@ -71,12 +71,14 @@ start_listener(Ref, Transport, TransOpts0, Protocol, ProtoOpts)
when is_atom(Transport), is_atom(Protocol) ->
TransOpts = normalize_opts(TransOpts0),
_ = code:ensure_loaded(Transport),
- case erlang:function_exported(Transport, name, 0) of
- false ->
- {error, badarg};
- true ->
+ case {erlang:function_exported(Transport, name, 0), validate_transport_opts(TransOpts)} of
+ {true, ok} ->
maybe_started(supervisor:start_child(ranch_sup, child_spec(Ref,
- Transport, TransOpts, Protocol, ProtoOpts)))
+ Transport, TransOpts, Protocol, ProtoOpts)));
+ {false, _} ->
+ {error, {bad_transport, Transport}};
+ {_, TransOptsError} ->
+ TransOptsError
end.
-spec normalize_opts(opts()) -> transport_opts(any()).
@@ -85,6 +87,53 @@ normalize_opts(Map) when is_map(Map) ->
normalize_opts(Any) ->
#{socket_opts => Any}.
+-spec validate_transport_opts(transport_opts(any())) -> ok | {error, any()}.
+validate_transport_opts(Opts) ->
+ maps:fold(fun
+ (Key, Value, ok) ->
+ case validate_transport_opt(Key, Value, Opts) of
+ true ->
+ ok;
+ false ->
+ {error, {bad_option, Key}}
+ end;
+ (_, _, Acc) ->
+ Acc
+ end, ok, Opts).
+
+-spec validate_transport_opt(any(), any(), transport_opts(any())) -> boolean().
+validate_transport_opt(connection_type, worker, _) ->
+ true;
+validate_transport_opt(connection_type, supervisor, _) ->
+ true;
+validate_transport_opt(handshake_timeout, infinity, _) ->
+ true;
+validate_transport_opt(handshake_timeout, Value, _) ->
+ is_integer(Value) andalso Value >= 0;
+validate_transport_opt(max_connections, infinity, _) ->
+ true;
+validate_transport_opt(max_connections, Value, _) ->
+ is_integer(Value) andalso Value >= 0;
+validate_transport_opt(logger, Value, _) ->
+ is_atom(Value);
+validate_transport_opt(num_acceptors, Value, _) ->
+ is_integer(Value) andalso Value > 0;
+validate_transport_opt(num_conns_sups, Value, _) ->
+ is_integer(Value) andalso Value > 0;
+validate_transport_opt(num_listen_sockets, Value, Opts) ->
+ is_integer(Value) andalso Value > 0
+ andalso Value =< maps:get(num_acceptors, Opts, 10);
+validate_transport_opt(shutdown, brutal_kill, _) ->
+ true;
+validate_transport_opt(shutdown, infinity, _) ->
+ true;
+validate_transport_opt(shutdown, Value, _) ->
+ is_integer(Value) andalso Value >= 0;
+validate_transport_opt(socket_opts, _, _) ->
+ true;
+validate_transport_opt(_, _, _) ->
+ false.
+
maybe_started({error, {{shutdown,
{failed_to_start_child, ranch_acceptors_sup,
{listen_error, _, Reason}}}, _}} = Error) ->
diff --git a/test/acceptor_SUITE.erl b/test/acceptor_SUITE.erl
index b6ddea4..294b07e 100644
--- a/test/acceptor_SUITE.erl
+++ b/test/acceptor_SUITE.erl
@@ -94,8 +94,8 @@ groups() ->
misc_bad_transport(_) ->
doc("Reject invalid transport modules."),
- {error, badarg} = ranch:start_listener(misc_bad_transport,
- bad_transport, #{},
+ {error, {bad_transport, invalid_transport}} = ranch:start_listener(misc_bad_transport,
+ invalid_transport, #{},
echo_protocol, []),
ok.
@@ -1202,7 +1202,7 @@ supervisor_changed_options_restart(_) ->
{ok, [{send_timeout, 300001}]}
= inet:getopts(do_get_listener_socket(ListenerSupPid1), [send_timeout]),
%% Crash the listener_sup process, allow a short time for restart to succeed.
- %% We silence the excepted log events coming from the relevant supervisors.
+ %% We silence the expected log events coming from the relevant supervisors.
ListenerChilds = [ChildPid || {_, ChildPid, _, _} <- supervisor:which_children(ListenerSupPid1)],
FilterFun = fun (#{meta := #{pid := EventPid}}, _) ->
case lists:member(EventPid, ListenerChilds) of