actix_connector/ssl/
openssl.rs1use 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
11pub 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}