aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2019-05-08 14:01:51 +0200
committerLoïc Hoguin <[email protected]>2019-05-08 14:01:51 +0200
commitcfd702a716f834c431abd46532e8cfa4debd1468 (patch)
tree3b7f76792a5459fb577e0b661c79a0f6135ca884 /src/gun.erl
parent3e62d24573c91c04eb9af5d7ba47f2c16d1948de (diff)
downloadgun-cfd702a716f834c431abd46532e8cfa4debd1468.tar.gz
gun-cfd702a716f834c431abd46532e8cfa4debd1468.tar.bz2
gun-cfd702a716f834c431abd46532e8cfa4debd1468.zip
Add event_handler with init/connect_start/connect_end
Diffstat (limited to 'src/gun.erl')
-rw-r--r--src/gun.erl80
1 files changed, 58 insertions, 22 deletions
diff --git a/src/gun.erl b/src/gun.erl
index 7376a33..e958d2e 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -106,6 +106,7 @@
-type opts() :: #{
connect_timeout => timeout(),
+ event_handler => {module(), any()},
http_opts => http_opts(),
http2_opts => http2_opts(),
protocols => [http | http2],
@@ -184,7 +185,9 @@
transport :: module(),
messages :: {atom(), atom(), atom()},
protocol :: module(),
- protocol_state :: any()
+ protocol_state :: any(),
+ event_handler :: module(),
+ event_handler_state :: any()
}).
%% Connection.
@@ -233,6 +236,8 @@ check_options([{connect_timeout, infinity}|Opts]) ->
check_options(Opts);
check_options([{connect_timeout, T}|Opts]) when is_integer(T), T >= 0 ->
check_options(Opts);
+check_options([{event_handler, {Mod, _}}|Opts]) when is_atom(Mod) ->
+ check_options(Opts);
check_options([{http_opts, ProtoOpts}|Opts]) when is_map(ProtoOpts) ->
case gun_http:check_options(ProtoOpts) of
ok ->
@@ -724,18 +729,29 @@ init({Owner, Host, Port, Opts}) ->
tls -> {<<"https">>, gun_tls}
end,
OwnerRef = monitor(process, Owner),
+ {EventHandler, EventHandlerState0} = maps:get(event_handler, Opts,
+ {gun_default_event_h, undefined}),
+ EventHandlerState = EventHandler:init(#{
+ owner => Owner,
+ transport => OriginTransport,
+ origin_scheme => OriginScheme,
+ origin_host => Host,
+ origin_port => Port,
+ opts => Opts
+ }, EventHandlerState0),
State = #state{owner=Owner, owner_ref=OwnerRef,
host=Host, port=Port, origin_scheme=OriginScheme,
origin_host=Host, origin_port=Port, opts=Opts,
- transport=Transport, messages=Transport:messages()},
+ transport=Transport, messages=Transport:messages(),
+ event_handler=EventHandler, event_handler_state=EventHandlerState},
{ok, not_connected, State,
{next_event, internal, {retries, Retry}}}.
default_transport(443) -> tls;
default_transport(_) -> tcp.
-not_connected(_, {retries, Retries},
- State=#state{host=Host, port=Port, opts=Opts, transport=Transport}) ->
+not_connected(_, {retries, Retries}, State0=#state{host=Host, port=Port, opts=Opts,
+ transport=Transport, event_handler=EventHandler, event_handler_state=EventHandlerState0}) ->
TransOpts0 = maps:get(transport_opts, Opts, []),
TransOpts1 = case Transport of
gun_tcp -> TransOpts0;
@@ -743,27 +759,47 @@ not_connected(_, {retries, Retries},
end,
TransOpts = [binary, {active, false}|TransOpts1],
ConnectTimeout = maps:get(connect_timeout, Opts, infinity),
+ ConnectEvent = #{
+ host => Host,
+ port => Port,
+ transport => Transport:name(),
+ transport_opts => TransOpts,
+ timeout => ConnectTimeout
+ },
+ EventHandlerState1 = EventHandler:connect_start(ConnectEvent, EventHandlerState0),
case Transport:connect(Host, Port, TransOpts, ConnectTimeout) of
- {ok, Socket} when Transport =:= gun_tcp ->
- Protocol = case maps:get(protocols, Opts, [http]) of
- [http] -> gun_http;
- [http2] -> gun_http2
+ {ok, Socket} ->
+ Protocol = case Transport of
+ gun_tcp ->
+ case maps:get(protocols, Opts, [http]) of
+ [http] -> gun_http;
+ [http2] -> gun_http2
+ end;
+ gun_tls ->
+ case ssl:negotiated_protocol(Socket) of
+ {ok, <<"h2">>} -> gun_http2;
+ _ -> gun_http
+ end
end,
- {next_state, connected, State,
+ EventHandlerState = EventHandler:connect_end(ConnectEvent#{
+ socket => Socket,
+ protocol => Protocol:name()
+ }, EventHandlerState1),
+ {next_state, connected, State0#state{event_handler_state=EventHandlerState},
{next_event, internal, {connected, Socket, Protocol}}};
- {ok, Socket} when Transport =:= gun_tls ->
- Protocol = case ssl:negotiated_protocol(Socket) of
- {ok, <<"h2">>} -> gun_http2;
- _ -> gun_http
- end,
- {next_state, connected, State,
- {next_event, internal, {connected, Socket, Protocol}}};
- {error, Reason} when Retries =:= 0 ->
- {stop, {shutdown, Reason}};
- {error, _Reason} ->
- Timeout = maps:get(retry_timeout, Opts, 5000),
- {keep_state, State,
- {state_timeout, Timeout, {retries, Retries - 1}}}
+ {error, Reason} ->
+ EventHandlerState = EventHandler:connect_end(ConnectEvent#{
+ error => Reason
+ }, EventHandlerState1),
+ State = State0#state{event_handler_state=EventHandlerState},
+ case Retries of
+ 0 ->
+ {stop, {shutdown, Reason}, State};
+ _ ->
+ Timeout = maps:get(retry_timeout, Opts, 5000),
+ {keep_state, State,
+ {state_timeout, Timeout, {retries, Retries - 1}}}
+ end
end;
not_connected({call, From}, {stream_info, _}, _) ->
{keep_state_and_data, {reply, From, {error, not_connected}}};