aboutsummaryrefslogtreecommitdiffstats
path: root/test/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'test/handlers')
-rw-r--r--test/handlers/content_types_provided_h.erl5
-rw-r--r--test/handlers/crash_h.erl3
-rw-r--r--test/handlers/resp_h.erl15
-rw-r--r--test/handlers/wt_echo_h.erl103
4 files changed, 126 insertions, 0 deletions
diff --git a/test/handlers/content_types_provided_h.erl b/test/handlers/content_types_provided_h.erl
index 5220c19..397026b 100644
--- a/test/handlers/content_types_provided_h.erl
+++ b/test/handlers/content_types_provided_h.erl
@@ -11,9 +11,14 @@
init(Req, Opts) ->
{cowboy_rest, Req, Opts}.
+content_types_provided(Req=#{qs := <<"invalid-type">>}, State) ->
+ ct_helper:ignore(cowboy_rest, normalize_content_types, 2),
+ {[{{'*', '*', '*'}, get_text_plain}], Req, State};
content_types_provided(Req=#{qs := <<"wildcard-param">>}, State) ->
{[{{<<"text">>, <<"plain">>, '*'}, get_text_plain}], Req, State}.
+get_text_plain(Req=#{qs := <<"invalid-type">>}, State) ->
+ {<<"invalid-type">>, Req, State};
get_text_plain(Req=#{qs := <<"wildcard-param">>}, State) ->
{_, _, Param} = maps:get(media_type, Req),
Body = if
diff --git a/test/handlers/crash_h.erl b/test/handlers/crash_h.erl
index b687aba..57d4d85 100644
--- a/test/handlers/crash_h.erl
+++ b/test/handlers/crash_h.erl
@@ -7,6 +7,9 @@
-export([init/2]).
-spec init(_, _) -> no_return().
+init(_, external_exit) ->
+ ct_helper:ignore(?MODULE, init, 2),
+ exit(self(), ct_helper_ignore);
init(_, no_reply) ->
ct_helper:ignore(?MODULE, init, 2),
error(crash);
diff --git a/test/handlers/resp_h.erl b/test/handlers/resp_h.erl
index 6e9b5f7..d1c46e0 100644
--- a/test/handlers/resp_h.erl
+++ b/test/handlers/resp_h.erl
@@ -43,12 +43,27 @@ do(<<"set_resp_headers">>, Req0, Opts) ->
<<"content-encoding">> => <<"compress">>
}, Req0),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
+do(<<"set_resp_headers_list">>, Req0, Opts) ->
+ Req = cowboy_req:set_resp_headers([
+ {<<"content-type">>, <<"text/plain">>},
+ {<<"test-header">>, <<"one">>},
+ {<<"content-encoding">>, <<"compress">>},
+ {<<"test-header">>, <<"two">>}
+ ], Req0),
+ {ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"set_resp_headers_cookie">>, Req0, Opts) ->
ct_helper:ignore(cowboy_req, set_resp_headers, 2),
Req = cowboy_req:set_resp_headers(#{
<<"set-cookie">> => <<"name=value">>
}, Req0),
{ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
+do(<<"set_resp_headers_list_cookie">>, Req0, Opts) ->
+ ct_helper:ignore(cowboy_req, set_resp_headers_list, 3),
+ Req = cowboy_req:set_resp_headers([
+ {<<"set-cookie">>, <<"name=value">>},
+ {<<"set-cookie">>, <<"name2=value2">>}
+ ], Req0),
+ {ok, cowboy_req:reply(200, #{}, "OK", Req), Opts};
do(<<"set_resp_headers_http11">>, Req0, Opts) ->
Req = cowboy_req:set_resp_headers(#{
<<"connection">> => <<"custom-header, close">>,
diff --git a/test/handlers/wt_echo_h.erl b/test/handlers/wt_echo_h.erl
new file mode 100644
index 0000000..5198565
--- /dev/null
+++ b/test/handlers/wt_echo_h.erl
@@ -0,0 +1,103 @@
+%% This module echoes client events back,
+%% including creating new streams.
+
+-module(wt_echo_h).
+-behavior(cowboy_webtransport).
+
+-export([init/2]).
+-export([webtransport_handle/2]).
+-export([webtransport_info/2]).
+-export([terminate/3]).
+
+%% -define(DEBUG, 1).
+-ifdef(DEBUG).
+-define(LOG(Fmt, Args), ct:pal(Fmt, Args)).
+-else.
+-define(LOG(Fmt, Args), _ = Fmt, _ = Args, ok).
+-endif.
+
+init(Req0, _) ->
+ ?LOG("WT init ~p~n", [Req0]),
+ Req = case cowboy_req:parse_header(<<"wt-available-protocols">>, Req0) of
+ undefined ->
+ Req0;
+ [Protocol|_] ->
+ cowboy_req:set_resp_header(<<"wt-protocol">>, cow_http_hd:wt_protocol(Protocol), Req0)
+ end,
+ {cowboy_webtransport, Req, #{}}.
+
+webtransport_handle(Event = {stream_open, StreamID, bidi}, Streams) ->
+ ?LOG("WT handle ~p~n", [Event]),
+ {[], Streams#{StreamID => bidi}};
+webtransport_handle(Event = {stream_open, StreamID, unidi}, Streams) ->
+ ?LOG("WT handle ~p~n", [Event]),
+ OpenStreamRef = make_ref(),
+ {[{open_stream, OpenStreamRef, unidi, <<>>}], Streams#{
+ StreamID => {unidi_remote, OpenStreamRef},
+ OpenStreamRef => {unidi_local, StreamID}}};
+webtransport_handle(Event = {opened_stream_id, OpenStreamRef, OpenStreamID}, Streams) ->
+ ?LOG("WT handle ~p~n", [Event]),
+ case Streams of
+ #{OpenStreamRef := bidi} ->
+ {[], maps:remove(OpenStreamRef, Streams#{
+ OpenStreamID => bidi
+ })};
+ #{OpenStreamRef := {unidi_local, RemoteStreamID}} ->
+ #{RemoteStreamID := {unidi_remote, OpenStreamRef}} = Streams,
+ {[], maps:remove(OpenStreamRef, Streams#{
+ RemoteStreamID => {unidi_remote, OpenStreamID},
+ OpenStreamID => {unidi_local, RemoteStreamID}
+ })}
+ end;
+webtransport_handle(Event = {stream_data, StreamID, _IsFin, <<"TEST:", Test/bits>>}, Streams) ->
+ ?LOG("WT handle ~p~n", [Event]),
+ case Test of
+ <<"open_bidi">> ->
+ OpenStreamRef = make_ref(),
+ {[{open_stream, OpenStreamRef, bidi, <<>>}],
+ Streams#{OpenStreamRef => bidi}};
+ <<"initiate_close">> ->
+ {[initiate_close], Streams};
+ <<"close">> ->
+ {[close], Streams};
+ <<"close_app_code">> ->
+ {[{close, 1234567890}], Streams};
+ <<"close_app_code_msg">> ->
+ {[{close, 1234567890, <<"onetwothreefourfivesixseveneightnineten">>}], Streams};
+ <<"event_pid:", EventPidBin/bits>> ->
+ {[{send, StreamID, nofin, <<"event_pid_received">>}],
+ Streams#{event_pid => binary_to_term(EventPidBin)}}
+ end;
+webtransport_handle(Event = {stream_data, StreamID, IsFin, Data}, Streams) ->
+ ?LOG("WT handle ~p~n", [Event]),
+ case Streams of
+ #{StreamID := bidi} ->
+ {[{send, StreamID, IsFin, Data}], Streams};
+ #{StreamID := {unidi_remote, Ref}} when is_reference(Ref) ->
+ %% The stream isn't ready. We try again later.
+ erlang:send_after(100, self(), {try_again, Event}),
+ {[], Streams};
+ #{StreamID := {unidi_remote, LocalStreamID}} ->
+ {[{send, LocalStreamID, IsFin, Data}], Streams}
+ end;
+webtransport_handle(Event = {datagram, Data}, Streams) ->
+ ?LOG("WT handle ~p~n", [Event]),
+ {[{send, datagram, Data}], Streams};
+webtransport_handle(Event = close_initiated, Streams) ->
+ ?LOG("WT handle ~p~n", [Event]),
+ {[{send, datagram, <<"TEST:close_initiated">>}], Streams};
+webtransport_handle(Event, Streams) ->
+ ?LOG("WT handle ignore ~p~n", [Event]),
+ {[], Streams}.
+
+webtransport_info({try_again, Event}, Streams) ->
+ ?LOG("WT try_again ~p", [Event]),
+ webtransport_handle(Event, Streams).
+
+terminate(Reason, Req, State=#{event_pid := EventPid}) ->
+ ?LOG("WT terminate ~0p~n~0p~n~0p", [Reason, Req, State]),
+ EventPid ! {'$wt_echo_h', terminate, Reason, Req, State},
+ ok;
+terminate(Reason, Req, State) ->
+ ?LOG("WT terminate ~0p~n~0p~n~0p", [Reason, Req, State]),
+ ok.