diff options
author | Loïc Hoguin <[email protected]> | 2023-01-31 11:07:31 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2024-03-26 15:53:48 +0100 |
commit | 8cb9d242b0a665cada6de8b9a9dfa329e0c06ee9 (patch) | |
tree | ae2c323c3825da367e54704ea0b9ad80096059c3 /test/cowboy_test.erl | |
parent | 3ea8395eb8f53a57acb5d3c00b99c70296e7cdbd (diff) | |
download | cowboy-8cb9d242b0a665cada6de8b9a9dfa329e0c06ee9.tar.gz cowboy-8cb9d242b0a665cada6de8b9a9dfa329e0c06ee9.tar.bz2 cowboy-8cb9d242b0a665cada6de8b9a9dfa329e0c06ee9.zip |
Initial HTTP/3 implementationhttp3
This includes Websocket over HTTP/3.
Since quicer, which provides the QUIC implementation,
is a NIF, Cowboy cannot depend directly on it. In order
to enable QUIC and HTTP/3, users have to set the
COWBOY_QUICER environment variable:
export COWBOY_QUICER=1
In order to run the test suites, the same must be done
for Gun:
export GUN_QUICER=1
HTTP/3 support is currently not available on Windows
due to compilation issues of quicer which have yet to
be looked at or resolved.
HTTP/3 support is also unavailable on the upcoming
OTP-27 due to compilation errors in quicer dependencies.
Once resolved HTTP/3 should work on OTP-27.
Because of how QUIC currently works, it's possible
that streams that get reset after sending a response
do not receive that response. The test suite was
modified to accomodate for that. A future extension
to QUIC will allow us to gracefully reset streams.
This also updates Erlang.mk.
Diffstat (limited to 'test/cowboy_test.erl')
-rw-r--r-- | test/cowboy_test.erl | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/test/cowboy_test.erl b/test/cowboy_test.erl index a8ee15b..5a8fb13 100644 --- a/test/cowboy_test.erl +++ b/test/cowboy_test.erl @@ -37,35 +37,82 @@ init_http2(Ref, ProtoOpts, Config) -> Port = ranch:get_port(Ref), [{ref, Ref}, {type, ssl}, {protocol, http2}, {port, Port}, {opts, Opts}|Config]. +%% @todo This will probably require TransOpts as argument. +init_http3(Ref, ProtoOpts, Config) -> + %% @todo Quicer does not currently support non-file cert/key, + %% so we use quicer test certificates for now. + %% @todo Quicer also does not support cacerts which means + %% we currently have no authentication based security. + DataDir = filename:dirname(filename:dirname(config(data_dir, Config))) + ++ "/rfc9114_SUITE_data", + TransOpts = #{ + socket_opts => [ + {certfile, DataDir ++ "/server.pem"}, + {keyfile, DataDir ++ "/server.key"} + ] + }, + {ok, Listener} = cowboy:start_quic(Ref, TransOpts, ProtoOpts), + {ok, {_, Port}} = quicer:sockname(Listener), + %% @todo Keep listener information around in a better place. + persistent_term:put({cowboy_test_quic, Ref}, Listener), + [{ref, Ref}, {type, quic}, {protocol, http3}, {port, Port}, {opts, TransOpts}|Config]. + +stop_group(Ref) -> + case persistent_term:get({cowboy_test_quic, Ref}, undefined) of + undefined -> + cowboy:stop_listener(Ref); + Listener -> + quicer:close_listener(Listener) + end. + %% Common group of listeners used by most suites. common_all() -> - [ + All = [ {group, http}, {group, https}, {group, h2}, {group, h2c}, + {group, h3}, {group, http_compress}, {group, https_compress}, {group, h2_compress}, - {group, h2c_compress} - ]. + {group, h2c_compress}, + {group, h3_compress} + ], + %% Don't run HTTP/3 tests on Windows for now. + case os:type() of + {win32, _} -> + All -- [{group, h3}, {group, h3_compress}]; + _ -> + All + end. common_groups(Tests) -> Opts = case os:getenv("NO_PARALLEL") of false -> [parallel]; _ -> [] end, - [ + Groups = [ {http, Opts, Tests}, {https, Opts, Tests}, {h2, Opts, Tests}, {h2c, Opts, Tests}, + {h3, Opts, Tests}, {http_compress, Opts, Tests}, {https_compress, Opts, Tests}, {h2_compress, Opts, Tests}, - {h2c_compress, Opts, Tests} - ]. + {h2c_compress, Opts, Tests}, + {h3_compress, Opts, Tests} + ], + %% Don't run HTTP/3 tests on Windows for now. + case os:type() of + {win32, _} -> + Groups -- [{h3, Opts, Tests}, {h3_compress, Opts, Tests}]; + _ -> + Groups + end. + init_common_groups(Name = http, Config, Mod) -> init_http(Name, #{ @@ -84,6 +131,10 @@ init_common_groups(Name = h2c, Config, Mod) -> env => #{dispatch => Mod:init_dispatch(Config)} }, [{flavor, vanilla}|Config]), lists:keyreplace(protocol, 1, Config1, {protocol, http2}); +init_common_groups(Name = h3, Config, Mod) -> + init_http3(Name, #{ + env => #{dispatch => Mod:init_dispatch(Config)} + }, [{flavor, vanilla}|Config]); init_common_groups(Name = http_compress, Config, Mod) -> init_http(Name, #{ env => #{dispatch => Mod:init_dispatch(Config)}, @@ -104,7 +155,12 @@ init_common_groups(Name = h2c_compress, Config, Mod) -> env => #{dispatch => Mod:init_dispatch(Config)}, stream_handlers => [cowboy_compress_h, cowboy_stream_h] }, [{flavor, compress}|Config]), - lists:keyreplace(protocol, 1, Config1, {protocol, http2}). + lists:keyreplace(protocol, 1, Config1, {protocol, http2}); +init_common_groups(Name = h3_compress, Config, Mod) -> + init_http3(Name, #{ + env => #{dispatch => Mod:init_dispatch(Config)}, + stream_handlers => [cowboy_compress_h, cowboy_stream_h] + }, [{flavor, compress}|Config]). %% Support functions for testing using Gun. @@ -114,7 +170,7 @@ gun_open(Config) -> gun_open(Config, Opts) -> TlsOpts = case proplists:get_value(no_cert, Config, false) of true -> [{verify, verify_none}]; - false -> ct_helper:get_certs_from_ets() + false -> ct_helper:get_certs_from_ets() %% @todo Wrong in current quicer. end, {ok, ConnPid} = gun:open("localhost", config(port, Config), Opts#{ retry => 0, |