Skip to content

Commit 1116dba

Browse files
moogle19mtrudel
andauthored
Fix config options merging (#111)
* Fix config options merging * Fixup existing tests * Add test coverage --------- Co-authored-by: Mat Trudel <mat@geeky.net>
1 parent 9a4b313 commit 1116dba

File tree

3 files changed

+91
-17
lines changed

3 files changed

+91
-17
lines changed

lib/thousand_island/transports/ssl.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ defmodule ThousandIsland.Transports.SSL do
5757
reuseaddr: true
5858
]
5959

60-
resolved_options = @hardcoded_options ++ user_options ++ default_options
60+
resolved_options =
61+
default_options
62+
|> Keyword.merge(user_options)
63+
|> Keyword.merge(@hardcoded_options)
6164

6265
if not Enum.any?(
6366
[:keyfile, :key, :sni_hosts, :sni_fun],

lib/thousand_island/transports/tcp.ex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ defmodule ThousandIsland.Transports.TCP do
5555
reuseaddr: true
5656
]
5757

58-
resolved_options = @hardcoded_options ++ user_options ++ default_options
58+
resolved_options =
59+
default_options
60+
|> Keyword.merge(user_options)
61+
|> Keyword.merge(@hardcoded_options)
62+
5963
:gen_tcp.listen(port, resolved_options)
6064
end
6165

test/thousand_island/server_test.exs

Lines changed: 82 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ defmodule ThousandIsland.ServerTest do
3535
end
3636
end
3737

38+
defmodule ReadOpt do
39+
use ThousandIsland.Handler
40+
41+
@impl ThousandIsland.Handler
42+
def handle_data(data, socket, state) do
43+
opts = [String.to_atom(data)]
44+
ThousandIsland.Socket.send(socket, inspect(ThousandIsland.Socket.getopts(socket, opts)))
45+
{:close, state}
46+
end
47+
end
48+
3849
defmodule Error do
3950
use ThousandIsland.Handler
4051

@@ -204,7 +215,7 @@ defmodule ThousandIsland.ServerTest do
204215
assert {:ok, []} == ThousandIsland.connection_pids(server_pid)
205216
end
206217

207-
describe "suspend / reume" do
218+
describe "suspend / resume" do
208219
test "suspend should stop accepting connections but keep existing ones open" do
209220
{:ok, server_pid, port} = start_handler(LongEcho, port: 9999)
210221
{:ok, client} = :gen_tcp.connect(:localhost, port, active: false)
@@ -364,23 +375,79 @@ defmodule ThousandIsland.ServerTest do
364375
end
365376
end
366377

378+
describe "configuration" do
379+
test "tcp should allow default options to be overridden" do
380+
{:ok, _, port} = start_handler(ReadOpt, transport_options: [send_timeout: 1230])
381+
{:ok, client} = :gen_tcp.connect(:localhost, port, active: false)
382+
:gen_tcp.send(client, "send_timeout")
383+
{:ok, ~c"{:ok, [send_timeout: 1230]}"} = :gen_tcp.recv(client, 0, 100)
384+
end
385+
386+
test "tcp should not allow hardcoded options to be overridden" do
387+
{:ok, _, port} = start_handler(ReadOpt, transport_options: [mode: :list])
388+
{:ok, client} = :gen_tcp.connect(:localhost, port, active: false)
389+
:gen_tcp.send(client, "mode")
390+
{:ok, ~c"{:ok, [mode: :binary]}"} = :gen_tcp.recv(client, 0, 100)
391+
end
392+
393+
test "ssl should allow default options to be overridden" do
394+
{:ok, _, port} =
395+
start_handler(ReadOpt,
396+
transport_module: ThousandIsland.Transports.SSL,
397+
transport_options: [
398+
send_timeout: 1230,
399+
certfile: Path.join(__DIR__, "../support/cert.pem"),
400+
keyfile: Path.join(__DIR__, "../support/key.pem")
401+
]
402+
)
403+
404+
{:ok, client} =
405+
:ssl.connect(:localhost, port,
406+
active: false,
407+
verify: :verify_none,
408+
cacertfile: Path.join(__DIR__, "../support/ca.pem")
409+
)
410+
411+
:ssl.send(client, "send_timeout")
412+
{:ok, ~c"{:ok, [send_timeout: 1230]}"} = :ssl.recv(client, 0, 100)
413+
end
414+
415+
test "ssl should not allow hardcoded options to be overridden" do
416+
{:ok, _, port} =
417+
start_handler(ReadOpt,
418+
transport_module: ThousandIsland.Transports.SSL,
419+
transport_options: [
420+
mode: :list,
421+
certfile: Path.join(__DIR__, "../support/cert.pem"),
422+
keyfile: Path.join(__DIR__, "../support/key.pem")
423+
]
424+
)
425+
426+
{:ok, client} =
427+
:ssl.connect(:localhost, port,
428+
active: false,
429+
verify: :verify_none,
430+
cacertfile: Path.join(__DIR__, "../support/ca.pem")
431+
)
432+
433+
:ssl.send(client, "mode")
434+
{:ok, ~c"{:ok, [mode: :binary]}"} = :ssl.recv(client, 0, 100)
435+
end
436+
end
437+
367438
describe "invalid configuration" do
368439
@tag capture_log: true
369440
test "it should error if a certificate is not found" do
370-
server_args = [
371-
port: 0,
372-
handler_module: Error,
373-
handler_options: [test_pid: self()],
374-
transport_module: ThousandIsland.Transports.SSL,
375-
transport_options: [
376-
certfile: Path.join(__DIR__, "./not/a/cert.pem"),
377-
keyfile: Path.join(__DIR__, "./not/a/key.pem"),
378-
alpn_preferred_protocols: ["foo"]
379-
]
380-
]
381-
382-
{:ok, server_pid} = start_supervised({ThousandIsland, server_args})
383-
{:ok, {_ip, port}} = ThousandIsland.listener_info(server_pid)
441+
{:ok, server_pid, port} =
442+
start_handler(Error,
443+
handler_options: [test_pid: self()],
444+
transport_module: ThousandIsland.Transports.SSL,
445+
transport_options: [
446+
certfile: Path.join(__DIR__, "./not/a/cert.pem"),
447+
keyfile: Path.join(__DIR__, "./not/a/key.pem"),
448+
alpn_preferred_protocols: ["foo"]
449+
]
450+
)
384451

385452
{:error, _} =
386453
:ssl.connect(~c"localhost", port,

0 commit comments

Comments
 (0)