http_types/
trailers.rs

1//! HTTP trailing headers.
2//!
3//! Trailing headers are headers that are send *after* the body payload has
4//! been sent. This is for example useful for sending integrity checks of
5//! streamed payloads that are computed on the fly.
6//!
7//! The way trailing headers are sent over the wire varies per protocol. But in
8//! `http-types` we provide a `Trailers` struct that's used to contain the headers.
9//!
10//! To send trailing headers, see `Request::{`[`send_trailers, `][req_send]
11//! [`recv_trailers`][req_recv]`}` and
12//! `Response::{`[`send_trailers, `][res_send][`recv_trailers`][res_recv]`}`.
13//!
14//! [req_send]: ../struct.Request.html#method.send_trailers
15//! [req_recv]: ../struct.Request.html#method.recv_trailers
16//! [res_send]: ../struct.Response.html#method.send_trailers
17//! [res_recv]: ../struct.Response.html#method.recv_trailers
18//!
19//! ## Example
20//!
21//! ```
22//! # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
23//! # async_std::task::block_on(async {
24//! #
25//! use http_types::{Url, Method, Request, Trailers};
26//! use http_types::headers::{HeaderName, HeaderValue};
27//! use async_std::task;
28//! use std::str::FromStr;
29//!
30//! let mut req = Request::new(Method::Get, Url::parse("https://example.com").unwrap());
31//!
32//! let sender = req.send_trailers();
33//! let mut trailers = Trailers::new();
34//! trailers.insert("Content-Type", "text/plain");
35//!
36//! task::spawn(async move {
37//!     let trailers = req.recv_trailers().await;
38//!     # drop(trailers)
39//! });
40//!
41//! sender.send(trailers).await;
42//! #
43//! # Ok(()) })}
44//! ```
45//!
46//! ## See Also
47//! - [MDN HTTP Headers: Trailer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer)
48//! - [HTTP/2 spec: HTTP Sequence](https://http2.github.io/http2-spec/#HttpSequence)
49
50use crate::headers::{
51    HeaderName, HeaderValues, Headers, Iter, IterMut, Names, ToHeaderValues, Values,
52};
53use futures_lite::Stream;
54
55use std::convert::Into;
56use std::future::Future;
57use std::ops::{Deref, DerefMut, Index};
58use std::pin::Pin;
59use std::task::{Context, Poll};
60
61/// A collection of trailing HTTP headers.
62#[derive(Debug)]
63pub struct Trailers {
64    headers: Headers,
65}
66
67impl Trailers {
68    /// Create a new instance of `Trailers`.
69    pub fn new() -> Self {
70        Self {
71            headers: Headers::new(),
72        }
73    }
74
75    /// Insert a header into the headers.
76    ///
77    /// # Examples
78    ///
79    /// ```
80    /// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
81    /// #
82    /// use http_types::Trailers;
83    ///
84    /// let mut trailers = Trailers::new();
85    /// trailers.insert("Content-Type", "text/plain");
86    /// #
87    /// # Ok(()) }
88    /// ```
89    pub fn insert(
90        &mut self,
91        name: impl Into<HeaderName>,
92        values: impl ToHeaderValues,
93    ) -> Option<HeaderValues> {
94        self.headers.insert(name, values)
95    }
96
97    /// Append a header to the headers.
98    ///
99    /// Unlike `insert` this function will not override the contents of a header, but insert a
100    /// header if there aren't any. Or else append to the existing list of headers.
101    ///
102    /// # Examples
103    ///
104    /// ```
105    /// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
106    /// #
107    /// use http_types::Trailers;
108    ///
109    /// let mut trailers = Trailers::new();
110    /// trailers.append("Content-Type", "text/plain");
111    /// #
112    /// # Ok(()) }
113    /// ```
114    pub fn append(&mut self, name: impl Into<HeaderName>, values: impl ToHeaderValues) {
115        self.headers.append(name, values)
116    }
117
118    /// Get a reference to a header.
119    pub fn get(&self, name: impl Into<HeaderName>) -> Option<&HeaderValues> {
120        self.headers.get(name)
121    }
122
123    /// Get a mutable reference to a header.
124    pub fn get_mut(&mut self, name: impl Into<HeaderName>) -> Option<&mut HeaderValues> {
125        self.headers.get_mut(name)
126    }
127
128    /// Remove a header.
129    pub fn remove(&mut self, name: impl Into<HeaderName>) -> Option<HeaderValues> {
130        self.headers.remove(name)
131    }
132
133    /// An iterator visiting all header pairs in arbitrary order.
134    pub fn iter(&self) -> Iter<'_> {
135        self.headers.iter()
136    }
137
138    /// An iterator visiting all header pairs in arbitrary order, with mutable references to the
139    /// values.
140    pub fn iter_mut(&mut self) -> IterMut<'_> {
141        self.headers.iter_mut()
142    }
143
144    /// An iterator visiting all header names in arbitrary order.
145    pub fn names(&self) -> Names<'_> {
146        self.headers.names()
147    }
148
149    /// An iterator visiting all header values in arbitrary order.
150    pub fn values(&self) -> Values<'_> {
151        self.headers.values()
152    }
153}
154
155impl Clone for Trailers {
156    fn clone(&self) -> Self {
157        Self {
158            headers: Headers {
159                headers: self.headers.headers.clone(),
160            },
161        }
162    }
163}
164
165impl Deref for Trailers {
166    type Target = Headers;
167
168    fn deref(&self) -> &Self::Target {
169        &self.headers
170    }
171}
172
173impl DerefMut for Trailers {
174    fn deref_mut(&mut self) -> &mut Self::Target {
175        &mut self.headers
176    }
177}
178
179impl Index<HeaderName> for Trailers {
180    type Output = HeaderValues;
181
182    /// Returns a reference to the value corresponding to the supplied name.
183    ///
184    /// # Panics
185    ///
186    /// Panics if the name is not present in `Trailers`.
187    #[inline]
188    fn index(&self, name: HeaderName) -> &HeaderValues {
189        self.headers.index(name)
190    }
191}
192
193impl Index<&str> for Trailers {
194    type Output = HeaderValues;
195
196    /// Returns a reference to the value corresponding to the supplied name.
197    ///
198    /// # Panics
199    ///
200    /// Panics if the name is not present in `Trailers`.
201    #[inline]
202    fn index(&self, name: &str) -> &HeaderValues {
203        self.headers.index(name)
204    }
205}
206
207/// The sending half of a channel to send trailers.
208///
209/// Unlike `async_channel::Sender` the `send` method on this type can only be
210/// called once, and cannot be cloned. That's because only a single instance of
211/// `Trailers` should be created.
212#[derive(Debug)]
213pub struct Sender {
214    sender: async_channel::Sender<Trailers>,
215}
216
217impl Sender {
218    /// Create a new instance of `Sender`.
219    #[doc(hidden)]
220    pub fn new(sender: async_channel::Sender<Trailers>) -> Self {
221        Self { sender }
222    }
223
224    /// Send a `Trailer`.
225    ///
226    /// The channel will be consumed after having sent trailers.
227    pub async fn send(self, trailers: Trailers) {
228        let _ = self.sender.send(trailers).await;
229    }
230}
231
232/// The receiving half of a channel to send trailers.
233///
234/// Unlike `async_channel::Sender` the `send` method on this type can only be
235/// called once, and cannot be cloned. That's because only a single instance of
236/// `Trailers` should be created.
237#[must_use = "Futures do nothing unless polled or .awaited"]
238#[derive(Debug)]
239pub struct Receiver {
240    receiver: async_channel::Receiver<Trailers>,
241}
242
243impl Receiver {
244    /// Create a new instance of `Receiver`.
245    pub(crate) fn new(receiver: async_channel::Receiver<Trailers>) -> Self {
246        Self { receiver }
247    }
248}
249
250impl Future for Receiver {
251    type Output = Option<Trailers>;
252
253    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
254        Pin::new(&mut self.receiver).poll_next(cx)
255    }
256}