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 continue
241 }
242 Some(Ok(buf)) => {
243 self.ping.record_data(buf.len());
244 break buf;
245 }
246 Some(Err(e)) => {
247 return Poll::Ready(match e.reason() {
248 Some(Reason::NO_ERROR) | Some(Reason::CANCEL) => Ok(()),
249 Some(Reason::STREAM_CLOSED) => {
250 Err(std::io::Error::new(std::io::ErrorKind::BrokenPipe, e))
251 }
252 _ => Err(h2_to_io_error(e)),
253 })
254 }
255 }
256 };
257 }
258 let cnt = std::cmp::min(self.buf.len(), read_buf.remaining());
259 read_buf.put_slice(&self.buf[..cnt]);
260 self.buf.advance(cnt);
261 let _ = self.recv_stream.flow_control().release_capacity(cnt);
262 Poll::Ready(Ok(()))
263 }
264}
265
266impl Write for H2Upgraded {
267 fn poll_write(
268 mut self: Pin<&mut Self>,
269 cx: &mut Context<'_>,
270 buf: &[u8],
271 ) -> Poll<Result<usize, std::io::Error>> {
272 if buf.is_empty() {
273 return Poll::Ready(Ok(0));
274 }
275
276 match self.send_stream.tx.poll_ready(cx) {
277 Poll::Ready(Ok(())) => {}
278 Poll::Ready(Err(_task_dropped)) => {
279 return match Pin::new(&mut self.send_stream.error_rx).poll(cx) {
282 Poll::Ready(Ok(reason)) => Poll::Ready(Err(io_error(reason))),
283 Poll::Ready(Err(_task_dropped)) => {
284 Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()))
285 }
286 Poll::Pending => Poll::Pending,
287 };
288 }
289 Poll::Pending => return Poll::Pending,
290 }
291
292 let n = buf.len();
293 match self.send_stream.tx.start_send(Cursor::new(buf.into())) {
294 Ok(()) => Poll::Ready(Ok(n)),
295 Err(_task_dropped) => {
296 match Pin::new(&mut self.send_stream.error_rx).poll(cx) {
299 Poll::Ready(Ok(reason)) => Poll::Ready(Err(io_error(reason))),
300 Poll::Ready(Err(_task_dropped)) => {
301 Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()))
302 }
303 Poll::Pending => Poll::Pending,
304 }
305 }
306 }
307 }
308
309 fn poll_flush(
310 mut self: Pin<&mut Self>,
311 cx: &mut Context<'_>,
312 ) -> Poll<Result<(), std::io::Error>> {
313 match self.send_stream.tx.poll_ready(cx) {
314 Poll::Ready(Ok(())) => Poll::Ready(Ok(())),
315 Poll::Ready(Err(_task_dropped)) => {
316 match Pin::new(&mut self.send_stream.error_rx).poll(cx) {
319 Poll::Ready(Ok(reason)) => Poll::Ready(Err(io_error(reason))),
320 Poll::Ready(Err(_task_dropped)) => Poll::Ready(Ok(())),
321 Poll::Pending => Poll::Pending,
322 }
323 }
324 Poll::Pending => Poll::Pending,
325 }
326 }
327
328 fn poll_shutdown(
329 mut self: Pin<&mut Self>,
330 cx: &mut Context<'_>,
331 ) -> Poll<Result<(), std::io::Error>> {
332 self.send_stream.tx.close_channel();
333 self.send_stream.close_notify.close();
334 match Pin::new(&mut self.send_stream.error_rx).poll(cx) {
335 Poll::Ready(Ok(reason)) => Poll::Ready(Err(io_error(reason))),
336 Poll::Ready(Err(_task_dropped)) => Poll::Ready(Ok(())),
337 Poll::Pending => Poll::Pending,
338 }
339 }
340}
341
342fn io_error(e: crate::Error) -> std::io::Error {
343 std::io::Error::new(std::io::ErrorKind::Other, e)
344}
345
346fn h2_to_io_error(e: h2::Error) -> std::io::Error {
347 if e.is_io() {
348 e.into_io()
349 .expect("h2 error reported io cause without an underlying io error")
350 } else {
351 std::io::Error::new(std::io::ErrorKind::Other, e)
352 }
353}