aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/rfc7540_SUITE.erl52
1 files changed, 52 insertions, 0 deletions
diff --git a/test/rfc7540_SUITE.erl b/test/rfc7540_SUITE.erl
index 8669b13..c8aff46 100644
--- a/test/rfc7540_SUITE.erl
+++ b/test/rfc7540_SUITE.erl
@@ -648,3 +648,55 @@ do_cowboy_origin(OriginTransport, OriginProtocol) ->
tls -> gun_test:init_cowboy_tls(Ref, ProtoOpts, [])
end,
{ok, Ref, Port}.
+
+connect_http_via_http_via_h2c(_) ->
+ doc("CONNECT can be used to establish a TCP connection "
+ "to an HTTP/1.1 server via a tunnel going through both "
+ "an HTTP/2 and an HTTP/1.1 proxy. (RFC7231 4.3.6)"),
+ do_connect_via_multiple_proxies(tcp, http, tcp, http, tcp).
+
+do_connect_via_multiple_proxies(OriginTransport, OriginProtocol,
+ Proxy2Transport, Proxy2Protocol, Proxy1Transport) ->
+ {ok, Ref, OriginPort} = do_cowboy_origin(OriginTransport, OriginProtocol),
+ try
+ {ok, Proxy1Pid, Proxy1Port} = do_proxy_start(Proxy1Transport, [
+ #proxy_stream{id=1, status=200}
+ ]),
+ {ok, Proxy2Pid, Proxy2Port} = rfc7231_SUITE:do_proxy_start(Proxy2Transport),
+ %% First proxy.
+ {ok, ConnPid} = gun:open("localhost", Proxy1Port, #{
+ protocols => [http2]
+ }),
+ {ok, http2} = gun:await_up(ConnPid),
+ %% Second proxy.
+ StreamRef1 = gun:connect(ConnPid, #{
+ host => "localhost",
+ port => Proxy2Port,
+ protocols => [Proxy2Protocol]
+ }, []),
+ handshake_completed = receive_from(Proxy1Pid),
+ Authority1 = iolist_to_binary(["localhost:", integer_to_binary(Proxy2Port)]),
+ {request, #{
+ <<":method">> := <<"CONNECT">>,
+ <<":authority">> := Authority1
+ }} = receive_from(Proxy1Pid),
+ {response, nofin, 200, _} = gun:await(ConnPid, StreamRef1),
+ {up, Proxy2Protocol} = gun:await(ConnPid, StreamRef1),
+ %% Origin.
+ StreamRef2 = gun:connect(ConnPid, #{
+ host => "localhost",
+ port => OriginPort,
+ protocols => [OriginProtocol]
+ }, [], #{tunnel => StreamRef1}),
+ Authority2 = iolist_to_binary(["localhost:", integer_to_binary(OriginPort)]),
+ {request, <<"CONNECT">>, Authority2, 'HTTP/1.1', _} = receive_from(Proxy2Pid),
+ %% @todo OK there's a mismatch between HTTP/1.1 (fin) and HTTP/2 (nofin).
+ {response, fin, 200, _} = gun:await(ConnPid, StreamRef2),
+ {up, OriginProtocol} = gun:await(ConnPid, StreamRef2),
+ %% Tunneled request to the origin.
+ ProxiedStreamRef = gun:get(ConnPid, "/proxied", [], #{tunnel => StreamRef2}),
+ {response, nofin, 200, _} = gun:await(ConnPid, ProxiedStreamRef),
+ gun:close(ConnPid)
+ after
+ cowboy:stop_listener(Ref)
+ end.