aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2020-07-17 14:05:43 +0200
committerLoïc Hoguin <[email protected]>2020-09-21 15:51:56 +0200
commitd7481d5f593f48327d16c29b48a74e49c7581e0a (patch)
tree044bd6efdf33a7d1f2cafe889af5626b2c2c0d97
parent510d49d8ef0a46e90374c3230f28b5354115293f (diff)
downloadgun-d7481d5f593f48327d16c29b48a74e49c7581e0a.tar.gz
gun-d7481d5f593f48327d16c29b48a74e49c7581e0a.tar.bz2
gun-d7481d5f593f48327d16c29b48a74e49c7581e0a.zip
Improve HTTP/2 CONNECT to non-HTTP origin
Now has a proper StreamRef given to it by the CONNECT stream.
-rw-r--r--src/gun_http2.erl4
-rw-r--r--src/gun_raw.erl10
-rw-r--r--test/raw_SUITE.erl43
3 files changed, 34 insertions, 23 deletions
diff --git a/src/gun_http2.erl b/src/gun_http2.erl
index 0dad3d9..e1a9873 100644
--- a/src/gun_http2.erl
+++ b/src/gun_http2.erl
@@ -407,7 +407,9 @@ headers_frame(State0=#http2_state{content_handlers=Handlers0, commands_queue=Com
stream_ref => StreamRef
},
OriginTransport = gun_tcp_proxy,
- {_, ProtoState} = Protocol:init(ReplyTo, OriginSocket, OriginTransport, ProtoOpts),
+ {_, ProtoState} = Protocol:init(ReplyTo, OriginSocket, OriginTransport,
+ %% @todo We are giving the wrong StreamRef we need to give the list (if any).
+ ProtoOpts#{stream_ref => StreamRef}),
%% @todo EvHandlerState = EvHandler:protocol_changed(#{protocol => Protocol:name()}, EvHandlerState0),
%% @todo What about keepalive?
{store_stream(State, Stream#stream{tunnel={Protocol, ProtoState,
diff --git a/src/gun_raw.erl b/src/gun_raw.erl
index bef2c1c..369353e 100644
--- a/src/gun_raw.erl
+++ b/src/gun_raw.erl
@@ -26,6 +26,7 @@
%% @todo down
-record(raw_state, {
+ ref :: reference() | undefined,
reply_to :: pid(),
socket :: inet:socket() | ssl:sslsocket(),
transport :: module()
@@ -39,12 +40,13 @@ name() -> raw.
opts_name() -> raw_opts.
has_keepalive() -> false.
-init(ReplyTo, Socket, Transport, _Opts) ->
- {connected_data_only, #raw_state{reply_to=ReplyTo, socket=Socket, transport=Transport}}.
+init(ReplyTo, Socket, Transport, Opts) ->
+ StreamRef = maps:get(stream_ref, Opts, undefined),
+ {connected_data_only, #raw_state{ref=StreamRef, reply_to=ReplyTo, socket=Socket, transport=Transport}}.
-handle(Data, State=#raw_state{reply_to=ReplyTo}, _, EvHandlerState) ->
+handle(Data, State=#raw_state{ref=StreamRef, reply_to=ReplyTo}, _, EvHandlerState) ->
%% When we take over the entire connection there is no stream reference.
- ReplyTo ! {gun_data, self(), undefined, nofin, Data},
+ ReplyTo ! {gun_data, self(), StreamRef, nofin, Data},
{{state, State}, EvHandlerState}.
%% We can always close immediately.
diff --git a/test/raw_SUITE.erl b/test/raw_SUITE.erl
index c3eec1d..29717e6 100644
--- a/test/raw_SUITE.erl
+++ b/test/raw_SUITE.erl
@@ -188,13 +188,13 @@ connect_raw_reply_to(_) ->
h2_connect_tcp_raw_tcp(_) ->
doc("Use CONNECT over clear HTTP/2 to connect to a remote endpoint using the raw protocol over TCP."),
- do_h2_connect_raw(tcp, tcp).
+ do_h2_connect_raw(tcp, <<"http">>, tcp).
h2_connect_tls_raw_tcp(_) ->
doc("Use CONNECT over secure HTTP/2 to connect to a remote endpoint using the raw protocol over TCP."),
- do_h2_connect_raw(tcp, tls).
+ do_h2_connect_raw(tcp, <<"https">>, tls).
-do_h2_connect_raw(OriginTransport, ProxyTransport) ->
+do_h2_connect_raw(OriginTransport, ProxyScheme, ProxyTransport) ->
{ok, OriginPid, OriginPort} = init_origin(OriginTransport, raw, fun do_echo/3),
{ok, ProxyPid, ProxyPort} = rfc7540_SUITE:do_proxy_start(ProxyTransport, [
{proxy_stream, 1, 200, [], 0, undefined}
@@ -219,21 +219,28 @@ do_h2_connect_raw(OriginTransport, ProxyTransport) ->
{response, nofin, 200, _} = gun:await(ConnPid, StreamRef),
handshake_completed = receive_from(OriginPid),
gun:data(ConnPid, StreamRef, nofin, <<"Hello world!">>),
- {data, nofin, <<"Hello world!">>} = gun:await(ConnPid, undefined),
-%% @todo
-% #{
-% transport := OriginTransport,
-% protocol := raw,
-% origin_scheme := _, %% @todo This should be 'undefined'.
-% origin_host := "localhost",
-% origin_port := OriginPort,
-% intermediaries := [#{
-% type := connect,
-% host := "localhost",
-% port := ProxyPort,
-% transport := ProxyTransport,
-% protocol := http
-% }]} = gun:info(ConnPid),
+ {data, nofin, <<"Hello world!">>} = gun:await(ConnPid, StreamRef),
+ #{
+ transport := ProxyTransport,
+ protocol := http2,
+ origin_scheme := ProxyScheme,
+ origin_host := "localhost",
+ origin_port := ProxyPort,
+ intermediaries := []
+ } = gun:info(ConnPid),
+ Self = self(),
+ {ok, #{
+ ref := StreamRef,
+ reply_to := Self,
+ state := running,
+ tunnel := #{
+ transport := OriginTransport,
+ protocol := raw,
+ origin_scheme := _, %% @todo This should be 'undefined'.
+ origin_host := "localhost",
+ origin_port := OriginPort
+ }
+ }} = gun:stream_info(ConnPid, StreamRef),
gun:close(ConnPid).
http11_upgrade_raw_tcp(_) ->