0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00
cowboy/test/handlers/wt_echo_h.erl

82 lines
2.8 KiB
Erlang
Raw Normal View History

2025-05-13 14:20:11 +02:00
%% This module echoes client events back,
%% including creating new streams.
-module(wt_echo_h).
%% @todo -behavior(cowboy_webtransport).
-export([init/2]).
-export([webtransport_handle/2]).
2025-05-16 17:47:27 +02:00
-export([webtransport_info/2]).
2025-05-13 14:20:11 +02:00
2025-05-23 14:02:03 +02:00
init(Req0, _) ->
Req = case cowboy_req:parse_header(<<"wt-available-protocols">>, Req0) of
undefined ->
Req0;
[Protocol|_] ->
cowboy_req:set_resp_header(<<"wt-protocol">>, Protocol, Req0)
end,
2025-05-16 17:47:27 +02:00
{cowboy_webtransport, Req, #{}}.
2025-05-13 14:20:11 +02:00
%% @todo WT handle {stream_open,4,bidi}
2025-05-16 17:47:27 +02:00
webtransport_handle(Event = {stream_open, StreamID, bidi}, Streams) ->
2025-05-13 14:20:11 +02:00
ct:pal("WT handle ~p~n", [Event]),
2025-05-16 17:47:27 +02:00
{[], Streams#{StreamID => bidi}};
webtransport_handle(Event = {stream_open, StreamID, unidi}, Streams) ->
2025-05-13 14:20:11 +02:00
ct:pal("WT handle ~p~n", [Event]),
2025-05-16 17:47:27 +02:00
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) ->
ct:pal("WT handle ~p~n", [Event]),
2025-05-23 14:02:03 +02:00
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;
2025-06-02 15:55:45 +02:00
webtransport_handle(Event = {stream_data, _StreamID, _IsFin, <<"TEST:", Test/bits>>}, Streams) ->
2025-05-23 14:02:03 +02:00
ct:pal("WT handle ~p~n", [Event]),
case Test of
<<"open_bidi">> ->
OpenStreamRef = make_ref(),
{[{open_stream, OpenStreamRef, bidi, <<>>}],
2025-06-02 15:55:45 +02:00
Streams#{OpenStreamRef => bidi}};
<<"initiate_close">> ->
2025-06-03 15:44:33 +02:00
{[initiate_close], Streams};
<<"close">> ->
{[close], Streams}
2025-05-23 14:02:03 +02:00
end;
2025-05-16 17:47:27 +02:00
webtransport_handle(Event = {stream_data, StreamID, IsFin, Data}, Streams) ->
ct:pal("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;
2025-05-23 14:02:03 +02:00
webtransport_handle(Event = {datagram, Data}, Streams) ->
2025-05-16 17:47:27 +02:00
ct:pal("WT handle ~p~n", [Event]),
2025-05-23 14:02:03 +02:00
{[{send, datagram, Data}], Streams};
2025-06-02 15:55:45 +02:00
webtransport_handle(Event = close_initiated, Streams) ->
ct:pal("WT handle ~p~n", [Event]),
{[{send, datagram, <<"TEST:close_initiated">>}], Streams};
2025-05-23 14:02:03 +02:00
webtransport_handle(Event, Streams) ->
ct:pal("WT handle ignore ~p~n", [Event]),
2025-05-16 17:47:27 +02:00
{[], Streams}.
webtransport_info({try_again, Event}, Streams) ->
ct:pal("try_again ~p", [Event]),
webtransport_handle(Event, Streams).