hyper_util/server/conn/auto/
upgrade.rs

1//! Upgrade utilities.
2
3use bytes::{Bytes, BytesMut};
4use hyper::{
5    rt::{Read, Write},
6    upgrade::Upgraded,
7};
8
9use crate::common::rewind::Rewind;
10
11/// Tries to downcast the internal trait object to the type passed.
12///
13/// On success, returns the downcasted parts. On error, returns the Upgraded back.
14/// This is a kludge to work around the fact that the machinery provided by
15/// [`hyper_util::server::con::auto`] wraps the inner `T` with a private type
16/// that is not reachable from outside the crate.
17///
18/// This kludge will be removed when this machinery is added back to the main
19/// `hyper` code.
20pub fn downcast<T>(upgraded: Upgraded) -> Result<Parts<T>, Upgraded>
21where
22    T: Read + Write + Unpin + 'static,
23{
24    let hyper::upgrade::Parts {
25        io: rewind,
26        mut read_buf,
27        ..
28    } = upgraded.downcast::<Rewind<T>>()?;
29
30    if let Some(pre) = rewind.pre {
31        read_buf = if read_buf.is_empty() {
32            pre
33        } else {
34            let mut buf = BytesMut::from(read_buf);
35
36            buf.extend_from_slice(&pre);
37
38            buf.freeze()
39        };
40    }
41
42    Ok(Parts {
43        io: rewind.inner,
44        read_buf,
45    })
46}
47
48/// The deconstructed parts of an [`Upgraded`] type.
49///
50/// Includes the original IO type, and a read buffer of bytes that the
51/// HTTP state machine may have already read before completing an upgrade.
52#[derive(Debug)]
53#[non_exhaustive]
54pub struct Parts<T> {
55    /// The original IO object used before the upgrade.
56    pub io: T,
57    /// A buffer of bytes that have been read but not processed as HTTP.
58    ///
59    /// For instance, if the `Connection` is used for an HTTP upgrade request,
60    /// it is possible the server sent back the first bytes of the new protocol
61    /// along with the response upgrade.
62    ///
63    /// You will want to check for any existing bytes if you plan to continue
64    /// communicating on the IO object.
65    pub read_buf: Bytes,
66}