summaryrefslogtreecommitdiffstats
path: root/third_party/rust/http-body
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/http-body')
-rw-r--r--third_party/rust/http-body/.cargo-checksum.json1
-rw-r--r--third_party/rust/http-body/CHANGELOG.md28
-rw-r--r--third_party/rust/http-body/Cargo.toml29
-rw-r--r--third_party/rust/http-body/LICENSE25
-rw-r--r--third_party/rust/http-body/README.md27
-rw-r--r--third_party/rust/http-body/src/lib.rs242
-rw-r--r--third_party/rust/http-body/src/next.rs31
-rw-r--r--third_party/rust/http-body/src/size_hint.rs86
-rw-r--r--third_party/rust/http-body/tests/is_end_stream.rs79
9 files changed, 548 insertions, 0 deletions
diff --git a/third_party/rust/http-body/.cargo-checksum.json b/third_party/rust/http-body/.cargo-checksum.json
new file mode 100644
index 0000000000..1ed5699702
--- /dev/null
+++ b/third_party/rust/http-body/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"f5b7d70cb2c2177a4c718c17ae87c452cec35525b3e43c56d9cd1c33c78c0ded","Cargo.toml":"264c2707f00a87f511e5f131ce2e4bd67d3458346e86600b15f99e647d559e0b","LICENSE":"0345e2b98685e3807fd802a2478085dcae35023e3da59b5a00f712504314d83a","README.md":"0f90f61ee419eefd4104005ef6900445fafce9a710dd1989463f3cebaf0fafe8","src/lib.rs":"6126e071569d147e36e8377135ddc456b4c89c00a7688487c84fd4e8ef6c0c17","src/next.rs":"d6863067b20c4bb42dced5c17bd954816b1338ce53e8d34ab81dbe240a1601cf","src/size_hint.rs":"017ed58c59b446b93aa4922e35b596490bf8f03af37c631610cc6576f1c21439","tests/is_end_stream.rs":"3a66d80d064f8a447bfa9fd212c2f91855604b1b41f554da3a029bc4a5be3a7e"},"package":"13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"} \ No newline at end of file
diff --git a/third_party/rust/http-body/CHANGELOG.md b/third_party/rust/http-body/CHANGELOG.md
new file mode 100644
index 0000000000..76e6dc8db4
--- /dev/null
+++ b/third_party/rust/http-body/CHANGELOG.md
@@ -0,0 +1,28 @@
+# 0.3.1 (December 13, 2019)
+
+- Implement `Body` for `http::Request<impl Body>` and `http::Response<impl Body>`.
+
+# 0.3.0 (December 4, 2019)
+
+- Rename `next` combinator to `data`.
+
+# 0.2.0 (December 3, 2019)
+
+- Update `http` to v0.2.
+- Update `bytes` to v0.5.
+
+# 0.2.0-alpha.3 (October 1, 2019)
+
+- Fix `Body` to be object-safe.
+
+# 0.2.0-alpha.2 (October 1, 2019)
+
+- Add `next` and `trailers` combinator methods.
+
+# 0.2.0-alpha.1 (August 20, 2019)
+
+- Update to use `Pin` in `poll_data` and `poll_trailers`.
+
+# 0.1.0 (May 7, 2019)
+
+- Initial release
diff --git a/third_party/rust/http-body/Cargo.toml b/third_party/rust/http-body/Cargo.toml
new file mode 100644
index 0000000000..f9cc50faf8
--- /dev/null
+++ b/third_party/rust/http-body/Cargo.toml
@@ -0,0 +1,29 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "http-body"
+version = "0.3.1"
+authors = ["Carl Lerche <me@carllerche.com>", "Lucio Franco <luciofranco14@gmail.com>", "Sean McArthur <sean@seanmonstar.com>"]
+description = "Trait representing an asynchronous, streaming, HTTP request or response body.\n"
+documentation = "https://docs.rs/http-body/0.3.0/http-body"
+readme = "README.md"
+keywords = ["http"]
+categories = ["web-programming"]
+license = "MIT"
+repository = "https://github.com/hyperium/http-body"
+[dependencies.bytes]
+version = "0.5"
+
+[dependencies.http]
+version = "0.2"
diff --git a/third_party/rust/http-body/LICENSE b/third_party/rust/http-body/LICENSE
new file mode 100644
index 0000000000..27b08f2874
--- /dev/null
+++ b/third_party/rust/http-body/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2019 Hyper Contributors
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/third_party/rust/http-body/README.md b/third_party/rust/http-body/README.md
new file mode 100644
index 0000000000..c82ba29056
--- /dev/null
+++ b/third_party/rust/http-body/README.md
@@ -0,0 +1,27 @@
+# HTTP Body
+
+A trait representing asynchronous operations on an HTTP body.
+
+[![crates.io][crates-badge]][crates-url]
+[![documentation][docs-badge]][docs-url]
+[![MIT License][mit-badge]][mit-url]
+[![CI Status][ci-badge]][ci-url]
+
+[crates-badge]: https://img.shields.io/crates/v/http-body.svg
+[crates-url]: https://crates.io/crates/http-body
+[docs-badge]: https://docs.rs/http-body/badge.svg
+[docs-url]: https://docs.rs/http-body
+[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
+[mit-url]: LICENSE
+[ci-badge]: https://github.com/hyperium/http-body/workflows/CI/badge.svg
+[ci-url]: https://github.com/hyperium/http-body/actions?query=workflow%3ACI
+
+## License
+
+This project is licensed under the [MIT license](LICENSE).
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in `http-body` by you, shall be licensed as MIT, without any additional
+terms or conditions.
diff --git a/third_party/rust/http-body/src/lib.rs b/third_party/rust/http-body/src/lib.rs
new file mode 100644
index 0000000000..0d0e061d98
--- /dev/null
+++ b/third_party/rust/http-body/src/lib.rs
@@ -0,0 +1,242 @@
+#![doc(html_root_url = "https://docs.rs/http-body/0.3.1")]
+#![deny(missing_debug_implementations, missing_docs, unreachable_pub)]
+#![cfg_attr(test, deny(warnings))]
+
+//! Asynchronous HTTP request or response body.
+//!
+//! See [`Body`] for more details.
+//!
+//! [`Body`]: trait.Body.html
+
+mod next;
+mod size_hint;
+
+pub use self::next::{Data, Trailers};
+pub use self::size_hint::SizeHint;
+
+use bytes::Buf;
+use http::HeaderMap;
+use std::ops;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+/// Trait representing a streaming body of a Request or Response.
+///
+/// Data is streamed via the `poll_data` function, which asynchronously yields `T: Buf` values. The
+/// `size_hint` function provides insight into the total number of bytes that will be streamed.
+///
+/// The `poll_trailers` function returns an optional set of trailers used to finalize the request /
+/// response exchange. This is mostly used when using the HTTP/2.0 protocol.
+///
+pub trait Body {
+ /// Values yielded by the `Body`.
+ type Data: Buf;
+
+ /// The error type this `Body` might generate.
+ type Error;
+
+ /// Attempt to pull out the next data buffer of this stream.
+ fn poll_data(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>>;
+
+ /// Poll for an optional **single** `HeaderMap` of trailers.
+ ///
+ /// This function should only be called once `poll_data` returns `None`.
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>>;
+
+ /// Returns `true` when the end of stream has been reached.
+ ///
+ /// An end of stream means that both `poll_data` and `poll_trailers` will
+ /// return `None`.
+ ///
+ /// A return value of `false` **does not** guarantee that a value will be
+ /// returned from `poll_stream` or `poll_trailers`.
+ fn is_end_stream(&self) -> bool {
+ false
+ }
+
+ /// Returns the bounds on the remaining length of the stream.
+ ///
+ /// When the **exact** remaining length of the stream is known, the upper bound will be set and
+ /// will equal the lower bound.
+ fn size_hint(&self) -> SizeHint {
+ SizeHint::default()
+ }
+
+ /// Returns future that resolves to next data chunk, if any.
+ fn data(&mut self) -> Data<'_, Self>
+ where
+ Self: Unpin + Sized,
+ {
+ Data(self)
+ }
+
+ /// Returns future that resolves to trailers, if any.
+ fn trailers(&mut self) -> Trailers<'_, Self>
+ where
+ Self: Unpin + Sized,
+ {
+ Trailers(self)
+ }
+}
+
+impl<T: Body + Unpin + ?Sized> Body for &mut T {
+ type Data = T::Data;
+ type Error = T::Error;
+
+ fn poll_data(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ Pin::new(&mut **self).poll_data(cx)
+ }
+
+ fn poll_trailers(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ Pin::new(&mut **self).poll_trailers(cx)
+ }
+
+ fn is_end_stream(&self) -> bool {
+ Pin::new(&**self).is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ Pin::new(&**self).size_hint()
+ }
+}
+
+impl<P> Body for Pin<P>
+where
+ P: Unpin + ops::DerefMut,
+ P::Target: Body,
+{
+ type Data = <<P as ops::Deref>::Target as Body>::Data;
+ type Error = <<P as ops::Deref>::Target as Body>::Error;
+
+ fn poll_data(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ Pin::get_mut(self).as_mut().poll_data(cx)
+ }
+
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ Pin::get_mut(self).as_mut().poll_trailers(cx)
+ }
+
+ fn is_end_stream(&self) -> bool {
+ self.as_ref().is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.as_ref().size_hint()
+ }
+}
+
+impl<T: Body + Unpin + ?Sized> Body for Box<T> {
+ type Data = T::Data;
+ type Error = T::Error;
+
+ fn poll_data(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ Pin::new(&mut **self).poll_data(cx)
+ }
+
+ fn poll_trailers(
+ mut self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ Pin::new(&mut **self).poll_trailers(cx)
+ }
+
+ fn is_end_stream(&self) -> bool {
+ self.as_ref().is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.as_ref().size_hint()
+ }
+}
+
+impl<B: Body> Body for http::Request<B> {
+ type Data = B::Data;
+ type Error = B::Error;
+
+ fn poll_data(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ unsafe {
+ self.map_unchecked_mut(http::Request::body_mut)
+ .poll_data(cx)
+ }
+ }
+
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ unsafe {
+ self.map_unchecked_mut(http::Request::body_mut)
+ .poll_trailers(cx)
+ }
+ }
+
+ fn is_end_stream(&self) -> bool {
+ self.body().is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.body().size_hint()
+ }
+}
+
+impl<B: Body> Body for http::Response<B> {
+ type Data = B::Data;
+ type Error = B::Error;
+
+ fn poll_data(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ unsafe {
+ self.map_unchecked_mut(http::Response::body_mut)
+ .poll_data(cx)
+ }
+ }
+
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ unsafe {
+ self.map_unchecked_mut(http::Response::body_mut)
+ .poll_trailers(cx)
+ }
+ }
+
+ fn is_end_stream(&self) -> bool {
+ self.body().is_end_stream()
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.body().size_hint()
+ }
+}
+
+#[cfg(test)]
+fn _assert_bounds() {
+ fn can_be_trait_object(_: &dyn Body<Data = std::io::Cursor<Vec<u8>>, Error = std::io::Error>) {}
+}
diff --git a/third_party/rust/http-body/src/next.rs b/third_party/rust/http-body/src/next.rs
new file mode 100644
index 0000000000..fc87ffcf01
--- /dev/null
+++ b/third_party/rust/http-body/src/next.rs
@@ -0,0 +1,31 @@
+use crate::Body;
+
+use core::future::Future;
+use core::pin::Pin;
+use core::task;
+
+#[must_use = "futures don't do anything unless polled"]
+#[derive(Debug)]
+/// Future that resolves to the next data chunk from `Body`
+pub struct Data<'a, T: ?Sized>(pub(crate) &'a mut T);
+
+impl<'a, T: Body + Unpin + ?Sized> Future for Data<'a, T> {
+ type Output = Option<Result<T::Data, T::Error>>;
+
+ fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
+ Pin::new(&mut self.0).poll_data(ctx)
+ }
+}
+
+#[must_use = "futures don't do anything unless polled"]
+#[derive(Debug)]
+/// Future that resolves to the optional trailers from `Body`
+pub struct Trailers<'a, T: ?Sized>(pub(crate) &'a mut T);
+
+impl<'a, T: Body + Unpin + ?Sized> Future for Trailers<'a, T> {
+ type Output = Result<Option<http::HeaderMap>, T::Error>;
+
+ fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
+ Pin::new(&mut self.0).poll_trailers(ctx)
+ }
+}
diff --git a/third_party/rust/http-body/src/size_hint.rs b/third_party/rust/http-body/src/size_hint.rs
new file mode 100644
index 0000000000..00a8f19177
--- /dev/null
+++ b/third_party/rust/http-body/src/size_hint.rs
@@ -0,0 +1,86 @@
+use std::u64;
+
+/// A `Body` size hint
+///
+/// The default implementation returns:
+///
+/// * 0 for `lower`
+/// * `None` for `upper`.
+#[derive(Debug, Default, Clone)]
+pub struct SizeHint {
+ lower: u64,
+ upper: Option<u64>,
+}
+
+impl SizeHint {
+ /// Returns a new `SizeHint` with default values
+ #[inline]
+ pub fn new() -> SizeHint {
+ SizeHint::default()
+ }
+
+ /// Returns a new `SizeHint` with both upper and lower bounds set to the
+ /// given value.
+ #[inline]
+ pub fn with_exact(value: u64) -> SizeHint {
+ SizeHint {
+ lower: value,
+ upper: Some(value),
+ }
+ }
+
+ /// Returns the lower bound of data that the `Body` will yield before
+ /// completing.
+ #[inline]
+ pub fn lower(&self) -> u64 {
+ self.lower
+ }
+
+ /// Set the value of the `lower` hint.
+ ///
+ /// # Panics
+ ///
+ /// The function panics if `value` is greater than `upper`.
+ #[inline]
+ pub fn set_lower(&mut self, value: u64) {
+ assert!(value <= self.upper.unwrap_or(u64::MAX));
+ self.lower = value;
+ }
+
+ /// Returns the upper bound of data the `Body` will yield before
+ /// completing, or `None` if the value is unknown.
+ #[inline]
+ pub fn upper(&self) -> Option<u64> {
+ self.upper
+ }
+
+ /// Set the value of the `upper` hint value.
+ ///
+ /// # Panics
+ ///
+ /// This function panics if `value` is less than `lower`.
+ #[inline]
+ pub fn set_upper(&mut self, value: u64) {
+ assert!(value >= self.lower, "`value` is less than than `lower`");
+
+ self.upper = Some(value);
+ }
+
+ /// Returns the exact size of data that will be yielded **if** the
+ /// `lower` and `upper` bounds are equal.
+ #[inline]
+ pub fn exact(&self) -> Option<u64> {
+ if Some(self.lower) == self.upper {
+ self.upper
+ } else {
+ None
+ }
+ }
+
+ /// Set the value of the `lower` and `upper` bounds to exactly the same.
+ #[inline]
+ pub fn set_exact(&mut self, value: u64) {
+ self.lower = value;
+ self.upper = Some(value);
+ }
+}
diff --git a/third_party/rust/http-body/tests/is_end_stream.rs b/third_party/rust/http-body/tests/is_end_stream.rs
new file mode 100644
index 0000000000..beaeb0b1a0
--- /dev/null
+++ b/third_party/rust/http-body/tests/is_end_stream.rs
@@ -0,0 +1,79 @@
+use http::HeaderMap;
+use http_body::{Body, SizeHint};
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+struct Mock {
+ size_hint: SizeHint,
+}
+
+impl Body for Mock {
+ type Data = ::std::io::Cursor<Vec<u8>>;
+ type Error = ();
+
+ fn poll_data(
+ self: Pin<&mut Self>,
+ _cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
+ Poll::Ready(None)
+ }
+
+ fn poll_trailers(
+ self: Pin<&mut Self>,
+ _cx: &mut Context<'_>,
+ ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
+ Poll::Ready(Ok(None))
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ self.size_hint.clone()
+ }
+}
+
+#[test]
+fn is_end_stream_true() {
+ let combos = [
+ (None, None, false),
+ (Some(123), None, false),
+ (Some(0), Some(123), false),
+ (Some(123), Some(123), false),
+ (Some(0), Some(0), false),
+ ];
+
+ for &(lower, upper, is_end_stream) in &combos {
+ let mut size_hint = SizeHint::new();
+ assert_eq!(0, size_hint.lower());
+ assert!(size_hint.upper().is_none());
+
+ if let Some(lower) = lower {
+ size_hint.set_lower(lower);
+ }
+
+ if let Some(upper) = upper {
+ size_hint.set_upper(upper);
+ }
+
+ let mut mock = Mock { size_hint };
+
+ assert_eq!(
+ is_end_stream,
+ Pin::new(&mut mock).is_end_stream(),
+ "size_hint = {:?}",
+ mock.size_hint.clone()
+ );
+ }
+}
+
+#[test]
+fn is_end_stream_default_false() {
+ let mut mock = Mock {
+ size_hint: SizeHint::default(),
+ };
+
+ assert_eq!(
+ false,
+ Pin::new(&mut mock).is_end_stream(),
+ "size_hint = {:?}",
+ mock.size_hint.clone()
+ );
+}