diff --git a/test/draft_h3_webtransport_SUITE.erl b/test/draft_h3_webtransport_SUITE.erl index b271f590..5e70f99a 100644 --- a/test/draft_h3_webtransport_SUITE.erl +++ b/test/draft_h3_webtransport_SUITE.erl @@ -18,6 +18,7 @@ -import(ct_helper, [config/2]). -import(ct_helper, [doc/1]). +-import(rfc9114_SUITE, [do_wait_stream_aborted/1]). %% @todo -ifdef(COWBOY_QUICER). @@ -436,9 +437,7 @@ close_wt_session_client(Config) -> doc("The WT client can close a single session. (draft_webtrans_http3 4.6)"), %% Connect to the WebTransport server. #{ - conn := Conn, - connect_stream_ref := ConnectStreamRef, - session_id := SessionID + connect_stream_ref := ConnectStreamRef } = do_webtransport_connect(Config), %% Send the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. {ok, _} = quicer:send(ConnectStreamRef, @@ -472,16 +471,51 @@ close_wt_session_server(Config) -> {fin, CloseWTSessionCapsule} = do_receive_data(ConnectStreamRef), ok. +wt_session_gone_client(Config) -> + doc("Upon learning that the session has been terminated, " + "the WT server must reset associated streams with the " + "WEBTRANSPORT_SESSION_GONE error code. (draft_webtrans_http3 4.6)"), + %% Connect to the WebTransport server. + #{ + conn := Conn, + connect_stream_ref := ConnectStreamRef, + session_id := SessionID + } = do_webtransport_connect(Config), + %% Create a unidi stream. + {ok, LocalUnidiStreamRef} = quicer:start_stream(Conn, + #{open_flag => ?QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL}), + {ok, _} = quicer:send(LocalUnidiStreamRef, + <<1:2, 16#54:14, 0:2, SessionID:6, "Hello">>), + %% Accept an identical unidi stream. + {unidi, RemoteUnidiStreamRef} = do_receive_new_stream(), + {nofin, <<1:2, 16#54:14, 0:2, SessionID:6>>} = do_receive_data(RemoteUnidiStreamRef), + {nofin, <<"Hello">>} = do_receive_data(RemoteUnidiStreamRef), + %% Create a bidi stream, send a special instruction + %% to make the server create another bidi stream. + {ok, LocalBidiStreamRef} = quicer:start_stream(Conn, #{}), + {ok, _} = quicer:send(LocalBidiStreamRef, <<1:2, 16#41:14, 0:2, SessionID:6, "TEST:open_bidi">>), + %% Accept the bidi stream and receive the data. + {bidi, RemoteBidiStreamRef} = do_receive_new_stream(), + {nofin, <<1:2, 16#41:14, 0:2, SessionID:6>>} = do_receive_data(RemoteBidiStreamRef), + {ok, _} = quicer:send(RemoteBidiStreamRef, <<"Hello">>), + {nofin, <<"Hello">>} = do_receive_data(RemoteBidiStreamRef), + %% Send the CLOSE_WEBTRANSPORT_SESSION capsule on the CONNECT stream. + {ok, _} = quicer:send(ConnectStreamRef, + cow_capsule:close_wt_session(0, <<>>), + ?QUIC_SEND_FLAG_FIN), + %% 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(RemoteUnidiStreamRef), + #{reason := webtransport_session_gone} = do_wait_stream_aborted(LocalBidiStreamRef), + #{reason := webtransport_session_gone} = do_wait_stream_aborted(RemoteBidiStreamRef), + ok. + +%% @todo wt_session_gone_server %% Upon learning that the session has been terminated, the endpoint MUST reset the send side and abort reading on the receive side of all of the streams associated with the session (see Section 2.4 of [RFC9000]) using the WEBTRANSPORT_SESSION_GONE error code; it MUST NOT send any new datagrams or open any new streams. (6) -%% @todo wt_session_gone_client/server - -%% To terminate a session with a detailed error message, an application MAY send an HTTP capsule [HTTP-DATAGRAM] of type CLOSE_WEBTRANSPORT_SESSION (0x2843). (6) -%% @todo close_wt_session_client/server - %% 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 close_wt_session_app_code_msg_client close_wt_session_app_code_msg_client(Config) -> doc("The WT client can close a single session with an application error code " "and an application error message. (draft_webtrans_http3 4.6)"),