diff options
Diffstat (limited to 'vendor/tower-http/src/decompression')
| -rw-r--r-- | vendor/tower-http/src/decompression/body.rs | 408 | ||||
| -rw-r--r-- | vendor/tower-http/src/decompression/future.rs | 80 | ||||
| -rw-r--r-- | vendor/tower-http/src/decompression/layer.rs | 92 | ||||
| -rw-r--r-- | vendor/tower-http/src/decompression/mod.rs | 233 | ||||
| -rw-r--r-- | vendor/tower-http/src/decompression/request/future.rs | 98 | ||||
| -rw-r--r-- | vendor/tower-http/src/decompression/request/layer.rs | 105 | ||||
| -rw-r--r-- | vendor/tower-http/src/decompression/request/mod.rs | 90 | ||||
| -rw-r--r-- | vendor/tower-http/src/decompression/request/service.rs | 198 | ||||
| -rw-r--r-- | vendor/tower-http/src/decompression/service.rs | 127 |
9 files changed, 0 insertions, 1431 deletions
diff --git a/vendor/tower-http/src/decompression/body.rs b/vendor/tower-http/src/decompression/body.rs deleted file mode 100644 index a2970d65..00000000 --- a/vendor/tower-http/src/decompression/body.rs +++ /dev/null @@ -1,408 +0,0 @@ -#![allow(unused_imports)] - -use crate::compression_utils::CompressionLevel; -use crate::{ - compression_utils::{AsyncReadBody, BodyIntoStream, DecorateAsyncRead, WrapBody}, - BoxError, -}; -#[cfg(feature = "decompression-br")] -use async_compression::tokio::bufread::BrotliDecoder; -#[cfg(feature = "decompression-gzip")] -use async_compression::tokio::bufread::GzipDecoder; -#[cfg(feature = "decompression-deflate")] -use async_compression::tokio::bufread::ZlibDecoder; -#[cfg(feature = "decompression-zstd")] -use async_compression::tokio::bufread::ZstdDecoder; -use bytes::{Buf, Bytes}; -use http::HeaderMap; -use http_body::{Body, SizeHint}; -use pin_project_lite::pin_project; -use std::task::Context; -use std::{ - io, - marker::PhantomData, - pin::Pin, - task::{ready, Poll}, -}; -use tokio_util::io::StreamReader; - -pin_project! { - /// Response body of [`RequestDecompression`] and [`Decompression`]. - /// - /// [`RequestDecompression`]: super::RequestDecompression - /// [`Decompression`]: super::Decompression - pub struct DecompressionBody<B> - where - B: Body - { - #[pin] - pub(crate) inner: BodyInner<B>, - } -} - -impl<B> Default for DecompressionBody<B> -where - B: Body + Default, -{ - fn default() -> Self { - Self { - inner: BodyInner::Identity { - inner: B::default(), - }, - } - } -} - -impl<B> DecompressionBody<B> -where - B: Body, -{ - pub(crate) fn new(inner: BodyInner<B>) -> Self { - Self { inner } - } - - /// Get a reference to the inner body - pub fn get_ref(&self) -> &B { - match &self.inner { - #[cfg(feature = "decompression-gzip")] - BodyInner::Gzip { inner } => inner.read.get_ref().get_ref().get_ref().get_ref(), - #[cfg(feature = "decompression-deflate")] - BodyInner::Deflate { inner } => inner.read.get_ref().get_ref().get_ref().get_ref(), - #[cfg(feature = "decompression-br")] - BodyInner::Brotli { inner } => inner.read.get_ref().get_ref().get_ref().get_ref(), - #[cfg(feature = "decompression-zstd")] - BodyInner::Zstd { inner } => inner.read.get_ref().get_ref().get_ref().get_ref(), - BodyInner::Identity { inner } => inner, - - // FIXME: Remove once possible; see https://github.com/rust-lang/rust/issues/51085 - #[cfg(not(feature = "decompression-gzip"))] - BodyInner::Gzip { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-deflate"))] - BodyInner::Deflate { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-br"))] - BodyInner::Brotli { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-zstd"))] - BodyInner::Zstd { inner } => match inner.0 {}, - } - } - - /// Get a mutable reference to the inner body - pub fn get_mut(&mut self) -> &mut B { - match &mut self.inner { - #[cfg(feature = "decompression-gzip")] - BodyInner::Gzip { inner } => inner.read.get_mut().get_mut().get_mut().get_mut(), - #[cfg(feature = "decompression-deflate")] - BodyInner::Deflate { inner } => inner.read.get_mut().get_mut().get_mut().get_mut(), - #[cfg(feature = "decompression-br")] - BodyInner::Brotli { inner } => inner.read.get_mut().get_mut().get_mut().get_mut(), - #[cfg(feature = "decompression-zstd")] - BodyInner::Zstd { inner } => inner.read.get_mut().get_mut().get_mut().get_mut(), - BodyInner::Identity { inner } => inner, - - #[cfg(not(feature = "decompression-gzip"))] - BodyInner::Gzip { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-deflate"))] - BodyInner::Deflate { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-br"))] - BodyInner::Brotli { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-zstd"))] - BodyInner::Zstd { inner } => match inner.0 {}, - } - } - - /// Get a pinned mutable reference to the inner body - pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut B> { - match self.project().inner.project() { - #[cfg(feature = "decompression-gzip")] - BodyInnerProj::Gzip { inner } => inner - .project() - .read - .get_pin_mut() - .get_pin_mut() - .get_pin_mut() - .get_pin_mut(), - #[cfg(feature = "decompression-deflate")] - BodyInnerProj::Deflate { inner } => inner - .project() - .read - .get_pin_mut() - .get_pin_mut() - .get_pin_mut() - .get_pin_mut(), - #[cfg(feature = "decompression-br")] - BodyInnerProj::Brotli { inner } => inner - .project() - .read - .get_pin_mut() - .get_pin_mut() - .get_pin_mut() - .get_pin_mut(), - #[cfg(feature = "decompression-zstd")] - BodyInnerProj::Zstd { inner } => inner - .project() - .read - .get_pin_mut() - .get_pin_mut() - .get_pin_mut() - .get_pin_mut(), - BodyInnerProj::Identity { inner } => inner, - - #[cfg(not(feature = "decompression-gzip"))] - BodyInnerProj::Gzip { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-deflate"))] - BodyInnerProj::Deflate { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-br"))] - BodyInnerProj::Brotli { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-zstd"))] - BodyInnerProj::Zstd { inner } => match inner.0 {}, - } - } - - /// Consume `self`, returning the inner body - pub fn into_inner(self) -> B { - match self.inner { - #[cfg(feature = "decompression-gzip")] - BodyInner::Gzip { inner } => inner - .read - .into_inner() - .into_inner() - .into_inner() - .into_inner(), - #[cfg(feature = "decompression-deflate")] - BodyInner::Deflate { inner } => inner - .read - .into_inner() - .into_inner() - .into_inner() - .into_inner(), - #[cfg(feature = "decompression-br")] - BodyInner::Brotli { inner } => inner - .read - .into_inner() - .into_inner() - .into_inner() - .into_inner(), - #[cfg(feature = "decompression-zstd")] - BodyInner::Zstd { inner } => inner - .read - .into_inner() - .into_inner() - .into_inner() - .into_inner(), - BodyInner::Identity { inner } => inner, - - #[cfg(not(feature = "decompression-gzip"))] - BodyInner::Gzip { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-deflate"))] - BodyInner::Deflate { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-br"))] - BodyInner::Brotli { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-zstd"))] - BodyInner::Zstd { inner } => match inner.0 {}, - } - } -} - -#[cfg(any( - not(feature = "decompression-gzip"), - not(feature = "decompression-deflate"), - not(feature = "decompression-br"), - not(feature = "decompression-zstd") -))] -pub(crate) enum Never {} - -#[cfg(feature = "decompression-gzip")] -type GzipBody<B> = WrapBody<GzipDecoder<B>>; -#[cfg(not(feature = "decompression-gzip"))] -type GzipBody<B> = (Never, PhantomData<B>); - -#[cfg(feature = "decompression-deflate")] -type DeflateBody<B> = WrapBody<ZlibDecoder<B>>; -#[cfg(not(feature = "decompression-deflate"))] -type DeflateBody<B> = (Never, PhantomData<B>); - -#[cfg(feature = "decompression-br")] -type BrotliBody<B> = WrapBody<BrotliDecoder<B>>; -#[cfg(not(feature = "decompression-br"))] -type BrotliBody<B> = (Never, PhantomData<B>); - -#[cfg(feature = "decompression-zstd")] -type ZstdBody<B> = WrapBody<ZstdDecoder<B>>; -#[cfg(not(feature = "decompression-zstd"))] -type ZstdBody<B> = (Never, PhantomData<B>); - -pin_project! { - #[project = BodyInnerProj] - pub(crate) enum BodyInner<B> - where - B: Body, - { - Gzip { - #[pin] - inner: GzipBody<B>, - }, - Deflate { - #[pin] - inner: DeflateBody<B>, - }, - Brotli { - #[pin] - inner: BrotliBody<B>, - }, - Zstd { - #[pin] - inner: ZstdBody<B>, - }, - Identity { - #[pin] - inner: B, - }, - } -} - -impl<B: Body> BodyInner<B> { - #[cfg(feature = "decompression-gzip")] - pub(crate) fn gzip(inner: WrapBody<GzipDecoder<B>>) -> Self { - Self::Gzip { inner } - } - - #[cfg(feature = "decompression-deflate")] - pub(crate) fn deflate(inner: WrapBody<ZlibDecoder<B>>) -> Self { - Self::Deflate { inner } - } - - #[cfg(feature = "decompression-br")] - pub(crate) fn brotli(inner: WrapBody<BrotliDecoder<B>>) -> Self { - Self::Brotli { inner } - } - - #[cfg(feature = "decompression-zstd")] - pub(crate) fn zstd(inner: WrapBody<ZstdDecoder<B>>) -> Self { - Self::Zstd { inner } - } - - pub(crate) fn identity(inner: B) -> Self { - Self::Identity { inner } - } -} - -impl<B> Body for DecompressionBody<B> -where - B: Body, - B::Error: Into<BoxError>, -{ - type Data = Bytes; - type Error = BoxError; - - fn poll_frame( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> { - match self.project().inner.project() { - #[cfg(feature = "decompression-gzip")] - BodyInnerProj::Gzip { inner } => inner.poll_frame(cx), - #[cfg(feature = "decompression-deflate")] - BodyInnerProj::Deflate { inner } => inner.poll_frame(cx), - #[cfg(feature = "decompression-br")] - BodyInnerProj::Brotli { inner } => inner.poll_frame(cx), - #[cfg(feature = "decompression-zstd")] - BodyInnerProj::Zstd { inner } => inner.poll_frame(cx), - BodyInnerProj::Identity { inner } => match ready!(inner.poll_frame(cx)) { - Some(Ok(frame)) => { - let frame = frame.map_data(|mut buf| buf.copy_to_bytes(buf.remaining())); - Poll::Ready(Some(Ok(frame))) - } - Some(Err(err)) => Poll::Ready(Some(Err(err.into()))), - None => Poll::Ready(None), - }, - - #[cfg(not(feature = "decompression-gzip"))] - BodyInnerProj::Gzip { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-deflate"))] - BodyInnerProj::Deflate { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-br"))] - BodyInnerProj::Brotli { inner } => match inner.0 {}, - #[cfg(not(feature = "decompression-zstd"))] - BodyInnerProj::Zstd { inner } => match inner.0 {}, - } - } - - fn size_hint(&self) -> SizeHint { - match self.inner { - BodyInner::Identity { ref inner } => inner.size_hint(), - _ => SizeHint::default(), - } - } -} - -#[cfg(feature = "decompression-gzip")] -impl<B> DecorateAsyncRead for GzipDecoder<B> -where - B: Body, -{ - type Input = AsyncReadBody<B>; - type Output = GzipDecoder<Self::Input>; - - fn apply(input: Self::Input, _quality: CompressionLevel) -> Self::Output { - let mut decoder = GzipDecoder::new(input); - decoder.multiple_members(true); - decoder - } - - fn get_pin_mut(pinned: Pin<&mut Self::Output>) -> Pin<&mut Self::Input> { - pinned.get_pin_mut() - } -} - -#[cfg(feature = "decompression-deflate")] -impl<B> DecorateAsyncRead for ZlibDecoder<B> -where - B: Body, -{ - type Input = AsyncReadBody<B>; - type Output = ZlibDecoder<Self::Input>; - - fn apply(input: Self::Input, _quality: CompressionLevel) -> Self::Output { - ZlibDecoder::new(input) - } - - fn get_pin_mut(pinned: Pin<&mut Self::Output>) -> Pin<&mut Self::Input> { - pinned.get_pin_mut() - } -} - -#[cfg(feature = "decompression-br")] -impl<B> DecorateAsyncRead for BrotliDecoder<B> -where - B: Body, -{ - type Input = AsyncReadBody<B>; - type Output = BrotliDecoder<Self::Input>; - - fn apply(input: Self::Input, _quality: CompressionLevel) -> Self::Output { - BrotliDecoder::new(input) - } - - fn get_pin_mut(pinned: Pin<&mut Self::Output>) -> Pin<&mut Self::Input> { - pinned.get_pin_mut() - } -} - -#[cfg(feature = "decompression-zstd")] -impl<B> DecorateAsyncRead for ZstdDecoder<B> -where - B: Body, -{ - type Input = AsyncReadBody<B>; - type Output = ZstdDecoder<Self::Input>; - - fn apply(input: Self::Input, _quality: CompressionLevel) -> Self::Output { - let mut decoder = ZstdDecoder::new(input); - decoder.multiple_members(true); - decoder - } - - fn get_pin_mut(pinned: Pin<&mut Self::Output>) -> Pin<&mut Self::Input> { - pinned.get_pin_mut() - } -} diff --git a/vendor/tower-http/src/decompression/future.rs b/vendor/tower-http/src/decompression/future.rs deleted file mode 100644 index 36867e97..00000000 --- a/vendor/tower-http/src/decompression/future.rs +++ /dev/null @@ -1,80 +0,0 @@ -#![allow(unused_imports)] - -use super::{body::BodyInner, DecompressionBody}; -use crate::compression_utils::{AcceptEncoding, CompressionLevel, WrapBody}; -use crate::content_encoding::SupportedEncodings; -use http::{header, Response}; -use http_body::Body; -use pin_project_lite::pin_project; -use std::{ - future::Future, - pin::Pin, - task::{ready, Context, Poll}, -}; - -pin_project! { - /// Response future of [`Decompression`]. - /// - /// [`Decompression`]: super::Decompression - #[derive(Debug)] - pub struct ResponseFuture<F> { - #[pin] - pub(crate) inner: F, - pub(crate) accept: AcceptEncoding, - } -} - -impl<F, B, E> Future for ResponseFuture<F> -where - F: Future<Output = Result<Response<B>, E>>, - B: Body, -{ - type Output = Result<Response<DecompressionBody<B>>, E>; - - #[allow(unreachable_code, unused_mut, unused_variables)] - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - let res = ready!(self.as_mut().project().inner.poll(cx)?); - let (mut parts, body) = res.into_parts(); - - let res = - if let header::Entry::Occupied(entry) = parts.headers.entry(header::CONTENT_ENCODING) { - let body = match entry.get().as_bytes() { - #[cfg(feature = "decompression-gzip")] - b"gzip" if self.accept.gzip() => DecompressionBody::new(BodyInner::gzip( - WrapBody::new(body, CompressionLevel::default()), - )), - - #[cfg(feature = "decompression-deflate")] - b"deflate" if self.accept.deflate() => DecompressionBody::new( - BodyInner::deflate(WrapBody::new(body, CompressionLevel::default())), - ), - - #[cfg(feature = "decompression-br")] - b"br" if self.accept.br() => DecompressionBody::new(BodyInner::brotli( - WrapBody::new(body, CompressionLevel::default()), - )), - - #[cfg(feature = "decompression-zstd")] - b"zstd" if self.accept.zstd() => DecompressionBody::new(BodyInner::zstd( - WrapBody::new(body, CompressionLevel::default()), - )), - - _ => { - return Poll::Ready(Ok(Response::from_parts( - parts, - DecompressionBody::new(BodyInner::identity(body)), - ))) - } - }; - - entry.remove(); - parts.headers.remove(header::CONTENT_LENGTH); - - Response::from_parts(parts, body) - } else { - Response::from_parts(parts, DecompressionBody::new(BodyInner::identity(body))) - }; - - Poll::Ready(Ok(res)) - } -} diff --git a/vendor/tower-http/src/decompression/layer.rs b/vendor/tower-http/src/decompression/layer.rs deleted file mode 100644 index 4a184c16..00000000 --- a/vendor/tower-http/src/decompression/layer.rs +++ /dev/null @@ -1,92 +0,0 @@ -use super::Decompression; -use crate::compression_utils::AcceptEncoding; -use tower_layer::Layer; - -/// Decompresses response bodies of the underlying service. -/// -/// This adds the `Accept-Encoding` header to requests and transparently decompresses response -/// bodies based on the `Content-Encoding` header. -/// -/// See the [module docs](crate::decompression) for more details. -#[derive(Debug, Default, Clone)] -pub struct DecompressionLayer { - accept: AcceptEncoding, -} - -impl<S> Layer<S> for DecompressionLayer { - type Service = Decompression<S>; - - fn layer(&self, service: S) -> Self::Service { - Decompression { - inner: service, - accept: self.accept, - } - } -} - -impl DecompressionLayer { - /// Creates a new `DecompressionLayer`. - pub fn new() -> Self { - Default::default() - } - - /// Sets whether to request the gzip encoding. - #[cfg(feature = "decompression-gzip")] - pub fn gzip(mut self, enable: bool) -> Self { - self.accept.set_gzip(enable); - self - } - - /// Sets whether to request the Deflate encoding. - #[cfg(feature = "decompression-deflate")] - pub fn deflate(mut self, enable: bool) -> Self { - self.accept.set_deflate(enable); - self - } - - /// Sets whether to request the Brotli encoding. - #[cfg(feature = "decompression-br")] - pub fn br(mut self, enable: bool) -> Self { - self.accept.set_br(enable); - self - } - - /// Sets whether to request the Zstd encoding. - #[cfg(feature = "decompression-zstd")] - pub fn zstd(mut self, enable: bool) -> Self { - self.accept.set_zstd(enable); - self - } - - /// Disables the gzip encoding. - /// - /// This method is available even if the `gzip` crate feature is disabled. - pub fn no_gzip(mut self) -> Self { - self.accept.set_gzip(false); - self - } - - /// Disables the Deflate encoding. - /// - /// This method is available even if the `deflate` crate feature is disabled. - pub fn no_deflate(mut self) -> Self { - self.accept.set_deflate(false); - self - } - - /// Disables the Brotli encoding. - /// - /// This method is available even if the `br` crate feature is disabled. - pub fn no_br(mut self) -> Self { - self.accept.set_br(false); - self - } - - /// Disables the Zstd encoding. - /// - /// This method is available even if the `zstd` crate feature is disabled. - pub fn no_zstd(mut self) -> Self { - self.accept.set_zstd(false); - self - } -} diff --git a/vendor/tower-http/src/decompression/mod.rs b/vendor/tower-http/src/decompression/mod.rs deleted file mode 100644 index 50d4d5fa..00000000 --- a/vendor/tower-http/src/decompression/mod.rs +++ /dev/null @@ -1,233 +0,0 @@ -//! Middleware that decompresses request and response bodies. -//! -//! # Examples -//! -//! #### Request -//! -//! ```rust -//! use bytes::Bytes; -//! use flate2::{write::GzEncoder, Compression}; -//! use http::{header, HeaderValue, Request, Response}; -//! use http_body_util::{Full, BodyExt}; -//! use std::{error::Error, io::Write}; -//! use tower::{Service, ServiceBuilder, service_fn, ServiceExt}; -//! use tower_http::{BoxError, decompression::{DecompressionBody, RequestDecompressionLayer}}; -//! -//! # #[tokio::main] -//! # async fn main() -> Result<(), BoxError> { -//! // A request encoded with gzip coming from some HTTP client. -//! let mut encoder = GzEncoder::new(Vec::new(), Compression::default()); -//! encoder.write_all(b"Hello?")?; -//! let request = Request::builder() -//! .header(header::CONTENT_ENCODING, "gzip") -//! .body(Full::from(encoder.finish()?))?; -//! -//! // Our HTTP server -//! let mut server = ServiceBuilder::new() -//! // Automatically decompress request bodies. -//! .layer(RequestDecompressionLayer::new()) -//! .service(service_fn(handler)); -//! -//! // Send the request, with the gzip encoded body, to our server. -//! let _response = server.ready().await?.call(request).await?; -//! -//! // Handler receives request whose body is decoded when read -//! async fn handler( -//! mut req: Request<DecompressionBody<Full<Bytes>>>, -//! ) -> Result<Response<Full<Bytes>>, BoxError>{ -//! let data = req.into_body().collect().await?.to_bytes(); -//! assert_eq!(&data[..], b"Hello?"); -//! Ok(Response::new(Full::from("Hello, World!"))) -//! } -//! # Ok(()) -//! # } -//! ``` -//! -//! #### Response -//! -//! ```rust -//! use bytes::Bytes; -//! use http::{Request, Response}; -//! use http_body_util::{Full, BodyExt}; -//! use std::convert::Infallible; -//! use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; -//! use tower_http::{compression::Compression, decompression::DecompressionLayer, BoxError}; -//! # -//! # #[tokio::main] -//! # async fn main() -> Result<(), tower_http::BoxError> { -//! # async fn handle(req: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, Infallible> { -//! # let body = Full::from("Hello, World!"); -//! # Ok(Response::new(body)) -//! # } -//! -//! // Some opaque service that applies compression. -//! let service = Compression::new(service_fn(handle)); -//! -//! // Our HTTP client. -//! let mut client = ServiceBuilder::new() -//! // Automatically decompress response bodies. -//! .layer(DecompressionLayer::new()) -//! .service(service); -//! -//! // Call the service. -//! // -//! // `DecompressionLayer` takes care of setting `Accept-Encoding`. -//! let request = Request::new(Full::<Bytes>::default()); -//! -//! let response = client -//! .ready() -//! .await? -//! .call(request) -//! .await?; -//! -//! // Read the body -//! let body = response.into_body(); -//! let bytes = body.collect().await?.to_bytes().to_vec(); -//! let body = String::from_utf8(bytes).map_err(Into::<BoxError>::into)?; -//! -//! assert_eq!(body, "Hello, World!"); -//! # -//! # Ok(()) -//! # } -//! ``` - -mod request; - -mod body; -mod future; -mod layer; -mod service; - -pub use self::{ - body::DecompressionBody, future::ResponseFuture, layer::DecompressionLayer, - service::Decompression, -}; - -pub use self::request::future::RequestDecompressionFuture; -pub use self::request::layer::RequestDecompressionLayer; -pub use self::request::service::RequestDecompression; - -#[cfg(test)] -mod tests { - use std::convert::Infallible; - use std::io::Write; - - use super::*; - use crate::test_helpers::Body; - use crate::{compression::Compression, test_helpers::WithTrailers}; - use flate2::write::GzEncoder; - use http::Response; - use http::{HeaderMap, HeaderName, Request}; - use http_body_util::BodyExt; - use tower::{service_fn, Service, ServiceExt}; - - #[tokio::test] - async fn works() { - let mut client = Decompression::new(Compression::new(service_fn(handle))); - - let req = Request::builder() - .header("accept-encoding", "gzip") - .body(Body::empty()) - .unwrap(); - let res = client.ready().await.unwrap().call(req).await.unwrap(); - - // read the body, it will be decompressed automatically - let body = res.into_body(); - let collected = body.collect().await.unwrap(); - let trailers = collected.trailers().cloned().unwrap(); - let decompressed_data = String::from_utf8(collected.to_bytes().to_vec()).unwrap(); - - assert_eq!(decompressed_data, "Hello, World!"); - - // maintains trailers - assert_eq!(trailers["foo"], "bar"); - } - - async fn handle(_req: Request<Body>) -> Result<Response<WithTrailers<Body>>, Infallible> { - let mut trailers = HeaderMap::new(); - trailers.insert(HeaderName::from_static("foo"), "bar".parse().unwrap()); - let body = Body::from("Hello, World!").with_trailers(trailers); - Ok(Response::builder().body(body).unwrap()) - } - - #[tokio::test] - async fn decompress_multi_gz() { - let mut client = Decompression::new(service_fn(handle_multi_gz)); - - let req = Request::builder() - .header("accept-encoding", "gzip") - .body(Body::empty()) - .unwrap(); - let res = client.ready().await.unwrap().call(req).await.unwrap(); - - // read the body, it will be decompressed automatically - let body = res.into_body(); - let decompressed_data = - String::from_utf8(body.collect().await.unwrap().to_bytes().to_vec()).unwrap(); - - assert_eq!(decompressed_data, "Hello, World!"); - } - - #[tokio::test] - async fn decompress_multi_zstd() { - let mut client = Decompression::new(service_fn(handle_multi_zstd)); - - let req = Request::builder() - .header("accept-encoding", "zstd") - .body(Body::empty()) - .unwrap(); - let res = client.ready().await.unwrap().call(req).await.unwrap(); - - // read the body, it will be decompressed automatically - let body = res.into_body(); - let decompressed_data = - String::from_utf8(body.collect().await.unwrap().to_bytes().to_vec()).unwrap(); - - assert_eq!(decompressed_data, "Hello, World!"); - } - - async fn handle_multi_gz(_req: Request<Body>) -> Result<Response<Body>, Infallible> { - let mut buf = Vec::new(); - let mut enc1 = GzEncoder::new(&mut buf, Default::default()); - enc1.write_all(b"Hello, ").unwrap(); - enc1.finish().unwrap(); - - let mut enc2 = GzEncoder::new(&mut buf, Default::default()); - enc2.write_all(b"World!").unwrap(); - enc2.finish().unwrap(); - - let mut res = Response::new(Body::from(buf)); - res.headers_mut() - .insert("content-encoding", "gzip".parse().unwrap()); - Ok(res) - } - - async fn handle_multi_zstd(_req: Request<Body>) -> Result<Response<Body>, Infallible> { - let mut buf = Vec::new(); - let mut enc1 = zstd::Encoder::new(&mut buf, Default::default()).unwrap(); - enc1.write_all(b"Hello, ").unwrap(); - enc1.finish().unwrap(); - - let mut enc2 = zstd::Encoder::new(&mut buf, Default::default()).unwrap(); - enc2.write_all(b"World!").unwrap(); - enc2.finish().unwrap(); - - let mut res = Response::new(Body::from(buf)); - res.headers_mut() - .insert("content-encoding", "zstd".parse().unwrap()); - Ok(res) - } - - #[allow(dead_code)] - async fn is_compatible_with_hyper() { - let client = - hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()) - .build_http(); - let mut client = Decompression::new(client); - - let req = Request::new(Body::empty()); - - let _: Response<DecompressionBody<_>> = - client.ready().await.unwrap().call(req).await.unwrap(); - } -} diff --git a/vendor/tower-http/src/decompression/request/future.rs b/vendor/tower-http/src/decompression/request/future.rs deleted file mode 100644 index bdb22f8b..00000000 --- a/vendor/tower-http/src/decompression/request/future.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::body::UnsyncBoxBody; -use crate::compression_utils::AcceptEncoding; -use crate::BoxError; -use bytes::Buf; -use http::{header, HeaderValue, Response, StatusCode}; -use http_body::Body; -use http_body_util::BodyExt; -use http_body_util::Empty; -use pin_project_lite::pin_project; -use std::future::Future; -use std::pin::Pin; -use std::task::Context; -use std::task::Poll; - -pin_project! { - #[derive(Debug)] - /// Response future of [`RequestDecompression`] - pub struct RequestDecompressionFuture<F, B, E> - where - F: Future<Output = Result<Response<B>, E>>, - B: Body - { - #[pin] - kind: Kind<F, B, E>, - } -} - -pin_project! { - #[derive(Debug)] - #[project = StateProj] - enum Kind<F, B, E> - where - F: Future<Output = Result<Response<B>, E>>, - B: Body - { - Inner { - #[pin] - fut: F - }, - Unsupported { - #[pin] - accept: AcceptEncoding - }, - } -} - -impl<F, B, E> RequestDecompressionFuture<F, B, E> -where - F: Future<Output = Result<Response<B>, E>>, - B: Body, -{ - #[must_use] - pub(super) fn unsupported_encoding(accept: AcceptEncoding) -> Self { - Self { - kind: Kind::Unsupported { accept }, - } - } - - #[must_use] - pub(super) fn inner(fut: F) -> Self { - Self { - kind: Kind::Inner { fut }, - } - } -} - -impl<F, B, E> Future for RequestDecompressionFuture<F, B, E> -where - F: Future<Output = Result<Response<B>, E>>, - B: Body + Send + 'static, - B::Data: Buf + 'static, - B::Error: Into<BoxError> + 'static, -{ - type Output = Result<Response<UnsyncBoxBody<B::Data, BoxError>>, E>; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - match self.project().kind.project() { - StateProj::Inner { fut } => fut.poll(cx).map_ok(|res| { - res.map(|body| UnsyncBoxBody::new(body.map_err(Into::into).boxed_unsync())) - }), - StateProj::Unsupported { accept } => { - let res = Response::builder() - .header( - header::ACCEPT_ENCODING, - accept - .to_header_value() - .unwrap_or(HeaderValue::from_static("identity")), - ) - .status(StatusCode::UNSUPPORTED_MEDIA_TYPE) - .body(UnsyncBoxBody::new( - Empty::new().map_err(Into::into).boxed_unsync(), - )) - .unwrap(); - Poll::Ready(Ok(res)) - } - } - } -} diff --git a/vendor/tower-http/src/decompression/request/layer.rs b/vendor/tower-http/src/decompression/request/layer.rs deleted file mode 100644 index 71200960..00000000 --- a/vendor/tower-http/src/decompression/request/layer.rs +++ /dev/null @@ -1,105 +0,0 @@ -use super::service::RequestDecompression; -use crate::compression_utils::AcceptEncoding; -use tower_layer::Layer; - -/// Decompresses request bodies and calls its underlying service. -/// -/// Transparently decompresses request bodies based on the `Content-Encoding` header. -/// When the encoding in the `Content-Encoding` header is not accepted an `Unsupported Media Type` -/// status code will be returned with the accepted encodings in the `Accept-Encoding` header. -/// -/// Enabling pass-through of unaccepted encodings will not return an `Unsupported Media Type`. But -/// will call the underlying service with the unmodified request if the encoding is not supported. -/// This is disabled by default. -/// -/// See the [module docs](crate::decompression) for more details. -#[derive(Debug, Default, Clone)] -pub struct RequestDecompressionLayer { - accept: AcceptEncoding, - pass_through_unaccepted: bool, -} - -impl<S> Layer<S> for RequestDecompressionLayer { - type Service = RequestDecompression<S>; - - fn layer(&self, service: S) -> Self::Service { - RequestDecompression { - inner: service, - accept: self.accept, - pass_through_unaccepted: self.pass_through_unaccepted, - } - } -} - -impl RequestDecompressionLayer { - /// Creates a new `RequestDecompressionLayer`. - pub fn new() -> Self { - Default::default() - } - - /// Sets whether to support gzip encoding. - #[cfg(feature = "decompression-gzip")] - pub fn gzip(mut self, enable: bool) -> Self { - self.accept.set_gzip(enable); - self - } - - /// Sets whether to support Deflate encoding. - #[cfg(feature = "decompression-deflate")] - pub fn deflate(mut self, enable: bool) -> Self { - self.accept.set_deflate(enable); - self - } - - /// Sets whether to support Brotli encoding. - #[cfg(feature = "decompression-br")] - pub fn br(mut self, enable: bool) -> Self { - self.accept.set_br(enable); - self - } - - /// Sets whether to support Zstd encoding. - #[cfg(feature = "decompression-zstd")] - pub fn zstd(mut self, enable: bool) -> Self { - self.accept.set_zstd(enable); - self - } - - /// Disables support for gzip encoding. - /// - /// This method is available even if the `gzip` crate feature is disabled. - pub fn no_gzip(mut self) -> Self { - self.accept.set_gzip(false); - self - } - - /// Disables support for Deflate encoding. - /// - /// This method is available even if the `deflate` crate feature is disabled. - pub fn no_deflate(mut self) -> Self { - self.accept.set_deflate(false); - self - } - - /// Disables support for Brotli encoding. - /// - /// This method is available even if the `br` crate feature is disabled. - pub fn no_br(mut self) -> Self { - self.accept.set_br(false); - self - } - - /// Disables support for Zstd encoding. - /// - /// This method is available even if the `zstd` crate feature is disabled. - pub fn no_zstd(mut self) -> Self { - self.accept.set_zstd(false); - self - } - - /// Sets whether to pass through the request even when the encoding is not supported. - pub fn pass_through_unaccepted(mut self, enable: bool) -> Self { - self.pass_through_unaccepted = enable; - self - } -} diff --git a/vendor/tower-http/src/decompression/request/mod.rs b/vendor/tower-http/src/decompression/request/mod.rs deleted file mode 100644 index da3d9409..00000000 --- a/vendor/tower-http/src/decompression/request/mod.rs +++ /dev/null @@ -1,90 +0,0 @@ -pub(super) mod future; -pub(super) mod layer; -pub(super) mod service; - -#[cfg(test)] -mod tests { - use super::service::RequestDecompression; - use crate::decompression::DecompressionBody; - use crate::test_helpers::Body; - use flate2::{write::GzEncoder, Compression}; - use http::{header, Request, Response, StatusCode}; - use http_body_util::BodyExt; - use std::{convert::Infallible, io::Write}; - use tower::{service_fn, Service, ServiceExt}; - - #[tokio::test] - async fn decompress_accepted_encoding() { - let req = request_gzip(); - let mut svc = RequestDecompression::new(service_fn(assert_request_is_decompressed)); - let _ = svc.ready().await.unwrap().call(req).await.unwrap(); - } - - #[tokio::test] - async fn support_unencoded_body() { - let req = Request::builder().body(Body::from("Hello?")).unwrap(); - let mut svc = RequestDecompression::new(service_fn(assert_request_is_decompressed)); - let _ = svc.ready().await.unwrap().call(req).await.unwrap(); - } - - #[tokio::test] - async fn unaccepted_content_encoding_returns_unsupported_media_type() { - let req = request_gzip(); - let mut svc = RequestDecompression::new(service_fn(should_not_be_called)).gzip(false); - let res = svc.ready().await.unwrap().call(req).await.unwrap(); - assert_eq!(StatusCode::UNSUPPORTED_MEDIA_TYPE, res.status()); - } - - #[tokio::test] - async fn pass_through_unsupported_encoding_when_enabled() { - let req = request_gzip(); - let mut svc = RequestDecompression::new(service_fn(assert_request_is_passed_through)) - .pass_through_unaccepted(true) - .gzip(false); - let _ = svc.ready().await.unwrap().call(req).await.unwrap(); - } - - async fn assert_request_is_decompressed( - req: Request<DecompressionBody<Body>>, - ) -> Result<Response<Body>, Infallible> { - let (parts, mut body) = req.into_parts(); - let body = read_body(&mut body).await; - - assert_eq!(body, b"Hello?"); - assert!(!parts.headers.contains_key(header::CONTENT_ENCODING)); - - Ok(Response::new(Body::from("Hello, World!"))) - } - - async fn assert_request_is_passed_through( - req: Request<DecompressionBody<Body>>, - ) -> Result<Response<Body>, Infallible> { - let (parts, mut body) = req.into_parts(); - let body = read_body(&mut body).await; - - assert_ne!(body, b"Hello?"); - assert!(parts.headers.contains_key(header::CONTENT_ENCODING)); - - Ok(Response::new(Body::empty())) - } - - async fn should_not_be_called( - _: Request<DecompressionBody<Body>>, - ) -> Result<Response<Body>, Infallible> { - panic!("Inner service should not be called"); - } - - fn request_gzip() -> Request<Body> { - let mut encoder = GzEncoder::new(Vec::new(), Compression::default()); - encoder.write_all(b"Hello?").unwrap(); - let body = encoder.finish().unwrap(); - Request::builder() - .header(header::CONTENT_ENCODING, "gzip") - .body(Body::from(body)) - .unwrap() - } - - async fn read_body(body: &mut DecompressionBody<Body>) -> Vec<u8> { - body.collect().await.unwrap().to_bytes().to_vec() - } -} diff --git a/vendor/tower-http/src/decompression/request/service.rs b/vendor/tower-http/src/decompression/request/service.rs deleted file mode 100644 index 663436e5..00000000 --- a/vendor/tower-http/src/decompression/request/service.rs +++ /dev/null @@ -1,198 +0,0 @@ -use super::future::RequestDecompressionFuture as ResponseFuture; -use super::layer::RequestDecompressionLayer; -use crate::body::UnsyncBoxBody; -use crate::compression_utils::CompressionLevel; -use crate::{ - compression_utils::AcceptEncoding, decompression::body::BodyInner, - decompression::DecompressionBody, BoxError, -}; -use bytes::Buf; -use http::{header, Request, Response}; -use http_body::Body; -use std::task::{Context, Poll}; -use tower_service::Service; - -#[cfg(any( - feature = "decompression-gzip", - feature = "decompression-deflate", - feature = "decompression-br", - feature = "decompression-zstd", -))] -use crate::content_encoding::SupportedEncodings; - -/// Decompresses request bodies and calls its underlying service. -/// -/// Transparently decompresses request bodies based on the `Content-Encoding` header. -/// When the encoding in the `Content-Encoding` header is not accepted an `Unsupported Media Type` -/// status code will be returned with the accepted encodings in the `Accept-Encoding` header. -/// -/// Enabling pass-through of unaccepted encodings will not return an `Unsupported Media Type` but -/// will call the underlying service with the unmodified request if the encoding is not supported. -/// This is disabled by default. -/// -/// See the [module docs](crate::decompression) for more details. -#[derive(Debug, Clone)] -pub struct RequestDecompression<S> { - pub(super) inner: S, - pub(super) accept: AcceptEncoding, - pub(super) pass_through_unaccepted: bool, -} - -impl<S, ReqBody, ResBody, D> Service<Request<ReqBody>> for RequestDecompression<S> -where - S: Service<Request<DecompressionBody<ReqBody>>, Response = Response<ResBody>>, - ReqBody: Body, - ResBody: Body<Data = D> + Send + 'static, - <ResBody as Body>::Error: Into<BoxError>, - D: Buf + 'static, -{ - type Response = Response<UnsyncBoxBody<D, BoxError>>; - type Error = S::Error; - type Future = ResponseFuture<S::Future, ResBody, S::Error>; - - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, req: Request<ReqBody>) -> Self::Future { - let (mut parts, body) = req.into_parts(); - - let body = - if let header::Entry::Occupied(entry) = parts.headers.entry(header::CONTENT_ENCODING) { - match entry.get().as_bytes() { - #[cfg(feature = "decompression-gzip")] - b"gzip" if self.accept.gzip() => { - entry.remove(); - parts.headers.remove(header::CONTENT_LENGTH); - BodyInner::gzip(crate::compression_utils::WrapBody::new( - body, - CompressionLevel::default(), - )) - } - #[cfg(feature = "decompression-deflate")] - b"deflate" if self.accept.deflate() => { - entry.remove(); - parts.headers.remove(header::CONTENT_LENGTH); - BodyInner::deflate(crate::compression_utils::WrapBody::new( - body, - CompressionLevel::default(), - )) - } - #[cfg(feature = "decompression-br")] - b"br" if self.accept.br() => { - entry.remove(); - parts.headers.remove(header::CONTENT_LENGTH); - BodyInner::brotli(crate::compression_utils::WrapBody::new( - body, - CompressionLevel::default(), - )) - } - #[cfg(feature = "decompression-zstd")] - b"zstd" if self.accept.zstd() => { - entry.remove(); - parts.headers.remove(header::CONTENT_LENGTH); - BodyInner::zstd(crate::compression_utils::WrapBody::new( - body, - CompressionLevel::default(), - )) - } - b"identity" => BodyInner::identity(body), - _ if self.pass_through_unaccepted => BodyInner::identity(body), - _ => return ResponseFuture::unsupported_encoding(self.accept), - } - } else { - BodyInner::identity(body) - }; - let body = DecompressionBody::new(body); - let req = Request::from_parts(parts, body); - ResponseFuture::inner(self.inner.call(req)) - } -} - -impl<S> RequestDecompression<S> { - /// Creates a new `RequestDecompression` wrapping the `service`. - pub fn new(service: S) -> Self { - Self { - inner: service, - accept: AcceptEncoding::default(), - pass_through_unaccepted: false, - } - } - - define_inner_service_accessors!(); - - /// Returns a new [`Layer`] that wraps services with a `RequestDecompression` middleware. - /// - /// [`Layer`]: tower_layer::Layer - pub fn layer() -> RequestDecompressionLayer { - RequestDecompressionLayer::new() - } - - /// Passes through the request even when the encoding is not supported. - /// - /// By default pass-through is disabled. - pub fn pass_through_unaccepted(mut self, enabled: bool) -> Self { - self.pass_through_unaccepted = enabled; - self - } - - /// Sets whether to support gzip encoding. - #[cfg(feature = "decompression-gzip")] - pub fn gzip(mut self, enable: bool) -> Self { - self.accept.set_gzip(enable); - self - } - - /// Sets whether to support Deflate encoding. - #[cfg(feature = "decompression-deflate")] - pub fn deflate(mut self, enable: bool) -> Self { - self.accept.set_deflate(enable); - self - } - - /// Sets whether to support Brotli encoding. - #[cfg(feature = "decompression-br")] - pub fn br(mut self, enable: bool) -> Self { - self.accept.set_br(enable); - self - } - - /// Sets whether to support Zstd encoding. - #[cfg(feature = "decompression-zstd")] - pub fn zstd(mut self, enable: bool) -> Self { - self.accept.set_zstd(enable); - self - } - - /// Disables support for gzip encoding. - /// - /// This method is available even if the `gzip` crate feature is disabled. - pub fn no_gzip(mut self) -> Self { - self.accept.set_gzip(false); - self - } - - /// Disables support for Deflate encoding. - /// - /// This method is available even if the `deflate` crate feature is disabled. - pub fn no_deflate(mut self) -> Self { - self.accept.set_deflate(false); - self - } - - /// Disables support for Brotli encoding. - /// - /// This method is available even if the `br` crate feature is disabled. - pub fn no_br(mut self) -> Self { - self.accept.set_br(false); - self - } - - /// Disables support for Zstd encoding. - /// - /// This method is available even if the `zstd` crate feature is disabled. - pub fn no_zstd(mut self) -> Self { - self.accept.set_zstd(false); - self - } -} diff --git a/vendor/tower-http/src/decompression/service.rs b/vendor/tower-http/src/decompression/service.rs deleted file mode 100644 index 50e8ead5..00000000 --- a/vendor/tower-http/src/decompression/service.rs +++ /dev/null @@ -1,127 +0,0 @@ -use super::{DecompressionBody, DecompressionLayer, ResponseFuture}; -use crate::compression_utils::AcceptEncoding; -use http::{ - header::{self, ACCEPT_ENCODING}, - Request, Response, -}; -use http_body::Body; -use std::task::{Context, Poll}; -use tower_service::Service; - -/// Decompresses response bodies of the underlying service. -/// -/// This adds the `Accept-Encoding` header to requests and transparently decompresses response -/// bodies based on the `Content-Encoding` header. -/// -/// See the [module docs](crate::decompression) for more details. -#[derive(Debug, Clone)] -pub struct Decompression<S> { - pub(crate) inner: S, - pub(crate) accept: AcceptEncoding, -} - -impl<S> Decompression<S> { - /// Creates a new `Decompression` wrapping the `service`. - pub fn new(service: S) -> Self { - Self { - inner: service, - accept: AcceptEncoding::default(), - } - } - - define_inner_service_accessors!(); - - /// Returns a new [`Layer`] that wraps services with a `Decompression` middleware. - /// - /// [`Layer`]: tower_layer::Layer - pub fn layer() -> DecompressionLayer { - DecompressionLayer::new() - } - - /// Sets whether to request the gzip encoding. - #[cfg(feature = "decompression-gzip")] - pub fn gzip(mut self, enable: bool) -> Self { - self.accept.set_gzip(enable); - self - } - - /// Sets whether to request the Deflate encoding. - #[cfg(feature = "decompression-deflate")] - pub fn deflate(mut self, enable: bool) -> Self { - self.accept.set_deflate(enable); - self - } - - /// Sets whether to request the Brotli encoding. - #[cfg(feature = "decompression-br")] - pub fn br(mut self, enable: bool) -> Self { - self.accept.set_br(enable); - self - } - - /// Sets whether to request the Zstd encoding. - #[cfg(feature = "decompression-zstd")] - pub fn zstd(mut self, enable: bool) -> Self { - self.accept.set_zstd(enable); - self - } - - /// Disables the gzip encoding. - /// - /// This method is available even if the `gzip` crate feature is disabled. - pub fn no_gzip(mut self) -> Self { - self.accept.set_gzip(false); - self - } - - /// Disables the Deflate encoding. - /// - /// This method is available even if the `deflate` crate feature is disabled. - pub fn no_deflate(mut self) -> Self { - self.accept.set_deflate(false); - self - } - - /// Disables the Brotli encoding. - /// - /// This method is available even if the `br` crate feature is disabled. - pub fn no_br(mut self) -> Self { - self.accept.set_br(false); - self - } - - /// Disables the Zstd encoding. - /// - /// This method is available even if the `zstd` crate feature is disabled. - pub fn no_zstd(mut self) -> Self { - self.accept.set_zstd(false); - self - } -} - -impl<S, ReqBody, ResBody> Service<Request<ReqBody>> for Decompression<S> -where - S: Service<Request<ReqBody>, Response = Response<ResBody>>, - ResBody: Body, -{ - type Response = Response<DecompressionBody<ResBody>>; - type Error = S::Error; - type Future = ResponseFuture<S::Future>; - - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future { - if let header::Entry::Vacant(entry) = req.headers_mut().entry(ACCEPT_ENCODING) { - if let Some(accept) = self.accept.to_header_value() { - entry.insert(accept); - } - } - - ResponseFuture { - inner: self.inner.call(req), - accept: self.accept, - } - } -} |
