actix_connector/ssl/
openssl.rs

1use std::marker::PhantomData;
2
3use actix_codec::{AsyncRead, AsyncWrite};
4use actix_service::{NewService, Service};
5use futures::{future::ok, future::FutureResult, Async, Future, Poll};
6use openssl::ssl::{HandshakeError, SslConnector};
7use tokio_openssl::{ConnectAsync, SslConnectorExt, SslStream};
8
9use crate::resolver::RequestHost;
10
11/// Openssl connector factory
12pub struct OpensslConnector<R, T, E> {
13    connector: SslConnector,
14    _t: PhantomData<(R, T, E)>,
15}
16
17impl<R, T, E> OpensslConnector<R, T, E> {
18    pub fn new(connector: SslConnector) -> Self {
19        OpensslConnector {
20            connector,
21            _t: PhantomData,
22        }
23    }
24}
25
26impl<R: RequestHost, T: AsyncRead + AsyncWrite> OpensslConnector<R, T, ()> {
27    pub fn service(
28        connector: SslConnector,
29    ) -> impl Service<Request = (R, T), Response = (R, SslStream<T>), Error = HandshakeError<T>>
30    {
31        OpensslConnectorService {
32            connector: connector,
33            _t: PhantomData,
34        }
35    }
36}
37
38impl<R, T, E> Clone for OpensslConnector<R, T, E> {
39    fn clone(&self) -> Self {
40        Self {
41            connector: self.connector.clone(),
42            _t: PhantomData,
43        }
44    }
45}
46
47impl<R: RequestHost, T: AsyncRead + AsyncWrite, E> NewService<()>
48    for OpensslConnector<R, T, E>
49{
50    type Request = (R, T);
51    type Response = (R, SslStream<T>);
52    type Error = HandshakeError<T>;
53    type Service = OpensslConnectorService<R, T>;
54    type InitError = E;
55    type Future = FutureResult<Self::Service, Self::InitError>;
56
57    fn new_service(&self, _: &()) -> Self::Future {
58        ok(OpensslConnectorService {
59            connector: self.connector.clone(),
60            _t: PhantomData,
61        })
62    }
63}
64
65pub struct OpensslConnectorService<R, T> {
66    connector: SslConnector,
67    _t: PhantomData<(R, T)>,
68}
69
70impl<R: RequestHost, T: AsyncRead + AsyncWrite> Service for OpensslConnectorService<R, T> {
71    type Request = (R, T);
72    type Response = (R, SslStream<T>);
73    type Error = HandshakeError<T>;
74    type Future = ConnectAsyncExt<R, T>;
75
76    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
77        Ok(Async::Ready(()))
78    }
79
80    fn call(&mut self, (req, stream): (R, T)) -> Self::Future {
81        ConnectAsyncExt {
82            fut: SslConnectorExt::connect_async(&self.connector, req.host(), stream),
83            req: Some(req),
84        }
85    }
86}
87
88pub struct ConnectAsyncExt<R, T> {
89    req: Option<R>,
90    fut: ConnectAsync<T>,
91}
92
93impl<R, T> Future for ConnectAsyncExt<R, T>
94where
95    R: RequestHost,
96    T: AsyncRead + AsyncWrite,
97{
98    type Item = (R, SslStream<T>);
99    type Error = HandshakeError<T>;
100
101    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
102        match self.fut.poll()? {
103            Async::Ready(stream) => Ok(Async::Ready((self.req.take().unwrap(), stream))),
104            Async::NotReady => Ok(Async::NotReady),
105        }
106    }
107}