diff options
author | Tony Han <[email protected]> | 2019-04-28 11:03:31 +0800 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2019-07-27 10:48:32 +0200 |
commit | 02fed8a1422c9ca6f33127509eebd244f0a74d3f (patch) | |
tree | 72c46e290890bd1e71d2672350b5a06be3fc2d3e | |
parent | cd50a0d3f42afd5e12a1470902a60b4fa9d84f73 (diff) | |
download | gun-02fed8a1422c9ca6f33127509eebd244f0a74d3f.tar.gz gun-02fed8a1422c9ca6f33127509eebd244f0a74d3f.tar.bz2 gun-02fed8a1422c9ca6f33127509eebd244f0a74d3f.zip |
Postpone operations until connected
-rw-r--r-- | src/gun.erl | 3 | ||||
-rw-r--r-- | test/gun_SUITE.erl | 20 |
2 files changed, 23 insertions, 0 deletions
diff --git a/src/gun.erl b/src/gun.erl index a548a5d..bb275f5 100644 --- a/src/gun.erl +++ b/src/gun.erl @@ -1061,6 +1061,9 @@ handle_common(cast, Any, _, #state{owner=Owner}) when element(2, Any) =/= Owner element(2, Any) ! {gun_error, self(), {notowner, "Operations are restricted to the owner of the connection."}}, keep_state_and_data; +%% We postpone all HTTP/Websocket operations until we are connected. +handle_common(cast, _, StateName, _) when StateName =/= connected -> + {keep_state_and_data, postpone}; handle_common(Type, Event, StateName, StateData) -> error_logger:error_msg("Unexpected event in state ~p of type ~p:~n~w~n~p~n", [StateName, Type, Event, StateData]), diff --git a/test/gun_SUITE.erl b/test/gun_SUITE.erl index 57d0bf1..4f99594 100644 --- a/test/gun_SUITE.erl +++ b/test/gun_SUITE.erl @@ -277,6 +277,26 @@ map_headers(_) -> [<<"user-agent: Gun/map-headers">>] = [L || <<"user-agent: ", _/bits>> = L <- Lines], gun:close(Pid). +postpone_request_while_not_connected(_) -> + doc("Ensure Gun doesn't raise error when requesting in retries"), + %% Try connecting to a server that isn't up yet. + {ok, Pid} = gun:open("localhost", 23456, #{retry => 5, retry_timeout => 1000}), + _ = gun:get(Pid, "/postponed"), + %% Make sure the connect call completed and we are waiting for a retry. + Timeout = case os:type() of + {win32, _} -> 2500; + _ -> 500 + end, + timer:sleep(Timeout), + %% Start the server so that next retry will result in the client connecting successfully. + {ok, ListenSocket} = gen_tcp:listen(23456, [binary, {active, false}]), + {ok, ClientSocket} = gen_tcp:accept(ListenSocket, 5000), + %% The client should now be up. + {ok, http} = gun:await_up(Pid), + %% The server receives the postponed request. + {ok, <<"GET /postponed HTTP/1.1\r\n", _/bits>>} = gen_tcp:recv(ClientSocket, 0, 5000), + ok. + reply_to(_) -> doc("The reply_to option allows using a separate process for requests."), do_reply_to(http), |