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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
//! # One TLS API to rule them all
//!
//! Support both:
//! * `tokio`
//! * `async-std`
//!
//! and four TLS implementations:
//! * `tls-api-openssl`, wraps `openssl` crate
//! * `tls-api-rustls`, wraps `rustls` crate
//! * `tls-api-native-tls`, wraps `native-tls` crate
//! * `tls-api-security-framework`, wraps `security-framework` crate
//!
//! The idea is that code can be written without the knowledge of the TLS implementation used,
//! like this:
//!
//! ```
//! # { #![cfg(feature = "runtime-tokio")]
//! use tls_api::{TlsConnector, TlsConnectorBuilder};
//! // or async_std::net::TcpStream;
//! use tokio::net::TcpStream;
//! # use tls_api::runtime::AsyncWriteExt;
//! # use tls_api::runtime::AsyncReadExt;
//!
//! async fn download_rust_lang_org<C: TlsConnector>() -> anyhow::Result<Vec<u8>> {
//! let stream = TcpStream::connect(("rust-lang.org", 443)).await?;
//! let mut stream = C::builder()?.build()?.connect("rust-lang.org", stream).await?;
//! stream.write_all(b"GET / HTTP/1.1\r\nHost: rust-lang.org\r\n\r\n").await?;
//! let mut buf = Vec::new();
//! stream.read_to_end(&mut buf).await?;
//! Ok(buf)
//! }
//! # }
//! ```
//!
//! or the same code with dynamic connector:
//!
//! ```
//! # { #![cfg(feature = "runtime-tokio")]
//! use tls_api::TlsConnectorType;
//! // or async_std::net::TcpStream;
//! use tokio::net::TcpStream;
//! # use tls_api::runtime::AsyncWriteExt;
//! # use tls_api::runtime::AsyncReadExt;
//!
//! async fn download_rust_lang_org(connector_type: &dyn TlsConnectorType) -> anyhow::Result<Vec<u8>> {
//! let stream = TcpStream::connect(("rust-lang.org", 443)).await?;
//! let mut stream = connector_type.builder()?.build()?.connect("rust-lang.org", stream).await?;
//! stream.write_all(b"GET / HTTP/1.1\r\nHost: rust-lang.org\r\n\r\n").await?;
//! let mut buf = Vec::new();
//! stream.read_to_end(&mut buf).await?;
//! Ok(buf)
//! }
//! # }
//! ```
//!
//! Have a look at working example invoking all implementation
//! [on GitHub](https://github.com/stepancheg/rust-tls-api/blob/master/examples/examples/download-rust-lang-org.rs#L66).
//!
//! There are also two fake implementations:
//! * `tls-api-stub` crate which returns an error on any operations, useful to check code compiles
//! * `tls-api-no-tls` fake implementation which returns plain sockets without TLS
//!
//! The API is provided to be compatible with both tokio and async-std.
//! Crate features:
//! * `runtime-tokio` enables the implementation over tokio
//! * `runtime-async-std` enables the implementation over async-std
//!
//! Currently the features are mutually exclusive.
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(missing_docs)]
pub use acceptor::TlsAcceptor;
pub use acceptor::TlsAcceptorBuilder;
pub use acceptor_box::TlsAcceptorBox;
pub use acceptor_box::TlsAcceptorBuilderBox;
pub use acceptor_box::TlsAcceptorType;
pub use connector::TlsConnector;
pub use connector::TlsConnectorBuilder;
pub use connector_box::TlsConnectorBox;
pub use connector_box::TlsConnectorBuilderBox;
pub use connector_box::TlsConnectorType;
pub use future::BoxFuture;
pub use info::ImplInfo;
pub use socket::AsyncSocket;
pub use socket_box::AsyncSocketBox;
pub use stream::TlsStream;
pub use stream_dyn::TlsStreamDyn;
pub use stream_dyn::TlsStreamWithSocketDyn;
pub use stream_with_socket::TlsStreamWithSocket;
pub(crate) use crate::assert_kinds::assert_send;
pub(crate) use crate::assert_kinds::assert_send_value;
pub(crate) use crate::assert_kinds::assert_sync;
pub(crate) use error::CommonError;
pub mod runtime;
/// Interfaces needed by API implementor (like `tls-api-rustls`),
/// and not needed by the users of API.
pub mod spi {
pub use crate::stream_dyn::TlsStreamWithUpcastDyn;
pub use crate::thread_local_context::restore_context;
pub use crate::thread_local_context::save_context;
}
mod acceptor;
mod acceptor_box;
mod assert_kinds;
pub mod async_as_sync;
mod connector;
mod connector_box;
mod error;
mod future;
mod info;
mod openssl;
mod socket;
mod socket_box;
mod stream;
mod stream_dyn;
mod stream_with_socket;
mod thread_local_context;
fn _assert_kinds() {
fn connect_future_is_send<C, S>(c: &C, s: S)
where
C: TlsConnector,
S: AsyncSocket,
{
let f = c.connect_with_socket("dom", s);
assert_send_value(f);
}
fn accept_future_is_send<A, S>(a: &A, s: S)
where
A: TlsAcceptor,
S: AsyncSocket,
{
let f = a.accept_with_socket(s);
assert_send_value(f);
}
}