From df032cfb917fc1083191f6f9fd35eda6bd185f2c Mon Sep 17 00:00:00 2001 From: Dan Schultzer <1254724+danschultzer@users.noreply.github.com> Date: Sat, 24 Feb 2024 07:32:02 -0800 Subject: [PATCH] Use unique bare list concatenation to allow non keyword options (#113) * Use bare list concatenation to allow non keyword options * Make options unique * Format fixes --------- Co-authored-by: Mat Trudel --- lib/thousand_island/transports/ssl.ex | 11 +++++++--- lib/thousand_island/transports/tcp.ex | 11 +++++++--- test/thousand_island/server_test.exs | 30 +++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/thousand_island/transports/ssl.ex b/lib/thousand_island/transports/ssl.ex index 118f315..a1b8229 100644 --- a/lib/thousand_island/transports/ssl.ex +++ b/lib/thousand_island/transports/ssl.ex @@ -57,10 +57,15 @@ defmodule ThousandIsland.Transports.SSL do reuseaddr: true ] + # We can't use Keyword functions here because :ssl accepts non-keyword style options resolved_options = - default_options - |> Keyword.merge(user_options) - |> Keyword.merge(@hardcoded_options) + Enum.uniq_by( + @hardcoded_options ++ user_options ++ default_options, + fn + {key, _} when is_atom(key) -> key + key when is_atom(key) -> key + end + ) if not Enum.any?( [:keyfile, :key, :sni_hosts, :sni_fun], diff --git a/lib/thousand_island/transports/tcp.ex b/lib/thousand_island/transports/tcp.ex index c7e0bd1..9ccacbd 100644 --- a/lib/thousand_island/transports/tcp.ex +++ b/lib/thousand_island/transports/tcp.ex @@ -55,10 +55,15 @@ defmodule ThousandIsland.Transports.TCP do reuseaddr: true ] + # We can't use Keyword functions here because :gen_tcp accepts non-keyword style options resolved_options = - default_options - |> Keyword.merge(user_options) - |> Keyword.merge(@hardcoded_options) + Enum.uniq_by( + @hardcoded_options ++ user_options ++ default_options, + fn + {key, _} when is_atom(key) -> key + key when is_atom(key) -> key + end + ) :gen_tcp.listen(port, resolved_options) end diff --git a/test/thousand_island/server_test.exs b/test/thousand_island/server_test.exs index 5fb508b..473ec6e 100644 --- a/test/thousand_island/server_test.exs +++ b/test/thousand_island/server_test.exs @@ -390,6 +390,13 @@ defmodule ThousandIsland.ServerTest do {:ok, ~c"{:ok, [mode: :binary]}"} = :gen_tcp.recv(client, 0, 100) end + test "tcp should allow Erlang style bare options" do + {:ok, _, port} = start_handler(Echo, transport_options: [:inet6]) + {:ok, client} = :gen_tcp.connect(:localhost, port, active: false) + :gen_tcp.send(client, "HI") + {:ok, ~c"HI"} = :gen_tcp.recv(client, 0, 100) + end + test "ssl should allow default options to be overridden" do {:ok, _, port} = start_handler(ReadOpt, @@ -433,6 +440,29 @@ defmodule ThousandIsland.ServerTest do :ssl.send(client, "mode") {:ok, ~c"{:ok, [mode: :binary]}"} = :ssl.recv(client, 0, 100) end + + test "ssl should allow Erlang style bare options" do + {:ok, _, port} = + start_handler(Echo, + transport_module: ThousandIsland.Transports.SSL, + transport_options: + [:inet6] ++ + [ + certfile: Path.join(__DIR__, "../support/cert.pem"), + keyfile: Path.join(__DIR__, "../support/key.pem") + ] + ) + + {:ok, client} = + :ssl.connect(:localhost, port, + active: false, + verify: :verify_none, + cacertfile: Path.join(__DIR__, "../support/ca.pem") + ) + + :ssl.send(client, "HI") + {:ok, ~c"HI"} = :ssl.recv(client, 0, 100) + end end describe "invalid configuration" do