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}