From b3695e08787679dfd7dbccbfd5cc407a6751dc2a Mon Sep 17 00:00:00 2001 From: juhlig Date: Mon, 17 Jun 2019 16:45:00 +0200 Subject: Validate transport options --- src/ranch.erl | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 5 deletions(-) (limited to 'src') 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) -> -- cgit v1.2.3