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}