//! A request the relay rejects is answered REQUEST_ERROR and FIN, and not cancelled //! (`draft-ietf-moq-transport-22` ยง6.4.2.3: "When an endpoint rejects a request without //! performing any application processing, it SHOULD send a REQUEST_ERROR and FIN the stream"; //! a request is cancelled by RESET_STREAM and STOP_SENDING). Over native QUIC and the WebSocket //! binding, a TRACK_STATUS for a track nobody publishes is answered REQUEST_ERROR and FIN; the //! requester then sends its own FIN, and its direction was never stopped: no STOP_SENDING came //! beside the REQUEST_ERROR. The relay used to drop the direction it was reading as it //! answered, and its transport stopped it. mod common; use common::*; use joule_moq::draft22::{ControlMessage, Parameters, TrackRequest}; use joule_moq_relay::client::ClientOptions; use joule_moq_relay::wire::MessageReader; use std::time::Duration; use tokio::time::timeout; #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn a_rejected_request_is_answered_and_finished_never_stopped() { timeout(Duration::from_secs(60), run()).await.expect("the test finishes in time"); } async fn run() { let server = relay(|_| {}).await; for via in [Via::Quic, Via::WebSocket] { let (c, _endpoint) = connect(&server, via, ClientOptions::default()).await; let (mut send, recv) = timeout(STEP, c.conn.open_bi()).await.expect("in time").expect("a request stream"); let ask = ControlMessage::TrackStatus(TrackRequest { request_id: c.next_request_id(), namespace: ns(&["nobody", "publishes"]), name: name("this"), params: Parameters::new() }); send.write_all(&ask.encode().unwrap()).await.expect("the request goes"); let mut reader = MessageReader::new(recv); let answer = timeout(STEP, reader.next()).await.expect("an answer in time").expect("it reads"); assert!(matches!(answer, Some(ControlMessage::RequestError(_))), "{via:?}: {answer:?}"); let after = timeout(STEP, reader.next()).await.expect("the relay's FIN in time").expect("it reads"); assert!(after.is_none(), "{via:?}: the relay's direction ends after its REQUEST_ERROR"); // Time for a STOP_SENDING the relay might send to arrive, then this end's own FIN. tokio::time::sleep(Duration::from_millis(300)).await; send.finish().expect("the requester's FIN"); let stopped = timeout(STEP, send.delivered()).await.expect("acknowledged in time").expect("no transport error"); assert_eq!(stopped, None, "{via:?}: the relay stopped the requester's direction (STOP_SENDING) beside its REQUEST_ERROR"); c.close(0, "done"); } server.shutdown().await; }