diff options
Diffstat (limited to 'vendor/tower-http/src/decompression/request')
| -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 |
4 files changed, 0 insertions, 491 deletions
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 - } -} |
