From 619ecf0c33a361ceeebde4b8544ad0926f7da90b Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 25 Jul 2025 14:39:03 +0000 Subject: [PATCH 1/4] docs(ext): improve extensions module overview --- src/ext/mod.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ext/mod.rs b/src/ext/mod.rs index da28da64a5..df85d317d0 100644 --- a/src/ext/mod.rs +++ b/src/ext/mod.rs @@ -1,4 +1,38 @@ -//! HTTP extensions. +//! Extensions for HTTP messages in Hyper. +//! +//! This module provides types and utilities that extend the capabilities of HTTP requests and responses +//! in Hyper. Extensions are additional pieces of information or features that can be attached to HTTP +//! messages via the [`http::Extensions`] map, which is +//! accessible through methods like [`http::Request::extensions`] and [`http::Response::extensions`]. +//! +//! # What are extensions? +//! +//! Extensions allow Hyper to associate extra metadata or behaviors with HTTP messages, beyond the standard +//! headers and body. These can be used by advanced users and library authors to access protocol-specific +//! features, track original header casing, handle informational responses, and more. +//! +//! # How to access extensions +//! +//! Extensions are stored in the `Extensions` map of a request or response. You can access them using: +//! +//! ```rust +//! if let Some(ext) = response.extensions().get::() { +//! // use the extension +//! } +//! ``` +//! +//! # Extension Groups +//! +//! The extensions in this module can be grouped as follows: +//! +//! - **HTTP/1 Reason Phrase**: [`ReasonPhrase`] — Access non-canonical reason phrases in HTTP/1 responses. +//! - **Informational Responses**: [`on_informational`] — Register callbacks for 1xx HTTP/1 responses on the client. +//! - **Header Case Tracking**: Internal types for tracking the original casing and order of headers as received. +//! - **HTTP/2 Protocol Extensions**: [`Protocol`] — Access the `:protocol` pseudo-header for Extended CONNECT in HTTP/2. +//! +//! Some extensions are only available for specific protocols (HTTP/1 or HTTP/2) or use cases (client, server, FFI). +//! +//! See the documentation on each item for details about its usage and requirements. #[cfg(all(any(feature = "client", feature = "server"), feature = "http1"))] use bytes::Bytes; From ac93a8e5fe1c11baaf57cb6dbad5e72d46a3c607 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 25 Jul 2025 19:20:11 +0000 Subject: [PATCH 2/4] docs(ext): improve docs for Protocol ext --- src/ext/mod.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/ext/mod.rs b/src/ext/mod.rs index df85d317d0..7ed33c018f 100644 --- a/src/ext/mod.rs +++ b/src/ext/mod.rs @@ -62,11 +62,26 @@ pub(crate) use informational::OnInformational; #[cfg(all(feature = "http1", feature = "client", feature = "ffi"))] pub(crate) use informational::{on_informational_raw, OnInformationalCallback}; + #[cfg(feature = "http2")] -/// Represents the `:protocol` pseudo-header used by -/// the [Extended CONNECT Protocol]. +/// Extension type representing the `:protocol` pseudo-header in HTTP/2. +/// +/// The `Protocol` extension allows access to the value of the `:protocol` pseudo-header +/// used by the [Extended CONNECT Protocol](https://datatracker.ietf.org/doc/html/rfc8441#section-4). +/// This extension is only sent on HTTP/2 CONNECT requests, most commonly with the value `websocket`. +/// +/// # Example /// -/// [Extended CONNECT Protocol]: https://datatracker.ietf.org/doc/html/rfc8441#section-4 +/// ```rust +/// use hyper::ext::Protocol; +/// use http::{Request, Method, Version}; +/// +/// let mut req = Request::new(()); +/// *req.method_mut() = Method::CONNECT; +/// *req.version_mut() = Version::HTTP_2; +/// req.extensions_mut().insert(Protocol::from_static("websocket")); +/// // Now the request will include the `:protocol` pseudo-header with value "websocket" +/// ``` #[derive(Clone, Eq, PartialEq)] pub struct Protocol { inner: h2::ext::Protocol, From 716474ba3398b35bf7afb1449f13782507b9d850 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 25 Jul 2025 19:44:18 +0000 Subject: [PATCH 3/4] fmt --- src/ext/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ext/mod.rs b/src/ext/mod.rs index 7ed33c018f..ad696260a1 100644 --- a/src/ext/mod.rs +++ b/src/ext/mod.rs @@ -62,7 +62,6 @@ pub(crate) use informational::OnInformational; #[cfg(all(feature = "http1", feature = "client", feature = "ffi"))] pub(crate) use informational::{on_informational_raw, OnInformationalCallback}; - #[cfg(feature = "http2")] /// Extension type representing the `:protocol` pseudo-header in HTTP/2. /// From c2384fce6f63f03304c277ac1583679303592769 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 25 Jul 2025 19:56:35 +0000 Subject: [PATCH 4/4] fix doc test --- src/ext/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ext/mod.rs b/src/ext/mod.rs index ad696260a1..b59d809dea 100644 --- a/src/ext/mod.rs +++ b/src/ext/mod.rs @@ -16,6 +16,7 @@ //! Extensions are stored in the `Extensions` map of a request or response. You can access them using: //! //! ```rust +//! # let response = http::Response::new(()); //! if let Some(ext) = response.extensions().get::() { //! // use the extension //! }