1use std::future::Future;
2use std::io::Cursor;
3use std::pin::Pin;
4use std::sync::atomic::{AtomicBool, Ordering};
5use std::sync::Arc;
6use std::task::{Context, Poll};
7
8use atomic_waker::AtomicWaker;
9use bytes::{Buf, Bytes};
10use futures_channel::{mpsc, oneshot};
11use futures_core::{ready, Stream};
12use h2::{Reason, RecvStream, SendStream};
13use pin_project_lite::pin_project;
14
15use super::ping::Recorder;
16use super::SendBuf;
17use crate::rt::{Read, ReadBufCursor, Write};
18
19pub(super) fn pair<B>(
20 send_stream: SendStream<SendBuf<B>>,
21 recv_stream: RecvStream,
22 ping: Recorder,
23) -> (H2Upgraded, UpgradedSendStreamTask<B>) {
24 let (tx, rx) = mpsc::channel(1);
25 let (error_tx, error_rx) = oneshot::channel();
26 let close_notify = Arc::new(UpgradedCloseNotify::new());
27
28 (
29 H2Upgraded {
30 send_stream: UpgradedSendStreamBridge {
31 tx,
32 error_rx,
33 close_notify: close_notify.clone(),
34 },
35 recv_stream,
36 ping,
37 buf: Bytes::new(),
38 },
39 UpgradedSendStreamTask {
40 h2_tx: send_stream,
41 rx,
42 close_notify,
43 error_tx: Some(error_tx),
44 },
45 )
46}
47
48pub(super) struct H2Upgraded {
49 ping: Recorder,
50 send_stream: UpgradedSendStreamBridge,
51 recv_stream: RecvStream,
52 buf: Bytes,
53}
54
55struct UpgradedSendStreamBridge {
56 tx: mpsc::Sender<Cursor<Box<[u8]>>>,
57 error_rx: oneshot::Receiver<crate::Error>,
58 close_notify: Arc<UpgradedCloseNotify>,
59}
60
61impl Drop for UpgradedSendStreamBridge {
62 fn drop(&mut self) {
63 self.close_notify.close();
64 }
65}
66
67struct UpgradedCloseNotify {
68 closed: AtomicBool,
69 task: AtomicWaker,
70}
71
72impl UpgradedCloseNotify {
73 fn new() -> Self {
74 Self {
75 closed: AtomicBool::new(false),
76 task: AtomicWaker::new(),
77 }
78 }
79
80 fn close(&self) {
81 self.closed.store(true, Ordering::Release);
82 self.task.wake();
83 }
84
85 fn poll_closed(&self, cx: &mut Context<'_>) -> Poll<()> {
86 if self.closed.load(Ordering::Acquire) {
87 return Poll::Ready(());
88 }
89
90 self.task.register(cx.waker());
91
92 if self.closed.load(Ordering::Acquire) {
93 Poll::Ready(())
94 } else {
95 Poll::Pending
96 }
97 }
98}
99
100pin_project! {
101 #[must_use = "futures do nothing unless polled"]
102 pub struct UpgradedSendStreamTask<B> {
103 #[pin]
104 h2_tx: SendStream<SendBuf<B>>,
105 #[pin]
106 rx: mpsc::Receiver<Cursor<Box<[u8]>>>,
107 close_notify: Arc<UpgradedCloseNotify>,
108 error_tx: Option<oneshot::Sender<crate::Error>>,
109 }
110}
111
112impl<B> UpgradedSendStreamTask<B>
115where
116 B: Buf,
117{
118 fn tick(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), crate::Error>> {
119 let mut me = self.project();
120
121 loop {
126 me.h2_tx.reserve_capacity(1);
130
131 let h2_has_capacity = if me.h2_tx.capacity() == 0 {
132 loop {
134 match me.h2_tx.poll_capacity(cx) {
135 Poll::Ready(Some(Ok(0))) => {}
136 Poll::Ready(Some(Ok(_))) => break true,
137 Poll::Ready(Some(Err(e))) => {
138 return Poll::Ready(Err(crate::Error::new_body_write(e)))
139 }
140 Poll::Ready(None) => {
141 return Poll::Ready(Err(crate::Error::new_body_write(
145 "send stream capacity unexpectedly closed",
146 )));
147 }
148 Poll::Pending => break false,
149 }
150 }
151 } else {
152 true
153 };
154
155 match me.h2_tx.poll_reset(cx) {
156 Poll::Ready(Ok(reason)) => {
157 trace!("stream received RST_STREAM: {:?}", reason);
158 return Poll::Ready(Err(crate::Error::new_body_write(::h2::Error::from(
159 reason,
160 ))));
161 }
162 Poll::Ready(Err(err)) => {
163 return Poll::Ready(Err(crate::Error::new_body_write(err)))
164 }
165 Poll::Pending => (),
166 }
167
168 if !h2_has_capacity {
175 if me.rx.size_hint().0 == 0 && me.close_notify.poll_closed(cx).is_ready() {
178 me.h2_tx
179 .send_data(SendBuf::None, true)
180 .map_err(crate::Error::new_body_write)?;
181 return Poll::Ready(Ok(()));
182 }
183
184 return Poll::Pending;
185 }
186
187 match me.rx.as_mut().poll_next(cx) {
188 Poll::Ready(Some(cursor)) => {
189 me.h2_tx
190 .send_data(SendBuf::Cursor(cursor), false)
191 .map_err(crate::Error::new_body_write)?;
192 }
193 Poll::Ready(None) => {
194 me.h2_tx
195 .send_data(SendBuf::None, true)
196 .map_err(crate::Error::new_body_write)?;
197 return Poll::Ready(Ok(()));
198 }
199 Poll::Pending => {
200 return Poll::Pending;
201 }
202 }
203 }
204 }
205}
206
207impl<B> Future for UpgradedSendStreamTask<B>
208where
209 B: Buf,
210{
211 type Output = ();
212
213 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
214 match self.as_mut().tick(cx) {
215 Poll::Ready(Ok(())) => Poll::Ready(()),
216 Poll::Ready(Err(err)) => {
217 if let Some(tx) = self.error_tx.take() {
218 let _oh_well = tx.send(err);
219 }
220 Poll::Ready(())
221 }
222 Poll::Pending => Poll::Pending,
223 }
224 }
225}
226
227impl Read for H2Upgraded {
230 fn poll_read(
231 mut self: Pin<&mut Self>,
232 cx: &mut Context<'_>,
233 mut read_buf: ReadBufCursor<'_>,
234 ) -> Poll<Result<(), std::io::Error>> {
235 if self.buf.is_empty() {
236 self.buf = loop {
237 match ready!(self.recv_stream.poll_data(cx)) {
238 None => return Poll::Ready(Ok(())),
239 Some(Ok(buf)) if buf.is_empty() && !self.recv_stream.is_end_stream() => {}
240 Some(Ok(buf)) => {
241 self.ping.record_data(buf.len());
242 break buf;
243 }
244 Some(Err(e)) => {
245 return Poll::Ready(match e.reason() {
246 Some(Reason::NO_ERROR) | Some(Reason::CANCEL) => Ok(()),
247 Some(Reason::STREAM_CLOSED) => {
248 Err(std::io::Error::new(std::io::ErrorKind::BrokenPipe, e))
249 }
250 _ => Err(h2_to_io_error(e)),
251 })
252 }
253 }
254 };
255 }
256 let cnt = std::cmp::min(self.buf.len(), read_buf.remaining());
257 read_buf.put_slice(&self.buf[..cnt]);
258 self.buf.advance(cnt);
259 let _ = self.recv_stream.flow_control().release_capacity(cnt);
260 Poll::Ready(Ok(()))
261 }
262}
263
264impl Write for H2Upgraded {
265 fn poll_write(
266 mut self: Pin<&mut Self>,
267 cx: &mut Context<'_>,
268 buf: &[u8],
269 ) -> Poll<Result<usize, std::io::Error>> {
270 if buf.is_empty() {
271 return Poll::Ready(Ok(0));
272 }
273
274 match self.send_stream.tx.poll_ready(cx) {
275 Poll::Ready(Ok(())) => {}
276 Poll::Ready(Err(_task_dropped)) => {
277 return match Pin::new(&mut self.send_stream.error_rx).poll(cx) {
280 Poll::Ready(Ok(reason)) => Poll::Ready(Err(io_error(reason))),
281 Poll::Ready(Err(_task_dropped)) => {
282 Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()))
283 }
284 Poll::Pending => Poll::Pending,
285 };
286 }
287 Poll::Pending => return Poll::Pending,
288 }
289
290 let n = buf.len();
291 match self.send_stream.tx.start_send(Cursor::new(buf.into())) {
292 Ok(()) => Poll::Ready(Ok(n)),
293 Err(_task_dropped) => {
294 match Pin::new(&mut self.send_stream.error_rx).poll(cx) {
297 Poll::Ready(Ok(reason)) => Poll::Ready(Err(io_error(reason))),
298 Poll::Ready(Err(_task_dropped)) => {
299 Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()))
300 }
301 Poll::Pending => Poll::Pending,
302 }
303 }
304 }
305 }
306
307 fn poll_flush(
308 mut self: Pin<&mut Self>,
309 cx: &mut Context<'_>,
310 ) -> Poll<Result<(), std::io::Error>> {
311 match self.send_stream.tx.poll_ready(cx) {
312 Poll::Ready(Ok(())) => Poll::Ready(Ok(())),
313 Poll::Ready(Err(_task_dropped)) => {
314 match Pin::new(&mut self.send_stream.error_rx).poll(cx) {
317 Poll::Ready(Ok(reason)) => Poll::Ready(Err(io_error(reason))),
318 Poll::Ready(Err(_task_dropped)) => Poll::Ready(Ok(())),
319 Poll::Pending => Poll::Pending,
320 }
321 }
322 Poll::Pending => Poll::Pending,
323 }
324 }
325
326 fn poll_shutdown(
327 mut self: Pin<&mut Self>,
328 cx: &mut Context<'_>,
329 ) -> Poll<Result<(), std::io::Error>> {
330 self.send_stream.tx.close_channel();
331 self.send_stream.close_notify.close();
332 match Pin::new(&mut self.send_stream.error_rx).poll(cx) {
333 Poll::Ready(Ok(reason)) => Poll::Ready(Err(io_error(reason))),
334 Poll::Ready(Err(_task_dropped)) => Poll::Ready(Ok(())),
335 Poll::Pending => Poll::Pending,
336 }
337 }
338}
339
340fn io_error(e: crate::Error) -> std::io::Error {
341 std::io::Error::new(std::io::ErrorKind::Other, e)
342}
343
344fn h2_to_io_error(e: h2::Error) -> std::io::Error {
345 if e.is_io() {
346 e.into_io()
347 .expect("h2 error reported io cause without an underlying io error")
348 } else {
349 std::io::Error::new(std::io::ErrorKind::Other, e)
350 }
351}