1use std::{
26 error::Error as StdError,
27 fmt,
28 future::Future,
29 io,
30 pin::Pin,
31 sync::{Arc, Mutex},
32 task::{Context, Poll},
33};
34
35use bytes::Bytes;
36use tokio::{
37 io::{AsyncRead, AsyncWrite, ReadBuf},
38 sync::oneshot,
39};
40
41use self::rewind::Rewind;
42use super::{Error, Result};
43use crate::lock::LockResultExt;
44
45pub struct Upgraded {
54 io: Rewind<Box<dyn Io + Send>>,
55}
56
57#[derive(Clone)]
61pub struct OnUpgrade {
62 rx: Option<Arc<Mutex<oneshot::Receiver<Result<Upgraded>>>>>,
63}
64
65#[inline]
74pub fn on<T: sealed::CanUpgrade>(msg: T) -> OnUpgrade {
75 msg.on_upgrade()
76}
77
78pub(crate) struct Pending {
79 tx: oneshot::Sender<Result<Upgraded>>,
80}
81
82pub(crate) fn pending() -> (Pending, OnUpgrade) {
83 let (tx, rx) = oneshot::channel();
84 (
85 Pending { tx },
86 OnUpgrade {
87 rx: Some(Arc::new(Mutex::new(rx))),
88 },
89 )
90}
91
92impl Upgraded {
95 #[inline]
96 pub(crate) fn new<T>(io: T, read_buf: Bytes) -> Self
97 where
98 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
99 {
100 Upgraded {
101 io: Rewind::new_buffered(Box::new(io), read_buf),
102 }
103 }
104}
105
106impl AsyncRead for Upgraded {
107 #[inline]
108 fn poll_read(
109 mut self: Pin<&mut Self>,
110 cx: &mut Context<'_>,
111 buf: &mut ReadBuf<'_>,
112 ) -> Poll<io::Result<()>> {
113 Pin::new(&mut self.io).poll_read(cx, buf)
114 }
115}
116
117impl AsyncWrite for Upgraded {
118 #[inline]
119 fn poll_write(
120 mut self: Pin<&mut Self>,
121 cx: &mut Context<'_>,
122 buf: &[u8],
123 ) -> Poll<io::Result<usize>> {
124 Pin::new(&mut self.io).poll_write(cx, buf)
125 }
126
127 #[inline]
128 fn poll_write_vectored(
129 mut self: Pin<&mut Self>,
130 cx: &mut Context<'_>,
131 bufs: &[io::IoSlice<'_>],
132 ) -> Poll<io::Result<usize>> {
133 Pin::new(&mut self.io).poll_write_vectored(cx, bufs)
134 }
135
136 #[inline]
137 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
138 Pin::new(&mut self.io).poll_flush(cx)
139 }
140
141 #[inline]
142 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
143 Pin::new(&mut self.io).poll_shutdown(cx)
144 }
145
146 #[inline]
147 fn is_write_vectored(&self) -> bool {
148 self.io.is_write_vectored()
149 }
150}
151
152impl fmt::Debug for Upgraded {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 f.debug_struct("Upgraded").finish()
155 }
156}
157
158impl OnUpgrade {
161 #[inline]
162 pub(super) fn none() -> Self {
163 OnUpgrade { rx: None }
164 }
165
166 #[inline]
167 pub(super) fn is_none(&self) -> bool {
168 self.rx.is_none()
169 }
170}
171
172impl Future for OnUpgrade {
173 type Output = Result<Upgraded, Error>;
174
175 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
176 match self.rx {
177 Some(ref rx) => Pin::new(&mut *rx.lock().panic_if_poisoned())
178 .poll(cx)
179 .map(|res| match res {
180 Ok(Ok(upgraded)) => Ok(upgraded),
181 Ok(Err(err)) => Err(err),
182 Err(_oneshot_canceled) => Err(Error::new_canceled().with(UpgradeExpected)),
183 }),
184 None => Poll::Ready(Err(Error::new_user_no_upgrade())),
185 }
186 }
187}
188
189impl Pending {
192 #[inline]
193 pub(super) fn fulfill(self, upgraded: Upgraded) {
194 trace!("pending upgrade fulfill");
195 let _ = self.tx.send(Ok(upgraded));
196 }
197
198 #[inline]
201 pub(super) fn manual(self) {
202 trace!("pending upgrade handled manually");
203 let _ = self.tx.send(Err(Error::new_user_manual_upgrade()));
204 }
205}
206
207#[derive(Debug)]
214struct UpgradeExpected;
215
216impl fmt::Display for UpgradeExpected {
217 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218 f.write_str("upgrade expected but not completed")
219 }
220}
221
222impl StdError for UpgradeExpected {}
223
224trait Io: AsyncRead + AsyncWrite + Unpin + 'static {}
227
228impl<T: AsyncRead + AsyncWrite + Unpin + 'static> Io for T {}
229
230mod sealed {
231 use super::OnUpgrade;
232
233 pub trait CanUpgrade {
234 fn on_upgrade(self) -> OnUpgrade;
235 }
236
237 impl<B> CanUpgrade for http::Request<B> {
238 fn on_upgrade(mut self) -> OnUpgrade {
239 self.extensions_mut()
240 .remove::<OnUpgrade>()
241 .unwrap_or_else(OnUpgrade::none)
242 }
243 }
244
245 impl<B> CanUpgrade for &'_ mut http::Request<B> {
246 fn on_upgrade(self) -> OnUpgrade {
247 self.extensions_mut()
248 .remove::<OnUpgrade>()
249 .unwrap_or_else(OnUpgrade::none)
250 }
251 }
252
253 impl<B> CanUpgrade for http::Response<B> {
254 fn on_upgrade(mut self) -> OnUpgrade {
255 self.extensions_mut()
256 .remove::<OnUpgrade>()
257 .unwrap_or_else(OnUpgrade::none)
258 }
259 }
260
261 impl<B> CanUpgrade for &'_ mut http::Response<B> {
262 fn on_upgrade(self) -> OnUpgrade {
263 self.extensions_mut()
264 .remove::<OnUpgrade>()
265 .unwrap_or_else(OnUpgrade::none)
266 }
267 }
268}
269
270mod rewind {
271 use std::{
272 cmp, io,
273 pin::Pin,
274 task::{Context, Poll},
275 };
276
277 use bytes::{Buf, Bytes};
278 use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
279
280 #[derive(Debug)]
282 pub(crate) struct Rewind<T> {
283 pre: Option<Bytes>,
284 inner: T,
285 }
286
287 impl<T> Rewind<T> {
288 #[inline]
289 pub(crate) fn new_buffered(io: T, buf: Bytes) -> Self {
290 Rewind {
291 pre: Some(buf),
292 inner: io,
293 }
294 }
295
296 #[cfg(test)]
297 pub(crate) fn rewind(&mut self, bs: Bytes) {
298 debug_assert!(self.pre.is_none());
299 self.pre = Some(bs);
300 }
301 }
302
303 impl<T> AsyncRead for Rewind<T>
304 where
305 T: AsyncRead + Unpin,
306 {
307 fn poll_read(
308 mut self: Pin<&mut Self>,
309 cx: &mut Context<'_>,
310 buf: &mut ReadBuf<'_>,
311 ) -> Poll<io::Result<()>> {
312 if let Some(mut prefix) = self.pre.take() {
313 if !prefix.is_empty() {
315 let copy_len = cmp::min(prefix.len(), buf.remaining());
316 buf.put_slice(&prefix[..copy_len]);
318 prefix.advance(copy_len);
319 if !prefix.is_empty() {
321 self.pre = Some(prefix);
322 }
323
324 return Poll::Ready(Ok(()));
325 }
326 }
327 Pin::new(&mut self.inner).poll_read(cx, buf)
328 }
329 }
330
331 impl<T> AsyncWrite for Rewind<T>
332 where
333 T: AsyncWrite + Unpin,
334 {
335 #[inline]
336 fn poll_write(
337 mut self: Pin<&mut Self>,
338 cx: &mut Context<'_>,
339 buf: &[u8],
340 ) -> Poll<io::Result<usize>> {
341 Pin::new(&mut self.inner).poll_write(cx, buf)
342 }
343
344 #[inline]
345 fn poll_write_vectored(
346 mut self: Pin<&mut Self>,
347 cx: &mut Context<'_>,
348 bufs: &[io::IoSlice<'_>],
349 ) -> Poll<io::Result<usize>> {
350 Pin::new(&mut self.inner).poll_write_vectored(cx, bufs)
351 }
352
353 #[inline]
354 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
355 Pin::new(&mut self.inner).poll_flush(cx)
356 }
357
358 #[inline]
359 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
360 Pin::new(&mut self.inner).poll_shutdown(cx)
361 }
362
363 #[inline]
364 fn is_write_vectored(&self) -> bool {
365 self.inner.is_write_vectored()
366 }
367 }
368
369 #[cfg(test)]
370 mod tests {
371 use bytes::Bytes;
372 use tokio::io::AsyncReadExt;
373
374 use super::Rewind;
375
376 #[tokio::test]
377 async fn partial_rewind() {
378 let underlying = [104, 101, 108, 108, 111];
379
380 let mock = tokio_test::io::Builder::new().read(&underlying).build();
381
382 let mut stream = Rewind::new_buffered(mock, Bytes::new());
383
384 let mut buf = [0; 2];
386 stream.read_exact(&mut buf).await.expect("read1");
387
388 stream.rewind(Bytes::copy_from_slice(&buf[..]));
390
391 let mut buf = [0; 5];
392 stream.read_exact(&mut buf).await.expect("read1");
393
394 assert_eq!(&buf, &underlying);
396 }
397
398 #[tokio::test]
399 async fn full_rewind() {
400 let underlying = [104, 101, 108, 108, 111];
401
402 let mock = tokio_test::io::Builder::new().read(&underlying).build();
403
404 let mut stream = Rewind::new_buffered(mock, Bytes::new());
405
406 let mut buf = [0; 5];
407 stream.read_exact(&mut buf).await.expect("read1");
408
409 stream.rewind(Bytes::copy_from_slice(&buf[..]));
411
412 let mut buf = [0; 5];
413 stream.read_exact(&mut buf).await.expect("read1");
414
415 assert_eq!(&buf, &underlying);
416 }
417 }
418}