From 21aa8179646c830d262f086a4f9c5234b6f05656 Mon Sep 17 00:00:00 2001 From: Amos Wenger Date: Sat, 1 Jun 2024 23:14:24 +0200 Subject: [PATCH] Section 5.3 --- crates/httpwg-macros/src/lib.rs | 21 +++++++ crates/httpwg/src/lib.rs | 27 +++++++++ .../src/rfc9113/_5_3_1_stream_dependencies.rs | 59 +++++++++++++++++++ crates/httpwg/src/rfc9113/mod.rs | 2 + 4 files changed, 109 insertions(+) create mode 100644 crates/httpwg/src/rfc9113/_5_3_1_stream_dependencies.rs diff --git a/crates/httpwg-macros/src/lib.rs b/crates/httpwg-macros/src/lib.rs index ed3c71a7..3ec12a25 100644 --- a/crates/httpwg-macros/src/lib.rs +++ b/crates/httpwg-macros/src/lib.rs @@ -310,6 +310,27 @@ macro_rules! tests { $body } } + + /// Section 5.3: Stream Dependencies + mod _5_3_1_stream_dependencies { + use super::__suite::_5_3_1_stream_dependencies as __group; + + /// A stream cannot depend on itself. An endpoint MUST treat this + /// as a stream error (Section 5.4.2) of type PROTOCOL_ERROR. + #[test] + fn headers_frame_depends_on_itself() { + use __group::headers_frame_depends_on_itself as test; + $body + } + + /// A stream cannot depend on itself. An endpoint MUST treat this + /// as a stream error (Section 5.4.2) of type PROTOCOL_ERROR. + #[test] + fn priority_frame_depends_on_itself() { + use __group::priority_frame_depends_on_itself as test; + $body + } + } } }; } diff --git a/crates/httpwg/src/lib.rs b/crates/httpwg/src/lib.rs index 9b67e57f..2c7632c3 100644 --- a/crates/httpwg/src/lib.rs +++ b/crates/httpwg/src/lib.rs @@ -645,6 +645,33 @@ impl Conn { Ok(()) } + pub async fn write_headers_with_priority( + &mut self, + stream_id: StreamId, + flags: impl Into>, + priority_spec: PrioritySpec, + block_fragment: Piece, + ) -> eyre::Result<()> { + let flags = flags.into() | HeadersFlags::Priority; + let frame = Frame::new(FrameType::Headers(flags), stream_id); + + let payload = block_fragment.into_piece(&mut self.scratch)?; + let frame = frame.with_len(payload.len().try_into().unwrap()); + + let priority_spec_piece = priority_spec.into_piece(&mut self.scratch)?; + + let header = frame.into_piece(&mut self.scratch)?; + self.w + .writev_all_owned( + PieceList::single(header) + .followed_by(priority_spec_piece) + .followed_by(payload), + ) + .await?; + + Ok(()) + } + pub async fn write_continuation( &mut self, stream_id: StreamId, diff --git a/crates/httpwg/src/rfc9113/_5_3_1_stream_dependencies.rs b/crates/httpwg/src/rfc9113/_5_3_1_stream_dependencies.rs new file mode 100644 index 00000000..3896f380 --- /dev/null +++ b/crates/httpwg/src/rfc9113/_5_3_1_stream_dependencies.rs @@ -0,0 +1,59 @@ +//! Section 5.3: Stream Dependencies + +use fluke_buffet::IntoHalves; +use fluke_h2_parse::{HeadersFlags, PrioritySpec, StreamId}; + +use crate::{Conn, ErrorC}; + +/// A stream cannot depend on itself. An endpoint MUST treat this +/// as a stream error (Section 5.4.2) of type PROTOCOL_ERROR. +pub async fn headers_frame_depends_on_itself( + mut conn: Conn, +) -> eyre::Result<()> { + let stream_id = StreamId(1); + + conn.handshake().await?; + + let headers = conn.common_headers(); + let block_fragment = conn.encode_headers(&headers)?; + + conn.write_headers_with_priority( + stream_id, + HeadersFlags::EndHeaders | HeadersFlags::EndStream, + PrioritySpec { + stream_dependency: stream_id, + exclusive: false, + weight: 255, + }, + block_fragment, + ) + .await?; + + conn.verify_stream_error(ErrorC::ProtocolError).await?; + + Ok(()) +} + +/// A stream cannot depend on itself. An endpoint MUST treat this +/// as a stream error (Section 5.4.2) of type PROTOCOL_ERROR. +pub async fn priority_frame_depends_on_itself( + mut conn: Conn, +) -> eyre::Result<()> { + let stream_id = StreamId(1); + + conn.handshake().await?; + + conn.write_priority( + stream_id, + PrioritySpec { + stream_dependency: stream_id, + exclusive: false, + weight: 255, + }, + ) + .await?; + + conn.verify_stream_error(ErrorC::ProtocolError).await?; + + Ok(()) +} diff --git a/crates/httpwg/src/rfc9113/mod.rs b/crates/httpwg/src/rfc9113/mod.rs index c6b6af79..74b1f45e 100644 --- a/crates/httpwg/src/rfc9113/mod.rs +++ b/crates/httpwg/src/rfc9113/mod.rs @@ -32,3 +32,5 @@ pub mod _4_3_header_compression_and_decompression; pub mod _5_1_1_stream_identifiers; pub mod _5_1_2_stream_concurrency; pub mod _5_1_stream_states; + +pub mod _5_3_1_stream_dependencies;