tower_http/decompression/
service.rs1use super::{DecompressionBody, DecompressionLayer, ResponseFuture};
2use crate::compression_utils::AcceptEncoding;
3use http::{
4 header::{self, ACCEPT_ENCODING},
5 Request, Response,
6};
7use http_body::Body;
8use std::task::{Context, Poll};
9use tower_service::Service;
10
11#[derive(Debug, Clone)]
18pub struct Decompression<S> {
19 pub(crate) inner: S,
20 pub(crate) accept: AcceptEncoding,
21}
22
23impl<S> Decompression<S> {
24 pub fn new(service: S) -> Self {
26 Self {
27 inner: service,
28 accept: AcceptEncoding::default(),
29 }
30 }
31
32 define_inner_service_accessors!();
33
34 pub fn layer() -> DecompressionLayer {
38 DecompressionLayer::new()
39 }
40
41 #[cfg(feature = "decompression-gzip")]
43 pub fn gzip(mut self, enable: bool) -> Self {
44 self.accept.set_gzip(enable);
45 self
46 }
47
48 #[cfg(feature = "decompression-deflate")]
50 pub fn deflate(mut self, enable: bool) -> Self {
51 self.accept.set_deflate(enable);
52 self
53 }
54
55 #[cfg(feature = "decompression-br")]
57 pub fn br(mut self, enable: bool) -> Self {
58 self.accept.set_br(enable);
59 self
60 }
61
62 #[cfg(feature = "decompression-zstd")]
64 pub fn zstd(mut self, enable: bool) -> Self {
65 self.accept.set_zstd(enable);
66 self
67 }
68
69 pub fn no_gzip(mut self) -> Self {
73 self.accept.set_gzip(false);
74 self
75 }
76
77 pub fn no_deflate(mut self) -> Self {
81 self.accept.set_deflate(false);
82 self
83 }
84
85 pub fn no_br(mut self) -> Self {
89 self.accept.set_br(false);
90 self
91 }
92
93 pub fn no_zstd(mut self) -> Self {
97 self.accept.set_zstd(false);
98 self
99 }
100}
101
102impl<S, ReqBody, ResBody> Service<Request<ReqBody>> for Decompression<S>
103where
104 S: Service<Request<ReqBody>, Response = Response<ResBody>>,
105 ResBody: Body,
106{
107 type Response = Response<DecompressionBody<ResBody>>;
108 type Error = S::Error;
109 type Future = ResponseFuture<S::Future>;
110
111 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
112 self.inner.poll_ready(cx)
113 }
114
115 fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
116 if let header::Entry::Vacant(entry) = req.headers_mut().entry(ACCEPT_ENCODING) {
117 if let Some(accept) = self.accept.to_header_value() {
118 entry.insert(accept);
119 }
120 }
121
122 ResponseFuture {
123 inner: self.inner.call(req),
124 accept: self.accept,
125 }
126 }
127}