1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! Chain service for decompressing request payload.
use std::marker::PhantomData;

use actix_http::encoding::Decoder;
use actix_service::{NewService, Service};
use bytes::Bytes;
use futures::future::{ok, FutureResult};
use futures::{Async, Poll, Stream};

use crate::dev::Payload;
use crate::error::{Error, PayloadError};
use crate::service::ServiceRequest;
use crate::HttpMessage;

/// `Middleware` for decompressing request's payload.
/// `Decompress` middleware must be added with `App::chain()` method.
///
/// ```rust
/// use actix_web::{web, middleware::encoding, App, HttpResponse};
///
/// fn main() {
///     let app = App::new()
///         .chain(encoding::Decompress::new())
///         .service(
///             web::resource("/test")
///                 .route(web::get().to(|| HttpResponse::Ok()))
///                 .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
///         );
/// }
/// ```
pub struct Decompress<P>(PhantomData<P>);

impl<P> Decompress<P>
where
    P: Stream<Item = Bytes, Error = PayloadError>,
{
    pub fn new() -> Self {
        Decompress(PhantomData)
    }
}

impl<P> NewService for Decompress<P>
where
    P: Stream<Item = Bytes, Error = PayloadError>,
{
    type Request = ServiceRequest<P>;
    type Response = ServiceRequest<Decoder<Payload<P>>>;
    type Error = Error;
    type InitError = ();
    type Service = Decompress<P>;
    type Future = FutureResult<Self::Service, Self::InitError>;

    fn new_service(&self, _: &()) -> Self::Future {
        ok(Decompress(PhantomData))
    }
}

impl<P> Service for Decompress<P>
where
    P: Stream<Item = Bytes, Error = PayloadError>,
{
    type Request = ServiceRequest<P>;
    type Response = ServiceRequest<Decoder<Payload<P>>>;
    type Error = Error;
    type Future = FutureResult<Self::Response, Self::Error>;

    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
        Ok(Async::Ready(()))
    }

    fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
        let (req, payload) = req.into_parts();
        let payload = Decoder::from_headers(payload, req.headers());
        ok(ServiceRequest::from_parts(req, Payload::Stream(payload)))
    }
}