From a9b0894bcd3be29d75aba25c723d1a30f6ee7ecf Mon Sep 17 00:00:00 2001 From: Tobias Casper Date: Thu, 3 Apr 2025 16:50:13 +0200 Subject: [PATCH 1/2] fix: add subprotocol header when upgrading connection --- lib/graphql_ws_client/drivers/gun.ex | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/graphql_ws_client/drivers/gun.ex b/lib/graphql_ws_client/drivers/gun.ex index edb2197..aa2791e 100644 --- a/lib/graphql_ws_client/drivers/gun.ex +++ b/lib/graphql_ws_client/drivers/gun.ex @@ -79,7 +79,10 @@ defmodule GraphQLWSClient.Drivers.Gun do with {:await_up, {:ok, _protocol}} <- {:await_up, opts.adapter.await_up(pid, opts.connect_options.connect_timeout)}, - stream_ref = opts.adapter.ws_upgrade(pid, config.path), + stream_ref = + opts.adapter.ws_upgrade(pid, config.path, [ + {"sec-websocket-protocol", "graphql-transport-ws"} + ]), :ok <- await_upgrade(opts.upgrade_timeout), :ok <- init_connection( From ce64e9beb13b734a5e82912285b850ccedbfd9aa Mon Sep 17 00:00:00 2001 From: Tobias Casper Date: Wed, 9 Apr 2025 21:46:00 +0200 Subject: [PATCH 2/2] fix: set subprotocol --- lib/graphql_ws_client/drivers/gun.ex | 11 +++++--- lib/graphql_ws_client/drivers/gun/opts.ex | 2 ++ test/graphql_ws_client/drivers/gun_test.exs | 28 ++++++++++++++------- test/support/ws_client.ex | 3 ++- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/lib/graphql_ws_client/drivers/gun.ex b/lib/graphql_ws_client/drivers/gun.ex index aa2791e..13f9287 100644 --- a/lib/graphql_ws_client/drivers/gun.ex +++ b/lib/graphql_ws_client/drivers/gun.ex @@ -80,9 +80,14 @@ defmodule GraphQLWSClient.Drivers.Gun do {:await_up, opts.adapter.await_up(pid, opts.connect_options.connect_timeout)}, stream_ref = - opts.adapter.ws_upgrade(pid, config.path, [ - {"sec-websocket-protocol", "graphql-transport-ws"} - ]), + opts.adapter.ws_upgrade( + pid, + config.path, + [{"sec-websocket-protocol", opts.subprotocol}], + %{ + protocols: [{opts.subprotocol, :gun_ws_h}] + } + ), :ok <- await_upgrade(opts.upgrade_timeout), :ok <- init_connection( diff --git a/lib/graphql_ws_client/drivers/gun/opts.ex b/lib/graphql_ws_client/drivers/gun/opts.ex index c7836c4..7c0cdf1 100644 --- a/lib/graphql_ws_client/drivers/gun/opts.ex +++ b/lib/graphql_ws_client/drivers/gun/opts.ex @@ -10,6 +10,7 @@ defmodule GraphQLWSClient.Drivers.Gun.Opts do adapter: :gun, connect_options: @default_connect_options, json_library: Jason, + subprotocol: "graphql-transport-ws", upgrade_timeout: :timer.seconds(5) @type t :: %__MODULE__{ @@ -17,6 +18,7 @@ defmodule GraphQLWSClient.Drivers.Gun.Opts do adapter: module, connect_options: %{optional(atom) => any}, json_library: module, + subprotocol: String.t(), upgrade_timeout: timeout } diff --git a/test/graphql_ws_client/drivers/gun_test.exs b/test/graphql_ws_client/drivers/gun_test.exs index 61ff500..9241d48 100644 --- a/test/graphql_ws_client/drivers/gun_test.exs +++ b/test/graphql_ws_client/drivers/gun_test.exs @@ -65,7 +65,17 @@ defmodule GraphQLWSClient.Drivers.GunTest do |> expect(:await_up, fn ^pid, 250 -> {:ok, :http} end) - |> expect(:ws_upgrade, fn ^pid, "/subscriptions" -> + |> expect(:ws_upgrade, fn ^pid, + "/subscriptions", + [ + {"sec-websocket-protocol", + "graphql-transport-ws"} + ], + %{ + protocols: [ + {"graphql-transport-ws", :gun_ws_h} + ] + } -> send(self(), {:gun_upgrade, pid, stream_ref, ["websocket"], nil}) stream_ref end) @@ -118,7 +128,7 @@ defmodule GraphQLWSClient.Drivers.GunTest do WSClientMock |> expect(:open, fn _, _, _ -> {:ok, pid} end) |> expect(:await_up, fn _, _ -> {:ok, :http} end) - |> expect(:ws_upgrade, fn _, _ -> stream_ref end) + |> expect(:ws_upgrade, fn _, _, _, _ -> stream_ref end) |> expect(:close, fn ^pid -> :ok end) assert Gun.connect(@conn) == {:error, %SocketError{cause: :timeout}} @@ -133,7 +143,7 @@ defmodule GraphQLWSClient.Drivers.GunTest do WSClientMock |> expect(:open, fn _, _, _ -> {:ok, pid} end) |> expect(:await_up, fn _, _ -> {:ok, :http} end) - |> expect(:ws_upgrade, fn _, _ -> + |> expect(:ws_upgrade, fn _, _, _, _ -> send(self(), {:gun_response, pid, stream_ref, nil, code, nil}) stream_ref end) @@ -153,7 +163,7 @@ defmodule GraphQLWSClient.Drivers.GunTest do WSClientMock |> expect(:open, fn _, _, _ -> {:ok, pid} end) |> expect(:await_up, fn _, _ -> {:ok, :http} end) - |> expect(:ws_upgrade, fn _, _ -> + |> expect(:ws_upgrade, fn _, _, _, _ -> send(self(), {:gun_error, pid, stream_ref, reason}) stream_ref end) @@ -171,7 +181,7 @@ defmodule GraphQLWSClient.Drivers.GunTest do WSClientMock |> expect(:open, fn _, _, _ -> {:ok, pid} end) |> expect(:await_up, fn _, _ -> {:ok, :http} end) - |> expect(:ws_upgrade, fn _, _ -> + |> expect(:ws_upgrade, fn _, _, _, _ -> send(self(), {:gun_upgrade, pid, stream_ref, ["websocket"], nil}) stream_ref end) @@ -188,7 +198,7 @@ defmodule GraphQLWSClient.Drivers.GunTest do WSClientMock |> expect(:open, fn _, _, _ -> {:ok, pid} end) |> expect(:await_up, fn _, _ -> {:ok, :http} end) - |> expect(:ws_upgrade, fn _, _ -> + |> expect(:ws_upgrade, fn _, _, _, _ -> send(self(), {:gun_upgrade, pid, stream_ref, ["websocket"], nil}) stream_ref end) @@ -209,7 +219,7 @@ defmodule GraphQLWSClient.Drivers.GunTest do WSClientMock |> expect(:open, fn _, _, _ -> {:ok, pid} end) |> expect(:await_up, fn _, _ -> {:ok, :http} end) - |> expect(:ws_upgrade, fn _, _ -> + |> expect(:ws_upgrade, fn _, _, _, _ -> send(self(), {:gun_upgrade, pid, stream_ref, ["websocket"], nil}) stream_ref end) @@ -227,7 +237,7 @@ defmodule GraphQLWSClient.Drivers.GunTest do WSClientMock |> expect(:open, fn _, _, _ -> {:ok, pid} end) |> expect(:await_up, fn _, _ -> {:ok, :http} end) - |> expect(:ws_upgrade, fn _, _ -> + |> expect(:ws_upgrade, fn _, _, _, _ -> send(self(), {:gun_upgrade, pid, stream_ref, ["websocket"], nil}) stream_ref end) @@ -253,7 +263,7 @@ defmodule GraphQLWSClient.Drivers.GunTest do WSClientMock |> expect(:open, fn _, _, _ -> {:ok, pid} end) |> expect(:await_up, fn _, _ -> {:ok, :http} end) - |> expect(:ws_upgrade, fn _, _ -> + |> expect(:ws_upgrade, fn _, _, _, _ -> send(self(), {:gun_upgrade, pid, stream_ref, ["websocket"], nil}) stream_ref end) diff --git a/test/support/ws_client.ex b/test/support/ws_client.ex index bb8afbc..9dcbcbc 100644 --- a/test/support/ws_client.ex +++ b/test/support/ws_client.ex @@ -10,7 +10,8 @@ defmodule GraphQLWSClient.WSClient do @callback await_up(pid, timeout) :: {:ok, :http | :http2 | :raw | :socks} | {:error, any} - @callback ws_upgrade(pid, binary) :: reference + @callback ws_upgrade(pid, binary, :gun.req_headers(), :gun.ws_opts()) :: + reference @callback ws_send(pid, reference, frame :: term) :: :ok