tower_web/middleware/deflate/
service.rs1use 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#[derive(Debug)]
11pub struct DeflateService<S> {
12 inner: S,
13 level: Compression,
14}
15
16#[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 response.headers_mut()
72 .insert(CONTENT_ENCODING, content_encoding);
73
74 Ok(response.into())
75 }
76}