Skip to content

Commit 4355741

Browse files
author
Bradford Folkens
committed
Fixed issues with unmatched data frame from setup/upgrade phase
1 parent a5e6bd0 commit 4355741

File tree

4 files changed

+35
-9
lines changed

4 files changed

+35
-9
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
77

88
## [Unreleased]
99

10+
- **BREAKING:** Return entire response from setup/3 and setup_await/2, this changes the return type.
11+
- Fixed issues for certain websocket servers that return extra data in the upgrade/setup phase (ws://echo.websocket.events/.ws)
12+
1013
## [0.2.4] - 2023-06-12
1114

1215
- Rolled back fix from 0.2.3

lib/wind.ex

+25-6
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,41 @@ defmodule Wind do
5050
## Examples
5151
5252
iex> Wind.setup(conn, ref, http_reply_message)
53-
{:ok, conn, ref, websocket}
53+
{:ok, conn, ref, websocket, response}
5454
5555
"""
5656
@spec setup(Mint.HTTP.t(), Mint.Types.request_ref(), term, list) ::
57-
{:ok, Mint.HTTP.t(), Mint.Types.request_ref(), Mint.WebSocket.t()}
57+
{:ok, Mint.HTTP.t(), Mint.Types.request_ref(), Mint.WebSocket.t(), [Mint.Types.response]}
5858
| {:error, Mint.HTTP.t(), Mint.Types.error(), [Mint.Types.response()]}
5959
| :unknown
6060
def setup(conn, ref, http_reply_message, opts \\ [])
6161
when not is_nil(conn) and not is_nil(ref) do
62-
with {:ok, conn, [{:status, ^ref, status}, {:headers, ^ref, resp_headers}, {:done, ^ref}]} <-
63-
Mint.WebSocket.stream(conn, http_reply_message),
62+
with {:ok, conn, response} <- Mint.WebSocket.stream(conn, http_reply_message),
63+
%{status: status, headers: resp_headers} <- decode_setup_response(response, ref),
6464
{:ok, conn, websocket} <- Mint.WebSocket.new(conn, ref, status, resp_headers, opts) do
65-
{:ok, conn, ref, websocket}
65+
{:ok, conn, ref, websocket, response}
6666
end
6767
end
6868

69+
defp decode_setup_response(response, ref, out \\ %{})
70+
71+
defp decode_setup_response([{:status, response_ref, status} | tail], ref, out) when response_ref == ref do
72+
decode_setup_response(tail, ref, Map.put(out, :status, status))
73+
end
74+
75+
defp decode_setup_response([{:headers, response_ref, headers} | tail], ref, out) when response_ref == ref do
76+
decode_setup_response(tail, ref, Map.update(out, :headers, headers, fn existing -> [headers | existing] end))
77+
end
78+
79+
defp decode_setup_response([{:data, response_ref, data} | tail], ref, out) when response_ref == ref do
80+
decode_setup_response(tail, ref, Map.update(out, :data, data, fn existing -> [data | existing] end))
81+
end
82+
83+
defp decode_setup_response([{:done, response_ref} | tail], ref, out) when response_ref == ref,
84+
do: decode_setup_response(tail, ref, out)
85+
86+
defp decode_setup_response(_, _, out), do: out
87+
6988
@doc """
7089
Synchronously setup a websocket connection. See `setup/3`.
7190
@@ -76,7 +95,7 @@ defmodule Wind do
7695
7796
"""
7897
@spec setup_await(Mint.HTTP.t(), Mint.Types.request_ref()) ::
79-
{:ok, Mint.HTTP.t(), Mint.Types.request_ref(), Mint.WebSocket.t()}
98+
{:ok, Mint.HTTP.t(), Mint.Types.request_ref(), Mint.WebSocket.t(), [Mint.Types.response()]}
8099
| {:error, Mint.HTTP.t(), Mint.Types.error(), [Mint.Types.response()]}
81100
| :unknown
82101
def setup_await(conn, ref)

lib/wind/client.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ defmodule Wind.Client do
142142
%{conn_info: {conn, ref, _}} = state
143143
) do
144144
Logger.debug(fn -> "Upgrading to websocket" end)
145-
{:ok, conn, ref, websocket} = Wind.setup(conn, ref, http_reply_message)
145+
{:ok, conn, ref, websocket, _response} = Wind.setup(conn, ref, http_reply_message)
146146
state = %{state | conn_info: {conn, ref, websocket}}
147147

148148
unquote do

test/wind_test.exs

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ defmodule WindTest do
66
describe "with a sample host" do
77
setup [:sample_uri]
88

9+
test "connect/1 should not connect to an invalid host" do
10+
assert {:error, _reason} = URI.new!("ws://bad-host/") |> Wind.connect()
11+
end
12+
913
test "connect/1 should connect", %{uri: uri} do
1014
assert {:ok, _conn, _ref} = Wind.connect(uri)
1115
end
@@ -15,7 +19,7 @@ defmodule WindTest do
1519
setup [:sample_uri, :connect]
1620

1721
test "setup_await/2 should upgrade the websocket connection", %{conn: conn, ref: ref} do
18-
assert {:ok, _conn, _ref, _websocket} = Wind.setup_await(conn, ref)
22+
assert {:ok, _conn, _ref, _websocket, _response} = Wind.setup_await(conn, ref)
1923
end
2024
end
2125

@@ -41,7 +45,7 @@ defmodule WindTest do
4145
end
4246

4347
defp upgrade(%{conn: conn, ref: ref}) do
44-
{:ok, conn, ref, websocket} = Wind.setup_await(conn, ref)
48+
{:ok, conn, ref, websocket, _response} = Wind.setup_await(conn, ref)
4549

4650
%{conn: conn, ref: ref, websocket: websocket}
4751
end

0 commit comments

Comments
 (0)