From d9547d4fe6af761ccc5a43686a34f630a7fe878e Mon Sep 17 00:00:00 2001 From: Rafal Studnicki Date: Fri, 5 Jan 2024 15:23:34 +0100 Subject: [PATCH 1/2] Allow configuration of dynamic socket timeout --- lib/phoenix/transports/websocket.ex | 5 +++++ test/phoenix/integration/websocket_socket_test.exs | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/phoenix/transports/websocket.ex b/lib/phoenix/transports/websocket.ex index f04cc4350d..16eadc1384 100644 --- a/lib/phoenix/transports/websocket.ex +++ b/lib/phoenix/transports/websocket.ex @@ -47,6 +47,11 @@ defmodule Phoenix.Transports.WebSocket do keys = Keyword.get(opts, :connect_info, []) connect_info = Transport.connect_info(conn, endpoint, keys) + opts = case Keyword.fetch!(opts, :timeout) do + {m, f, a} -> Keyword.put(opts, :timeout, apply(m, f, a)) + _ -> opts + end + config = %{ endpoint: endpoint, transport: :websocket, diff --git a/test/phoenix/integration/websocket_socket_test.exs b/test/phoenix/integration/websocket_socket_test.exs index aa249f4138..d8ab7fbf1c 100644 --- a/test/phoenix/integration/websocket_socket_test.exs +++ b/test/phoenix/integration/websocket_socket_test.exs @@ -91,12 +91,18 @@ defmodule Phoenix.Integration.WebSocketTest do websocket: [path: "nested/path", check_origin: ["//example.com"], timeout: 200], custom: :value + socket "/custom/timeout", UserSocket, + websocket: [path: "/", timeout: {Endpoint, :websocket_timeout, []}], + custom: :value + socket "/custom/:socket_var", UserSocket, websocket: [path: ":path_var/path", check_origin: ["//example.com"], timeout: 200], custom: :value socket "/ws/ping", PingSocket, websocket: true + + def websocket_timeout, do: 300 end setup_all do @@ -161,6 +167,13 @@ defmodule Phoenix.Integration.WebSocketTest do assert {:ok, _} = WebsocketClient.connect(self(), "#{path}?key=value", :noop) end + test "websocket timeout can be provided via MFA" do + path = "ws://127.0.0.1:#{@port}/custom/timeout/" + {:ok, client} = WebsocketClient.connect(self(), path, :noop) + WebsocketClient.send(client, {:text, "ping"}) + assert_receive {:text, "pong"} + end + test "allows a path with variables" do path = "ws://127.0.0.1:#{@port}/custom/123/456/path" assert {:ok, client} = WebsocketClient.connect(self(), "#{path}?key=value", :noop) From 39b6ba86461c0363fa98d0cc835186c6fb8588df Mon Sep 17 00:00:00 2001 From: Rafal Studnicki Date: Mon, 8 Jan 2024 11:56:12 +0100 Subject: [PATCH 2/2] Verify in test that the dynamic idle timeout disconnects the socket --- test/phoenix/integration/websocket_socket_test.exs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/phoenix/integration/websocket_socket_test.exs b/test/phoenix/integration/websocket_socket_test.exs index d8ab7fbf1c..0660692792 100644 --- a/test/phoenix/integration/websocket_socket_test.exs +++ b/test/phoenix/integration/websocket_socket_test.exs @@ -102,7 +102,7 @@ defmodule Phoenix.Integration.WebSocketTest do socket "/ws/ping", PingSocket, websocket: true - def websocket_timeout, do: 300 + def websocket_timeout, do: 50 end setup_all do @@ -172,6 +172,9 @@ defmodule Phoenix.Integration.WebSocketTest do {:ok, client} = WebsocketClient.connect(self(), path, :noop) WebsocketClient.send(client, {:text, "ping"}) assert_receive {:text, "pong"} + + Process.sleep(100) + refute Process.alive?(client) end test "allows a path with variables" do