aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gun.erl4
-rw-r--r--src/gun_ws.erl3
-rw-r--r--test/gun_SUITE.erl29
3 files changed, 36 insertions, 0 deletions
diff --git a/src/gun.erl b/src/gun.erl
index 3eafe10..bf988da 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -769,6 +769,10 @@ ws_loop(State=#state{parent=Parent, owner=Owner, socket=Socket,
{shutdown, Owner} ->
%% @todo Protocol:shutdown? %% @todo close frame
ok;
+ {'DOWN', OwnerRef, process, Owner, Reason} ->
+ Protocol:close(owner_gone, ProtoState),
+ Transport:close(Socket),
+ error({owner_gone, Reason});
{system, From, Request} ->
sys:handle_system_msg(Request, From, Parent, ?MODULE, [],
{ws_loop, State});
diff --git a/src/gun_ws.erl b/src/gun_ws.erl
index 81682d6..6501893 100644
--- a/src/gun_ws.erl
+++ b/src/gun_ws.erl
@@ -18,6 +18,7 @@
-export([name/0]).
-export([init/7]).
-export([handle/2]).
+-export([close/2]).
-export([send/2]).
-export([down/1]).
@@ -135,6 +136,8 @@ close(Reason, State) ->
%% @todo We need to send a close frame from gun:ws_loop on close.
% Normal when Normal =:= stop; Normal =:= timeout ->
% send({close, 1000, <<>>}, State);
+ owner_gone ->
+ send({close, 1001, <<>>}, State);
{error, badframe} ->
send({close, 1002, <<>>}, State);
{error, badencoding} ->
diff --git a/test/gun_SUITE.erl b/test/gun_SUITE.erl
index dbd51b5..842d40c 100644
--- a/test/gun_SUITE.erl
+++ b/test/gun_SUITE.erl
@@ -64,6 +64,35 @@ detect_owner_gone(_) ->
error(timeout)
end.
+detect_owner_gone_ws(_) ->
+ Self = self(),
+ spawn(fun() ->
+ {ok, ConnPid} = gun:open("echo.websocket.org", 80),
+ Self ! {conn, ConnPid},
+ gun:await_up(ConnPid),
+ gun:ws_upgrade(ConnPid, "/", []),
+ receive
+ {gun_ws_upgrade, Pid, ok, _} ->
+ ok
+ after 1000 ->
+ error(timeout)
+ end
+ end),
+ Pid = receive
+ {conn, C} ->
+ C
+ after 1000 ->
+ error(timeout)
+ end,
+ Ref = monitor(process, Pid),
+ receive
+ {'DOWN', Ref, process, Pid, {{owner_gone, _}, _}} ->
+ ok
+ after 1000 ->
+ true = erlang:is_process_alive(Pid),
+ error(timeout)
+ end.
+
gone_reason(_) ->
doc("The last connection failure must be propagated."),
{ok, Pid} = gun:open("localhost", 12345, #{retry => 0}),