@@ -60,6 +60,8 @@ pub struct RequestDescription<'b, T: RequestTarget> {
6060#[ derive( Display ) ]
6161pub enum SessionAcceptAction {
6262 Accept ,
63+ /// Accept the session and include additional headers in the 200 response.
64+ AcceptWith ( Vec < Header > ) ,
6365 Reject ( Vec < Header > ) ,
6466}
6567
@@ -1334,44 +1336,63 @@ impl Http3Connection {
13341336 }
13351337 Ok ( ( ) )
13361338 }
1337- ( Some ( s) , Some ( _r) , SessionAcceptAction :: Accept ) => {
1338- let mut response_headers = vec ! [ Header :: new( ":status" , "200" ) ] ;
1339- if connect_type == ExtendedConnectType :: ConnectUdp {
1340- response_headers. push ( Header :: new ( "capsule-protocol" , "?1" ) ) ;
1341- }
1342-
1343- if s. http_stream ( )
1344- . ok_or ( Error :: InvalidStreamId ) ?
1345- . send_headers ( & response_headers, conn)
1346- . is_ok ( )
1347- {
1348- let extended_conn = Rc :: new ( RefCell :: new (
1349- extended_connect:: session:: Session :: new_with_http_streams (
1350- stream_id,
1351- events,
1352- self . role ,
1353- self . recv_streams
1354- . remove ( & stream_id)
1355- . ok_or ( Error :: Internal ) ?,
1356- self . send_streams
1357- . remove ( & stream_id)
1358- . ok_or ( Error :: Internal ) ?,
1359- connect_type,
1360- ) ?,
1361- ) ) ;
1362- self . add_streams (
1363- stream_id,
1364- Box :: new ( Rc :: clone ( & extended_conn) ) ,
1365- Box :: new ( extended_conn) ,
1366- ) ;
1367- self . streams_with_pending_data . insert ( stream_id) ;
1368- } else {
1369- self . cancel_fetch ( stream_id, Error :: HttpRequestRejected . code ( ) , conn) ?;
1370- return Err ( Error :: InvalidStreamId ) ;
1371- }
1372- Ok ( ( ) )
1339+ ( Some ( _) , Some ( _) , SessionAcceptAction :: Accept ) => {
1340+ self . do_accept_extended_connect ( conn, stream_id, events, connect_type, & [ ] )
13731341 }
1342+ ( Some ( _) , Some ( _) , SessionAcceptAction :: AcceptWith ( extra) ) => {
1343+ self . do_accept_extended_connect ( conn, stream_id, events, connect_type, extra)
1344+ }
1345+ }
1346+ }
1347+
1348+ fn do_accept_extended_connect (
1349+ & mut self ,
1350+ conn : & mut Connection ,
1351+ stream_id : StreamId ,
1352+ events : Box < dyn ExtendedConnectEvents > ,
1353+ connect_type : ExtendedConnectType ,
1354+ extra_headers : & [ Header ] ,
1355+ ) -> Res < ( ) > {
1356+ let mut response_headers = vec ! [ Header :: new( ":status" , "200" ) ] ;
1357+ if connect_type == ExtendedConnectType :: ConnectUdp {
1358+ response_headers. push ( Header :: new ( "capsule-protocol" , "?1" ) ) ;
1359+ }
1360+ response_headers. extend_from_slice ( extra_headers) ;
1361+
1362+ if self
1363+ . send_streams
1364+ . get_mut ( & stream_id)
1365+ . ok_or ( Error :: InvalidStreamId ) ?
1366+ . http_stream ( )
1367+ . ok_or ( Error :: InvalidStreamId ) ?
1368+ . send_headers ( & response_headers, conn)
1369+ . is_ok ( )
1370+ {
1371+ let extended_conn = Rc :: new ( RefCell :: new (
1372+ extended_connect:: session:: Session :: new_with_http_streams (
1373+ stream_id,
1374+ events,
1375+ self . role ,
1376+ self . recv_streams
1377+ . remove ( & stream_id)
1378+ . ok_or ( Error :: Internal ) ?,
1379+ self . send_streams
1380+ . remove ( & stream_id)
1381+ . ok_or ( Error :: Internal ) ?,
1382+ connect_type,
1383+ ) ?,
1384+ ) ) ;
1385+ self . add_streams (
1386+ stream_id,
1387+ Box :: new ( Rc :: clone ( & extended_conn) ) ,
1388+ Box :: new ( extended_conn) ,
1389+ ) ;
1390+ self . streams_with_pending_data . insert ( stream_id) ;
1391+ } else {
1392+ self . cancel_fetch ( stream_id, Error :: HttpRequestRejected . code ( ) , conn) ?;
1393+ return Err ( Error :: InvalidStreamId ) ;
13741394 }
1395+ Ok ( ( ) )
13751396 }
13761397
13771398 pub ( crate ) fn webtransport_close_session (
@@ -1398,6 +1419,22 @@ impl Http3Connection {
13981419 } )
13991420 }
14001421
1422+ /// Get the negotiated protocol for a WebTransport session.
1423+ ///
1424+ /// Returns `Ok(None)` if no protocol was negotiated.
1425+ /// Returns an error if the session does not exist or is not an extended CONNECT session.
1426+ pub ( crate ) fn webtransport_session_protocol (
1427+ & self ,
1428+ session_id : StreamId ,
1429+ ) -> Res < Option < String > > {
1430+ let stream = self
1431+ . send_streams
1432+ . get ( & session_id)
1433+ . filter ( |s| s. stream_type ( ) == Http3StreamType :: ExtendedConnect )
1434+ . ok_or ( Error :: InvalidStreamId ) ?;
1435+ Ok ( stream. session_protocol ( ) )
1436+ }
1437+
14011438 pub ( crate ) fn connect_udp_close_session (
14021439 & mut self ,
14031440 conn : & mut Connection ,
0 commit comments