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