0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 04:10:24 +00:00

Rename WT capsules

This commit is contained in:
Loïc Hoguin 2025-06-13 15:17:56 +02:00
parent 804dbb77a6
commit 28b6ebe9e7
No known key found for this signature in database
GPG key ID: 8A9DF795F6FED764
2 changed files with 43 additions and 43 deletions

View file

@ -258,10 +258,10 @@ parse1(State=#state{http3_machine=HTTP3Machine0},
%% @todo Handle when IsFin = fin which must terminate the WT session. %% @todo Handle when IsFin = fin which must terminate the WT session.
parse1(State, Stream=#stream{id=SessionID, status=webtransport_session}, Data, IsFin) -> parse1(State, Stream=#stream{id=SessionID, status=webtransport_session}, Data, IsFin) ->
case cow_capsule:parse(Data) of case cow_capsule:parse(Data) of
{ok, drain_wt_session, Rest} -> {ok, wt_drain_session, Rest} ->
webtransport_event(State, SessionID, close_initiated), webtransport_event(State, SessionID, close_initiated),
parse1(State, Stream, Rest, IsFin); parse1(State, Stream, Rest, IsFin);
{ok, {close_wt_session, AppCode, AppMsg}, Rest} -> {ok, {wt_close_session, AppCode, AppMsg}, Rest} ->
%% This event will be handled specially and lead %% This event will be handled specially and lead
%% to the termination of the session process. %% to the termination of the session process.
webtransport_event(State, SessionID, {closed, AppCode, AppMsg}), webtransport_event(State, SessionID, {closed, AppCode, AppMsg}),
@ -969,9 +969,9 @@ wt_commands(State=#state{conn=Conn}, Session, [{send, StreamID, IsFin, Data}|Tai
%% @todo Handle errors. %% @todo Handle errors.
end; end;
wt_commands(State=#state{conn=Conn}, Session=#stream{id=SessionID}, [initiate_close|Tail]) -> wt_commands(State=#state{conn=Conn}, Session=#stream{id=SessionID}, [initiate_close|Tail]) ->
%% We must send a DRAIN_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% We must send a WT_DRAIN_SESSION capsule on the CONNECT stream.
%% @todo I don't think capsules should go over stream handlers. %% @todo I don't think capsules should go over stream handlers.
Capsule = cow_capsule:drain_wt_session(), Capsule = cow_capsule:wt_drain_session(),
case cowboy_quicer:send(Conn, SessionID, Capsule, nofin) of case cowboy_quicer:send(Conn, SessionID, Capsule, nofin) of
ok -> ok ->
wt_commands(State, Session, Tail) wt_commands(State, Session, Tail)
@ -979,13 +979,13 @@ wt_commands(State=#state{conn=Conn}, Session=#stream{id=SessionID}, [initiate_cl
end; end;
wt_commands(State0=#state{conn=Conn}, Session=#stream{id=SessionID}, [Cmd|Tail]) wt_commands(State0=#state{conn=Conn}, Session=#stream{id=SessionID}, [Cmd|Tail])
when Cmd =:= close; element(1, Cmd) =:= close -> when Cmd =:= close; element(1, Cmd) =:= close ->
%% We must send a CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% We must send a WT_CLOSE_SESSION capsule on the CONNECT stream.
{AppCode, AppMsg} = case Cmd of {AppCode, AppMsg} = case Cmd of
close -> {0, <<>>}; close -> {0, <<>>};
{close, AppCode0} -> {AppCode0, <<>>}; {close, AppCode0} -> {AppCode0, <<>>};
{close, AppCode0, AppMsg0} -> {AppCode0, AppMsg0} {close, AppCode0, AppMsg0} -> {AppCode0, AppMsg0}
end, end,
Capsule = cow_capsule:close_wt_session(AppCode, AppMsg), Capsule = cow_capsule:wt_close_session(AppCode, AppMsg),
case cowboy_quicer:send(Conn, SessionID, Capsule, fin) of case cowboy_quicer:send(Conn, SessionID, Capsule, fin) of
ok -> ok ->
%% @todo The endpoint MAY send a STOP_SENDING to indicate it is no longer reading from the CONNECT stream. %% @todo The endpoint MAY send a STOP_SENDING to indicate it is no longer reading from the CONNECT stream.

View file

@ -273,7 +273,7 @@ datagrams(Config) ->
% {datagram, SessionID, <<"TEST:close_initiated">>} = do_receive_datagram(Conn), % {datagram, SessionID, <<"TEST:close_initiated">>} = do_receive_datagram(Conn),
% ok. % ok.
drain_wt_session_client(Config) -> wt_drain_session_client(Config) ->
doc("The WT client can initiate the close of a single session. " doc("The WT client can initiate the close of a single session. "
"(draft_webtrans_http3 4.6)"), "(draft_webtrans_http3 4.6)"),
%% Connect to the WebTransport server. %% Connect to the WebTransport server.
@ -282,13 +282,13 @@ drain_wt_session_client(Config) ->
connect_stream_ref := ConnectStreamRef, connect_stream_ref := ConnectStreamRef,
session_id := SessionID session_id := SessionID
} = do_webtransport_connect(Config), } = do_webtransport_connect(Config),
%% Send the DRAIN_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Send the WT_DRAIN_SESSION capsule on the CONNECT stream.
{ok, _} = quicer:send(ConnectStreamRef, cow_capsule:drain_wt_session()), {ok, _} = quicer:send(ConnectStreamRef, cow_capsule:wt_drain_session()),
%% Receive a datagram indicating processing by the WT handler. %% Receive a datagram indicating processing by the WT handler.
{datagram, SessionID, <<"TEST:close_initiated">>} = do_receive_datagram(Conn), {datagram, SessionID, <<"TEST:close_initiated">>} = do_receive_datagram(Conn),
ok. ok.
drain_wt_session_server(Config) -> wt_drain_session_server(Config) ->
doc("The WT server can initiate the close of a single session. " doc("The WT server can initiate the close of a single session. "
"(draft_webtrans_http3 4.6)"), "(draft_webtrans_http3 4.6)"),
%% Connect to the WebTransport server. %% Connect to the WebTransport server.
@ -300,12 +300,12 @@ drain_wt_session_server(Config) ->
%% Create a bidi stream, send a special instruction to make it initiate the close. %% Create a bidi stream, send a special instruction to make it initiate the close.
{ok, LocalStreamRef} = quicer:start_stream(Conn, #{}), {ok, LocalStreamRef} = quicer:start_stream(Conn, #{}),
{ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, "TEST:initiate_close">>), {ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, "TEST:initiate_close">>),
%% Receive the DRAIN_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Receive the WT_DRAIN_SESSION capsule on the CONNECT stream.
DrainWTSessionCapsule = cow_capsule:drain_wt_session(), DrainWTSessionCapsule = cow_capsule:wt_drain_session(),
{nofin, DrainWTSessionCapsule} = do_receive_data(ConnectStreamRef), {nofin, DrainWTSessionCapsule} = do_receive_data(ConnectStreamRef),
ok. ok.
drain_wt_session_continue_client(Config) -> wt_drain_session_continue_client(Config) ->
doc("After the WT client has initiated the close of the session, " doc("After the WT client has initiated the close of the session, "
"both client and server can continue using the session and " "both client and server can continue using the session and "
"open new streams. (draft_webtrans_http3 4.6)"), "open new streams. (draft_webtrans_http3 4.6)"),
@ -315,8 +315,8 @@ drain_wt_session_continue_client(Config) ->
connect_stream_ref := ConnectStreamRef, connect_stream_ref := ConnectStreamRef,
session_id := SessionID session_id := SessionID
} = do_webtransport_connect(Config), } = do_webtransport_connect(Config),
%% Send the DRAIN_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Send the WT_DRAIN_SESSION capsule on the CONNECT stream.
{ok, _} = quicer:send(ConnectStreamRef, cow_capsule:drain_wt_session()), {ok, _} = quicer:send(ConnectStreamRef, cow_capsule:wt_drain_session()),
%% Receive a datagram indicating processing by the WT handler. %% Receive a datagram indicating processing by the WT handler.
{datagram, SessionID, <<"TEST:close_initiated">>} = do_receive_datagram(Conn), {datagram, SessionID, <<"TEST:close_initiated">>} = do_receive_datagram(Conn),
%% Create a new bidi stream, send Hello, get Hello back. %% Create a new bidi stream, send Hello, get Hello back.
@ -325,7 +325,7 @@ drain_wt_session_continue_client(Config) ->
{nofin, <<"Hello">>} = do_receive_data(ContinueStreamRef), {nofin, <<"Hello">>} = do_receive_data(ContinueStreamRef),
ok. ok.
drain_wt_session_continue_server(Config) -> wt_drain_session_continue_server(Config) ->
doc("After the WT server has initiated the close of the session, " doc("After the WT server has initiated the close of the session, "
"both client and server can continue using the session and " "both client and server can continue using the session and "
"open new streams. (draft_webtrans_http3 4.6)"), "open new streams. (draft_webtrans_http3 4.6)"),
@ -338,8 +338,8 @@ drain_wt_session_continue_server(Config) ->
%% Create a bidi stream, send a special instruction to make it initiate the close. %% Create a bidi stream, send a special instruction to make it initiate the close.
{ok, LocalStreamRef} = quicer:start_stream(Conn, #{}), {ok, LocalStreamRef} = quicer:start_stream(Conn, #{}),
{ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, "TEST:initiate_close">>), {ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, "TEST:initiate_close">>),
%% Receive the DRAIN_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Receive the WT_DRAIN_SESSION capsule on the CONNECT stream.
DrainWTSessionCapsule = cow_capsule:drain_wt_session(), DrainWTSessionCapsule = cow_capsule:wt_drain_session(),
{nofin, DrainWTSessionCapsule} = do_receive_data(ConnectStreamRef), {nofin, DrainWTSessionCapsule} = do_receive_data(ConnectStreamRef),
%% Create a new bidi stream, send Hello, get Hello back. %% Create a new bidi stream, send Hello, get Hello back.
{ok, ContinueStreamRef} = quicer:start_stream(Conn, #{}), {ok, ContinueStreamRef} = quicer:start_stream(Conn, #{}),
@ -427,18 +427,18 @@ drain_wt_session_continue_server(Config) ->
%% A WebTransport session over HTTP/3 is considered terminated when either of the following conditions is met: %% A WebTransport session over HTTP/3 is considered terminated when either of the following conditions is met:
%% * the CONNECT stream is closed, either cleanly or abruptly, on either side; or %% * the CONNECT stream is closed, either cleanly or abruptly, on either side; or
%% * a CLOSE_WEBTRANSPORT_SESSION capsule is either sent or received. %% * a WT_CLOSE_SESSION capsule is either sent or received.
%% (6) %% (6)
close_wt_session_client(Config) -> wt_close_session_client(Config) ->
doc("The WT client can close a single session. (draft_webtrans_http3 4.6)"), doc("The WT client can close a single session. (draft_webtrans_http3 4.6)"),
%% Connect to the WebTransport server. %% Connect to the WebTransport server.
#{ #{
connect_stream_ref := ConnectStreamRef connect_stream_ref := ConnectStreamRef
} = do_webtransport_connect(Config), } = do_webtransport_connect(Config),
%% Send the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Send the WT_CLOSE_SESSION capsule on the CONNECT stream.
{ok, _} = quicer:send(ConnectStreamRef, {ok, _} = quicer:send(ConnectStreamRef,
cow_capsule:close_wt_session(0, <<>>), cow_capsule:wt_close_session(0, <<>>),
?QUIC_SEND_FLAG_FIN), ?QUIC_SEND_FLAG_FIN),
%% Normally we should also stop reading but in order to detect %% Normally we should also stop reading but in order to detect
%% that the server stops the stream we must not otherwise the %% that the server stops the stream we must not otherwise the
@ -452,7 +452,7 @@ close_wt_session_client(Config) ->
error({timeout, waiting_for_stream_closed}) error({timeout, waiting_for_stream_closed})
end. end.
close_wt_session_server(Config) -> wt_close_session_server(Config) ->
doc("The WT server can close a single session. (draft_webtrans_http3 4.6)"), doc("The WT server can close a single session. (draft_webtrans_http3 4.6)"),
%% Connect to the WebTransport server. %% Connect to the WebTransport server.
#{ #{
@ -463,8 +463,8 @@ close_wt_session_server(Config) ->
%% Create a bidi stream, send a special instruction to make it initiate the close. %% Create a bidi stream, send a special instruction to make it initiate the close.
{ok, LocalStreamRef} = quicer:start_stream(Conn, #{}), {ok, LocalStreamRef} = quicer:start_stream(Conn, #{}),
{ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, "TEST:close">>), {ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, "TEST:close">>),
%% Receive the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Receive the WT_CLOSE_SESSION capsule on the CONNECT stream.
CloseWTSessionCapsule = cow_capsule:close_wt_session(0, <<>>), CloseWTSessionCapsule = cow_capsule:wt_close_session(0, <<>>),
{fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef), {fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef),
ok. ok.
@ -496,9 +496,9 @@ wt_session_gone_client(Config) ->
{nofin, <<1:2, 16#41:14, 0:2, SessionID:6>>} = do_receive_data(RemoteBidiStreamRef), {nofin, <<1:2, 16#41:14, 0:2, SessionID:6>>} = do_receive_data(RemoteBidiStreamRef),
{ok, _} = quicer:send(RemoteBidiStreamRef, <<"Hello">>), {ok, _} = quicer:send(RemoteBidiStreamRef, <<"Hello">>),
{nofin, <<"Hello">>} = do_receive_data(RemoteBidiStreamRef), {nofin, <<"Hello">>} = do_receive_data(RemoteBidiStreamRef),
%% Send the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Send the WT_CLOSE_SESSION capsule on the CONNECT stream.
{ok, _} = quicer:send(ConnectStreamRef, {ok, _} = quicer:send(ConnectStreamRef,
cow_capsule:close_wt_session(0, <<>>), cow_capsule:wt_close_session(0, <<>>),
?QUIC_SEND_FLAG_FIN), ?QUIC_SEND_FLAG_FIN),
%% All streams from that WT session have been aborted. %% All streams from that WT session have been aborted.
#{reason := webtransport_session_gone} = do_wait_stream_aborted(LocalUnidiStreamRef), #{reason := webtransport_session_gone} = do_wait_stream_aborted(LocalUnidiStreamRef),
@ -538,8 +538,8 @@ wt_session_gone_server(Config) ->
%% Send a special instruction to make the server initiate the close. %% Send a special instruction to make the server initiate the close.
{ok, _} = quicer:send(LocalBidiStreamRef, <<"TEST:close">>), {ok, _} = quicer:send(LocalBidiStreamRef, <<"TEST:close">>),
%% Receive the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Receive the WT_CLOSE_SESSION capsule on the CONNECT stream.
CloseWTSessionCapsule = cow_capsule:close_wt_session(0, <<>>), CloseWTSessionCapsule = cow_capsule:wt_close_session(0, <<>>),
{fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef), {fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef),
%% All streams from that WT session have been aborted. %% All streams from that WT session have been aborted.
#{reason := webtransport_session_gone} = do_wait_stream_aborted(LocalUnidiStreamRef), #{reason := webtransport_session_gone} = do_wait_stream_aborted(LocalUnidiStreamRef),
@ -551,7 +551,7 @@ wt_session_gone_server(Config) ->
%% Application Error Message: A UTF-8 encoded error message string provided by the application closing the session. The message takes up the remainder of the capsule, and its length MUST NOT exceed 1024 bytes. (6) %% Application Error Message: A UTF-8 encoded error message string provided by the application closing the session. The message takes up the remainder of the capsule, and its length MUST NOT exceed 1024 bytes. (6)
%% @todo What if it's larger? %% @todo What if it's larger?
close_wt_session_app_code_msg_client(Config) -> wt_close_session_app_code_msg_client(Config) ->
doc("The WT client can close a single session with an application error code " doc("The WT client can close a single session with an application error code "
"and an application error message. (draft_webtrans_http3 4.6)"), "and an application error message. (draft_webtrans_http3 4.6)"),
%% Connect to the WebTransport server. %% Connect to the WebTransport server.
@ -565,9 +565,9 @@ close_wt_session_app_code_msg_client(Config) ->
EventPidBin = term_to_binary(self()), EventPidBin = term_to_binary(self()),
{ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, {ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6,
"TEST:event_pid:", EventPidBin/binary>>), "TEST:event_pid:", EventPidBin/binary>>),
%% Send the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Send the WT_CLOSE_SESSION capsule on the CONNECT stream.
{ok, _} = quicer:send(ConnectStreamRef, {ok, _} = quicer:send(ConnectStreamRef,
cow_capsule:close_wt_session(17, <<"seventeen">>), cow_capsule:wt_close_session(17, <<"seventeen">>),
?QUIC_SEND_FLAG_FIN), ?QUIC_SEND_FLAG_FIN),
%% @todo Stop reading from the CONNECt stream too. (STOP_SENDING) %% @todo Stop reading from the CONNECt stream too. (STOP_SENDING)
%% Receive the terminate event from the WT handler. %% Receive the terminate event from the WT handler.
@ -578,7 +578,7 @@ close_wt_session_app_code_msg_client(Config) ->
error({timeout, waiting_for_terminate_event}) error({timeout, waiting_for_terminate_event})
end. end.
close_wt_session_app_code_server(Config) -> wt_close_session_app_code_server(Config) ->
doc("The WT server can close a single session with an application error code. " doc("The WT server can close a single session with an application error code. "
"(draft_webtrans_http3 4.6)"), "(draft_webtrans_http3 4.6)"),
%% Connect to the WebTransport server. %% Connect to the WebTransport server.
@ -591,12 +591,12 @@ close_wt_session_app_code_server(Config) ->
{ok, LocalStreamRef} = quicer:start_stream(Conn, #{}), {ok, LocalStreamRef} = quicer:start_stream(Conn, #{}),
{ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, {ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6,
"TEST:close_app_code">>), "TEST:close_app_code">>),
%% Receive the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Receive the WT_CLOSE_SESSION capsule on the CONNECT stream.
CloseWTSessionCapsule = cow_capsule:close_wt_session(1234567890, <<>>), CloseWTSessionCapsule = cow_capsule:wt_close_session(1234567890, <<>>),
{fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef), {fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef),
ok. ok.
close_wt_session_app_code_msg_server(Config) -> wt_close_session_app_code_msg_server(Config) ->
doc("The WT server can close a single session with an application error code " doc("The WT server can close a single session with an application error code "
"and an application error message. (draft_webtrans_http3 4.6)"), "and an application error message. (draft_webtrans_http3 4.6)"),
%% Connect to the WebTransport server. %% Connect to the WebTransport server.
@ -609,18 +609,18 @@ close_wt_session_app_code_msg_server(Config) ->
{ok, LocalStreamRef} = quicer:start_stream(Conn, #{}), {ok, LocalStreamRef} = quicer:start_stream(Conn, #{}),
{ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, {ok, _} = quicer:send(LocalStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6,
"TEST:close_app_code_msg">>), "TEST:close_app_code_msg">>),
%% Receive the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. %% Receive the WT_CLOSE_SESSION capsule on the CONNECT stream.
CloseWTSessionCapsule = iolist_to_binary(cow_capsule:close_wt_session(1234567890, CloseWTSessionCapsule = iolist_to_binary(cow_capsule:wt_close_session(1234567890,
<<"onetwothreefourfivesixseveneightnineten">>)), <<"onetwothreefourfivesixseveneightnineten">>)),
{fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef), {fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef),
ok. ok.
%% An endpoint that sends a CLOSE_WEBTRANSPORT_SESSION capsule MUST immediately send a FIN. The endpoint MAY send a STOP_SENDING to indicate it is no longer reading from the CONNECT stream. The recipient MUST either close or reset the stream in response. (6) %% An endpoint that sends a WT_CLOSE_SESSION capsule MUST immediately send a FIN. The endpoint MAY send a STOP_SENDING to indicate it is no longer reading from the CONNECT stream. The recipient MUST either close or reset the stream in response. (6)
%% @todo close_wt_session_server_fin %% @todo wt_close_session_server_fin
%% @todo The part about close/reset should be tested in close_wt_session_client. %% @todo The part about close/reset should be tested in wt_close_session_client.
%% If any additional stream data is received on the CONNECT stream after receiving a CLOSE_WEBTRANSPORT_SESSION capsule, the stream MUST be reset with code H3_MESSAGE_ERROR. (6) %% If any additional stream data is received on the CONNECT stream after receiving a WT_CLOSE_SESSION capsule, the stream MUST be reset with code H3_MESSAGE_ERROR. (6)
%% @todo close_wt_session_followed_by_data %% @todo wt_close_session_followed_by_data
connect_stream_closed_cleanly_fin(Config) -> connect_stream_closed_cleanly_fin(Config) ->
doc("The WT client closing the CONNECT stream cleanly " doc("The WT client closing the CONNECT stream cleanly "