From 8c6adf73d9d3fa1ebb49d4b9bd71caab1815dcb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 24 Jul 2019 13:04:56 +0200 Subject: Add push_promise_start/push_promise_end events --- src/gun_default_event_h.erl | 8 ++++++++ src/gun_event.erl | 24 ++++++++++++++++++++++-- src/gun_http2.erl | 31 ++++++++++++++++++++++--------- src/gun_tcp.erl | 2 +- 4 files changed, 53 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gun_default_event_h.erl b/src/gun_default_event_h.erl index 9b56e71..25076ac 100644 --- a/src/gun_default_event_h.erl +++ b/src/gun_default_event_h.erl @@ -25,6 +25,8 @@ -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]). @@ -70,6 +72,12 @@ request_headers(_EventData, State) -> request_end(_EventData, State) -> State. +push_promise_start(_EventData, State) -> + State. + +push_promise_end(_EventData, State) -> + State. + response_start(_EventData, State) -> State. diff --git a/src/gun_event.erl b/src/gun_event.erl index 4716f47..f27d336 100644 --- a/src/gun_event.erl +++ b/src/gun_event.erl @@ -92,6 +92,28 @@ -callback request_end(request_end_event(), State) -> State. +%% push_promise_start. + +-type push_promise_start_event() :: #{ + stream_ref := reference(), + reply_to := pid() +}. + +-callback push_promise_start(push_promise_start_event(), State) -> State. + +%% push_promise_end. + +-type push_promise_end_event() :: #{ + stream_ref := reference(), + reply_to := pid(), + promised_stream_ref := reference(), + method := binary(), + uri := binary(), + headers := [{binary(), iodata()}] +}. + +-callback push_promise_end(push_promise_end_event(), State) -> State. + %% response_start. -type response_start_event() :: #{ @@ -233,7 +255,5 @@ %% @todo origin_changed %% @todo transport_changed -%% @todo push_promise_start -%% @todo push_promise_end %% @todo cancel_start %% @todo cancel_end diff --git a/src/gun_http2.erl b/src/gun_http2.erl index 55e7c06..d039ecb 100644 --- a/src/gun_http2.erl +++ b/src/gun_http2.erl @@ -115,12 +115,16 @@ parse(Data, State0=#http2_state{http2_machine=HTTP2Machine}, EvHandler, EvHandle frame(State=#http2_state{http2_machine=HTTP2Machine0}, Frame, EvHandler, EvHandlerState0) -> EvHandlerState = if - is_tuple(Frame) andalso element(1, Frame) =:= headers -> + element(1, Frame) =:= headers; element(1, Frame) =:= push_promise -> EvStreamID = element(2, Frame), case cow_http2_machine:get_stream_remote_state(EvStreamID, HTTP2Machine0) of {ok, idle} -> #stream{ref=StreamRef, reply_to=ReplyTo} = get_stream_by_id(State, EvStreamID), - EvHandler:response_start(#{ + EvCallback = case element(1, Frame) of + headers -> response_start; + push_promise -> push_promise_start + end, + EvHandler:EvCallback(#{ stream_ref => StreamRef, reply_to => ReplyTo }, EvHandlerState0); @@ -149,9 +153,9 @@ frame(State=#http2_state{http2_machine=HTTP2Machine0}, Frame, EvHandler, EvHandl {rst_stream_frame(State#http2_state{http2_machine=HTTP2Machine}, StreamID, Reason), EvHandlerState}; {ok, {push_promise, StreamID, PromisedStreamID, Headers, PseudoHeaders}, HTTP2Machine} -> - {push_promise_frame(State#http2_state{http2_machine=HTTP2Machine}, - StreamID, PromisedStreamID, Headers, PseudoHeaders), - EvHandlerState}; + push_promise_frame(State#http2_state{http2_machine=HTTP2Machine}, + StreamID, PromisedStreamID, Headers, PseudoHeaders, + EvHandler, EvHandlerState); {ok, Frame={goaway, _StreamID, _Reason, _Data}, HTTP2Machine} -> {terminate(State#http2_state{http2_machine=HTTP2Machine}, {stop, Frame, 'Server is going away.'}), @@ -277,13 +281,22 @@ rst_stream_frame(State=#http2_state{streams=Streams0}, StreamID, Reason) -> push_promise_frame(State=#http2_state{streams=Streams}, StreamID, PromisedStreamID, Headers, #{ method := Method, scheme := Scheme, - authority := Authority, path := Path}) -> + authority := Authority, path := Path}, + EvHandler, EvHandlerState0) -> #stream{ref=StreamRef, reply_to=ReplyTo} = get_stream_by_id(State, StreamID), PromisedStreamRef = make_ref(), - ReplyTo ! {gun_push, self(), StreamRef, PromisedStreamRef, Method, - iolist_to_binary([Scheme, <<"://">>, Authority, Path]), Headers}, + URI = iolist_to_binary([Scheme, <<"://">>, Authority, Path]), + ReplyTo ! {gun_push, self(), StreamRef, PromisedStreamRef, Method, URI, Headers}, + EvHandlerState = EvHandler:push_promise_end(#{ + stream_ref => StreamRef, + reply_to => ReplyTo, + promised_stream_ref => PromisedStreamRef, + method => Method, + uri => URI, + headers => Headers + }, EvHandlerState0), NewStream = #stream{id=PromisedStreamID, ref=PromisedStreamRef, reply_to=ReplyTo}, - State#http2_state{streams=[NewStream|Streams]}. + {State#http2_state{streams=[NewStream|Streams]}, EvHandlerState}. ignored_frame(State=#http2_state{http2_machine=HTTP2Machine0}) -> case cow_http2_machine:ignored_frame(HTTP2Machine0) of diff --git a/src/gun_tcp.erl b/src/gun_tcp.erl index 2d091a0..615e925 100644 --- a/src/gun_tcp.erl +++ b/src/gun_tcp.erl @@ -27,7 +27,7 @@ ip_addresses := [inet:ip_address()], port := inet:port_number(), tcp_module := module(), - tcp_opts := [gen_tcp:connect_option()] | [ssl:connect_option()] + tcp_opts := [gen_tcp:connect_option()] }. -export_type([lookup_info/0]). -- cgit v1.2.3