//! HTTP Upgrades //! //! This module deals with managing [HTTP Upgrades][mdn] in hyper. Since //! several concepts in HTTP allow for first talking HTTP, and then converting //! to a different protocol, this module conflates them into a single API. //! Those include: //! //! - HTTP/1.1 Upgrades //! - HTTP `CONNECT` //! //! You are responsible for any other pre-requisites to establish an upgrade, //! such as sending the appropriate headers, methods, and status codes. You can //! then use [`on`][] to grab a `Future` which will resolve to the upgraded //! connection object, or an error if the upgrade fails. //! //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism //! //! # Client //! //! Sending an HTTP upgrade from the [`client`](super::client) involves setting //! either the appropriate method, if wanting to `CONNECT`, or headers such as //! `Upgrade` and `Connection`, on the `http::Request`. Once receiving the //! `http::Response` back, you must check for the specific information that the //! upgrade is agreed upon by the server (such as a `101` status code), and then //! get the `Future` from the `Response`. //! //! # Server //! //! Receiving upgrade requests in a server requires you to check the relevant //! headers in a `Request`, and if an upgrade should be done, you then send the //! corresponding headers in a response. To then wait for hyper to finish the //! upgrade, you call `on()` with the `Request`, and then can spawn a task //! awaiting it. //! //! # Example //! //! See [this example][example] showing how upgrades work with both //! Clients and Servers. //! //! [example]: https://github.com/hyperium/hyper/blob/master/examples/upgrades.rs
use std::any::TypeId; use std::error::Error as StdError; use std::fmt; use std::io; use std::marker::Unpin;
use bytes::Bytes; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio::sync::oneshot; #[cfg(any(feature = "http1", feature = "http2"))] use tracing::trace;
/// An upgraded HTTP connection. /// /// This type holds a trait object internally of the original IO that /// was used to speak HTTP before the upgrade. It can be used directly /// as a `Read` or `Write` for convenience. /// /// Alternatively, if the exact type is known, this can be deconstructed /// into its parts. pubstruct Upgraded {
io: Rewind<Box<dyn Io + Send>>,
}
/// A future for a possible HTTP upgrade. /// /// If no upgrade was available, or it doesn't succeed, yields an `Error`. pubstruct OnUpgrade {
rx: Option<oneshot::Receiver<crate::Result<Upgraded>>>,
}
/// The deconstructed parts of an [`Upgraded`](Upgraded) type. /// /// Includes the original IO type, and a read buffer of bytes that the /// HTTP state machine may have already read before completing an upgrade. #[derive(Debug)] pubstruct Parts<T> { /// The original IO object used before the upgrade. pub io: T, /// A buffer of bytes that have been read but not processed as HTTP. /// /// For instance, if the `Connection` is used for an HTTP upgrade request, /// it is possible the server sent back the first bytes of the new protocol /// along with the response upgrade. /// /// You will want to check for any existing bytes if you plan to continue /// communicating on the IO object. pub read_buf: Bytes,
_inner: (),
}
/// Gets a pending HTTP upgrade from this message. /// /// This can be called on the following types: /// /// - `http::Request<B>` /// - `http::Response<B>` /// - `&mut http::Request<B>` /// - `&mut http::Response<B>` pubfn on<T: sealed::CanUpgrade>(msg: T) -> OnUpgrade {
msg.on_upgrade()
}
#[cfg(feature = "http1")] /// Don't fulfill the pending Upgrade, but instead signal that /// upgrades are handled manually. pub(super) fn manual(self) {
trace!("pending upgrade handled manually"); let _ = self.tx.send(Err(crate::Error::new_user_manual_upgrade()));
}
}
// ===== impl UpgradeExpected =====
/// Error cause returned when an upgrade was expected but canceled /// for whatever reason. /// /// This likely means the actual `Conn` future wasn't polled and upgraded. #[derive(Debug)] struct UpgradeExpected;
impl fmt::Display for UpgradeExpected { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("upgrade expected but not completed")
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.