You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2026/10/05 23:21:52 UTC

(couchdb-gun) 02/16: Do not crash when set_owner is called after shutdown

This is an automated email from the ASF dual-hosted git repository.

nickva pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb-gun.git

commit 99ab87bf59ec3427d39458e1c2103be21b4c2d76
Author: Loïc Hoguin <es...@ninenines.eu>
AuthorDate: Fri Sep 25 13:59:44 2026 +0200

    Do not crash when set_owner is called after shutdown
---
 src/gun.erl        |  2 +-
 test/gun_SUITE.erl | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/gun.erl b/src/gun.erl
index 003864d..d03e43a 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -1820,7 +1820,7 @@ handle_common(cast, {set_owner, CurrentOwner, NewOwner}, _,
 handle_common(cast, {set_owner, CurrentOwner, _}, _, #state{owner=CurrentOwner}) ->
 	reply(CurrentOwner, {gun_error, self(), {badstate,
 		"The owner of the connection cannot be changed when the connection is shutting down."}}),
-	keep_state_and_state;
+	keep_state_and_data;
 handle_common(cast, shutdown, StateName, State=#state{
 		status=Status, socket=Socket, transport=Transport, protocol=Protocol}) ->
 	case {Socket, Protocol} of
diff --git a/test/gun_SUITE.erl b/test/gun_SUITE.erl
index 1535001..65c0d5b 100644
--- a/test/gun_SUITE.erl
+++ b/test/gun_SUITE.erl
@@ -806,6 +806,34 @@ set_owner(_) ->
 	#{owner := Self} = gun:info(ConnPid),
 	gun:close(ConnPid).
 
+set_owner_after_shutdown_no_crash(_) ->
+	doc("set_owner during shutdown must reply with an error "
+		"instead of crashing the connection."),
+	{ok, _, OriginPort} = init_origin(tcp, http,
+		fun(_, _, _, _) -> timer:sleep(5000) end),
+	{ok, ConnPid} = gun:open("localhost", OriginPort, #{
+		http_opts => #{closing_timeout => 5000}
+	}),
+	{ok, http} = gun:await_up(ConnPid),
+	_ = gun:get(ConnPid, "/"),
+	MRef = monitor(process, ConnPid),
+	ok = gun:shutdown(ConnPid),
+	gun:set_owner(ConnPid, self()),
+	receive
+		{gun_error, ConnPid, {badstate, _}} ->
+			ok
+	after 5000 ->
+		error(timeout)
+	end,
+	receive
+		{'DOWN', MRef, process, ConnPid, Reason} ->
+			error({unexpected_crash, Reason})
+	after 500 ->
+		ok
+	end,
+	demonitor(MRef, [flush]),
+	gun:close(ConnPid).
+
 shutdown_reason(_) ->
 	doc("The last connection failure must be propagated."),
 	do_shutdown_reason().