aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun_pool_events_h.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gun_pool_events_h.erl')
-rw-r--r--src/gun_pool_events_h.erl157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/gun_pool_events_h.erl b/src/gun_pool_events_h.erl
new file mode 100644
index 0000000..1871a00
--- /dev/null
+++ b/src/gun_pool_events_h.erl
@@ -0,0 +1,157 @@
+%% Copyright (c) 2021, Loïc Hoguin <[email protected]>
+%%
+%% Permission to use, copy, modify, and/or distribute this software for any
+%% purpose with or without fee is hereby granted, provided that the above
+%% copyright notice and this permission notice appear in all copies.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-module(gun_pool_events_h).
+
+-export([init/2]).
+-export([domain_lookup_start/2]).
+-export([domain_lookup_end/2]).
+-export([connect_start/2]).
+-export([connect_end/2]).
+-export([tls_handshake_start/2]).
+-export([tls_handshake_end/2]).
+-export([request_start/2]).
+-export([request_headers/2]).
+-export([request_end/2]).
+-export([push_promise_start/2]).
+-export([push_promise_end/2]).
+-export([response_start/2]).
+-export([response_inform/2]).
+-export([response_headers/2]).
+-export([response_trailers/2]).
+-export([response_end/2]).
+-export([ws_upgrade/2]).
+-export([ws_recv_frame_start/2]).
+-export([ws_recv_frame_header/2]).
+-export([ws_recv_frame_end/2]).
+-export([ws_send_frame_start/2]).
+-export([ws_send_frame_end/2]).
+-export([protocol_changed/2]).
+-export([origin_changed/2]).
+-export([cancel/2]).
+-export([disconnect/2]).
+-export([terminate/2]).
+
+init(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+domain_lookup_start(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+domain_lookup_end(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+connect_start(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+connect_end(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+tls_handshake_start(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+tls_handshake_end(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+request_start(Event=#{stream_ref := StreamRef}, State=#{table := Tid}) ->
+ _ = ets:update_counter(Tid, self(), +1, {self(), 0}),
+ propagate(Event, State#{
+ StreamRef => {nofin, nofin}
+ }, ?FUNCTION_NAME).
+
+request_headers(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+request_end(Event=#{stream_ref := StreamRef}, State0=#{table := Tid}) ->
+ State = case State0 of
+ #{StreamRef := {nofin, fin}} ->
+ _ = ets:update_counter(Tid, self(), -1),
+ maps:remove(StreamRef, State0);
+ #{StreamRef := {nofin, IsFin}} ->
+ State0#{StreamRef => {fin, IsFin}}
+ end,
+ propagate(Event, State, ?FUNCTION_NAME).
+
+push_promise_start(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+push_promise_end(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+response_start(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+response_inform(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+response_headers(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+response_trailers(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+response_end(Event=#{stream_ref := StreamRef}, State0=#{table := Tid}) ->
+ State = case State0 of
+ #{StreamRef := {fin, nofin}} ->
+ _ = ets:update_counter(Tid, self(), -1),
+ maps:remove(StreamRef, State0);
+ #{StreamRef := {IsFin, nofin}} ->
+ State0#{StreamRef => {IsFin, fin}}
+ end,
+ propagate(Event, State, ?FUNCTION_NAME).
+
+ws_upgrade(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+ws_recv_frame_start(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+ws_recv_frame_header(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+ws_recv_frame_end(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+ws_send_frame_start(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+ws_send_frame_end(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+protocol_changed(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+origin_changed(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+cancel(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+disconnect(Event, State=#{table := Tid}) ->
+ %% The ets:delete/2 call might fail when the pool has shut down.
+ try
+ true = ets:delete(Tid, self())
+ catch _:_ ->
+ ok
+ end,
+ propagate(Event, maps:with([event_handler, table], State), ?FUNCTION_NAME).
+
+terminate(Event, State) ->
+ propagate(Event, State, ?FUNCTION_NAME).
+
+propagate(Event, State=#{event_handler := {Mod, ModState0}}, Fun) ->
+ ModState = Mod:Fun(Event, ModState0),
+ State#{event_handler => {Mod, ModState}};
+propagate(_, State, _) ->
+ State.