conmonrs/streaming_server/spdy/
stream.rs1use super::{
5 Live, Queued, QueuedData, Shared,
6 frame::{Frame, Headers},
7};
8use crate::streaming_server::budget::Held;
9use anyhow::{Result, anyhow, bail};
10use bytes::Bytes;
11use std::sync::{
12 Arc,
13 atomic::{AtomicBool, Ordering},
14};
15use tokio::{select, sync::mpsc};
16use tokio_util::sync::{CancellationToken, WaitForCancellationFutureOwned};
17
18pub(crate) struct Stream {
20 pub(super) headers: Headers,
21 pub(super) receiver: StreamReceiver,
22 pub(super) sender: StreamSender,
23}
24
25impl Stream {
26 pub(crate) fn headers(&self) -> &Headers {
28 &self.headers
29 }
30
31 pub(crate) fn id(&self) -> u32 {
33 self.sender.id
34 }
35
36 pub(crate) fn is_reset(&self) -> bool {
38 self.receiver.is_reset()
39 }
40
41 pub(crate) fn reset_watch(&self) -> WaitForCancellationFutureOwned {
44 self.receiver.reset.clone().cancelled_owned()
45 }
46
47 pub(crate) fn split(self) -> (StreamReceiver, StreamSender) {
50 (self.receiver, self.sender)
51 }
52
53 #[cfg(test)]
55 pub(crate) async fn send(&mut self, data: Bytes) -> Result<()> {
56 self.sender.send(data).await
57 }
58
59 #[cfg(test)]
61 pub(crate) async fn close(&mut self) -> Result<()> {
62 self.sender.close().await
63 }
64}
65
66pub(crate) struct StreamReceiver {
68 pub(super) data: mpsc::Receiver<Held>,
69 pub(super) reset: CancellationToken,
70 pub(super) remote_closed: Arc<AtomicBool>,
71 pub(super) _live: Arc<Live>,
72}
73
74impl StreamReceiver {
75 pub(crate) async fn recv(&mut self) -> Option<Bytes> {
78 self.data.recv().await.map(Held::into_bytes)
79 }
80
81 pub(crate) async fn recv_held(&mut self) -> Option<Held> {
84 self.data.recv().await
85 }
86
87 pub(crate) fn is_reset(&self) -> bool {
89 self.reset.is_cancelled()
90 }
91
92 pub(crate) fn is_closed_by_client(&self) -> bool {
95 self.remote_closed.load(Ordering::Acquire)
96 }
97}
98
99pub(crate) struct StreamSender {
102 pub(super) id: u32,
103 pub(super) shared: Arc<Shared>,
104 pub(super) reset: CancellationToken,
105
106 pub(super) queued: Arc<Queued>,
108 pub(super) closed: bool,
109 pub(super) _live: Arc<Live>,
110}
111
112impl StreamSender {
113 #[expect(
117 clippy::needless_pass_by_ref_mut,
118 reason = "one send at a time keeps the frames in order"
119 )]
120 pub(crate) async fn send(&mut self, data: Bytes) -> Result<()> {
121 if self.closed {
122 bail!("SPDY stream {} is closed", self.id);
123 }
124 self.queue(false, data).await
125 }
126
127 async fn queue(&self, fin: bool, data: Bytes) -> Result<()> {
129 self.queued.add();
130 let mut unqueued = Unqueued {
131 sender: self,
132 queued: false,
133 };
134 let frame = QueuedData {
135 frame: Frame::Data {
136 stream_id: self.id,
137 fin,
138 data,
139 },
140 queued: self.queued.clone(),
141 };
142 select! {
143 biased;
144 () = self.reset.cancelled() => bail!("SPDY stream {} got reset", self.id),
145 result = self.shared.data.send(frame) => {
146 result.map_err(|_| anyhow!("SPDY connection closed"))?;
147 unqueued.queued = true;
148 Ok(())
149 }
150 }
151 }
152
153 pub(crate) async fn close(&mut self) -> Result<()> {
156 if self.closed {
157 return Ok(());
158 }
159 let result = self.queue(true, Bytes::new()).await;
160 self.closed = true;
161 self.shared.local_closed(self.id);
162 result
163 }
164
165 pub(super) fn reset(&mut self) {
169 self.closed = true;
170 if !self.reset.is_cancelled() && self.queued.reset() {
171 self.shared.queue_reset(self.id);
172 }
173 self.shared.remove(self.id);
174 }
175
176 pub(crate) async fn reset_by_peer(&self) {
178 self.reset.cancelled().await;
179 }
180
181 pub(crate) fn is_reset(&self) -> bool {
183 self.reset.is_cancelled()
184 }
185}
186
187impl Drop for StreamSender {
188 fn drop(&mut self) {
189 if !self.closed {
190 self.reset();
191 }
192 }
193}
194
195struct Unqueued<'a> {
198 sender: &'a StreamSender,
199 queued: bool,
200}
201
202impl Drop for Unqueued<'_> {
203 fn drop(&mut self) {
204 if !self.queued && self.sender.queued.remove() {
205 self.sender.shared.queue_reset(self.sender.id);
206 }
207 }
208}