tower_web/middleware/deflate/
service.rs

1use flate2::Compression;
2use futures::{Future, Poll};
3use http;
4use http::header::{CONTENT_ENCODING, HeaderValue};
5use tower_service::Service;
6use util::buf_stream::BufStream;
7use util::buf_stream::deflate::CompressStream;
8
9/// Deflates the inner service's response bodies.
10#[derive(Debug)]
11pub struct DeflateService<S> {
12    inner: S,
13    level: Compression,
14}
15
16/// Deflate the response body.
17#[derive(Debug)]
18pub struct ResponseFuture<T> {
19    inner: T,
20    level: Compression,
21}
22
23impl<S> DeflateService<S> {
24    pub(super) fn new(inner: S, level: Compression) -> DeflateService<S> {
25        DeflateService {
26            inner,
27            level,
28        }
29    }
30}
31
32impl<S, RequestBody, ResponseBody> Service for DeflateService<S>
33where S: Service<Request = http::Request<RequestBody>,
34                Response = http::Response<ResponseBody>>,
35      ResponseBody: BufStream,
36      S::Error: ::std::error::Error,
37{
38    type Request = http::Request<RequestBody>;
39    type Response = http::Response<CompressStream<ResponseBody>>;
40    type Error = S::Error;
41    type Future = ResponseFuture<S::Future>;
42
43    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
44        self.inner.poll_ready()
45    }
46
47    fn call(&mut self, request: Self::Request) -> Self::Future {
48        ResponseFuture {
49            inner: self.inner.call(request),
50            level: self.level,
51        }
52    }
53}
54
55impl<T, B> Future for ResponseFuture<T>
56where
57    T: Future<Item = http::Response<B>>,
58    B: BufStream,
59    T::Error: ::std::error::Error,
60{
61    type Item = http::Response<CompressStream<B>>;
62    type Error = T::Error;
63
64    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
65        let mut response = try_ready!(self.inner.poll())
66            .map(|body| CompressStream::new(body, self.level));
67
68        let content_encoding = HeaderValue::from_static("deflate");
69
70        // Set content-encoding
71        response.headers_mut()
72            .insert(CONTENT_ENCODING, content_encoding);
73
74        Ok(response.into())
75    }
76}