/rust/registry/src/index.crates.io-1949cf8c6b5b557f/http-body-1.0.1/src/lib.rs
Line | Count | Source |
1 | | #![deny( |
2 | | missing_debug_implementations, |
3 | | missing_docs, |
4 | | unreachable_pub, |
5 | | clippy::missing_safety_doc, |
6 | | clippy::undocumented_unsafe_blocks |
7 | | )] |
8 | | #![cfg_attr(test, deny(warnings))] |
9 | | |
10 | | //! Asynchronous HTTP request or response body. |
11 | | //! |
12 | | //! See [`Body`] for more details. |
13 | | //! |
14 | | //! [`Body`]: trait.Body.html |
15 | | |
16 | | mod frame; |
17 | | mod size_hint; |
18 | | |
19 | | pub use self::frame::Frame; |
20 | | pub use self::size_hint::SizeHint; |
21 | | |
22 | | use bytes::{Buf, Bytes}; |
23 | | use std::convert::Infallible; |
24 | | use std::ops; |
25 | | use std::pin::Pin; |
26 | | use std::task::{Context, Poll}; |
27 | | |
28 | | /// Trait representing a streaming body of a Request or Response. |
29 | | /// |
30 | | /// Individual frames are streamed via the `poll_frame` function, which asynchronously yields |
31 | | /// instances of [`Frame<Data>`]. |
32 | | /// |
33 | | /// Frames can contain a data buffer of type `Self::Data`. Frames can also contain an optional |
34 | | /// set of trailers used to finalize the request/response exchange. This is mostly used when using |
35 | | /// the HTTP/2.0 protocol. |
36 | | /// |
37 | | /// The `size_hint` function provides insight into the total number of bytes that will be streamed. |
38 | | pub trait Body { |
39 | | /// Values yielded by the `Body`. |
40 | | type Data: Buf; |
41 | | |
42 | | /// The error type this `Body` might generate. |
43 | | type Error; |
44 | | |
45 | | #[allow(clippy::type_complexity)] |
46 | | /// Attempt to pull out the next data buffer of this stream. |
47 | | fn poll_frame( |
48 | | self: Pin<&mut Self>, |
49 | | cx: &mut Context<'_>, |
50 | | ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>>; |
51 | | |
52 | | /// Returns `true` when the end of stream has been reached. |
53 | | /// |
54 | | /// An end of stream means that `poll_frame` will return `None`. |
55 | | /// |
56 | | /// A return value of `false` **does not** guarantee that a value will be |
57 | | /// returned from `poll_frame`. |
58 | 0 | fn is_end_stream(&self) -> bool { |
59 | 0 | false |
60 | 0 | } |
61 | | |
62 | | /// Returns the bounds on the remaining length of the stream. |
63 | | /// |
64 | | /// When the **exact** remaining length of the stream is known, the upper bound will be set and |
65 | | /// will equal the lower bound. |
66 | 0 | fn size_hint(&self) -> SizeHint { |
67 | 0 | SizeHint::default() |
68 | 0 | } Unexecuted instantiation: <http_body_util::combinators::map_frame::MapFrame<hyper::body::incoming::Incoming, <tonic::codec::decode::Streaming<ztunnel::xds::types::istio::ca::IstioCertificateResponse>>::new<hyper::body::incoming::Incoming, tonic_prost::codec::ProstDecoder<ztunnel::xds::types::istio::ca::IstioCertificateResponse>>::{closure#0}> as http_body::Body>::size_hintUnexecuted instantiation: <http_body_util::combinators::map_frame::MapFrame<hyper::body::incoming::Incoming, <tonic::codec::decode::Streaming<ztunnel::xds::types::service::discovery::v3::DeltaDiscoveryResponse>>::new<hyper::body::incoming::Incoming, tonic_prost::codec::ProstDecoder<ztunnel::xds::types::service::discovery::v3::DeltaDiscoveryResponse>>::{closure#0}> as http_body::Body>::size_hintUnexecuted instantiation: <tonic::codec::encode::EncodeBody<tonic_prost::codec::ProstEncoder<ztunnel::xds::types::istio::ca::IstioCertificateRequest>, tokio_stream::stream_ext::map::Map<tokio_stream::once::Once<ztunnel::xds::types::istio::ca::IstioCertificateRequest>, core::result::Result<ztunnel::xds::types::istio::ca::IstioCertificateRequest, tonic::status::Status>::Ok>> as http_body::Body>::size_hint Unexecuted instantiation: <tonic::codec::encode::EncodeBody<tonic_prost::codec::ProstEncoder<ztunnel::xds::types::service::discovery::v3::DeltaDiscoveryRequest>, tokio_stream::stream_ext::map::Map<async_stream::async_stream::AsyncStream<ztunnel::xds::types::service::discovery::v3::DeltaDiscoveryRequest, <ztunnel::xds::client::AdsClient>::run_internal::{closure#0}::{closure#3}>, core::result::Result<ztunnel::xds::types::service::discovery::v3::DeltaDiscoveryRequest, tonic::status::Status>::Ok>> as http_body::Body>::size_hintUnexecuted instantiation: <_ as http_body::Body>::size_hint |
69 | | } |
70 | | |
71 | | impl<T: Body + Unpin + ?Sized> Body for &mut T { |
72 | | type Data = T::Data; |
73 | | type Error = T::Error; |
74 | | |
75 | 0 | fn poll_frame( |
76 | 0 | mut self: Pin<&mut Self>, |
77 | 0 | cx: &mut Context<'_>, |
78 | 0 | ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> { |
79 | 0 | Pin::new(&mut **self).poll_frame(cx) |
80 | 0 | } |
81 | | |
82 | 0 | fn is_end_stream(&self) -> bool { |
83 | 0 | Pin::new(&**self).is_end_stream() |
84 | 0 | } |
85 | | |
86 | 0 | fn size_hint(&self) -> SizeHint { |
87 | 0 | Pin::new(&**self).size_hint() |
88 | 0 | } |
89 | | } |
90 | | |
91 | | impl<P> Body for Pin<P> |
92 | | where |
93 | | P: Unpin + ops::DerefMut, |
94 | | P::Target: Body, |
95 | | { |
96 | | type Data = <<P as ops::Deref>::Target as Body>::Data; |
97 | | type Error = <<P as ops::Deref>::Target as Body>::Error; |
98 | | |
99 | 0 | fn poll_frame( |
100 | 0 | self: Pin<&mut Self>, |
101 | 0 | cx: &mut Context<'_>, |
102 | 0 | ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> { |
103 | 0 | Pin::get_mut(self).as_mut().poll_frame(cx) |
104 | 0 | } |
105 | | |
106 | 0 | fn is_end_stream(&self) -> bool { |
107 | 0 | self.as_ref().is_end_stream() |
108 | 0 | } Unexecuted instantiation: <core::pin::Pin<&mut http_body_util::full::Full<bytes::bytes::Bytes>> as http_body::Body>::is_end_stream Unexecuted instantiation: <core::pin::Pin<&mut tonic::body::Body> as http_body::Body>::is_end_stream Unexecuted instantiation: <core::pin::Pin<alloc::boxed::Box<dyn http_body::Body<Error = tonic::status::Status, Data = bytes::bytes::Bytes> + core::marker::Send>> as http_body::Body>::is_end_stream Unexecuted instantiation: <core::pin::Pin<_> as http_body::Body>::is_end_stream |
109 | | |
110 | 0 | fn size_hint(&self) -> SizeHint { |
111 | 0 | self.as_ref().size_hint() |
112 | 0 | } Unexecuted instantiation: <core::pin::Pin<alloc::boxed::Box<dyn http_body::Body<Error = tonic::status::Status, Data = bytes::bytes::Bytes> + core::marker::Send>> as http_body::Body>::size_hint Unexecuted instantiation: <core::pin::Pin<_> as http_body::Body>::size_hint |
113 | | } |
114 | | |
115 | | impl<T: Body + Unpin + ?Sized> Body for Box<T> { |
116 | | type Data = T::Data; |
117 | | type Error = T::Error; |
118 | | |
119 | 0 | fn poll_frame( |
120 | 0 | mut self: Pin<&mut Self>, |
121 | 0 | cx: &mut Context<'_>, |
122 | 0 | ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> { |
123 | 0 | Pin::new(&mut **self).poll_frame(cx) |
124 | 0 | } |
125 | | |
126 | 0 | fn is_end_stream(&self) -> bool { |
127 | 0 | self.as_ref().is_end_stream() |
128 | 0 | } |
129 | | |
130 | 0 | fn size_hint(&self) -> SizeHint { |
131 | 0 | self.as_ref().size_hint() |
132 | 0 | } |
133 | | } |
134 | | |
135 | | impl<B: Body> Body for http::Request<B> { |
136 | | type Data = B::Data; |
137 | | type Error = B::Error; |
138 | | |
139 | 0 | fn poll_frame( |
140 | 0 | self: Pin<&mut Self>, |
141 | 0 | cx: &mut Context<'_>, |
142 | 0 | ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> { |
143 | | // SAFETY: |
144 | | // A pin projection. |
145 | | unsafe { |
146 | 0 | self.map_unchecked_mut(http::Request::body_mut) |
147 | 0 | .poll_frame(cx) |
148 | | } |
149 | 0 | } |
150 | | |
151 | 0 | fn is_end_stream(&self) -> bool { |
152 | 0 | self.body().is_end_stream() |
153 | 0 | } |
154 | | |
155 | 0 | fn size_hint(&self) -> SizeHint { |
156 | 0 | self.body().size_hint() |
157 | 0 | } |
158 | | } |
159 | | |
160 | | impl<B: Body> Body for http::Response<B> { |
161 | | type Data = B::Data; |
162 | | type Error = B::Error; |
163 | | |
164 | 0 | fn poll_frame( |
165 | 0 | self: Pin<&mut Self>, |
166 | 0 | cx: &mut Context<'_>, |
167 | 0 | ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> { |
168 | | // SAFETY: |
169 | | // A pin projection. |
170 | | unsafe { |
171 | 0 | self.map_unchecked_mut(http::Response::body_mut) |
172 | 0 | .poll_frame(cx) |
173 | | } |
174 | 0 | } |
175 | | |
176 | 0 | fn is_end_stream(&self) -> bool { |
177 | 0 | self.body().is_end_stream() |
178 | 0 | } |
179 | | |
180 | 0 | fn size_hint(&self) -> SizeHint { |
181 | 0 | self.body().size_hint() |
182 | 0 | } |
183 | | } |
184 | | |
185 | | impl Body for String { |
186 | | type Data = Bytes; |
187 | | type Error = Infallible; |
188 | | |
189 | 0 | fn poll_frame( |
190 | 0 | mut self: Pin<&mut Self>, |
191 | 0 | _cx: &mut Context<'_>, |
192 | 0 | ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> { |
193 | 0 | if !self.is_empty() { |
194 | 0 | let s = std::mem::take(&mut *self); |
195 | 0 | Poll::Ready(Some(Ok(Frame::data(s.into_bytes().into())))) |
196 | | } else { |
197 | 0 | Poll::Ready(None) |
198 | | } |
199 | 0 | } |
200 | | |
201 | 0 | fn is_end_stream(&self) -> bool { |
202 | 0 | self.is_empty() |
203 | 0 | } |
204 | | |
205 | 0 | fn size_hint(&self) -> SizeHint { |
206 | 0 | SizeHint::with_exact(self.len() as u64) |
207 | 0 | } |
208 | | } |
209 | | |
210 | | #[cfg(test)] |
211 | | fn _assert_bounds() { |
212 | | fn can_be_trait_object(_: &dyn Body<Data = std::io::Cursor<Vec<u8>>, Error = std::io::Error>) {} |
213 | | } |