diff --git a/lib/minch/conn.ex b/lib/minch/conn.ex index 84f3c8a..5376eeb 100644 --- a/lib/minch/conn.ex +++ b/lib/minch/conn.ex @@ -240,6 +240,8 @@ defmodule Minch.Conn do end end + defp send_reply({:close, _, _} = frame, state), do: state |> send_frame(frame) |> handle_close() + defp send_reply(:close = frame, state), do: state |> send_frame(frame) |> handle_close() defp send_reply(frame, state), do: state |> send_frame(frame) |> handle_send() defp handle_send({:ok, state}), do: {:noreply, state} diff --git a/test/minch/client_test.exs b/test/minch/client_test.exs index cfe7de8..bef16a4 100644 --- a/test/minch/client_test.exs +++ b/test/minch/client_test.exs @@ -211,9 +211,12 @@ defmodule Minch.ClientTest do test "starts the close handshake for a :close frame sent with send_frame/2", ctx do assert_receive {:client, :handle_connect, _} + # suspended so the server cannot answer, and end the handshake, mid-assertions + :sys.suspend(ctx.server) assert :ok = Minch.send_frame(ctx.client, {:close, 1000, "bye"}) assert {:error, :closing} = Minch.send_frame(ctx.client, {:text, "hello"}) assert {:error, :closing} = Minch.send_frame(ctx.client, {:close, 1001, "again"}) + :sys.resume(ctx.server) assert_receive {:server, :terminate, {:remote, 1000, "bye"}} assert_receive {:client, :handle_disconnect, [{:close, 1000, "bye"}, 1, _]} end @@ -261,6 +264,18 @@ defmodule Minch.ClientTest do assert_receive {:client, :handle_disconnect, [{:close, 1000, ""}, 1, _state]} end + @tag client_state: %{opts: [close_timeout: 200]} + test "a :close frame replied during the close handshake is ignored", ctx do + assert_receive {:client, :handle_connect, _} + # suspended so the server never answers our close frame + :sys.suspend(ctx.server) + assert :ok = Minch.send_frame(ctx.client, {:close, 1000, "bye"}) + send(ctx.client, {:reply, {:close, 1001, "again"}}) + refute_receive {:client, :handle_error, _}, 50 + assert_receive {:client, :handle_disconnect, [{:close, 1000, "bye"}, 1, _state]}, 300 + :sys.resume(ctx.server) + end + @tag client_state: %{opts: [close_timeout: 200]} test "a :close result during the close handshake is ignored", ctx do assert_receive {:client, :handle_connect, _}