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