actix-tls-3.4.0/.cargo_vcs_info.json0000644000000001470000000000100127520ustar { "git": { "sha1": "24be36b18d0a649867de0a7a9740cc7599e4bf13" }, "path_in_vcs": "actix-tls" }actix-tls-3.4.0/CHANGES.md000064400000000000000000000163221046102023000131360ustar 00000000000000# Changes ## Unreleased ## 3.4.0 - Add `rustls-0_23`, `rustls-0_23-webpki-roots`, and `rustls-0_23-native-roots` crate features. - Minimum supported Rust version (MSRV) is now 1.70. ## 3.3.0 - Add `rustls-0_22` crate feature which excludes any root certificate methods or re-exports. ## 3.2.0 - Support Rustls v0.22. - Add `{accept, connect}::rustls_0_22` modules. - Add `rustls-0_21-native-roots` and `rustls-0_20-native-roots` crate features which utilize the `rustls-native-certs` crate to enable a `native_roots_cert_store()` functions in each rustls-based `connect` module. - Implement `Host` for `http::Uri` (`http` crate version `1`). ## 3.1.1 - Fix `rustls` v0.21 version requirement. ## 3.1.0 - Support Rustls v0.21. - Add `{accept, connect}::rustls_0_21` modules. - Add `{accept, connect}::rustls_0_20` alias for `{accept, connect}::rustls` modules. - Minimum supported Rust version (MSRV) is now 1.65. ## 3.0.4 - Logs emitted now use the `tracing` crate with `log` compatibility. [#451] [#451]: https://github.com/actix/actix-net/pull/451 ## 3.0.3 - No significant changes since `3.0.2`. ## 3.0.2 - Expose `connect::Connection::new`. [#439] [#439]: https://github.com/actix/actix-net/pull/439 ## 3.0.1 - No significant changes since `3.0.0`. ## 3.0.0 - No significant changes since `3.0.0-rc.2`. ## 3.0.0-rc.2 - Re-export `openssl::SslConnectorBuilder` in `connect::openssl::reexports`. [#429] [#429]: https://github.com/actix/actix-net/pull/429 ## 3.0.0-rc.1 ### Added - Derive `Debug` for `connect::Connection`. [#422] - Implement `Display` for `accept::TlsError`. [#422] - Implement `Error` for `accept::TlsError` where both types also implement `Error`. [#422] - Implement `Default` for `connect::Resolver`. [#422] - Implement `Error` for `connect::ConnectError`. [#422] - Implement `Default` for `connect::tcp::{TcpConnector, TcpConnectorService}`. [#423] - Implement `Default` for `connect::ConnectorService`. [#423] ### Changed - The crate's default features flags no longer include `uri`. [#422] - Useful re-exports from underlying TLS crates are exposed in a `reexports` modules in all acceptors and connectors. - Convert `connect::ResolverService` from enum to struct. [#422] - Make `ConnectAddrsIter` private. [#422] - Mark `tcp::{TcpConnector, TcpConnectorService}` structs `#[non_exhaustive]`. [#423] - Rename `accept::native_tls::{NativeTlsAcceptorService => AcceptorService}`. [#422] - Rename `connect::{Address => Host}` trait. [#422] - Rename method `connect::Connection::{host => hostname}`. [#422] - Rename struct `connect::{Connect => ConnectInfo}`. [#422] - Rename struct `connect::{ConnectService => ConnectorService}`. [#422] - Rename struct `connect::{ConnectServiceFactory => Connector}`. [#422] - Rename TLS acceptor service future types and hide from docs. [#422] - Unbox some service futures types. [#422] - Inline modules in `connect::tls` to `connect` module. [#422] ### Removed - Remove `connect::{new_connector, new_connector_factory, default_connector, default_connector_factory}` methods. [#422] - Remove `connect::native_tls::Connector::service` method. [#422] - Remove redundant `connect::Connection::from_parts` method. [#422] [#422]: https://github.com/actix/actix-net/pull/422 [#423]: https://github.com/actix/actix-net/pull/423 ## 3.0.0-beta.9 - Add configurable timeout for accepting TLS connection. [#393] - Added `TlsError::Timeout` variant. [#393] - All TLS acceptor services now use `TlsError` for their error types. [#393] - Added `TlsError::into_service_error`. [#420] [#393]: https://github.com/actix/actix-net/pull/393 [#420]: https://github.com/actix/actix-net/pull/420 ## 3.0.0-beta.8 - Add `Connect::request` for getting a reference to the connection request. [#415] [#415]: https://github.com/actix/actix-net/pull/415 ## 3.0.0-beta.7 - Add `webpki_roots_cert_store()` to get rustls compatible webpki roots cert store. [#401] - Alias `connect::ssl` to `connect::tls`. [#401] [#401]: https://github.com/actix/actix-net/pull/401 ## 3.0.0-beta.6 - Update `tokio-rustls` to `0.23` which uses `rustls` `0.20`. [#396] - Removed a re-export of `Session` from `rustls` as it no longer exist. [#396] - Minimum supported Rust version (MSRV) is now 1.52. [#396]: https://github.com/actix/actix-net/pull/396 ## 3.0.0-beta.5 - Changed `connect::ssl::rustls::RustlsConnectorService` to return error when `DNSNameRef` generation failed instead of panic. [#296] - Remove `connect::ssl::openssl::OpensslConnectServiceFactory`. [#297] - Remove `connect::ssl::openssl::OpensslConnectService`. [#297] - Add `connect::ssl::native_tls` module for native tls support. [#295] - Rename `accept::{nativetls => native_tls}`. [#295] - Remove `connect::TcpConnectService` type. Service caller expecting a `TcpStream` should use `connect::ConnectService` instead and call `Connection::into_parts`. [#299] [#295]: https://github.com/actix/actix-net/pull/295 [#296]: https://github.com/actix/actix-net/pull/296 [#297]: https://github.com/actix/actix-net/pull/297 [#299]: https://github.com/actix/actix-net/pull/299 ## 3.0.0-beta.4 - Rename `accept::openssl::{SslStream => TlsStream}`. - Add `connect::Connect::set_local_addr` to attach local `IpAddr`. [#282] - `connector::TcpConnector` service will try to bind to local_addr of `IpAddr` when given. [#282] [#282]: https://github.com/actix/actix-net/pull/282 ## 3.0.0-beta.3 - Remove `trust-dns-proto` and `trust-dns-resolver`. [#248] - Use `std::net::ToSocketAddrs` as simple and basic default resolver. [#248] - Add `Resolve` trait for custom DNS resolvers. [#248] - Add `Resolver::new_custom` function to construct custom resolvers. [#248] - Export `webpki_roots::TLS_SERVER_ROOTS` in `actix_tls::connect` mod and remove the export from `actix_tls::accept` [#248] - Remove `ConnectTakeAddrsIter`. `Connect::take_addrs` now returns `ConnectAddrsIter<'static>` as owned iterator. [#248] - Rename `Address::{host => hostname}` to more accurately describe which URL segment is returned. - Update `actix-rt` to `2.0.0`. [#273] [#248]: https://github.com/actix/actix-net/pull/248 [#273]: https://github.com/actix/actix-net/pull/273 ## 3.0.0-beta.2 - Depend on stable trust-dns packages. [#204] [#204]: https://github.com/actix/actix-net/pull/204 ## 3.0.0-beta.1 - Move acceptors under `accept` module. [#238] - Merge `actix-connect` crate under `connect` module. [#238] - Add feature flags to enable acceptors and/or connectors individually. [#238] [#238]: https://github.com/actix/actix-net/pull/238 ## 2.0.0 - `nativetls::NativeTlsAcceptor` is renamed to `nativetls::Acceptor`. - Where possible, "SSL" terminology is replaced with "TLS". - `SslError` is renamed to `TlsError`. - `TlsError::Ssl` enum variant is renamed to `TlsError::Tls`. - `max_concurrent_ssl_connect` is renamed to `max_concurrent_tls_connect`. ## 2.0.0-alpha.2 - Update `rustls` dependency to 0.18 - Update `tokio-rustls` dependency to 0.14 - Update `webpki-roots` dependency to 0.20 ## [2.0.0-alpha.1] - Update `rustls` dependency to 0.17 - Update `tokio-rustls` dependency to 0.13 - Update `webpki-roots` dependency to 0.19 ## [1.0.0] - 1.0.0 release ## [1.0.0-alpha.3] - Migrate to tokio 0.2 - Enable rustls acceptor service - Enable native-tls acceptor service ## [1.0.0-alpha.1] - Split openssl acceptor from actix-server package actix-tls-3.4.0/Cargo.lock0000644000001443670000000000100107420ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "actix-codec" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ "bitflags", "bytes", "futures-core", "futures-sink", "memchr", "pin-project-lite", "tokio", "tokio-util", "tracing", ] [[package]] name = "actix-macros" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", "syn", ] [[package]] name = "actix-rt" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" dependencies = [ "actix-macros", "futures-core", "tokio", ] [[package]] name = "actix-server" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" dependencies = [ "actix-rt", "actix-service", "actix-utils", "futures-core", "futures-util", "mio", "socket2", "tokio", "tracing", ] [[package]] name = "actix-service" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" dependencies = [ "futures-core", "paste", "pin-project-lite", ] [[package]] name = "actix-tls" version = "3.4.0" dependencies = [ "actix-codec", "actix-rt", "actix-server", "actix-service", "actix-utils", "bytes", "futures-core", "futures-util", "http 0.2.12", "http 1.1.0", "impl-more", "itertools", "openssl", "pin-project-lite", "pretty_env_logger", "rcgen", "rustls 0.21.12", "rustls-native-certs 0.6.3", "rustls-native-certs 0.7.0", "rustls-pemfile 2.1.2", "rustls-pki-types", "rustls-webpki 0.101.7", "tokio", "tokio-native-tls", "tokio-openssl", "tokio-rustls 0.23.4", "tokio-rustls 0.24.1", "tokio-rustls 0.25.0", "tokio-rustls 0.26.0", "tokio-util", "tracing", "trust-dns-resolver", "webpki-roots 0.22.6", "webpki-roots 0.25.4", "webpki-roots 0.26.1", ] [[package]] name = "actix-utils" version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" dependencies = [ "local-waker", "pin-project-lite", ] [[package]] name = "addr2line" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "async-trait" version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "aws-lc-rs" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8487b59d62764df8231cb371c459314df895b41756df457a1fb1243d65c89195" dependencies = [ "aws-lc-sys", "mirai-annotations", "paste", "zeroize", ] [[package]] name = "aws-lc-sys" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c15eb61145320320eb919d9bab524617a7aa4216c78d342fae3a758bc33073e4" dependencies = [ "bindgen", "cc", "cmake", "dunce", "fs_extra", "libc", "paste", ] [[package]] name = "backtrace" version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", ] [[package]] name = "base64" version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bindgen" version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ "bitflags", "cexpr", "clang-sys", "itertools", "lazy_static", "lazycell", "log", "prettyplease", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", "syn", "which", ] [[package]] name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytes" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" dependencies = [ "jobserver", "libc", "once_cell", ] [[package]] name = "cexpr" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ "nom", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clang-sys" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", "libloading", ] [[package]] name = "cmake" version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" dependencies = [ "cc", ] [[package]] name = "core-foundation" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "data-encoding" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "deranged" version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] [[package]] name = "dunce" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "either" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "enum-as-inner" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "env_logger" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", "log", "regex", "termcolor", ] [[package]] name = "errno" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", ] [[package]] name = "fastrand" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ "foreign-types-shared", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "fs_extra" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures-channel" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", ] [[package]] name = "futures-core" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-io" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-sink" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-sink", "futures-task", "pin-project-lite", "pin-utils", "slab", ] [[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "gimli" version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "home" version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "hostname" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" dependencies = [ "libc", "match_cfg", "winapi", ] [[package]] name = "http" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", "itoa", ] [[package]] name = "http" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", "itoa", ] [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "idna" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", ] [[package]] name = "idna" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", ] [[package]] name = "impl-more" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" [[package]] name = "ipconfig" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ "socket2", "widestring", "windows-sys 0.48.0", "winreg", ] [[package]] name = "ipnet" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", "libc", "windows-sys 0.52.0", ] [[package]] name = "itertools" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] [[package]] name = "js-sys" version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", "windows-targets 0.52.5", ] [[package]] name = "linked-hash-map" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-waker" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", ] [[package]] name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru-cache" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" dependencies = [ "linked-hash-map", ] [[package]] name = "match_cfg" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] [[package]] name = "mio" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", "wasi", "windows-sys 0.48.0", ] [[package]] name = "mirai-annotations" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" [[package]] name = "native-tls" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", "log", "openssl", "openssl-probe", "openssl-sys", "schannel", "security-framework", "security-framework-sys", "tempfile", ] [[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", ] [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num_cpus" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ "hermit-abi", "libc", ] [[package]] name = "object" version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", "once_cell", "openssl-macros", "openssl-sys", ] [[package]] name = "openssl-macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", "pkg-config", "vcpkg", ] [[package]] name = "parking_lot" version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", "windows-targets 0.52.5", ] [[package]] name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pem" version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ "base64 0.22.1", "serde", ] [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pretty_env_logger" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" dependencies = [ "env_logger", "log", ] [[package]] name = "prettyplease" version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", "syn", ] [[package]] name = "proc-macro2" version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] name = "rcgen" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48406db8ac1f3cbc7dcdb56ec355343817958a356ff430259bb07baf7607e1e1" dependencies = [ "pem", "ring 0.17.8", "time", "yasna", ] [[package]] name = "redox_syscall" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ "bitflags", ] [[package]] name = "regex" version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "resolv-conf" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" dependencies = [ "hostname", "quick-error", ] [[package]] name = "ring" version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ "cc", "libc", "once_cell", "spin 0.5.2", "untrusted 0.7.1", "web-sys", "winapi", ] [[package]] name = "ring" version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", "windows-sys 0.52.0", ] [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.52.0", ] [[package]] name = "rustls" version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring 0.16.20", "sct", "webpki", ] [[package]] name = "rustls" version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", "rustls-webpki 0.101.7", "sct", ] [[package]] name = "rustls" version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", "rustls-webpki 0.102.4", "subtle", "zeroize", ] [[package]] name = "rustls" version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebbbdb961df0ad3f2652da8f3fdc4b36122f568f968f45ad3316f26c025c677b" dependencies = [ "aws-lc-rs", "log", "once_cell", "rustls-pki-types", "rustls-webpki 0.102.4", "subtle", "zeroize", ] [[package]] name = "rustls-native-certs" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile 1.0.4", "schannel", "security-framework", ] [[package]] name = "rustls-native-certs" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", "rustls-pemfile 2.1.2", "rustls-pki-types", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64 0.21.7", ] [[package]] name = "rustls-pemfile" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "rustls-webpki" version = "0.102.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" dependencies = [ "aws-lc-rs", "ring 0.17.8", "rustls-pki-types", "untrusted 0.9.0", ] [[package]] name = "schannel" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "security-framework" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ "bitflags", "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "serde" version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] [[package]] name = "slab" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", ] [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "subtle" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" version = "2.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "tempfile" version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", "rustix", "windows-sys 0.52.0", ] [[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "time" version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "num-conv", "powerfmt", "serde", "time-core", ] [[package]] name = "time-core" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "tinyvec" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "windows-sys 0.48.0", ] [[package]] name = "tokio-native-tls" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", ] [[package]] name = "tokio-openssl" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ffab79df67727f6acf57f1ff743091873c24c579b1e2ce4d8f53e47ded4d63d" dependencies = [ "futures-util", "openssl", "openssl-sys", "tokio", ] [[package]] name = "tokio-rustls" version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ "rustls 0.20.9", "tokio", "webpki", ] [[package]] name = "tokio-rustls" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls 0.21.12", "tokio", ] [[package]] name = "tokio-rustls" version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ "rustls 0.22.4", "rustls-pki-types", "tokio", ] [[package]] name = "tokio-rustls" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ "rustls 0.23.7", "rustls-pki-types", "tokio", ] [[package]] name = "tokio-util" version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", ] [[package]] name = "tracing" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", "pin-project-lite", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "trust-dns-proto" version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" dependencies = [ "async-trait", "cfg-if", "data-encoding", "enum-as-inner", "futures-channel", "futures-io", "futures-util", "idna 0.4.0", "ipnet", "once_cell", "rand", "smallvec", "thiserror", "tinyvec", "tokio", "tracing", "url", ] [[package]] name = "trust-dns-resolver" version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" dependencies = [ "cfg-if", "futures-util", "ipconfig", "lru-cache", "once_cell", "parking_lot", "rand", "resolv-conf", "smallvec", "thiserror", "tokio", "tracing", "trust-dns-proto", ] [[package]] name = "unicode-bidi" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna 0.5.0", "percent-encoding", ] [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "webpki" version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "webpki-roots" version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ "webpki", ] [[package]] name = "webpki-roots" version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" dependencies = [ "rustls-pki-types", ] [[package]] name = "which" version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", "home", "once_cell", "rustix", ] [[package]] name = "widestring" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets 0.48.5", ] [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets 0.52.5", ] [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm 0.48.5", "windows_aarch64_msvc 0.48.5", "windows_i686_gnu 0.48.5", "windows_i686_msvc 0.48.5", "windows_x86_64_gnu 0.48.5", "windows_x86_64_gnullvm 0.48.5", "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ "windows_aarch64_gnullvm 0.52.5", "windows_aarch64_msvc 0.52.5", "windows_i686_gnu 0.52.5", "windows_i686_gnullvm", "windows_i686_msvc 0.52.5", "windows_x86_64_gnu 0.52.5", "windows_x86_64_gnullvm 0.52.5", "windows_x86_64_msvc 0.52.5", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" [[package]] name = "windows_i686_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winreg" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", "windows-sys 0.48.0", ] [[package]] name = "yasna" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ "time", ] [[package]] name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" actix-tls-3.4.0/Cargo.toml0000644000000121550000000000100107520ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.70" name = "actix-tls" version = "3.4.0" authors = [ "Nikolay Kim ", "Rob Ede ", ] description = "TLS acceptor and connector services for Actix ecosystem" readme = "README.md" keywords = [ "network", "tls", "ssl", "async", "transport", ] categories = [ "network-programming", "asynchronous", "cryptography", ] license = "MIT OR Apache-2.0" repository = "https://github.com/actix/actix-net.git" [package.metadata.cargo-machete] ignored = [ "rustls_021", "rustls_webpki_0101", ] [package.metadata.cargo_check_external_types] allowed_external_types = [ "actix_service::*", "actix_utils::*", "futures_core::*", "tokio::*", ] [package.metadata.docs.rs] all-features = true rustdoc-args = [ "--cfg", "docsrs", ] [[example]] name = "accept-rustls" required-features = [ "accept", "rustls-0_23", ] [dependencies.actix-rt] version = "2.2" default-features = false [dependencies.actix-service] version = "2" [dependencies.actix-utils] version = "3" [dependencies.futures-core] version = "0.3.7" features = ["alloc"] default-features = false [dependencies.http-0_2] version = "0.2.3" optional = true package = "http" [dependencies.http-1] version = "1" optional = true package = "http" [dependencies.impl-more] version = "0.1" [dependencies.pin-project-lite] version = "0.2.7" [dependencies.rustls-native-certs-06] version = "0.6" optional = true package = "rustls-native-certs" [dependencies.rustls-native-certs-07] version = "0.7" optional = true package = "rustls-native-certs" [dependencies.rustls-pki-types-1] version = "1" optional = true package = "rustls-pki-types" [dependencies.tls-openssl] version = "0.10.55" optional = true package = "openssl" [dependencies.tokio] version = "1.23.1" [dependencies.tokio-native-tls] version = "0.3" optional = true [dependencies.tokio-openssl] version = "0.6" optional = true [dependencies.tokio-rustls-023] version = "0.23" optional = true package = "tokio-rustls" [dependencies.tokio-rustls-024] version = "0.24" optional = true package = "tokio-rustls" [dependencies.tokio-rustls-025] version = "0.25" optional = true package = "tokio-rustls" [dependencies.tokio-rustls-026] version = "0.26" optional = true default-features = false package = "tokio-rustls" [dependencies.tokio-util] version = "0.7" [dependencies.tracing] version = "0.1.30" features = ["log"] default-features = false [dependencies.webpki-roots-022] version = "0.22" optional = true package = "webpki-roots" [dependencies.webpki-roots-025] version = "0.25" optional = true package = "webpki-roots" [dependencies.webpki-roots-026] version = "0.26" optional = true package = "webpki-roots" [dev-dependencies.actix-codec] version = "0.5" [dev-dependencies.actix-rt] version = "2.2" [dev-dependencies.actix-server] version = "2" [dev-dependencies.bytes] version = "1" [dev-dependencies.futures-util] version = "0.3.17" features = ["sink"] default-features = false [dev-dependencies.itertools] version = "0.12" [dev-dependencies.pretty_env_logger] version = "0.5" [dev-dependencies.rcgen] version = "0.12" [dev-dependencies.rustls-pemfile] version = "2" [dev-dependencies.tokio-rustls-026] version = "0.26" package = "tokio-rustls" [dev-dependencies.trust-dns-resolver] version = "0.23" [features] accept = [] connect = [] default = [ "accept", "connect", ] native-tls = ["dep:tokio-native-tls"] openssl = [ "dep:tls-openssl", "dep:tokio-openssl", ] rustls = ["rustls-0_20"] rustls-0_20 = ["rustls-0_20-webpki-roots"] rustls-0_20-native-roots = [ "tokio-rustls-023", "dep:rustls-native-certs-06", ] rustls-0_20-webpki-roots = [ "tokio-rustls-023", "webpki-roots-022", ] rustls-0_21 = ["rustls-0_21-webpki-roots"] rustls-0_21-native-roots = [ "tokio-rustls-024", "dep:rustls-native-certs-06", ] rustls-0_21-webpki-roots = [ "tokio-rustls-024", "webpki-roots-025", ] rustls-0_22 = [ "dep:tokio-rustls-025", "dep:rustls-pki-types-1", ] rustls-0_22-native-roots = [ "rustls-0_22", "dep:rustls-native-certs-07", ] rustls-0_22-webpki-roots = [ "rustls-0_22", "dep:webpki-roots-026", ] rustls-0_23 = [ "dep:tokio-rustls-026", "dep:rustls-pki-types-1", ] rustls-0_23-native-roots = [ "rustls-0_23", "dep:rustls-native-certs-07", ] rustls-0_23-webpki-roots = [ "rustls-0_23", "dep:webpki-roots-026", ] uri = [ "dep:http-0_2", "dep:http-1", ] [target."cfg(any())".dependencies.rustls-021] version = "0.21.6" optional = true package = "rustls" [target."cfg(any())".dependencies.rustls-webpki-0101] version = "0.101.4" optional = true package = "rustls-webpki" actix-tls-3.4.0/Cargo.toml.orig0000644000000110420000000000100117030ustar [package] name = "actix-tls" version = "3.4.0" authors = [ "Nikolay Kim ", "Rob Ede ", ] description = "TLS acceptor and connector services for Actix ecosystem" keywords = ["network", "tls", "ssl", "async", "transport"] repository = "https://github.com/actix/actix-net.git" categories = ["network-programming", "asynchronous", "cryptography"] license.workspace = true edition.workspace = true rust-version.workspace = true [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] [package.metadata.cargo_check_external_types] allowed_external_types = [ "actix_service::*", "actix_utils::*", "futures_core::*", "tokio::*", ] [package.metadata.cargo-machete] ignored = [ "rustls_021", # specified to force version with add_trust_anchors method "rustls_webpki_0101", # specified to force secure version ] [features] default = ["accept", "connect"] # enable acceptor services accept = [] # enable connector services connect = [] # use openssl impls openssl = ["dep:tls-openssl", "dep:tokio-openssl"] # alias for backwards compat rustls = ["rustls-0_20"] # use rustls v0.20 impls rustls-0_20 = ["rustls-0_20-webpki-roots"] rustls-0_20-webpki-roots = ["tokio-rustls-023", "webpki-roots-022"] rustls-0_20-native-roots = ["tokio-rustls-023", "dep:rustls-native-certs-06"] # use rustls v0.21 impls rustls-0_21 = ["rustls-0_21-webpki-roots"] rustls-0_21-webpki-roots = ["tokio-rustls-024", "webpki-roots-025"] rustls-0_21-native-roots = ["tokio-rustls-024", "dep:rustls-native-certs-06"] # use rustls v0.22 impls rustls-0_22 = ["dep:tokio-rustls-025", "dep:rustls-pki-types-1"] rustls-0_22-webpki-roots = ["rustls-0_22", "dep:webpki-roots-026"] rustls-0_22-native-roots = ["rustls-0_22", "dep:rustls-native-certs-07"] # use rustls v0.23 impls rustls-0_23 = ["dep:tokio-rustls-026", "dep:rustls-pki-types-1"] rustls-0_23-webpki-roots = ["rustls-0_23", "dep:webpki-roots-026"] rustls-0_23-native-roots = ["rustls-0_23", "dep:rustls-native-certs-07"] # use native-tls impls native-tls = ["dep:tokio-native-tls"] # support http::Uri as connect address uri = ["dep:http-0_2", "dep:http-1"] [dependencies] actix-rt = { version = "2.2", default-features = false } actix-service = "2" actix-utils = "3" futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } impl-more = "0.1" pin-project-lite = "0.2.7" tokio = "1.23.1" tokio-util = "0.7" tracing = { version = "0.1.30", default-features = false, features = ["log"] } # uri http-0_2 = { package = "http", version = "0.2.3", optional = true } http-1 = { package = "http", version = "1", optional = true } # openssl tls-openssl = { package = "openssl", version = "0.10.55", optional = true } tokio-openssl = { version = "0.6", optional = true } # rustls PKI types rustls-pki-types-1 = { package = "rustls-pki-types", version = "1", optional = true } # rustls v0.20 tokio-rustls-023 = { package = "tokio-rustls", version = "0.23", optional = true } # rustls v0.21 tokio-rustls-024 = { package = "tokio-rustls", version = "0.24", optional = true } # rustls v0.22 tokio-rustls-025 = { package = "tokio-rustls", version = "0.25", optional = true } # rustls v0.23 tokio-rustls-026 = { package = "tokio-rustls", version = "0.26", default-features = false, optional = true } # webpki-roots used with rustls features webpki-roots-022 = { package = "webpki-roots", version = "0.22", optional = true } webpki-roots-025 = { package = "webpki-roots", version = "0.25", optional = true } webpki-roots-026 = { package = "webpki-roots", version = "0.26", optional = true } # native root certificates for rustls impls rustls-native-certs-06 = { package = "rustls-native-certs", version = "0.6", optional = true } rustls-native-certs-07 = { package = "rustls-native-certs", version = "0.7", optional = true } # native-tls tokio-native-tls = { version = "0.3", optional = true } [target.'cfg(any())'.dependencies] rustls-021 = { package = "rustls", version = "0.21.6", optional = true } # force version with add_trust_anchors method rustls-webpki-0101 = { package = "rustls-webpki", version = "0.101.4", optional = true } # force secure version [dev-dependencies] actix-codec = "0.5" actix-rt = "2.2" actix-server = "2" bytes = "1" pretty_env_logger = "0.5" futures-util = { version = "0.3.17", default-features = false, features = ["sink"] } itertools = "0.12" rcgen = "0.12" rustls-pemfile = "2" tokio-rustls-026 = { package = "tokio-rustls", version = "0.26" } trust-dns-resolver = "0.23" [[example]] name = "accept-rustls" required-features = ["accept", "rustls-0_23"] actix-tls-3.4.0/Cargo.toml.orig000064400000000000000000000110421046102023000144250ustar 00000000000000[package] name = "actix-tls" version = "3.4.0" authors = [ "Nikolay Kim ", "Rob Ede ", ] description = "TLS acceptor and connector services for Actix ecosystem" keywords = ["network", "tls", "ssl", "async", "transport"] repository = "https://github.com/actix/actix-net.git" categories = ["network-programming", "asynchronous", "cryptography"] license.workspace = true edition.workspace = true rust-version.workspace = true [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] [package.metadata.cargo_check_external_types] allowed_external_types = [ "actix_service::*", "actix_utils::*", "futures_core::*", "tokio::*", ] [package.metadata.cargo-machete] ignored = [ "rustls_021", # specified to force version with add_trust_anchors method "rustls_webpki_0101", # specified to force secure version ] [features] default = ["accept", "connect"] # enable acceptor services accept = [] # enable connector services connect = [] # use openssl impls openssl = ["dep:tls-openssl", "dep:tokio-openssl"] # alias for backwards compat rustls = ["rustls-0_20"] # use rustls v0.20 impls rustls-0_20 = ["rustls-0_20-webpki-roots"] rustls-0_20-webpki-roots = ["tokio-rustls-023", "webpki-roots-022"] rustls-0_20-native-roots = ["tokio-rustls-023", "dep:rustls-native-certs-06"] # use rustls v0.21 impls rustls-0_21 = ["rustls-0_21-webpki-roots"] rustls-0_21-webpki-roots = ["tokio-rustls-024", "webpki-roots-025"] rustls-0_21-native-roots = ["tokio-rustls-024", "dep:rustls-native-certs-06"] # use rustls v0.22 impls rustls-0_22 = ["dep:tokio-rustls-025", "dep:rustls-pki-types-1"] rustls-0_22-webpki-roots = ["rustls-0_22", "dep:webpki-roots-026"] rustls-0_22-native-roots = ["rustls-0_22", "dep:rustls-native-certs-07"] # use rustls v0.23 impls rustls-0_23 = ["dep:tokio-rustls-026", "dep:rustls-pki-types-1"] rustls-0_23-webpki-roots = ["rustls-0_23", "dep:webpki-roots-026"] rustls-0_23-native-roots = ["rustls-0_23", "dep:rustls-native-certs-07"] # use native-tls impls native-tls = ["dep:tokio-native-tls"] # support http::Uri as connect address uri = ["dep:http-0_2", "dep:http-1"] [dependencies] actix-rt = { version = "2.2", default-features = false } actix-service = "2" actix-utils = "3" futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } impl-more = "0.1" pin-project-lite = "0.2.7" tokio = "1.23.1" tokio-util = "0.7" tracing = { version = "0.1.30", default-features = false, features = ["log"] } # uri http-0_2 = { package = "http", version = "0.2.3", optional = true } http-1 = { package = "http", version = "1", optional = true } # openssl tls-openssl = { package = "openssl", version = "0.10.55", optional = true } tokio-openssl = { version = "0.6", optional = true } # rustls PKI types rustls-pki-types-1 = { package = "rustls-pki-types", version = "1", optional = true } # rustls v0.20 tokio-rustls-023 = { package = "tokio-rustls", version = "0.23", optional = true } # rustls v0.21 tokio-rustls-024 = { package = "tokio-rustls", version = "0.24", optional = true } # rustls v0.22 tokio-rustls-025 = { package = "tokio-rustls", version = "0.25", optional = true } # rustls v0.23 tokio-rustls-026 = { package = "tokio-rustls", version = "0.26", default-features = false, optional = true } # webpki-roots used with rustls features webpki-roots-022 = { package = "webpki-roots", version = "0.22", optional = true } webpki-roots-025 = { package = "webpki-roots", version = "0.25", optional = true } webpki-roots-026 = { package = "webpki-roots", version = "0.26", optional = true } # native root certificates for rustls impls rustls-native-certs-06 = { package = "rustls-native-certs", version = "0.6", optional = true } rustls-native-certs-07 = { package = "rustls-native-certs", version = "0.7", optional = true } # native-tls tokio-native-tls = { version = "0.3", optional = true } [target.'cfg(any())'.dependencies] rustls-021 = { package = "rustls", version = "0.21.6", optional = true } # force version with add_trust_anchors method rustls-webpki-0101 = { package = "rustls-webpki", version = "0.101.4", optional = true } # force secure version [dev-dependencies] actix-codec = "0.5" actix-rt = "2.2" actix-server = "2" bytes = "1" pretty_env_logger = "0.5" futures-util = { version = "0.3.17", default-features = false, features = ["sink"] } itertools = "0.12" rcgen = "0.12" rustls-pemfile = "2" tokio-rustls-026 = { package = "tokio-rustls", version = "0.26" } trust-dns-resolver = "0.23" [[example]] name = "accept-rustls" required-features = ["accept", "rustls-0_23"] actix-tls-3.4.0/LICENSE-APACHE000064400000000000000000000261201046102023000134650ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2017-NOW Actix Team Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. actix-tls-3.4.0/LICENSE-MIT000064400000000000000000000020421046102023000131720ustar 00000000000000Copyright (c) 2017-NOW Actix Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. actix-tls-3.4.0/README.md000064400000000000000000000016751046102023000130300ustar 00000000000000# `actix-tls` > TLS acceptor and connector services for the Actix ecosystem. [![crates.io](https://img.shields.io/crates/v/actix-tls?label=latest)](https://crates.io/crates/actix-tls) [![Documentation](https://docs.rs/actix-tls/badge.svg?version=3.4.0)](https://docs.rs/actix-tls/3.4.0) [![Version](https://img.shields.io/badge/rustc-1.52+-ab6000.svg)](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-tls.svg)
[![Dependency Status](https://deps.rs/crate/actix-tls/3.4.0/status.svg)](https://deps.rs/crate/actix-tls/3.4.0) ![Download](https://img.shields.io/crates/d/actix-tls.svg) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) ## Resources - [Library Documentation](https://docs.rs/actix-tls) - [Examples](/actix-tls/examples) actix-tls-3.4.0/examples/accept-rustls.rs000064400000000000000000000055161046102023000165240ustar 00000000000000//! No-Op TLS Acceptor Server //! //! Using either HTTPie (`http`) or cURL: //! //! This commands will produce errors in the server log: //! ```sh //! curl 127.0.0.1:8443 //! http 127.0.0.1:8443 //! ``` //! //! These commands will show "empty reply" on the client but will debug print the TLS stream info //! in the server log, indicating a successful TLS handshake: //! ```sh //! curl -k https://127.0.0.1:8443 //! http --verify=false https://127.0.0.1:8443 //! ``` // this `use` is only exists because of how we have organised the crate // it is not necessary for your actual code; you should import from `rustls` normally use std::{ fs::File, io::{self, BufReader}, path::PathBuf, sync::{ atomic::{AtomicUsize, Ordering}, Arc, }, }; use actix_rt::net::TcpStream; use actix_server::Server; use actix_service::ServiceFactoryExt as _; use actix_tls::accept::rustls_0_23::{Acceptor as RustlsAcceptor, TlsStream}; use futures_util::future::ok; use itertools::Itertools as _; use rustls::server::ServerConfig; use rustls_pemfile::{certs, rsa_private_keys}; use rustls_pki_types_1::PrivateKeyDer; use tokio_rustls_026::rustls; use tracing::info; #[actix_rt::main] async fn main() -> io::Result<()> { pretty_env_logger::formatted_timed_builder() .parse_env(pretty_env_logger::env_logger::Env::default().default_filter_or("info")); let root_path = env!("CARGO_MANIFEST_DIR") .parse::() .unwrap() .join("examples"); let cert_path = root_path.clone().join("cert.pem"); let key_path = root_path.clone().join("key.pem"); // Load TLS key and cert files let cert_file = &mut BufReader::new(File::open(cert_path).unwrap()); let key_file = &mut BufReader::new(File::open(key_path).unwrap()); let cert_chain = certs(cert_file); let mut keys = rsa_private_keys(key_file); let tls_config = ServerConfig::builder() .with_no_client_auth() .with_single_cert( cert_chain.try_collect::<_, Vec<_>, _>()?, PrivateKeyDer::Pkcs1(keys.next().unwrap()?), ) .unwrap(); let tls_acceptor = RustlsAcceptor::new(tls_config); let count = Arc::new(AtomicUsize::new(0)); let addr = ("127.0.0.1", 8443); info!("starting server at: {addr:?}"); Server::build() .bind("tls-example", addr, move || { let count = Arc::clone(&count); // Set up TLS service factory tls_acceptor .clone() .map_err(|err| println!("Rustls error: {:?}", err)) .and_then(move |stream: TlsStream| { let num = count.fetch_add(1, Ordering::Relaxed); info!("[{}] Got TLS connection: {:?}", num, &*stream); ok(()) }) })? .workers(1) .run() .await } actix-tls-3.4.0/examples/cert.pem000064400000000000000000000027611046102023000150240ustar 00000000000000-----BEGIN CERTIFICATE----- MIIENjCCAp6gAwIBAgIRANp+D9pBErdacw6KjrwJ+4swDQYJKoZIhvcNAQELBQAw bTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSEwHwYDVQQLDBhyb2JA c29tYnJhLng1Mi5kZXYgKFJvYikxKDAmBgNVBAMMH21rY2VydCByb2JAc29tYnJh Lng1Mi5kZXYgKFJvYikwHhcNMTkwNjAxMDAwMDAwWhcNMzAwOTEzMDIzNDI0WjBM MScwJQYDVQQKEx5ta2NlcnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxITAfBgNV BAsMGHJvYkBzb21icmEueDUyLmRldiAoUm9iKTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBALYAn8dsQUDTp8SptAtkiAySvQYLpAOct3/OjBn+dSYfbQcp Ph9w/Zo83Msl7Fb1DBvADHFtyBpESATZ2chS5fwCAwUFTlKrzMk3qauEoJ3cCQa8 ccqhTMLeT38jRlhXrMHWBfz0ipqy+yTLWeM32LX8s0jPbbsZ3gVJ/Ls4qm0CTaqb zRdcQ7GTVKYet5DR7ZvwvAaLtWk/iiHKwnOveuF27HNlxj0Rwd/lhJ/t9x8xJwyR MTdm852KQadI8xOSbWNK4j9419yzKjUEMKgn78wT/7DQfeKKCAreHa4MaEw4+koD 2Bqb+V4fI6T84VvXkNG3CjSpmIiYGlIE1LVgBL8CAwEAAaNyMHAwDgYDVR0PAQH/ BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHwYDVR0j BBgwFoAUto/ox0MqZShmQpViV/gjfJKrMDkwGgYDVR0RBBMwEYIJbG9jYWxob3N0 hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBgQBUCMzqTY0sg+61gh8gKS5TCL6qs0R1 xys/EFFaD5JYUsfM/HyhHd0jq+x5Pd3mB2Jvhoq9xhjMwP11H8Uw5lLBHA8USdF9 EiLW1GvT3/gLfMqb0lPk0RMRBeX8c0QbDtqdiUCE7S6zJbZ5gjFeRuFNjdcGA1Ss 8CPPts2mns5cwah6H7T/BFzj5aR9Qe14vo1Rpr5gD5CpHvk1t16q7YsczQfVMvt3 Ydk6p0rwA8Z5okQK7y3qKPZI+//ygWL6ZBjVjl1/Al8vybG2UYjYgfMBwaVvMiDJ j/vCdVmlvGb+MZlZID/p2veaNeEKgi1A1EOj3sNuQYXXFfSD9mdamX7JIfGi/U7v ivvUjJUbzGrUngldt5iCKqcCQum7nlzu9sT1Tm2t/n4tz/btrI+Wimg8riSzM+Nk dfuvv4NbWe6Th5460HH8mMvfPZSB8dCoxwm98tuqcMXLkR1RJX5Z8LYAaPTsUs/h HxQCY4EaY7feZ/qFal9FGwvpzVr3/XjgSCU= -----END CERTIFICATE----- actix-tls-3.4.0/examples/key.pem000064400000000000000000000032171046102023000146540ustar 00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAtgCfx2xBQNOnxKm0C2SIDJK9BgukA5y3f86MGf51Jh9tByk+ H3D9mjzcyyXsVvUMG8AMcW3IGkRIBNnZyFLl/AIDBQVOUqvMyTepq4SgndwJBrxx yqFMwt5PfyNGWFeswdYF/PSKmrL7JMtZ4zfYtfyzSM9tuxneBUn8uziqbQJNqpvN F1xDsZNUph63kNHtm/C8Bou1aT+KIcrCc6964Xbsc2XGPRHB3+WEn+33HzEnDJEx N2bznYpBp0jzE5JtY0riP3jX3LMqNQQwqCfvzBP/sNB94ooICt4drgxoTDj6SgPY Gpv5Xh8jpPzhW9eQ0bcKNKmYiJgaUgTUtWAEvwIDAQABAoIBADC0Zg21+Jhii6jj SR0rYAUNV6xAfTnCPJDlMzTZlXwIOOMLtGYxlIwr8WIj2eVDWmQqtqm8GSp+T0+N BOzI0mboGurDCryw4PKQBMWzjk/wTDITR9hT5fjYCSoaxH5rp/2PSrbwsg7ICtFD 4eAeV84Lu+amK9VADNwZepqXhXP6EDOY5yovkwzOQNDM/qVzHSe9EoFP74M/oWnY ohIuWdZzwAZuTA5SUjPygiVzs/vhsrSE9crMIzr5VgKBi+C+ALkrL7Lc4GlRPI4r 6VsbIxZHa7who+FhjZ0cVfdXHH47QDdf10X5bEXsaFBvGGCLtkQ3XEpov6GOlaH+ aY7fzPECgYEA4LGloaMC9J27uyPxHkQwEehexmJdIu0vNUefv5yiO9PbvrjvYnh7 JxRVgv1fy2bRMOvg19TujCYRZdkrLDqSDsfFfEiThvlFBRZfKKIHmWdyfvIe9Jp9 rqdxhWAco7FoM+W6c8c4iR4xs8/GA60CVcAiTLqgPWWzn12fesiULi0CgYEAz1xD OulJyfpHVGQ6ZM1wR0SZ9H9GS3BenpL2ue5uBfe3hM+JIAAM61Y48wJuCWT5EvfL FgnH3oCo7SYGcgGkERS8H7k67DJCLlqDo/3FC7lX/irz+ya/FoZmKBagvjEUWhpe Bb2dRIbqsG0lsCzU9MVrgtvodD0MBTyt0RM5fhsCgYEAhgYQiLhGBAituLN4mBgO IDBdj7GOYk3dkcc2J0HTlyIIeduvlinNM4Myel6NrDKY5rhbtgGhhGEUkY6W7NvG 0SAh0L8tmB3JKH6upfr3023b4pKjGj2oZ+wij27DxnQEdqg5reOP+mHTPbDaKMki kml3TBMpj1XBbXaXsNJBaMUCgYEAnnNzEC4563QrU2pvUJ3HgT4Dotgqv/Sy6NuG W1e9jSPYgU0RDHndZWtygwdFTDpzNbJR5po8t2J7MxQOcsmcNE0y387sHpbdCYyy 8Po2uxm7CoaJ/02BUVYL8/Aujob0dVGWrS5SYY3zAjO1S+VGKXA+EjW2cDRB3jKa 45ucICcCgYBdMxB5Oj6GpdewWWaBss9dwHtDaD4oVGYIBbIc2qdyCYixWdW9NccV fRJs0ulGrpg9OtyWbwZASu2jz55+s3hi4rnrcaXKiIh9Rs25v1irF6Dmduvo7CaN Mf7zBg7LUttmqN6D3npIAxmBULl8KRfjnt6U2tJolF5X0qQ1uqnnTA== -----END RSA PRIVATE KEY----- actix-tls-3.4.0/src/accept/mod.rs000064400000000000000000000067011046102023000147170ustar 00000000000000//! TLS connection acceptor services. use std::{ convert::Infallible, error::Error, fmt, sync::atomic::{AtomicUsize, Ordering}, }; use actix_utils::counter::Counter; #[cfg(feature = "openssl")] pub mod openssl; #[cfg(feature = "rustls-0_20")] pub mod rustls_0_20; #[doc(hidden)] #[cfg(feature = "rustls-0_20")] pub use rustls_0_20 as rustls; #[cfg(feature = "rustls-0_21")] pub mod rustls_0_21; #[cfg(feature = "rustls-0_22")] pub mod rustls_0_22; #[cfg(feature = "rustls-0_23")] pub mod rustls_0_23; #[cfg(feature = "native-tls")] pub mod native_tls; pub(crate) static MAX_CONN: AtomicUsize = AtomicUsize::new(256); #[cfg(any( feature = "openssl", feature = "rustls-0_20", feature = "rustls-0_21", feature = "rustls-0_22", feature = "rustls-0_23", feature = "native-tls", ))] pub(crate) const DEFAULT_TLS_HANDSHAKE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(3); thread_local! { static MAX_CONN_COUNTER: Counter = Counter::new(MAX_CONN.load(Ordering::Relaxed)); } /// Sets the maximum per-worker concurrent TLS connection limit. /// /// All listeners will stop accepting connections when this limit is reached. /// It can be used to regulate the global TLS CPU usage. /// /// By default, the connection limit is 256. pub fn max_concurrent_tls_connect(num: usize) { MAX_CONN.store(num, Ordering::Relaxed); } /// TLS handshake error, TLS timeout, or inner service error. /// /// All TLS acceptors from this crate will return the `SvcErr` type parameter as [`Infallible`], /// which can be cast to your own service type, inferred or otherwise, using [`into_service_error`]. /// /// [`into_service_error`]: Self::into_service_error #[derive(Debug)] pub enum TlsError { /// TLS handshake has timed-out. Timeout, /// Wraps TLS service errors. Tls(TlsErr), /// Wraps service errors. Service(SvcErr), } impl TlsError { /// Casts the infallible service error type returned from acceptors into caller's type. /// /// # Examples /// ``` /// # use std::convert::Infallible; /// # use actix_tls::accept::TlsError; /// let a: TlsError = TlsError::Tls(42); /// let _b: TlsError = a.into_service_error(); /// ``` pub fn into_service_error(self) -> TlsError { match self { Self::Timeout => TlsError::Timeout, Self::Tls(err) => TlsError::Tls(err), Self::Service(err) => match err {}, } } } impl fmt::Display for TlsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Timeout => f.write_str("TLS handshake has timed-out"), Self::Tls(_) => f.write_str("TLS handshake error"), Self::Service(_) => f.write_str("Service error"), } } } impl Error for TlsError where TlsErr: Error + 'static, SvcErr: Error + 'static, { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { TlsError::Tls(err) => Some(err), TlsError::Service(err) => Some(err), TlsError::Timeout => None, } } } #[cfg(test)] mod tests { use super::*; #[test] fn tls_service_error_inference() { let a: TlsError = TlsError::Tls(42); let _b: TlsError = a.into_service_error(); } } actix-tls-3.4.0/src/accept/native_tls.rs000064400000000000000000000122661046102023000163130ustar 00000000000000//! `native-tls` based TLS connection acceptor service. //! //! See [`Acceptor`] for main service factory docs. use std::{ convert::Infallible, io::{self, IoSlice}, pin::Pin, task::{Context, Poll}, time::Duration, }; use actix_rt::{ net::{ActixStream, Ready}, time::timeout, }; use actix_service::{Service, ServiceFactory}; use actix_utils::{ counter::Counter, future::{ready, Ready as FutReady}, }; use futures_core::future::LocalBoxFuture; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_native_tls::{native_tls::Error, TlsAcceptor}; use super::{TlsError, DEFAULT_TLS_HANDSHAKE_TIMEOUT, MAX_CONN_COUNTER}; pub mod reexports { //! Re-exports from `native-tls` that are useful for acceptors. pub use tokio_native_tls::{native_tls::Error, TlsAcceptor}; } /// Wraps a `native-tls` based async TLS stream in order to implement [`ActixStream`]. pub struct TlsStream(tokio_native_tls::TlsStream); impl_more::impl_from!( in tokio_native_tls::TlsStream => TlsStream); impl_more::impl_deref_and_mut!( in TlsStream => tokio_native_tls::TlsStream); impl AsyncRead for TlsStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_read(cx, buf) } } impl AsyncWrite for TlsStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_flush(cx) } fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_shutdown(cx) } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write_vectored(cx, bufs) } fn is_write_vectored(&self) -> bool { (**self).is_write_vectored() } } impl ActixStream for TlsStream { fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_read_ready((**self).get_ref().get_ref().get_ref(), cx) } fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_write_ready((**self).get_ref().get_ref().get_ref(), cx) } } /// Accept TLS connections via the `native-tls` crate. pub struct Acceptor { acceptor: TlsAcceptor, handshake_timeout: Duration, } impl Acceptor { /// Constructs `native-tls` based acceptor service factory. pub fn new(acceptor: TlsAcceptor) -> Self { Acceptor { acceptor, handshake_timeout: DEFAULT_TLS_HANDSHAKE_TIMEOUT, } } /// Limit the amount of time that the acceptor will wait for a TLS handshake to complete. /// /// Default timeout is 3 seconds. pub fn set_handshake_timeout(&mut self, handshake_timeout: Duration) -> &mut Self { self.handshake_timeout = handshake_timeout; self } } impl Clone for Acceptor { #[inline] fn clone(&self) -> Self { Self { acceptor: self.acceptor.clone(), handshake_timeout: self.handshake_timeout, } } } impl ServiceFactory for Acceptor { type Response = TlsStream; type Error = TlsError; type Config = (); type Service = AcceptorService; type InitError = (); type Future = FutReady>; fn new_service(&self, _: ()) -> Self::Future { let res = MAX_CONN_COUNTER.with(|conns| { Ok(AcceptorService { acceptor: self.acceptor.clone(), conns: conns.clone(), handshake_timeout: self.handshake_timeout, }) }); ready(res) } } /// Native-TLS based acceptor service. pub struct AcceptorService { acceptor: TlsAcceptor, conns: Counter, handshake_timeout: Duration, } impl Service for AcceptorService { type Response = TlsStream; type Error = TlsError; type Future = LocalBoxFuture<'static, Result>; fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { if self.conns.available(cx) { Poll::Ready(Ok(())) } else { Poll::Pending } } fn call(&self, io: IO) -> Self::Future { let guard = self.conns.get(); let acceptor = self.acceptor.clone(); let dur = self.handshake_timeout; Box::pin(async move { match timeout(dur, acceptor.accept(io)).await { Ok(Ok(io)) => { drop(guard); Ok(TlsStream(io)) } Ok(Err(err)) => Err(TlsError::Tls(err)), Err(_timeout) => Err(TlsError::Timeout), } }) } } actix-tls-3.4.0/src/accept/openssl.rs000064400000000000000000000136331046102023000156250ustar 00000000000000//! `openssl` based TLS acceptor service. //! //! See [`Acceptor`] for main service factory docs. use std::{ convert::Infallible, future::Future, io::{self, IoSlice}, pin::Pin, task::{Context, Poll}, time::Duration, }; use actix_rt::{ net::{ActixStream, Ready}, time::{sleep, Sleep}, }; use actix_service::{Service, ServiceFactory}; use actix_utils::{ counter::{Counter, CounterGuard}, future::{ready, Ready as FutReady}, }; use openssl::ssl::{Error, Ssl, SslAcceptor}; use pin_project_lite::pin_project; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use super::{TlsError, DEFAULT_TLS_HANDSHAKE_TIMEOUT, MAX_CONN_COUNTER}; pub mod reexports { //! Re-exports from `openssl` that are useful for acceptors. pub use openssl::ssl::{ AlpnError, Error, HandshakeError, Ssl, SslAcceptor, SslAcceptorBuilder, }; } /// Wraps an `openssl` based async TLS stream in order to implement [`ActixStream`]. pub struct TlsStream(tokio_openssl::SslStream); impl_more::impl_from!( in tokio_openssl::SslStream => TlsStream); impl_more::impl_deref_and_mut!( in TlsStream => tokio_openssl::SslStream); impl AsyncRead for TlsStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_read(cx, buf) } } impl AsyncWrite for TlsStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_flush(cx) } fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_shutdown(cx) } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write_vectored(cx, bufs) } fn is_write_vectored(&self) -> bool { (**self).is_write_vectored() } } impl ActixStream for TlsStream { fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_read_ready((**self).get_ref(), cx) } fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_write_ready((**self).get_ref(), cx) } } /// Accept TLS connections via the `openssl` crate. pub struct Acceptor { acceptor: SslAcceptor, handshake_timeout: Duration, } impl Acceptor { /// Create `openssl` based acceptor service factory. #[inline] pub fn new(acceptor: SslAcceptor) -> Self { Acceptor { acceptor, handshake_timeout: DEFAULT_TLS_HANDSHAKE_TIMEOUT, } } /// Limit the amount of time that the acceptor will wait for a TLS handshake to complete. /// /// Default timeout is 3 seconds. pub fn set_handshake_timeout(&mut self, handshake_timeout: Duration) -> &mut Self { self.handshake_timeout = handshake_timeout; self } } impl Clone for Acceptor { #[inline] fn clone(&self) -> Self { Self { acceptor: self.acceptor.clone(), handshake_timeout: self.handshake_timeout, } } } impl ServiceFactory for Acceptor { type Response = TlsStream; type Error = TlsError; type Config = (); type Service = AcceptorService; type InitError = (); type Future = FutReady>; fn new_service(&self, _: ()) -> Self::Future { let res = MAX_CONN_COUNTER.with(|conns| { Ok(AcceptorService { acceptor: self.acceptor.clone(), conns: conns.clone(), handshake_timeout: self.handshake_timeout, }) }); ready(res) } } /// OpenSSL based acceptor service. pub struct AcceptorService { acceptor: SslAcceptor, conns: Counter, handshake_timeout: Duration, } impl Service for AcceptorService { type Response = TlsStream; type Error = TlsError; type Future = AcceptFut; fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll> { if self.conns.available(ctx) { Poll::Ready(Ok(())) } else { Poll::Pending } } fn call(&self, io: IO) -> Self::Future { let ssl_ctx = self.acceptor.context(); let ssl = Ssl::new(ssl_ctx).expect("Provided SSL acceptor was invalid."); AcceptFut { _guard: self.conns.get(), timeout: sleep(self.handshake_timeout), stream: Some(tokio_openssl::SslStream::new(ssl, io).unwrap()), } } } pin_project! { /// Accept future for OpenSSL service. #[doc(hidden)] pub struct AcceptFut { stream: Option>, #[pin] timeout: Sleep, _guard: CounterGuard, } } impl Future for AcceptFut { type Output = Result, TlsError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); match Pin::new(this.stream.as_mut().unwrap()).poll_accept(cx) { Poll::Ready(Ok(())) => Poll::Ready(Ok(this .stream .take() .expect("Acceptor should not be polled after it has completed.") .into())), Poll::Ready(Err(err)) => Poll::Ready(Err(TlsError::Tls(err))), Poll::Pending => this.timeout.poll(cx).map(|_| Err(TlsError::Timeout)), } } } actix-tls-3.4.0/src/accept/rustls_0_20.rs000064400000000000000000000131621046102023000162130ustar 00000000000000//! `rustls` v0.20 based TLS connection acceptor service. //! //! See [`Acceptor`] for main service factory docs. use std::{ convert::Infallible, future::Future, io::{self, IoSlice}, pin::Pin, sync::Arc, task::{Context, Poll}, time::Duration, }; use actix_rt::{ net::{ActixStream, Ready}, time::{sleep, Sleep}, }; use actix_service::{Service, ServiceFactory}; use actix_utils::{ counter::{Counter, CounterGuard}, future::{ready, Ready as FutReady}, }; use pin_project_lite::pin_project; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_rustls::{Accept, TlsAcceptor}; use tokio_rustls_023 as tokio_rustls; use super::{TlsError, DEFAULT_TLS_HANDSHAKE_TIMEOUT, MAX_CONN_COUNTER}; pub mod reexports { //! Re-exports from `rustls` that are useful for acceptors. pub use tokio_rustls_023::rustls::ServerConfig; } /// Wraps a `rustls` based async TLS stream in order to implement [`ActixStream`]. pub struct TlsStream(tokio_rustls::server::TlsStream); impl_more::impl_from!( in tokio_rustls::server::TlsStream => TlsStream); impl_more::impl_deref_and_mut!( in TlsStream => tokio_rustls::server::TlsStream); impl AsyncRead for TlsStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_read(cx, buf) } } impl AsyncWrite for TlsStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_flush(cx) } fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_shutdown(cx) } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write_vectored(cx, bufs) } fn is_write_vectored(&self) -> bool { (**self).is_write_vectored() } } impl ActixStream for TlsStream { fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_read_ready((**self).get_ref().0, cx) } fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_write_ready((**self).get_ref().0, cx) } } /// Accept TLS connections via the `rustls` crate. pub struct Acceptor { config: Arc, handshake_timeout: Duration, } impl Acceptor { /// Constructs `rustls` based acceptor service factory. pub fn new(config: reexports::ServerConfig) -> Self { Acceptor { config: Arc::new(config), handshake_timeout: DEFAULT_TLS_HANDSHAKE_TIMEOUT, } } /// Limit the amount of time that the acceptor will wait for a TLS handshake to complete. /// /// Default timeout is 3 seconds. pub fn set_handshake_timeout(&mut self, handshake_timeout: Duration) -> &mut Self { self.handshake_timeout = handshake_timeout; self } } impl Clone for Acceptor { fn clone(&self) -> Self { Self { config: self.config.clone(), handshake_timeout: self.handshake_timeout, } } } impl ServiceFactory for Acceptor { type Response = TlsStream; type Error = TlsError; type Config = (); type Service = AcceptorService; type InitError = (); type Future = FutReady>; fn new_service(&self, _: ()) -> Self::Future { let res = MAX_CONN_COUNTER.with(|conns| { Ok(AcceptorService { acceptor: self.config.clone().into(), conns: conns.clone(), handshake_timeout: self.handshake_timeout, }) }); ready(res) } } /// Rustls based acceptor service. pub struct AcceptorService { acceptor: TlsAcceptor, conns: Counter, handshake_timeout: Duration, } impl Service for AcceptorService { type Response = TlsStream; type Error = TlsError; type Future = AcceptFut; fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { if self.conns.available(cx) { Poll::Ready(Ok(())) } else { Poll::Pending } } fn call(&self, req: IO) -> Self::Future { AcceptFut { fut: self.acceptor.accept(req), timeout: sleep(self.handshake_timeout), _guard: self.conns.get(), } } } pin_project! { /// Accept future for Rustls service. #[doc(hidden)] pub struct AcceptFut { fut: Accept, #[pin] timeout: Sleep, _guard: CounterGuard, } } impl Future for AcceptFut { type Output = Result, TlsError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); match Pin::new(&mut this.fut).poll(cx) { Poll::Ready(Ok(stream)) => Poll::Ready(Ok(TlsStream(stream))), Poll::Ready(Err(err)) => Poll::Ready(Err(TlsError::Tls(err))), Poll::Pending => this.timeout.poll(cx).map(|_| Err(TlsError::Timeout)), } } } actix-tls-3.4.0/src/accept/rustls_0_21.rs000064400000000000000000000131621046102023000162140ustar 00000000000000//! `rustls` v0.21 based TLS connection acceptor service. //! //! See [`Acceptor`] for main service factory docs. use std::{ convert::Infallible, future::Future, io::{self, IoSlice}, pin::Pin, sync::Arc, task::{Context, Poll}, time::Duration, }; use actix_rt::{ net::{ActixStream, Ready}, time::{sleep, Sleep}, }; use actix_service::{Service, ServiceFactory}; use actix_utils::{ counter::{Counter, CounterGuard}, future::{ready, Ready as FutReady}, }; use pin_project_lite::pin_project; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_rustls::{Accept, TlsAcceptor}; use tokio_rustls_024 as tokio_rustls; use super::{TlsError, DEFAULT_TLS_HANDSHAKE_TIMEOUT, MAX_CONN_COUNTER}; pub mod reexports { //! Re-exports from `rustls` that are useful for acceptors. pub use tokio_rustls_024::rustls::ServerConfig; } /// Wraps a `rustls` based async TLS stream in order to implement [`ActixStream`]. pub struct TlsStream(tokio_rustls::server::TlsStream); impl_more::impl_from!( in tokio_rustls::server::TlsStream => TlsStream); impl_more::impl_deref_and_mut!( in TlsStream => tokio_rustls::server::TlsStream); impl AsyncRead for TlsStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_read(cx, buf) } } impl AsyncWrite for TlsStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_flush(cx) } fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_shutdown(cx) } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write_vectored(cx, bufs) } fn is_write_vectored(&self) -> bool { (**self).is_write_vectored() } } impl ActixStream for TlsStream { fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_read_ready((**self).get_ref().0, cx) } fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_write_ready((**self).get_ref().0, cx) } } /// Accept TLS connections via the `rustls` crate. pub struct Acceptor { config: Arc, handshake_timeout: Duration, } impl Acceptor { /// Constructs `rustls` based acceptor service factory. pub fn new(config: reexports::ServerConfig) -> Self { Acceptor { config: Arc::new(config), handshake_timeout: DEFAULT_TLS_HANDSHAKE_TIMEOUT, } } /// Limit the amount of time that the acceptor will wait for a TLS handshake to complete. /// /// Default timeout is 3 seconds. pub fn set_handshake_timeout(&mut self, handshake_timeout: Duration) -> &mut Self { self.handshake_timeout = handshake_timeout; self } } impl Clone for Acceptor { fn clone(&self) -> Self { Self { config: self.config.clone(), handshake_timeout: self.handshake_timeout, } } } impl ServiceFactory for Acceptor { type Response = TlsStream; type Error = TlsError; type Config = (); type Service = AcceptorService; type InitError = (); type Future = FutReady>; fn new_service(&self, _: ()) -> Self::Future { let res = MAX_CONN_COUNTER.with(|conns| { Ok(AcceptorService { acceptor: self.config.clone().into(), conns: conns.clone(), handshake_timeout: self.handshake_timeout, }) }); ready(res) } } /// Rustls based acceptor service. pub struct AcceptorService { acceptor: TlsAcceptor, conns: Counter, handshake_timeout: Duration, } impl Service for AcceptorService { type Response = TlsStream; type Error = TlsError; type Future = AcceptFut; fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { if self.conns.available(cx) { Poll::Ready(Ok(())) } else { Poll::Pending } } fn call(&self, req: IO) -> Self::Future { AcceptFut { fut: self.acceptor.accept(req), timeout: sleep(self.handshake_timeout), _guard: self.conns.get(), } } } pin_project! { /// Accept future for Rustls service. #[doc(hidden)] pub struct AcceptFut { fut: Accept, #[pin] timeout: Sleep, _guard: CounterGuard, } } impl Future for AcceptFut { type Output = Result, TlsError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); match Pin::new(&mut this.fut).poll(cx) { Poll::Ready(Ok(stream)) => Poll::Ready(Ok(TlsStream(stream))), Poll::Ready(Err(err)) => Poll::Ready(Err(TlsError::Tls(err))), Poll::Pending => this.timeout.poll(cx).map(|_| Err(TlsError::Timeout)), } } } actix-tls-3.4.0/src/accept/rustls_0_22.rs000064400000000000000000000131621046102023000162150ustar 00000000000000//! `rustls` v0.22 based TLS connection acceptor service. //! //! See [`Acceptor`] for main service factory docs. use std::{ convert::Infallible, future::Future, io::{self, IoSlice}, pin::Pin, sync::Arc, task::{Context, Poll}, time::Duration, }; use actix_rt::{ net::{ActixStream, Ready}, time::{sleep, Sleep}, }; use actix_service::{Service, ServiceFactory}; use actix_utils::{ counter::{Counter, CounterGuard}, future::{ready, Ready as FutReady}, }; use pin_project_lite::pin_project; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_rustls::{Accept, TlsAcceptor}; use tokio_rustls_025 as tokio_rustls; use super::{TlsError, DEFAULT_TLS_HANDSHAKE_TIMEOUT, MAX_CONN_COUNTER}; pub mod reexports { //! Re-exports from `rustls` that are useful for acceptors. pub use tokio_rustls_025::rustls::ServerConfig; } /// Wraps a `rustls` based async TLS stream in order to implement [`ActixStream`]. pub struct TlsStream(tokio_rustls::server::TlsStream); impl_more::impl_from!( in tokio_rustls::server::TlsStream => TlsStream); impl_more::impl_deref_and_mut!( in TlsStream => tokio_rustls::server::TlsStream); impl AsyncRead for TlsStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_read(cx, buf) } } impl AsyncWrite for TlsStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_flush(cx) } fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_shutdown(cx) } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write_vectored(cx, bufs) } fn is_write_vectored(&self) -> bool { (**self).is_write_vectored() } } impl ActixStream for TlsStream { fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_read_ready((**self).get_ref().0, cx) } fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_write_ready((**self).get_ref().0, cx) } } /// Accept TLS connections via the `rustls` crate. pub struct Acceptor { config: Arc, handshake_timeout: Duration, } impl Acceptor { /// Constructs `rustls` based acceptor service factory. pub fn new(config: reexports::ServerConfig) -> Self { Acceptor { config: Arc::new(config), handshake_timeout: DEFAULT_TLS_HANDSHAKE_TIMEOUT, } } /// Limit the amount of time that the acceptor will wait for a TLS handshake to complete. /// /// Default timeout is 3 seconds. pub fn set_handshake_timeout(&mut self, handshake_timeout: Duration) -> &mut Self { self.handshake_timeout = handshake_timeout; self } } impl Clone for Acceptor { fn clone(&self) -> Self { Self { config: self.config.clone(), handshake_timeout: self.handshake_timeout, } } } impl ServiceFactory for Acceptor { type Response = TlsStream; type Error = TlsError; type Config = (); type Service = AcceptorService; type InitError = (); type Future = FutReady>; fn new_service(&self, _: ()) -> Self::Future { let res = MAX_CONN_COUNTER.with(|conns| { Ok(AcceptorService { acceptor: self.config.clone().into(), conns: conns.clone(), handshake_timeout: self.handshake_timeout, }) }); ready(res) } } /// Rustls based acceptor service. pub struct AcceptorService { acceptor: TlsAcceptor, conns: Counter, handshake_timeout: Duration, } impl Service for AcceptorService { type Response = TlsStream; type Error = TlsError; type Future = AcceptFut; fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { if self.conns.available(cx) { Poll::Ready(Ok(())) } else { Poll::Pending } } fn call(&self, req: IO) -> Self::Future { AcceptFut { fut: self.acceptor.accept(req), timeout: sleep(self.handshake_timeout), _guard: self.conns.get(), } } } pin_project! { /// Accept future for Rustls service. #[doc(hidden)] pub struct AcceptFut { fut: Accept, #[pin] timeout: Sleep, _guard: CounterGuard, } } impl Future for AcceptFut { type Output = Result, TlsError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); match Pin::new(&mut this.fut).poll(cx) { Poll::Ready(Ok(stream)) => Poll::Ready(Ok(TlsStream(stream))), Poll::Ready(Err(err)) => Poll::Ready(Err(TlsError::Tls(err))), Poll::Pending => this.timeout.poll(cx).map(|_| Err(TlsError::Timeout)), } } } actix-tls-3.4.0/src/accept/rustls_0_23.rs000064400000000000000000000131621046102023000162160ustar 00000000000000//! `rustls` v0.23 based TLS connection acceptor service. //! //! See [`Acceptor`] for main service factory docs. use std::{ convert::Infallible, future::Future, io::{self, IoSlice}, pin::Pin, sync::Arc, task::{Context, Poll}, time::Duration, }; use actix_rt::{ net::{ActixStream, Ready}, time::{sleep, Sleep}, }; use actix_service::{Service, ServiceFactory}; use actix_utils::{ counter::{Counter, CounterGuard}, future::{ready, Ready as FutReady}, }; use pin_project_lite::pin_project; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_rustls::{Accept, TlsAcceptor}; use tokio_rustls_026 as tokio_rustls; use super::{TlsError, DEFAULT_TLS_HANDSHAKE_TIMEOUT, MAX_CONN_COUNTER}; pub mod reexports { //! Re-exports from `rustls` that are useful for acceptors. pub use tokio_rustls_026::rustls::ServerConfig; } /// Wraps a `rustls` based async TLS stream in order to implement [`ActixStream`]. pub struct TlsStream(tokio_rustls::server::TlsStream); impl_more::impl_from!( in tokio_rustls::server::TlsStream => TlsStream); impl_more::impl_deref_and_mut!( in TlsStream => tokio_rustls::server::TlsStream); impl AsyncRead for TlsStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_read(cx, buf) } } impl AsyncWrite for TlsStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write(cx, buf) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_flush(cx) } fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { Pin::new(&mut **self.get_mut()).poll_shutdown(cx) } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { Pin::new(&mut **self.get_mut()).poll_write_vectored(cx, bufs) } fn is_write_vectored(&self) -> bool { (**self).is_write_vectored() } } impl ActixStream for TlsStream { fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_read_ready((**self).get_ref().0, cx) } fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll> { IO::poll_write_ready((**self).get_ref().0, cx) } } /// Accept TLS connections via the `rustls` crate. pub struct Acceptor { config: Arc, handshake_timeout: Duration, } impl Acceptor { /// Constructs `rustls` based acceptor service factory. pub fn new(config: reexports::ServerConfig) -> Self { Acceptor { config: Arc::new(config), handshake_timeout: DEFAULT_TLS_HANDSHAKE_TIMEOUT, } } /// Limit the amount of time that the acceptor will wait for a TLS handshake to complete. /// /// Default timeout is 3 seconds. pub fn set_handshake_timeout(&mut self, handshake_timeout: Duration) -> &mut Self { self.handshake_timeout = handshake_timeout; self } } impl Clone for Acceptor { fn clone(&self) -> Self { Self { config: self.config.clone(), handshake_timeout: self.handshake_timeout, } } } impl ServiceFactory for Acceptor { type Response = TlsStream; type Error = TlsError; type Config = (); type Service = AcceptorService; type InitError = (); type Future = FutReady>; fn new_service(&self, _: ()) -> Self::Future { let res = MAX_CONN_COUNTER.with(|conns| { Ok(AcceptorService { acceptor: self.config.clone().into(), conns: conns.clone(), handshake_timeout: self.handshake_timeout, }) }); ready(res) } } /// Rustls based acceptor service. pub struct AcceptorService { acceptor: TlsAcceptor, conns: Counter, handshake_timeout: Duration, } impl Service for AcceptorService { type Response = TlsStream; type Error = TlsError; type Future = AcceptFut; fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { if self.conns.available(cx) { Poll::Ready(Ok(())) } else { Poll::Pending } } fn call(&self, req: IO) -> Self::Future { AcceptFut { fut: self.acceptor.accept(req), timeout: sleep(self.handshake_timeout), _guard: self.conns.get(), } } } pin_project! { /// Accept future for Rustls service. #[doc(hidden)] pub struct AcceptFut { fut: Accept, #[pin] timeout: Sleep, _guard: CounterGuard, } } impl Future for AcceptFut { type Output = Result, TlsError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut this = self.project(); match Pin::new(&mut this.fut).poll(cx) { Poll::Ready(Ok(stream)) => Poll::Ready(Ok(TlsStream(stream))), Poll::Ready(Err(err)) => Poll::Ready(Err(TlsError::Tls(err))), Poll::Pending => this.timeout.poll(cx).map(|_| Err(TlsError::Timeout)), } } } actix-tls-3.4.0/src/connect/connect_addrs.rs000064400000000000000000000037321046102023000171410ustar 00000000000000use std::{ collections::{vec_deque, VecDeque}, fmt, iter, net::SocketAddr, }; #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub(crate) enum ConnectAddrs { None, One(SocketAddr), // TODO: consider using smallvec Multi(VecDeque), } impl ConnectAddrs { pub(crate) fn is_unresolved(&self) -> bool { matches!(self, Self::None) } pub(crate) fn is_resolved(&self) -> bool { !self.is_unresolved() } } impl Default for ConnectAddrs { fn default() -> Self { Self::None } } impl From> for ConnectAddrs { fn from(addr: Option) -> Self { match addr { Some(addr) => ConnectAddrs::One(addr), None => ConnectAddrs::None, } } } /// Iterator over addresses in a [`Connect`] request. #[derive(Clone)] pub(crate) enum ConnectAddrsIter<'a> { None, One(SocketAddr), Multi(vec_deque::Iter<'a, SocketAddr>), MultiOwned(vec_deque::IntoIter), } impl Iterator for ConnectAddrsIter<'_> { type Item = SocketAddr; fn next(&mut self) -> Option { match *self { Self::None => None, Self::One(addr) => { *self = Self::None; Some(addr) } Self::Multi(ref mut iter) => iter.next().copied(), Self::MultiOwned(ref mut iter) => iter.next(), } } fn size_hint(&self) -> (usize, Option) { match *self { Self::None => (0, Some(0)), Self::One(_) => (1, Some(1)), Self::Multi(ref iter) => iter.size_hint(), Self::MultiOwned(ref iter) => iter.size_hint(), } } } impl fmt::Debug for ConnectAddrsIter<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } impl iter::ExactSizeIterator for ConnectAddrsIter<'_> {} impl iter::FusedIterator for ConnectAddrsIter<'_> {} actix-tls-3.4.0/src/connect/connection.rs000064400000000000000000000024021046102023000164630ustar 00000000000000use super::Host; /// Wraps underlying I/O and the connection request that initiated it. #[derive(Debug)] pub struct Connection { pub(crate) req: R, pub(crate) io: IO, } impl_more::impl_deref_and_mut!( in Connection => io: IO); impl Connection { /// Construct new `Connection` from request and IO parts. pub fn new(req: R, io: IO) -> Self { Self { req, io } } } impl Connection { /// Deconstructs into IO and request parts. pub fn into_parts(self) -> (IO, R) { (self.io, self.req) } /// Replaces underlying IO, returning old IO and new `Connection`. pub fn replace_io(self, io: IO2) -> (IO, Connection) { (self.io, Connection { io, req: self.req }) } /// Returns a shared reference to the underlying IO. pub fn io_ref(&self) -> &IO { &self.io } /// Returns a mutable reference to the underlying IO. pub fn io_mut(&mut self) -> &mut IO { &mut self.io } /// Returns a reference to the connection request. pub fn request(&self) -> &R { &self.req } } impl Connection { /// Returns hostname. pub fn hostname(&self) -> &str { self.req.hostname() } } actix-tls-3.4.0/src/connect/connector.rs000064400000000000000000000070671046102023000163320ustar 00000000000000use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; use actix_rt::net::TcpStream; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::ready; use super::{ error::ConnectError, resolver::{Resolver, ResolverService}, tcp::{TcpConnector, TcpConnectorService}, ConnectInfo, Connection, Host, }; /// Combined resolver and TCP connector service factory. /// /// Used to create [`ConnectorService`]s which receive connection information, resolve DNS if /// required, and return a TCP stream. #[derive(Clone, Default)] pub struct Connector { resolver: Resolver, } impl Connector { /// Constructs new connector factory with the given resolver. pub fn new(resolver: Resolver) -> Self { Connector { resolver } } /// Build connector service. pub fn service(&self) -> ConnectorService { ConnectorService { tcp: TcpConnector::default().service(), resolver: self.resolver.service(), } } } impl ServiceFactory> for Connector { type Response = Connection; type Error = ConnectError; type Config = (); type Service = ConnectorService; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(self.service()) } } /// Combined resolver and TCP connector service. /// /// Service implementation receives connection information, resolves DNS if required, and returns /// a TCP stream. #[derive(Clone, Default)] pub struct ConnectorService { tcp: TcpConnectorService, resolver: ResolverService, } impl Service> for ConnectorService { type Response = Connection; type Error = ConnectError; type Future = ConnectServiceResponse; actix_service::always_ready!(); fn call(&self, req: ConnectInfo) -> Self::Future { ConnectServiceResponse { fut: ConnectFut::Resolve(self.resolver.call(req)), tcp: self.tcp, } } } /// Chains futures of resolve and connect steps. pub(crate) enum ConnectFut { Resolve(>>::Future), Connect(>>::Future), } /// Container for the intermediate states of [`ConnectFut`]. pub(crate) enum ConnectFutState { Resolved(ConnectInfo), Connected(Connection), } impl ConnectFut { fn poll_connect( &mut self, cx: &mut Context<'_>, ) -> Poll, ConnectError>> { match self { ConnectFut::Resolve(ref mut fut) => { Pin::new(fut).poll(cx).map_ok(ConnectFutState::Resolved) } ConnectFut::Connect(ref mut fut) => { Pin::new(fut).poll(cx).map_ok(ConnectFutState::Connected) } } } } pub struct ConnectServiceResponse { fut: ConnectFut, tcp: TcpConnectorService, } impl Future for ConnectServiceResponse { type Output = Result, ConnectError>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(self.fut.poll_connect(cx))? { ConnectFutState::Resolved(res) => { self.fut = ConnectFut::Connect(self.tcp.call(res)); } ConnectFutState::Connected(res) => return Poll::Ready(Ok(res)), } } } } actix-tls-3.4.0/src/connect/error.rs000064400000000000000000000023311046102023000154560ustar 00000000000000use std::{error::Error, fmt, io}; /// Errors that can result from using a connector service. #[derive(Debug)] pub enum ConnectError { /// Failed to resolve the hostname. Resolver(Box), /// No DNS records. NoRecords, /// Invalid input. InvalidInput, /// Unresolved host name. Unresolved, /// Connection IO error. Io(io::Error), } impl fmt::Display for ConnectError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::NoRecords => f.write_str("No DNS records found for the input"), Self::InvalidInput => f.write_str("Invalid input"), Self::Unresolved => { f.write_str("Connector received `Connect` method with unresolved host") } Self::Resolver(_) => f.write_str("Failed to resolve hostname"), Self::Io(_) => f.write_str("I/O error"), } } } impl Error for ConnectError { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { Self::Resolver(err) => Some(&**err), Self::Io(err) => Some(err), Self::NoRecords | Self::InvalidInput | Self::Unresolved => None, } } } actix-tls-3.4.0/src/connect/host.rs000064400000000000000000000036241046102023000153100ustar 00000000000000//! The [`Host`] trait. /// An interface for types where host parts (hostname and port) can be derived. /// /// The [WHATWG URL Standard] defines the terminology used for this trait and its methods. /// /// ```plain /// +------------------------+ /// | host | /// +-----------------+------+ /// | hostname | port | /// | | | /// | sub.example.com : 8080 | /// +-----------------+------+ /// ``` /// /// [WHATWG URL Standard]: https://url.spec.whatwg.org/ pub trait Host: Unpin + 'static { /// Extract hostname. fn hostname(&self) -> &str; /// Extract optional port. fn port(&self) -> Option { None } } impl Host for String { fn hostname(&self) -> &str { self.split_once(':') .map(|(hostname, _)| hostname) .unwrap_or(self) } fn port(&self) -> Option { self.split_once(':').and_then(|(_, port)| port.parse().ok()) } } impl Host for &'static str { fn hostname(&self) -> &str { self.split_once(':') .map(|(hostname, _)| hostname) .unwrap_or(self) } fn port(&self) -> Option { self.split_once(':').and_then(|(_, port)| port.parse().ok()) } } #[cfg(test)] mod tests { use super::*; macro_rules! assert_connection_info_eq { ($req:expr, $hostname:expr, $port:expr) => {{ assert_eq!($req.hostname(), $hostname); assert_eq!($req.port(), $port); }}; } #[test] fn host_parsing() { assert_connection_info_eq!("example.com", "example.com", None); assert_connection_info_eq!("example.com:8080", "example.com", Some(8080)); assert_connection_info_eq!("example:8080", "example", Some(8080)); assert_connection_info_eq!("example.com:false", "example.com", None); assert_connection_info_eq!("example.com:false:false", "example.com", None); } } actix-tls-3.4.0/src/connect/info.rs000064400000000000000000000163301046102023000152640ustar 00000000000000//! Connection info struct. use std::{ collections::VecDeque, fmt, iter::{self, FromIterator as _}, mem, net::{IpAddr, SocketAddr}, }; use super::{ connect_addrs::{ConnectAddrs, ConnectAddrsIter}, Host, }; /// Connection request information. /// /// May contain known/pre-resolved socket address(es) or a host that needs resolving with DNS. #[derive(Debug, PartialEq, Eq, Hash)] pub struct ConnectInfo { pub(crate) request: R, pub(crate) port: u16, pub(crate) addr: ConnectAddrs, pub(crate) local_addr: Option, } impl ConnectInfo { /// Constructs new connection info using a request. pub fn new(request: R) -> ConnectInfo { let port = request.port(); ConnectInfo { request, port: port.unwrap_or(0), addr: ConnectAddrs::None, local_addr: None, } } /// Constructs new connection info from request and known socket address. /// /// Since socket address is known, [`Connector`](super::Connector) will skip the DNS /// resolution step. pub fn with_addr(request: R, addr: SocketAddr) -> ConnectInfo { ConnectInfo { request, port: 0, addr: ConnectAddrs::One(addr), local_addr: None, } } /// Set connection port. /// /// If request provided a port, this will override it. pub fn set_port(mut self, port: u16) -> Self { self.port = port; self } /// Set connection socket address. pub fn set_addr(mut self, addr: impl Into>) -> Self { self.addr = ConnectAddrs::from(addr.into()); self } /// Set list of addresses. pub fn set_addrs(mut self, addrs: I) -> Self where I: IntoIterator, { let mut addrs = VecDeque::from_iter(addrs); self.addr = if addrs.len() < 2 { ConnectAddrs::from(addrs.pop_front()) } else { ConnectAddrs::Multi(addrs) }; self } /// Set local address to connection with. /// /// Useful in situations where the IP address bound to a particular network interface is known. /// This would make sure the socket is opened through that interface. pub fn set_local_addr(mut self, addr: impl Into) -> Self { self.local_addr = Some(addr.into()); self } /// Returns a reference to the connection request. pub fn request(&self) -> &R { &self.request } /// Returns request hostname. pub fn hostname(&self) -> &str { self.request.hostname() } /// Returns request port. pub fn port(&self) -> u16 { self.request.port().unwrap_or(self.port) } /// Get borrowed iterator of resolved request addresses. /// /// # Examples /// ``` /// # use std::net::SocketAddr; /// # use actix_tls::connect::ConnectInfo; /// let addr = SocketAddr::from(([127, 0, 0, 1], 4242)); /// /// let conn = ConnectInfo::new("localhost"); /// let mut addrs = conn.addrs(); /// assert!(addrs.next().is_none()); /// /// let conn = ConnectInfo::with_addr("localhost", addr); /// let mut addrs = conn.addrs(); /// assert_eq!(addrs.next().unwrap(), addr); /// ``` #[allow(clippy::implied_bounds_in_impls)] pub fn addrs( &self, ) -> impl Iterator + ExactSizeIterator + iter::FusedIterator + Clone + fmt::Debug + '_ { match self.addr { ConnectAddrs::None => ConnectAddrsIter::None, ConnectAddrs::One(addr) => ConnectAddrsIter::One(addr), ConnectAddrs::Multi(ref addrs) => ConnectAddrsIter::Multi(addrs.iter()), } } /// Take owned iterator resolved request addresses. /// /// # Examples /// ``` /// # use std::net::SocketAddr; /// # use actix_tls::connect::ConnectInfo; /// let addr = SocketAddr::from(([127, 0, 0, 1], 4242)); /// /// let mut conn = ConnectInfo::new("localhost"); /// let mut addrs = conn.take_addrs(); /// assert!(addrs.next().is_none()); /// /// let mut conn = ConnectInfo::with_addr("localhost", addr); /// let mut addrs = conn.take_addrs(); /// assert_eq!(addrs.next().unwrap(), addr); /// ``` #[allow(clippy::implied_bounds_in_impls)] pub fn take_addrs( &mut self, ) -> impl Iterator + ExactSizeIterator + iter::FusedIterator + Clone + fmt::Debug + 'static { match mem::take(&mut self.addr) { ConnectAddrs::None => ConnectAddrsIter::None, ConnectAddrs::One(addr) => ConnectAddrsIter::One(addr), ConnectAddrs::Multi(addrs) => ConnectAddrsIter::MultiOwned(addrs.into_iter()), } } } impl From for ConnectInfo { fn from(addr: R) -> Self { ConnectInfo::new(addr) } } impl fmt::Display for ConnectInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}:{}", self.hostname(), self.port()) } } #[cfg(test)] mod tests { use std::net::Ipv4Addr; use super::*; #[test] fn test_addr_iter_multi() { let localhost = SocketAddr::from((IpAddr::from(Ipv4Addr::LOCALHOST), 8080)); let unspecified = SocketAddr::from((IpAddr::from(Ipv4Addr::UNSPECIFIED), 8080)); let mut addrs = VecDeque::new(); addrs.push_back(localhost); addrs.push_back(unspecified); let mut iter = ConnectAddrsIter::Multi(addrs.iter()); assert_eq!(iter.next(), Some(localhost)); assert_eq!(iter.next(), Some(unspecified)); assert_eq!(iter.next(), None); let mut iter = ConnectAddrsIter::MultiOwned(addrs.into_iter()); assert_eq!(iter.next(), Some(localhost)); assert_eq!(iter.next(), Some(unspecified)); assert_eq!(iter.next(), None); } #[test] fn test_addr_iter_single() { let localhost = SocketAddr::from((IpAddr::from(Ipv4Addr::LOCALHOST), 8080)); let mut iter = ConnectAddrsIter::One(localhost); assert_eq!(iter.next(), Some(localhost)); assert_eq!(iter.next(), None); let mut iter = ConnectAddrsIter::None; assert_eq!(iter.next(), None); } #[test] fn test_local_addr() { let conn = ConnectInfo::new("hello").set_local_addr([127, 0, 0, 1]); assert_eq!( conn.local_addr.unwrap(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)) ) } #[test] fn request_ref() { let conn = ConnectInfo::new("hello"); assert_eq!(conn.request(), &"hello") } #[test] fn set_connect_addr_into_option() { let addr = SocketAddr::from(([127, 0, 0, 1], 4242)); let conn = ConnectInfo::new("hello").set_addr(None); let mut addrs = conn.addrs(); assert!(addrs.next().is_none()); let conn = ConnectInfo::new("hello").set_addr(addr); let mut addrs = conn.addrs(); assert_eq!(addrs.next().unwrap(), addr); let conn = ConnectInfo::new("hello").set_addr(Some(addr)); let mut addrs = conn.addrs(); assert_eq!(addrs.next().unwrap(), addr); } } actix-tls-3.4.0/src/connect/mod.rs000064400000000000000000000030001046102023000150760ustar 00000000000000//! TCP and TLS connector services. //! //! # Stages of the TCP connector service: //! 1. Resolve [`Host`] (if needed) with given [`Resolver`] and collect list of socket addresses. //! 1. Establish TCP connection and return [`TcpStream`]. //! //! # Stages of TLS connector services: //! 1. Resolve DNS and establish a [`TcpStream`] with the TCP connector service. //! 1. Wrap the stream and perform connect handshake with remote peer. //! 1. Return wrapped stream type that implements `AsyncRead` and `AsyncWrite`. //! //! [`TcpStream`]: actix_rt::net::TcpStream mod connect_addrs; mod connection; mod connector; mod error; mod host; mod info; mod resolve; mod resolver; pub mod tcp; #[cfg(feature = "uri")] mod uri; #[cfg(feature = "openssl")] pub mod openssl; #[cfg(any( feature = "rustls-0_20-webpki-roots", feature = "rustls-0_20-native-roots", ))] pub mod rustls_0_20; #[doc(hidden)] #[cfg(any( feature = "rustls-0_20-webpki-roots", feature = "rustls-0_20-native-roots", ))] pub use rustls_0_20 as rustls; #[cfg(any( feature = "rustls-0_21-webpki-roots", feature = "rustls-0_21-native-roots", ))] pub mod rustls_0_21; #[cfg(feature = "rustls-0_22")] pub mod rustls_0_22; #[cfg(feature = "rustls-0_23")] pub mod rustls_0_23; #[cfg(feature = "native-tls")] pub mod native_tls; pub use self::{ connection::Connection, connector::{Connector, ConnectorService}, error::ConnectError, host::Host, info::ConnectInfo, resolve::Resolve, resolver::{Resolver, ResolverService}, }; actix-tls-3.4.0/src/connect/native_tls.rs000064400000000000000000000053371046102023000165060ustar 00000000000000//! Native-TLS based connector service. //! //! See [`TlsConnector`] for main connector service factory docs. use std::io; use actix_rt::net::ActixStream; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::future::LocalBoxFuture; use tokio_native_tls::{ native_tls::TlsConnector as NativeTlsConnector, TlsConnector as AsyncNativeTlsConnector, TlsStream as AsyncTlsStream, }; use tracing::trace; use crate::connect::{Connection, Host}; pub mod reexports { //! Re-exports from `native-tls` and `tokio-native-tls` that are useful for connectors. pub use tokio_native_tls::{native_tls::TlsConnector, TlsStream as AsyncTlsStream}; } /// Connector service and factory using `native-tls`. #[derive(Clone)] pub struct TlsConnector { connector: AsyncNativeTlsConnector, } impl TlsConnector { /// Constructs new connector service from a `native-tls` connector. /// /// This type is it's own service factory, so it can be used in that setting, too. pub fn new(connector: NativeTlsConnector) -> Self { Self { connector: AsyncNativeTlsConnector::from(connector), } } } impl ServiceFactory> for TlsConnector where IO: ActixStream + 'static, { type Response = Connection>; type Error = io::Error; type Config = (); type Service = Self; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(self.clone()) } } /// The `native-tls` connector is both it's ServiceFactory and Service impl type. /// As the factory and service share the same type and state. impl Service> for TlsConnector where R: Host, IO: ActixStream + 'static, { type Response = Connection>; type Error = io::Error; type Future = LocalBoxFuture<'static, Result>; actix_service::always_ready!(); fn call(&self, stream: Connection) -> Self::Future { let (io, stream) = stream.replace_io(()); let connector = self.connector.clone(); Box::pin(async move { trace!("TLS handshake start for: {:?}", stream.hostname()); connector .connect(stream.hostname(), io) .await .map(|res| { trace!("TLS handshake success: {:?}", stream.hostname()); stream.replace_io(res).1 }) .map_err(|e| { trace!("TLS handshake error: {:?}", e); io::Error::new(io::ErrorKind::Other, format!("{}", e)) }) }) } } actix-tls-3.4.0/src/connect/openssl.rs000064400000000000000000000076711046102023000160240ustar 00000000000000//! OpenSSL based connector service. //! //! See [`TlsConnector`] for main connector service factory docs. use std::{ future::Future, io, pin::Pin, task::{Context, Poll}, }; use actix_rt::net::ActixStream; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::ready; use openssl::ssl::SslConnector; use tokio_openssl::SslStream as AsyncSslStream; use tracing::trace; use crate::connect::{Connection, Host}; pub mod reexports { //! Re-exports from `openssl` and `tokio-openssl` that are useful for connectors. pub use openssl::ssl::{Error, HandshakeError, SslConnector, SslConnectorBuilder, SslMethod}; pub use tokio_openssl::SslStream as AsyncSslStream; } /// Connector service factory using `openssl`. pub struct TlsConnector { connector: SslConnector, } impl TlsConnector { /// Constructs new connector service factory from an `openssl` connector. pub fn new(connector: SslConnector) -> Self { TlsConnector { connector } } /// Constructs new connector service from an `openssl` connector. pub fn service(connector: SslConnector) -> TlsConnectorService { TlsConnectorService { connector } } } impl Clone for TlsConnector { fn clone(&self) -> Self { Self { connector: self.connector.clone(), } } } impl ServiceFactory> for TlsConnector where R: Host, IO: ActixStream + 'static, { type Response = Connection>; type Error = io::Error; type Config = (); type Service = TlsConnectorService; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(TlsConnectorService { connector: self.connector.clone(), }) } } /// Connector service using `openssl`. pub struct TlsConnectorService { connector: SslConnector, } impl Clone for TlsConnectorService { fn clone(&self) -> Self { Self { connector: self.connector.clone(), } } } impl Service> for TlsConnectorService where R: Host, IO: ActixStream, { type Response = Connection>; type Error = io::Error; type Future = ConnectFut; actix_service::always_ready!(); fn call(&self, stream: Connection) -> Self::Future { trace!("TLS handshake start for: {:?}", stream.hostname()); let (io, stream) = stream.replace_io(()); let host = stream.hostname(); let config = self .connector .configure() .expect("SSL connect configuration was invalid."); let ssl = config .into_ssl(host) .expect("SSL connect configuration was invalid."); ConnectFut { io: Some(AsyncSslStream::new(ssl, io).unwrap()), stream: Some(stream), } } } /// Connect future for OpenSSL service. #[doc(hidden)] pub struct ConnectFut { io: Option>, stream: Option>, } impl Future for ConnectFut where R: Host, IO: ActixStream, { type Output = Result>, io::Error>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); match ready!(Pin::new(this.io.as_mut().unwrap()).poll_connect(cx)) { Ok(_) => { let stream = this.stream.take().unwrap(); trace!("TLS handshake success: {:?}", stream.hostname()); Poll::Ready(Ok(stream.replace_io(this.io.take().unwrap()).1)) } Err(err) => { trace!("TLS handshake error: {:?}", err); Poll::Ready(Err(io::Error::new( io::ErrorKind::Other, format!("{}", err), ))) } } } } actix-tls-3.4.0/src/connect/resolve.rs000064400000000000000000000035061046102023000160110ustar 00000000000000//! The [`Resolve`] trait. use std::{error::Error as StdError, net::SocketAddr}; use futures_core::future::LocalBoxFuture; /// Custom async DNS resolvers. /// /// # Examples /// ``` /// use std::net::SocketAddr; /// /// use actix_tls::connect::{Resolve, Resolver}; /// use futures_util::future::LocalBoxFuture; /// /// // use trust-dns async tokio resolver /// use trust_dns_resolver::TokioAsyncResolver; /// /// struct MyResolver { /// trust_dns: TokioAsyncResolver, /// }; /// /// // impl Resolve trait and convert given host address str and port to SocketAddr. /// impl Resolve for MyResolver { /// fn lookup<'a>( /// &'a self, /// host: &'a str, /// port: u16, /// ) -> LocalBoxFuture<'a, Result, Box>> { /// Box::pin(async move { /// let res = self /// .trust_dns /// .lookup_ip(host) /// .await? /// .iter() /// .map(|ip| SocketAddr::new(ip, port)) /// .collect(); /// Ok(res) /// }) /// } /// } /// /// let my_resolver = MyResolver { /// trust_dns: TokioAsyncResolver::tokio_from_system_conf().unwrap(), /// }; /// /// // wrap custom resolver /// let resolver = Resolver::custom(my_resolver); /// /// // resolver can be passed to connector factory where returned service factory /// // can be used to construct new connector services for use in clients /// let factory = actix_tls::connect::Connector::new(resolver); /// let connector = factory.service(); /// ``` pub trait Resolve { /// Given DNS lookup information, returns a future that completes with socket information. fn lookup<'a>( &'a self, host: &'a str, port: u16, ) -> LocalBoxFuture<'a, Result, Box>>; } actix-tls-3.4.0/src/connect/resolver.rs000064400000000000000000000136361046102023000162000ustar 00000000000000use std::{ future::Future, io, net::SocketAddr, pin::Pin, rc::Rc, task::{Context, Poll}, vec::IntoIter, }; use actix_rt::task::{spawn_blocking, JoinHandle}; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::{future::LocalBoxFuture, ready}; use tracing::trace; use super::{ConnectError, ConnectInfo, Host, Resolve}; /// DNS resolver service factory. #[derive(Clone, Default)] pub struct Resolver { resolver: ResolverService, } impl Resolver { /// Constructs a new resolver factory with a custom resolver. pub fn custom(resolver: impl Resolve + 'static) -> Self { Self { resolver: ResolverService::custom(resolver), } } /// Returns a new resolver service. pub fn service(&self) -> ResolverService { self.resolver.clone() } } impl ServiceFactory> for Resolver { type Response = ConnectInfo; type Error = ConnectError; type Config = (); type Service = ResolverService; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(self.resolver.clone()) } } #[derive(Clone)] enum ResolverKind { /// Built-in DNS resolver. /// /// See [`std::net::ToSocketAddrs`] trait. Default, /// Custom, user-provided DNS resolver. Custom(Rc), } impl Default for ResolverKind { fn default() -> Self { Self::Default } } /// DNS resolver service. #[derive(Clone, Default)] pub struct ResolverService { kind: ResolverKind, } impl ResolverService { /// Constructor for custom Resolve trait object and use it as resolver. pub fn custom(resolver: impl Resolve + 'static) -> Self { Self { kind: ResolverKind::Custom(Rc::new(resolver)), } } /// Resolve DNS with default resolver. fn default_lookup( req: &ConnectInfo, ) -> JoinHandle>> { // reconstruct host; concatenate hostname and port together let host = format!("{}:{}", req.hostname(), req.port()); // run blocking DNS lookup in thread pool since DNS lookups can take upwards of seconds on // some platforms if conditions are poor and OS-level cache is not populated spawn_blocking(move || std::net::ToSocketAddrs::to_socket_addrs(&host)) } } impl Service> for ResolverService { type Response = ConnectInfo; type Error = ConnectError; type Future = ResolverFut; actix_service::always_ready!(); fn call(&self, req: ConnectInfo) -> Self::Future { if req.addr.is_resolved() { // socket address(es) already resolved; return existing connection request ResolverFut::Resolved(Some(req)) } else if let Ok(ip) = req.hostname().parse() { // request hostname is valid ip address; add address to request and return let addr = SocketAddr::new(ip, req.port()); let req = req.set_addr(Some(addr)); ResolverFut::Resolved(Some(req)) } else { trace!("DNS resolver: resolving host {:?}", req.hostname()); match &self.kind { ResolverKind::Default => { let fut = Self::default_lookup(&req); ResolverFut::LookUp(fut, Some(req)) } ResolverKind::Custom(resolver) => { let resolver = Rc::clone(resolver); ResolverFut::LookupCustom(Box::pin(async move { let addrs = resolver .lookup(req.hostname(), req.port()) .await .map_err(ConnectError::Resolver)?; let req = req.set_addrs(addrs); if req.addr.is_unresolved() { Err(ConnectError::NoRecords) } else { Ok(req) } })) } } } } } /// Future for resolver service. #[doc(hidden)] pub enum ResolverFut { Resolved(Option>), LookUp( JoinHandle>>, Option>, ), LookupCustom(LocalBoxFuture<'static, Result, ConnectError>>), } impl Future for ResolverFut { type Output = Result, ConnectError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.get_mut() { Self::Resolved(conn) => Poll::Ready(Ok(conn .take() .expect("ResolverFuture polled after finished"))), Self::LookUp(fut, req) => { let res = match ready!(Pin::new(fut).poll(cx)) { Ok(Ok(res)) => Ok(res), Ok(Err(err)) => Err(ConnectError::Resolver(Box::new(err))), Err(err) => Err(ConnectError::Io(err.into())), }; let req = req.take().unwrap(); let addrs = res.map_err(|err| { trace!( "DNS resolver: failed to resolve host {:?} err: {:?}", req.hostname(), err ); err })?; let req = req.set_addrs(addrs); trace!( "DNS resolver: host {:?} resolved to {:?}", req.hostname(), req.addrs() ); if req.addr.is_unresolved() { Poll::Ready(Err(ConnectError::NoRecords)) } else { Poll::Ready(Ok(req)) } } Self::LookupCustom(fut) => fut.as_mut().poll(cx), } } } actix-tls-3.4.0/src/connect/rustls_0_20.rs000064400000000000000000000125301046102023000164030ustar 00000000000000//! Rustls based connector service. //! //! See [`TlsConnector`] for main connector service factory docs. use std::{ future::Future, io, pin::Pin, sync::Arc, task::{Context, Poll}, }; use actix_rt::net::ActixStream; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::ready; use tokio_rustls::{ client::TlsStream as AsyncTlsStream, rustls::{client::ServerName, ClientConfig, RootCertStore}, Connect as RustlsConnect, TlsConnector as RustlsTlsConnector, }; use tokio_rustls_023 as tokio_rustls; use crate::connect::{Connection, Host}; pub mod reexports { //! Re-exports from the `rustls` v0.20 ecosystem that are useful for connectors. pub use tokio_rustls_023::{client::TlsStream as AsyncTlsStream, rustls::ClientConfig}; #[cfg(feature = "rustls-0_20-webpki-roots")] pub use webpki_roots_022::TLS_SERVER_ROOTS; } /// Returns root certificates via `rustls-native-certs` crate as a rustls certificate store. /// /// See [`rustls_native_certs::load_native_certs()`] for more info on behavior and errors. /// /// [`rustls_native_certs::load_native_certs()`]: rustls_native_certs_06::load_native_certs() #[cfg(feature = "rustls-0_20-native-roots")] pub fn native_roots_cert_store() -> io::Result { let mut root_certs = RootCertStore::empty(); for cert in rustls_native_certs_06::load_native_certs()? { root_certs .add(&tokio_rustls_023::rustls::Certificate(cert.0)) .unwrap(); } Ok(root_certs) } /// Returns standard root certificates from `webpki-roots` crate as a rustls certificate store. #[cfg(feature = "rustls-0_20-webpki-roots")] pub fn webpki_roots_cert_store() -> RootCertStore { use tokio_rustls_023::rustls; let mut root_certs = RootCertStore::empty(); for cert in webpki_roots_022::TLS_SERVER_ROOTS.0 { let cert = rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( cert.subject, cert.spki, cert.name_constraints, ); let certs = vec![cert].into_iter(); root_certs.add_server_trust_anchors(certs); } root_certs } /// Connector service factory using `rustls`. #[derive(Clone)] pub struct TlsConnector { connector: Arc, } impl TlsConnector { /// Constructs new connector service factory from a `rustls` client configuration. pub fn new(connector: Arc) -> Self { TlsConnector { connector } } /// Constructs new connector service from a `rustls` client configuration. pub fn service(connector: Arc) -> TlsConnectorService { TlsConnectorService { connector } } } impl ServiceFactory> for TlsConnector where R: Host, IO: ActixStream + 'static, { type Response = Connection>; type Error = io::Error; type Config = (); type Service = TlsConnectorService; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(TlsConnectorService { connector: self.connector.clone(), }) } } /// Connector service using `rustls`. #[derive(Clone)] pub struct TlsConnectorService { connector: Arc, } impl Service> for TlsConnectorService where R: Host, IO: ActixStream, { type Response = Connection>; type Error = io::Error; type Future = ConnectFut; actix_service::always_ready!(); fn call(&self, connection: Connection) -> Self::Future { tracing::trace!("TLS handshake start for: {:?}", connection.hostname()); let (stream, connection) = connection.replace_io(()); match ServerName::try_from(connection.hostname()) { Ok(host) => ConnectFut::Future { connect: RustlsTlsConnector::from(Arc::clone(&self.connector)) .connect(host, stream), connection: Some(connection), }, Err(_) => ConnectFut::InvalidDns, } } } /// Connect future for Rustls service. #[doc(hidden)] #[allow(clippy::large_enum_variant)] pub enum ConnectFut { /// See issue InvalidDns, Future { connect: RustlsConnect, connection: Option>, }, } impl Future for ConnectFut where R: Host, IO: ActixStream, { type Output = io::Result>>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.get_mut() { Self::InvalidDns => Poll::Ready(Err(io::Error::new( io::ErrorKind::Other, "Rustls v0.20 can only handle hostname-based connections. Enable the `rustls-0_21` \ feature and use the Rustls v0.21 utilities to gain this feature.", ))), Self::Future { connect, connection, } => { let stream = ready!(Pin::new(connect).poll(cx))?; let connection = connection.take().unwrap(); tracing::trace!("TLS handshake success: {:?}", connection.hostname()); Poll::Ready(Ok(connection.replace_io(stream).1)) } } } } actix-tls-3.4.0/src/connect/rustls_0_21.rs000064400000000000000000000122671046102023000164130ustar 00000000000000//! Rustls based connector service. //! //! See [`TlsConnector`] for main connector service factory docs. use std::{ future::Future, io, pin::Pin, sync::Arc, task::{Context, Poll}, }; use actix_rt::net::ActixStream; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::ready; use tokio_rustls::{ client::TlsStream as AsyncTlsStream, rustls::{client::ServerName, ClientConfig, RootCertStore}, Connect as RustlsConnect, TlsConnector as RustlsTlsConnector, }; use tokio_rustls_024 as tokio_rustls; use crate::connect::{Connection, Host}; pub mod reexports { //! Re-exports from the `rustls` v0.21 ecosystem that are useful for connectors. pub use tokio_rustls_024::{client::TlsStream as AsyncTlsStream, rustls::ClientConfig}; #[cfg(feature = "rustls-0_21-webpki-roots")] pub use webpki_roots_025::TLS_SERVER_ROOTS; } /// Returns root certificates via `rustls-native-certs` crate as a rustls certificate store. /// /// See [`rustls_native_certs::load_native_certs()`] for more info on behavior and errors. /// /// [`rustls_native_certs::load_native_certs()`]: rustls_native_certs_06::load_native_certs() #[cfg(feature = "rustls-0_21-native-roots")] pub fn native_roots_cert_store() -> io::Result { let mut root_certs = RootCertStore::empty(); for cert in rustls_native_certs_06::load_native_certs()? { root_certs .add(&tokio_rustls_024::rustls::Certificate(cert.0)) .unwrap(); } Ok(root_certs) } /// Returns standard root certificates from `webpki-roots` crate as a rustls certificate store. #[cfg(feature = "rustls-0_21-webpki-roots")] pub fn webpki_roots_cert_store() -> RootCertStore { use tokio_rustls_024::rustls; let mut root_certs = RootCertStore::empty(); for cert in webpki_roots_025::TLS_SERVER_ROOTS { let cert = rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( cert.subject, cert.spki, cert.name_constraints, ); let certs = vec![cert].into_iter(); root_certs.add_trust_anchors(certs); } root_certs } /// Connector service factory using `rustls`. #[derive(Clone)] pub struct TlsConnector { connector: Arc, } impl TlsConnector { /// Constructs new connector service factory from a `rustls` client configuration. pub fn new(connector: Arc) -> Self { TlsConnector { connector } } /// Constructs new connector service from a `rustls` client configuration. pub fn service(connector: Arc) -> TlsConnectorService { TlsConnectorService { connector } } } impl ServiceFactory> for TlsConnector where R: Host, IO: ActixStream + 'static, { type Response = Connection>; type Error = io::Error; type Config = (); type Service = TlsConnectorService; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(TlsConnectorService { connector: self.connector.clone(), }) } } /// Connector service using `rustls`. #[derive(Clone)] pub struct TlsConnectorService { connector: Arc, } impl Service> for TlsConnectorService where R: Host, IO: ActixStream, { type Response = Connection>; type Error = io::Error; type Future = ConnectFut; actix_service::always_ready!(); fn call(&self, connection: Connection) -> Self::Future { tracing::trace!("TLS handshake start for: {:?}", connection.hostname()); let (stream, connection) = connection.replace_io(()); match ServerName::try_from(connection.hostname()) { Ok(host) => ConnectFut::Future { connect: RustlsTlsConnector::from(Arc::clone(&self.connector)) .connect(host, stream), connection: Some(connection), }, Err(_) => ConnectFut::InvalidServerName, } } } /// Connect future for Rustls service. #[doc(hidden)] #[allow(clippy::large_enum_variant)] pub enum ConnectFut { InvalidServerName, Future { connect: RustlsConnect, connection: Option>, }, } impl Future for ConnectFut where R: Host, IO: ActixStream, { type Output = io::Result>>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.get_mut() { Self::InvalidServerName => Poll::Ready(Err(io::Error::new( io::ErrorKind::InvalidInput, "connection parameters specified invalid server name", ))), Self::Future { connect, connection, } => { let stream = ready!(Pin::new(connect).poll(cx))?; let connection = connection.take().unwrap(); tracing::trace!("TLS handshake success: {:?}", connection.hostname()); Poll::Ready(Ok(connection.replace_io(stream).1)) } } } } actix-tls-3.4.0/src/connect/rustls_0_22.rs000064400000000000000000000116341046102023000164110ustar 00000000000000//! Rustls based connector service. //! //! See [`TlsConnector`] for main connector service factory docs. use std::{ future::Future, io, pin::Pin, sync::Arc, task::{Context, Poll}, }; use actix_rt::net::ActixStream; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::ready; use rustls_pki_types_1::ServerName; use tokio_rustls::{ client::TlsStream as AsyncTlsStream, rustls::ClientConfig, Connect as RustlsConnect, TlsConnector as RustlsTlsConnector, }; use tokio_rustls_025 as tokio_rustls; use crate::connect::{Connection, Host}; pub mod reexports { //! Re-exports from the `rustls` v0.22 ecosystem that are useful for connectors. pub use tokio_rustls_025::{client::TlsStream as AsyncTlsStream, rustls::ClientConfig}; #[cfg(feature = "rustls-0_22-webpki-roots")] pub use webpki_roots_026::TLS_SERVER_ROOTS; } /// Returns root certificates via `rustls-native-certs` crate as a rustls certificate store. /// /// See [`rustls_native_certs::load_native_certs()`] for more info on behavior and errors. /// /// [`rustls_native_certs::load_native_certs()`]: rustls_native_certs_07::load_native_certs() #[cfg(feature = "rustls-0_22-native-roots")] pub fn native_roots_cert_store() -> io::Result { let mut root_certs = tokio_rustls::rustls::RootCertStore::empty(); for cert in rustls_native_certs_07::load_native_certs()? { root_certs.add(cert).unwrap(); } Ok(root_certs) } /// Returns standard root certificates from `webpki-roots` crate as a rustls certificate store. #[cfg(feature = "rustls-0_22-webpki-roots")] pub fn webpki_roots_cert_store() -> tokio_rustls::rustls::RootCertStore { let mut root_certs = tokio_rustls::rustls::RootCertStore::empty(); root_certs.extend(webpki_roots_026::TLS_SERVER_ROOTS.to_owned()); root_certs } /// Connector service factory using `rustls`. #[derive(Clone)] pub struct TlsConnector { connector: Arc, } impl TlsConnector { /// Constructs new connector service factory from a `rustls` client configuration. pub fn new(connector: Arc) -> Self { TlsConnector { connector } } /// Constructs new connector service from a `rustls` client configuration. pub fn service(connector: Arc) -> TlsConnectorService { TlsConnectorService { connector } } } impl ServiceFactory> for TlsConnector where R: Host, IO: ActixStream + 'static, { type Response = Connection>; type Error = io::Error; type Config = (); type Service = TlsConnectorService; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(TlsConnectorService { connector: self.connector.clone(), }) } } /// Connector service using `rustls`. #[derive(Clone)] pub struct TlsConnectorService { connector: Arc, } impl Service> for TlsConnectorService where R: Host, IO: ActixStream, { type Response = Connection>; type Error = io::Error; type Future = ConnectFut; actix_service::always_ready!(); fn call(&self, connection: Connection) -> Self::Future { tracing::trace!("TLS handshake start for: {:?}", connection.hostname()); let (stream, conn) = connection.replace_io(()); match ServerName::try_from(conn.hostname()) { Ok(host) => ConnectFut::Future { connect: RustlsTlsConnector::from(Arc::clone(&self.connector)) .connect(host.to_owned(), stream), connection: Some(conn), }, Err(_) => ConnectFut::InvalidServerName, } } } /// Connect future for Rustls service. #[doc(hidden)] #[allow(clippy::large_enum_variant)] pub enum ConnectFut { InvalidServerName, Future { connect: RustlsConnect, connection: Option>, }, } impl Future for ConnectFut where R: Host, IO: ActixStream, { type Output = io::Result>>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.get_mut() { Self::InvalidServerName => Poll::Ready(Err(io::Error::new( io::ErrorKind::InvalidInput, "connection parameters specified invalid server name", ))), Self::Future { connect, connection, } => { let stream = ready!(Pin::new(connect).poll(cx))?; let connection = connection.take().unwrap(); tracing::trace!("TLS handshake success: {:?}", connection.hostname()); Poll::Ready(Ok(connection.replace_io(stream).1)) } } } } actix-tls-3.4.0/src/connect/rustls_0_23.rs000064400000000000000000000116341046102023000164120ustar 00000000000000//! Rustls based connector service. //! //! See [`TlsConnector`] for main connector service factory docs. use std::{ future::Future, io, pin::Pin, sync::Arc, task::{Context, Poll}, }; use actix_rt::net::ActixStream; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::ready; use rustls_pki_types_1::ServerName; use tokio_rustls::{ client::TlsStream as AsyncTlsStream, rustls::ClientConfig, Connect as RustlsConnect, TlsConnector as RustlsTlsConnector, }; use tokio_rustls_026 as tokio_rustls; use crate::connect::{Connection, Host}; pub mod reexports { //! Re-exports from the `rustls` v0.23 ecosystem that are useful for connectors. pub use tokio_rustls_026::{client::TlsStream as AsyncTlsStream, rustls::ClientConfig}; #[cfg(feature = "rustls-0_23-webpki-roots")] pub use webpki_roots_026::TLS_SERVER_ROOTS; } /// Returns root certificates via `rustls-native-certs` crate as a rustls certificate store. /// /// See [`rustls_native_certs::load_native_certs()`] for more info on behavior and errors. /// /// [`rustls_native_certs::load_native_certs()`]: rustls_native_certs_07::load_native_certs() #[cfg(feature = "rustls-0_23-native-roots")] pub fn native_roots_cert_store() -> io::Result { let mut root_certs = tokio_rustls::rustls::RootCertStore::empty(); for cert in rustls_native_certs_07::load_native_certs()? { root_certs.add(cert).unwrap(); } Ok(root_certs) } /// Returns standard root certificates from `webpki-roots` crate as a rustls certificate store. #[cfg(feature = "rustls-0_23-webpki-roots")] pub fn webpki_roots_cert_store() -> tokio_rustls::rustls::RootCertStore { let mut root_certs = tokio_rustls::rustls::RootCertStore::empty(); root_certs.extend(webpki_roots_026::TLS_SERVER_ROOTS.to_owned()); root_certs } /// Connector service factory using `rustls`. #[derive(Clone)] pub struct TlsConnector { connector: Arc, } impl TlsConnector { /// Constructs new connector service factory from a `rustls` client configuration. pub fn new(connector: Arc) -> Self { TlsConnector { connector } } /// Constructs new connector service from a `rustls` client configuration. pub fn service(connector: Arc) -> TlsConnectorService { TlsConnectorService { connector } } } impl ServiceFactory> for TlsConnector where R: Host, IO: ActixStream + 'static, { type Response = Connection>; type Error = io::Error; type Config = (); type Service = TlsConnectorService; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(TlsConnectorService { connector: self.connector.clone(), }) } } /// Connector service using `rustls`. #[derive(Clone)] pub struct TlsConnectorService { connector: Arc, } impl Service> for TlsConnectorService where R: Host, IO: ActixStream, { type Response = Connection>; type Error = io::Error; type Future = ConnectFut; actix_service::always_ready!(); fn call(&self, connection: Connection) -> Self::Future { tracing::trace!("TLS handshake start for: {:?}", connection.hostname()); let (stream, conn) = connection.replace_io(()); match ServerName::try_from(conn.hostname()) { Ok(host) => ConnectFut::Future { connect: RustlsTlsConnector::from(Arc::clone(&self.connector)) .connect(host.to_owned(), stream), connection: Some(conn), }, Err(_) => ConnectFut::InvalidServerName, } } } /// Connect future for Rustls service. #[doc(hidden)] #[allow(clippy::large_enum_variant)] pub enum ConnectFut { InvalidServerName, Future { connect: RustlsConnect, connection: Option>, }, } impl Future for ConnectFut where R: Host, IO: ActixStream, { type Output = io::Result>>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.get_mut() { Self::InvalidServerName => Poll::Ready(Err(io::Error::new( io::ErrorKind::InvalidInput, "connection parameters specified invalid server name", ))), Self::Future { connect, connection, } => { let stream = ready!(Pin::new(connect).poll(cx))?; let connection = connection.take().unwrap(); tracing::trace!("TLS handshake success: {:?}", connection.hostname()); Poll::Ready(Ok(connection.replace_io(stream).1)) } } } } actix-tls-3.4.0/src/connect/tcp.rs000064400000000000000000000140121046102023000151120ustar 00000000000000//! TCP connector service. //! //! See [`TcpConnector`] for main connector service factory docs. use std::{ collections::VecDeque, future::Future, io, net::{IpAddr, SocketAddr, SocketAddrV4, SocketAddrV6}, pin::Pin, task::{Context, Poll}, }; use actix_rt::net::{TcpSocket, TcpStream}; use actix_service::{Service, ServiceFactory}; use actix_utils::future::{ok, Ready}; use futures_core::ready; use tokio_util::sync::ReusableBoxFuture; use tracing::{error, trace}; use super::{connect_addrs::ConnectAddrs, error::ConnectError, ConnectInfo, Connection, Host}; /// TCP connector service factory. #[derive(Debug, Clone, Copy, Default)] #[non_exhaustive] pub struct TcpConnector; impl TcpConnector { /// Returns a new TCP connector service. pub fn service(&self) -> TcpConnectorService { TcpConnectorService::default() } } impl ServiceFactory> for TcpConnector { type Response = Connection; type Error = ConnectError; type Config = (); type Service = TcpConnectorService; type InitError = (); type Future = Ready>; fn new_service(&self, _: ()) -> Self::Future { ok(self.service()) } } /// TCP connector service. #[derive(Debug, Copy, Clone, Default)] #[non_exhaustive] pub struct TcpConnectorService; impl Service> for TcpConnectorService { type Response = Connection; type Error = ConnectError; type Future = TcpConnectorFut; actix_service::always_ready!(); fn call(&self, req: ConnectInfo) -> Self::Future { let port = req.port(); let ConnectInfo { request: req, addr, local_addr, .. } = req; TcpConnectorFut::new(req, port, local_addr, addr) } } /// Connect future for TCP service. #[doc(hidden)] pub enum TcpConnectorFut { Response { req: Option, port: u16, local_addr: Option, addrs: Option>, stream: ReusableBoxFuture<'static, Result>, }, Error(Option), } impl TcpConnectorFut { pub(crate) fn new( req: R, port: u16, local_addr: Option, addr: ConnectAddrs, ) -> TcpConnectorFut { if addr.is_unresolved() { error!("TCP connector: unresolved connection address"); return TcpConnectorFut::Error(Some(ConnectError::Unresolved)); } trace!( "TCP connector: connecting to {} on port {}", req.hostname(), port ); match addr { ConnectAddrs::None => unreachable!("none variant already checked"), ConnectAddrs::One(addr) => TcpConnectorFut::Response { req: Some(req), port, local_addr, addrs: None, stream: ReusableBoxFuture::new(connect(addr, local_addr)), }, // When resolver returns multiple socket addr for request they would be popped from // front end of queue and returns with the first successful TCP connection. ConnectAddrs::Multi(mut addrs) => { let addr = addrs.pop_front().unwrap(); TcpConnectorFut::Response { req: Some(req), port, local_addr, addrs: Some(addrs), stream: ReusableBoxFuture::new(connect(addr, local_addr)), } } } } } impl Future for TcpConnectorFut { type Output = Result, ConnectError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.get_mut() { TcpConnectorFut::Error(err) => Poll::Ready(Err(err.take().unwrap())), TcpConnectorFut::Response { req, port, local_addr, addrs, stream, } => loop { match ready!(stream.poll(cx)) { Ok(sock) => { let req = req.take().unwrap(); trace!( "TCP connector: successfully connected to {:?} - {:?}", req.hostname(), sock.peer_addr() ); return Poll::Ready(Ok(Connection::new(req, sock))); } Err(err) => { trace!( "TCP connector: failed to connect to {:?} port: {}", req.as_ref().unwrap().hostname(), port, ); if let Some(addr) = addrs.as_mut().and_then(|addrs| addrs.pop_front()) { stream.set(connect(addr, *local_addr)); } else { return Poll::Ready(Err(ConnectError::Io(err))); } } } }, } } } async fn connect(addr: SocketAddr, local_addr: Option) -> io::Result { // use local addr if connect asks for it match local_addr { Some(ip_addr) => { let socket = match ip_addr { IpAddr::V4(ip_addr) => { let socket = TcpSocket::new_v4()?; let addr = SocketAddr::V4(SocketAddrV4::new(ip_addr, 0)); socket.bind(addr)?; socket } IpAddr::V6(ip_addr) => { let socket = TcpSocket::new_v6()?; let addr = SocketAddr::V6(SocketAddrV6::new(ip_addr, 0, 0, 0)); socket.bind(addr)?; socket } }; socket.connect(addr).await } None => TcpStream::connect(addr).await, } } actix-tls-3.4.0/src/connect/uri.rs000064400000000000000000000026401046102023000151270ustar 00000000000000use super::Host; impl Host for http_0_2::Uri { fn hostname(&self) -> &str { self.host().unwrap_or("") } fn port(&self) -> Option { match self.port_u16() { Some(port) => Some(port), None => scheme_to_port(self.scheme_str()), } } } impl Host for http_1::Uri { fn hostname(&self) -> &str { self.host().unwrap_or("") } fn port(&self) -> Option { match self.port_u16() { Some(port) => Some(port), None => scheme_to_port(self.scheme_str()), } } } // Get port from well-known URL schemes. fn scheme_to_port(scheme: Option<&str>) -> Option { match scheme { // HTTP Some("http") => Some(80), Some("https") => Some(443), // WebSockets Some("ws") => Some(80), Some("wss") => Some(443), // Advanced Message Queuing Protocol (AMQP) Some("amqp") => Some(5672), Some("amqps") => Some(5671), // Message Queuing Telemetry Transport (MQTT) Some("mqtt") => Some(1883), Some("mqtts") => Some(8883), // File Transfer Protocol (FTP) Some("ftp") => Some(21), Some("ftps") => Some(990), // Redis Some("redis") => Some(6379), // MySQL Some("mysql") => Some(3306), // PostgreSQL Some("postgres") => Some(5432), _ => None, } } actix-tls-3.4.0/src/lib.rs000064400000000000000000000007671046102023000134550ustar 00000000000000//! TLS acceptor and connector services for the Actix ecosystem. #![deny(rust_2018_idioms, nonstandard_style)] #![warn(future_incompatible, missing_docs)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #[cfg(feature = "openssl")] #[allow(unused_extern_crates)] extern crate tls_openssl as openssl; #[cfg(feature = "accept")] pub mod accept; #[cfg(feature = "connect")] pub mod connect; actix-tls-3.4.0/tests/test_connect.rs000064400000000000000000000127301046102023000157430ustar 00000000000000#![cfg(feature = "connect")] use std::{ io, net::{IpAddr, Ipv4Addr}, }; use actix_codec::{BytesCodec, Framed}; use actix_rt::net::TcpStream; use actix_server::TestServer; use actix_service::{fn_service, Service, ServiceFactory}; use actix_tls::connect::{ConnectError, ConnectInfo, Connection, Connector, Host}; use bytes::Bytes; use futures_util::sink::SinkExt as _; #[cfg(feature = "openssl")] #[actix_rt::test] async fn test_string() { let srv = TestServer::start(|| { fn_service(|io: TcpStream| async { let mut framed = Framed::new(io, BytesCodec); framed.send(Bytes::from_static(b"test")).await?; Ok::<_, io::Error>(()) }) }); let connector = Connector::default().service(); let addr = format!("localhost:{}", srv.port()); let con = connector.call(addr.into()).await.unwrap(); assert_eq!(con.peer_addr().unwrap(), srv.addr()); } #[cfg(feature = "rustls-0_23")] #[actix_rt::test] async fn test_rustls_string() { let srv = TestServer::start(|| { fn_service(|io: TcpStream| async { let mut framed = Framed::new(io, BytesCodec); framed.send(Bytes::from_static(b"test")).await?; Ok::<_, io::Error>(()) }) }); let conn = Connector::default().service(); let addr = format!("localhost:{}", srv.port()); let con = conn.call(addr.into()).await.unwrap(); assert_eq!(con.peer_addr().unwrap(), srv.addr()); } #[actix_rt::test] async fn test_static_str() { let srv = TestServer::start(|| { fn_service(|io: TcpStream| async { let mut framed = Framed::new(io, BytesCodec); framed.send(Bytes::from_static(b"test")).await?; Ok::<_, io::Error>(()) }) }); let info = ConnectInfo::with_addr("10", srv.addr()); let connector = Connector::default().service(); let conn = connector.call(info).await.unwrap(); assert_eq!(conn.peer_addr().unwrap(), srv.addr()); let info = ConnectInfo::new(srv.host().to_owned()); let connector = Connector::default().service(); let conn = connector.call(info).await; assert!(conn.is_err()); } #[actix_rt::test] async fn service_factory() { pub fn default_connector_factory() -> impl ServiceFactory< ConnectInfo, Config = (), Response = Connection, Error = ConnectError, InitError = (), > { Connector::default() } let srv = TestServer::start(|| { fn_service(|io: TcpStream| async { let mut framed = Framed::new(io, BytesCodec); framed.send(Bytes::from_static(b"test")).await?; Ok::<_, io::Error>(()) }) }); let info = ConnectInfo::with_addr("10", srv.addr()); let factory = default_connector_factory(); let connector = factory.new_service(()).await.unwrap(); let con = connector.call(info).await; assert_eq!(con.unwrap().peer_addr().unwrap(), srv.addr()); } #[cfg(all(feature = "openssl", feature = "uri"))] #[actix_rt::test] async fn test_openssl_uri() { let srv = TestServer::start(|| { fn_service(|io: TcpStream| async { let mut framed = Framed::new(io, BytesCodec); framed.send(Bytes::from_static(b"test")).await?; Ok::<_, io::Error>(()) }) }); let connector = Connector::default().service(); let addr = http_0_2::Uri::try_from(format!("https://localhost:{}", srv.port())).unwrap(); let con = connector.call(addr.into()).await.unwrap(); assert_eq!(con.peer_addr().unwrap(), srv.addr()); } #[cfg(all(feature = "rustls-0_23", feature = "uri"))] #[actix_rt::test] async fn test_rustls_uri_http1() { let srv = TestServer::start(|| { fn_service(|io: TcpStream| async { let mut framed = Framed::new(io, BytesCodec); framed.send(Bytes::from_static(b"test")).await?; Ok::<_, io::Error>(()) }) }); let conn = Connector::default().service(); let addr = http_1::Uri::try_from(format!("https://localhost:{}", srv.port())).unwrap(); let con = conn.call(addr.into()).await.unwrap(); assert_eq!(con.peer_addr().unwrap(), srv.addr()); } #[cfg(all(feature = "rustls-0_23", feature = "uri"))] #[actix_rt::test] async fn test_rustls_uri() { let srv = TestServer::start(|| { fn_service(|io: TcpStream| async { let mut framed = Framed::new(io, BytesCodec); framed.send(Bytes::from_static(b"test")).await?; Ok::<_, io::Error>(()) }) }); let conn = Connector::default().service(); let addr = http_1::Uri::try_from(format!("https://localhost:{}", srv.port())).unwrap(); let con = conn.call(addr.into()).await.unwrap(); assert_eq!(con.peer_addr().unwrap(), srv.addr()); } #[actix_rt::test] async fn test_local_addr() { let srv = TestServer::start(|| { fn_service(|io: TcpStream| async { let mut framed = Framed::new(io, BytesCodec); framed.send(Bytes::from_static(b"test")).await?; Ok::<_, io::Error>(()) }) }); // if you've arrived here because of a failing test on macOS run this in your terminal: // sudo ifconfig lo0 alias 127.0.0.3 let conn = Connector::default().service(); let local = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3)); let (con, _) = conn .call(ConnectInfo::with_addr("10", srv.addr()).set_local_addr(local)) .await .unwrap() .into_parts(); assert_eq!(con.local_addr().unwrap().ip(), local) }