|
@@ -31,50 +31,42 @@ groups() ->
|
|
|
|
|
|
%% We set this module as a logger in order to silence expected errors.
|
|
|
init_per_group(Name = http, Config) ->
|
|
|
- cowboy_test:init_http(Name, #{
|
|
|
- logger => ?MODULE,
|
|
|
- stream_handlers => [stream_handler_h]
|
|
|
- }, Config);
|
|
|
+ cowboy_test:init_http(Name, init_plain_opts(), Config);
|
|
|
init_per_group(Name = https, Config) ->
|
|
|
- cowboy_test:init_https(Name, #{
|
|
|
- logger => ?MODULE,
|
|
|
- stream_handlers => [stream_handler_h]
|
|
|
- }, Config);
|
|
|
+ cowboy_test:init_https(Name, init_plain_opts(), Config);
|
|
|
init_per_group(Name = h2, Config) ->
|
|
|
- cowboy_test:init_http2(Name, #{
|
|
|
- logger => ?MODULE,
|
|
|
- stream_handlers => [stream_handler_h]
|
|
|
- }, Config);
|
|
|
+ cowboy_test:init_http2(Name, init_plain_opts(), Config);
|
|
|
init_per_group(Name = h2c, Config) ->
|
|
|
- Config1 = cowboy_test:init_http(Name, #{
|
|
|
- logger => ?MODULE,
|
|
|
- stream_handlers => [stream_handler_h]
|
|
|
- }, Config),
|
|
|
+ Config1 = cowboy_test:init_http(Name, init_plain_opts(), Config),
|
|
|
lists:keyreplace(protocol, 1, Config1, {protocol, http2});
|
|
|
+init_per_group(Name = h3, Config) ->
|
|
|
+ cowboy_test:init_http3(Name, init_plain_opts(), Config);
|
|
|
init_per_group(Name = http_compress, Config) ->
|
|
|
- cowboy_test:init_http(Name, #{
|
|
|
- logger => ?MODULE,
|
|
|
- stream_handlers => [cowboy_compress_h, stream_handler_h]
|
|
|
- }, Config);
|
|
|
+ cowboy_test:init_http(Name, init_compress_opts(), Config);
|
|
|
init_per_group(Name = https_compress, Config) ->
|
|
|
- cowboy_test:init_https(Name, #{
|
|
|
- logger => ?MODULE,
|
|
|
- stream_handlers => [cowboy_compress_h, stream_handler_h]
|
|
|
- }, Config);
|
|
|
+ cowboy_test:init_https(Name, init_compress_opts(), Config);
|
|
|
init_per_group(Name = h2_compress, Config) ->
|
|
|
- cowboy_test:init_http2(Name, #{
|
|
|
- logger => ?MODULE,
|
|
|
- stream_handlers => [cowboy_compress_h, stream_handler_h]
|
|
|
- }, Config);
|
|
|
+ cowboy_test:init_http2(Name, init_compress_opts(), Config);
|
|
|
init_per_group(Name = h2c_compress, Config) ->
|
|
|
- Config1 = cowboy_test:init_http(Name, #{
|
|
|
- logger => ?MODULE,
|
|
|
- stream_handlers => [cowboy_compress_h, stream_handler_h]
|
|
|
- }, Config),
|
|
|
- lists:keyreplace(protocol, 1, Config1, {protocol, http2}).
|
|
|
+ Config1 = cowboy_test:init_http(Name, init_compress_opts(), Config),
|
|
|
+ lists:keyreplace(protocol, 1, Config1, {protocol, http2});
|
|
|
+init_per_group(Name = h3_compress, Config) ->
|
|
|
+ cowboy_test:init_http3(Name, init_compress_opts(), Config).
|
|
|
|
|
|
end_per_group(Name, _) ->
|
|
|
- cowboy:stop_listener(Name).
|
|
|
+ cowboy_test:stop_group(Name).
|
|
|
+
|
|
|
+init_plain_opts() ->
|
|
|
+ #{
|
|
|
+ logger => ?MODULE,
|
|
|
+ stream_handlers => [stream_handler_h]
|
|
|
+ }.
|
|
|
+
|
|
|
+init_compress_opts() ->
|
|
|
+ #{
|
|
|
+ logger => ?MODULE,
|
|
|
+ stream_handlers => [cowboy_compress_h, stream_handler_h]
|
|
|
+ }.
|
|
|
|
|
|
%% Logger function silencing the expected crashes.
|
|
|
|
|
@@ -99,15 +91,20 @@ crash_in_init(Config) ->
|
|
|
%% Confirm terminate/3 is NOT called. We have no state to give to it.
|
|
|
receive {Self, Pid, terminate, _, _, _} -> error(terminate) after 1000 -> ok end,
|
|
|
%% Confirm early_error/5 is called in HTTP/1.1's case.
|
|
|
- %% HTTP/2 does not send a response back so there is no early_error call.
|
|
|
+ %% HTTP/2 and HTTP/3 do not send a response back so there is no early_error call.
|
|
|
case config(protocol, Config) of
|
|
|
http -> receive {Self, Pid, early_error, _, _, _, _, _} -> ok after 1000 -> error(timeout) end;
|
|
|
- http2 -> ok
|
|
|
+ http2 -> ok;
|
|
|
+ http3 -> ok
|
|
|
end,
|
|
|
- %% Receive a 500 error response.
|
|
|
- case gun:await(ConnPid, Ref) of
|
|
|
- {response, fin, 500, _} -> ok;
|
|
|
- {error, {stream_error, {stream_error, internal_error, _}}} -> ok
|
|
|
+ do_await_internal_error(ConnPid, Ref, Config).
|
|
|
+
|
|
|
+do_await_internal_error(ConnPid, Ref, Config) ->
|
|
|
+ Protocol = config(protocol, Config),
|
|
|
+ case {Protocol, gun:await(ConnPid, Ref)} of
|
|
|
+ {http, {response, fin, 500, _}} -> ok;
|
|
|
+ {http2, {error, {stream_error, {stream_error, internal_error, _}}}} -> ok;
|
|
|
+ {http3, {error, {stream_error, {stream_error, h3_internal_error, _}}}} -> ok
|
|
|
end.
|
|
|
|
|
|
crash_in_data(Config) ->
|
|
@@ -126,11 +123,7 @@ crash_in_data(Config) ->
|
|
|
gun:data(ConnPid, Ref, fin, <<"Hello!">>),
|
|
|
%% Confirm terminate/3 is called, indicating the stream ended.
|
|
|
receive {Self, Pid, terminate, _, _, _} -> ok after 1000 -> error(timeout) end,
|
|
|
- %% Receive a 500 error response.
|
|
|
- case gun:await(ConnPid, Ref) of
|
|
|
- {response, fin, 500, _} -> ok;
|
|
|
- {error, {stream_error, {stream_error, internal_error, _}}} -> ok
|
|
|
- end.
|
|
|
+ do_await_internal_error(ConnPid, Ref, Config).
|
|
|
|
|
|
crash_in_info(Config) ->
|
|
|
doc("Confirm an error is sent when a stream handler crashes in info/3."),
|
|
@@ -144,14 +137,14 @@ crash_in_info(Config) ->
|
|
|
%% Confirm init/3 is called.
|
|
|
Pid = receive {Self, P, init, _, _, _} -> P after 1000 -> error(timeout) end,
|
|
|
%% Send a message to make the stream handler crash.
|
|
|
- Pid ! {{Pid, 1}, crash},
|
|
|
+ StreamID = case config(protocol, Config) of
|
|
|
+ http3 -> 0;
|
|
|
+ _ -> 1
|
|
|
+ end,
|
|
|
+ Pid ! {{Pid, StreamID}, crash},
|
|
|
%% Confirm terminate/3 is called, indicating the stream ended.
|
|
|
receive {Self, Pid, terminate, _, _, _} -> ok after 1000 -> error(timeout) end,
|
|
|
- %% Receive a 500 error response.
|
|
|
- case gun:await(ConnPid, Ref) of
|
|
|
- {response, fin, 500, _} -> ok;
|
|
|
- {error, {stream_error, {stream_error, internal_error, _}}} -> ok
|
|
|
- end.
|
|
|
+ do_await_internal_error(ConnPid, Ref, Config).
|
|
|
|
|
|
crash_in_terminate(Config) ->
|
|
|
doc("Confirm the state is correct when a stream handler crashes in terminate/3."),
|
|
@@ -185,10 +178,12 @@ crash_in_terminate(Config) ->
|
|
|
{ok, <<"Hello world!">>} = gun:await_body(ConnPid, Ref2),
|
|
|
ok.
|
|
|
|
|
|
+%% @todo The callbacks ARE used for HTTP/2 and HTTP/3 CONNECT/TRACE requests.
|
|
|
crash_in_early_error(Config) ->
|
|
|
case config(protocol, Config) of
|
|
|
http -> do_crash_in_early_error(Config);
|
|
|
- http2 -> doc("The callback early_error/5 is not currently used for HTTP/2.")
|
|
|
+ http2 -> doc("The callback early_error/5 is not currently used for HTTP/2.");
|
|
|
+ http3 -> doc("The callback early_error/5 is not currently used for HTTP/3.")
|
|
|
end.
|
|
|
|
|
|
do_crash_in_early_error(Config) ->
|
|
@@ -225,10 +220,12 @@ do_crash_in_early_error(Config) ->
|
|
|
{response, fin, 500, _} = gun:await(ConnPid, Ref2),
|
|
|
ok.
|
|
|
|
|
|
+%% @todo The callbacks ARE used for HTTP/2 and HTTP/3 CONNECT/TRACE requests.
|
|
|
crash_in_early_error_fatal(Config) ->
|
|
|
case config(protocol, Config) of
|
|
|
http -> do_crash_in_early_error_fatal(Config);
|
|
|
- http2 -> doc("The callback early_error/5 is not currently used for HTTP/2.")
|
|
|
+ http2 -> doc("The callback early_error/5 is not currently used for HTTP/2.");
|
|
|
+ http3 -> doc("The callback early_error/5 is not currently used for HTTP/3.")
|
|
|
end.
|
|
|
|
|
|
do_crash_in_early_error_fatal(Config) ->
|
|
@@ -262,7 +259,8 @@ early_error_stream_error_reason(Config) ->
|
|
|
%% reason in both protocols.
|
|
|
{Method, Headers, Status, Error} = case config(protocol, Config) of
|
|
|
http -> {<<"GET">>, [{<<"host">>, <<"host:port">>}], 400, protocol_error};
|
|
|
- http2 -> {<<"TRACE">>, [], 501, no_error}
|
|
|
+ http2 -> {<<"TRACE">>, [], 501, no_error};
|
|
|
+ http3 -> {<<"TRACE">>, [], 501, h3_no_error}
|
|
|
end,
|
|
|
Ref = gun:request(ConnPid, Method, "/long_polling", [
|
|
|
{<<"accept-encoding">>, <<"gzip">>},
|
|
@@ -418,21 +416,24 @@ switch_protocol_after_headers(Config) ->
|
|
|
case config(protocol, Config) of
|
|
|
http -> do_switch_protocol_after_response(
|
|
|
<<"switch_protocol_after_headers">>, Config);
|
|
|
- http2 -> doc("The switch_protocol command is not currently supported for HTTP/2.")
|
|
|
+ http2 -> doc("The switch_protocol command is not currently supported for HTTP/2.");
|
|
|
+ http3 -> doc("The switch_protocol command is not currently supported for HTTP/3.")
|
|
|
end.
|
|
|
|
|
|
switch_protocol_after_headers_data(Config) ->
|
|
|
case config(protocol, Config) of
|
|
|
http -> do_switch_protocol_after_response(
|
|
|
<<"switch_protocol_after_headers_data">>, Config);
|
|
|
- http2 -> doc("The switch_protocol command is not currently supported for HTTP/2.")
|
|
|
+ http2 -> doc("The switch_protocol command is not currently supported for HTTP/2.");
|
|
|
+ http3 -> doc("The switch_protocol command is not currently supported for HTTP/3.")
|
|
|
end.
|
|
|
|
|
|
switch_protocol_after_response(Config) ->
|
|
|
case config(protocol, Config) of
|
|
|
http -> do_switch_protocol_after_response(
|
|
|
<<"switch_protocol_after_response">>, Config);
|
|
|
- http2 -> doc("The switch_protocol command is not currently supported for HTTP/2.")
|
|
|
+ http2 -> doc("The switch_protocol command is not currently supported for HTTP/2.");
|
|
|
+ http3 -> doc("The switch_protocol command is not currently supported for HTTP/3.")
|
|
|
end.
|
|
|
|
|
|
do_switch_protocol_after_response(TestCase, Config) ->
|
|
@@ -502,7 +503,12 @@ terminate_on_stop(Config) ->
|
|
|
{response, fin, 204, _} = gun:await(ConnPid, Ref),
|
|
|
%% Confirm the stream is still alive even though we
|
|
|
%% received the response fully, and tell it to stop.
|
|
|
- Pid ! {{Pid, 1}, please_stop},
|
|
|
+ StreamID = case config(protocol, Config) of
|
|
|
+ http -> 1;
|
|
|
+ http2 -> 1;
|
|
|
+ http3 -> 0
|
|
|
+ end,
|
|
|
+ Pid ! {{Pid, StreamID}, please_stop},
|
|
|
receive {Self, Pid, info, _, please_stop, _} -> ok after 1000 -> error(timeout) end,
|
|
|
%% Confirm terminate/3 is called.
|
|
|
receive {Self, Pid, terminate, _, _, _} -> ok after 1000 -> error(timeout) end,
|
|
@@ -511,7 +517,8 @@ terminate_on_stop(Config) ->
|
|
|
terminate_on_switch_protocol(Config) ->
|
|
|
case config(protocol, Config) of
|
|
|
http -> do_terminate_on_switch_protocol(Config);
|
|
|
- http2 -> doc("The switch_protocol command is not currently supported for HTTP/2.")
|
|
|
+ http2 -> doc("The switch_protocol command is not currently supported for HTTP/2.");
|
|
|
+ http3 -> doc("The switch_protocol command is not currently supported for HTTP/3.")
|
|
|
end.
|
|
|
|
|
|
do_terminate_on_switch_protocol(Config) ->
|