1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! Streaming bodies for Requests and Responses
//!
//! Both clients and servers use streaming bodies for requests and responses, instead of fully
//! buffering them. This approach avoids unnecessary memory usage and enables back-pressure by only
//! reading when needed.
//!
//! There are two main components:
//!
//! - **[`http_body::Body`] trait**: Describes all possible body types. Any type implementing this
//! trait can be used as a body, allowing applications to have fine-grained control over
//! streaming.
//! - **[`Incoming`] concrete type**: An implementation of `Body` provided by this module, used as a
//! receive stream (for server requests and client responses).
//!
//! Additional implementations are available in [`http-body-util`][], such as `Full` or `Empty`
//! bodies.
//!
//! ## Reading a body
//!
//! The [`BodyExt`][] extension trait provides an asynchronous way to read the
//! frames of a body. A frame can contain either data or trailers:
//!
//! ```
//! use http_body_util::BodyExt as _;
//! use hwire::body::Incoming;
//!
//! async fn read_body(mut body: Incoming) -> Result<(), hwire::Error> {
//! while let Some(frame) = body.frame().await {
//! let frame = frame?;
//!
//! if let Some(data) = frame.data_ref() {
//! println!("received {} bytes", data.len());
//! }
//!
//! if let Some(trailers) = frame.trailers_ref() {
//! println!("received trailers: {trailers:?}");
//! }
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! A body only advances when it is polled. Processing each frame before
//! polling for the next one preserves back-pressure on the connection.
//!
//! If a body is known to be small, it can be collected into memory instead:
//!
//! ```
//! use http_body_util::BodyExt as _;
//! use bytes::Bytes;
//! use hwire::body::Incoming;
//!
//! /// Consider using `Limited` if the body is untrusted.
//! async fn read_entire_body(body: Incoming) -> Result<Bytes, hwire::Error> {
//! Ok(body.collect().await?.to_bytes())
//! }
//! ```
//!
//! Collecting buffers the whole body, so it should be avoided for large or
//! untrusted bodies unless their size is limited.
//!
//! [`http-body-util`]: https://docs.rs/http-body-util
//! [`BodyExt`]: https://docs.rs/http-body-util/latest/http_body_util/trait.BodyExt.html
//! [`http_body::Body`]: https://docs.rs/http-body
pub use Incoming;
pub use ;