tokio_postgres/
tls.rs
1use std::error::Error;
4use std::future::Future;
5use std::pin::Pin;
6use std::task::{Context, Poll};
7use std::{fmt, io};
8use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
9
10pub(crate) mod private {
11 pub struct ForcePrivateApi;
12}
13
14pub struct ChannelBinding {
16 pub(crate) tls_server_end_point: Option<Vec<u8>>,
17}
18
19impl ChannelBinding {
20 pub fn none() -> ChannelBinding {
22 ChannelBinding {
23 tls_server_end_point: None,
24 }
25 }
26
27 pub fn tls_server_end_point(tls_server_end_point: Vec<u8>) -> ChannelBinding {
29 ChannelBinding {
30 tls_server_end_point: Some(tls_server_end_point),
31 }
32 }
33}
34
35#[cfg(feature = "runtime")]
39pub trait MakeTlsConnect<S> {
40 type Stream: TlsStream + Unpin;
42 type TlsConnect: TlsConnect<S, Stream = Self::Stream>;
44 type Error: Into<Box<dyn Error + Sync + Send>>;
46
47 fn make_tls_connect(&mut self, domain: &str) -> Result<Self::TlsConnect, Self::Error>;
51}
52
53pub trait TlsConnect<S> {
55 type Stream: TlsStream + Unpin;
57 type Error: Into<Box<dyn Error + Sync + Send>>;
59 type Future: Future<Output = Result<Self::Stream, Self::Error>>;
61
62 fn connect(self, stream: S) -> Self::Future;
64
65 #[doc(hidden)]
66 fn can_connect(&self, _: private::ForcePrivateApi) -> bool {
67 true
68 }
69}
70
71pub trait TlsStream: AsyncRead + AsyncWrite {
73 fn channel_binding(&self) -> ChannelBinding;
75}
76
77#[derive(Debug, Copy, Clone)]
81pub struct NoTls;
82
83#[cfg(feature = "runtime")]
84impl<S> MakeTlsConnect<S> for NoTls {
85 type Stream = NoTlsStream;
86 type TlsConnect = NoTls;
87 type Error = NoTlsError;
88
89 fn make_tls_connect(&mut self, _: &str) -> Result<NoTls, NoTlsError> {
90 Ok(NoTls)
91 }
92}
93
94impl<S> TlsConnect<S> for NoTls {
95 type Stream = NoTlsStream;
96 type Error = NoTlsError;
97 type Future = NoTlsFuture;
98
99 fn connect(self, _: S) -> NoTlsFuture {
100 NoTlsFuture(())
101 }
102
103 fn can_connect(&self, _: private::ForcePrivateApi) -> bool {
104 false
105 }
106}
107
108pub struct NoTlsFuture(());
110
111impl Future for NoTlsFuture {
112 type Output = Result<NoTlsStream, NoTlsError>;
113
114 fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
115 Poll::Ready(Err(NoTlsError(())))
116 }
117}
118
119pub enum NoTlsStream {}
123
124impl AsyncRead for NoTlsStream {
125 fn poll_read(
126 self: Pin<&mut Self>,
127 _: &mut Context<'_>,
128 _: &mut ReadBuf<'_>,
129 ) -> Poll<io::Result<()>> {
130 match *self {}
131 }
132}
133
134impl AsyncWrite for NoTlsStream {
135 fn poll_write(self: Pin<&mut Self>, _: &mut Context<'_>, _: &[u8]) -> Poll<io::Result<usize>> {
136 match *self {}
137 }
138
139 fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
140 match *self {}
141 }
142
143 fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
144 match *self {}
145 }
146}
147
148impl TlsStream for NoTlsStream {
149 fn channel_binding(&self) -> ChannelBinding {
150 match *self {}
151 }
152}
153
154#[derive(Debug)]
156pub struct NoTlsError(());
157
158impl fmt::Display for NoTlsError {
159 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
160 fmt.write_str("no TLS implementation configured")
161 }
162}
163
164impl Error for NoTlsError {}