Repository: poem-web/poem (language: rust)

Issue:
Webpki roots for acme client
## Description of the feature
When static linking native TLS roots don't work, or may not be available.  I need to use webpki roots for this. Right now the acme client is hardcoded with
```
                .with_native_roots()
```

Other libraries expose features for each of the 3 roots types (native, manual, and webpki) but alternatively maybe AcmeClient could take an http client as a parameter.

## Code example (if possible)


Discussion / hints:

Fix patch:
diff --git a/poem/Cargo.toml b/poem/Cargo.toml
index a43489adca..353daa5d0e 100644
--- a/poem/Cargo.toml
+++ b/poem/Cargo.toml
@@ -48,7 +48,10 @@ i18n = [
     "unic-langid",
     "intl-memoizer",
 ]
-acme = [
+acme = ["acme-native-roots"]
+acme-native-roots = ["acme-base", "hyper-rustls/native-tokio"]
+acme-webpki-roots = ["acme-base", "hyper-rustls/webpki-tokio"]
+acme-base = [
     "server",
     "hyper/client",
     "rustls",
@@ -143,7 +146,12 @@ fluent-syntax = { version = "0.11.0", optional = true }
 unic-langid = { version = "0.9.0", optional = true, features = ["macros"] }
 intl-memoizer = { version = "0.5.1", optional = true }
 ring = { version = "0.16.20", optional = true }
-hyper-rustls = { version = "0.23.0", optional = true }
+hyper-rustls = { version = "0.23.0", optional = true, default-features = false, features = [
+    "http1",
+    "http2",
+    "tls12",
+    "logging",
+] }
 rcgen = { version = "0.10.0", optional = true }
 x509-parser = { version = "0.14.0", optional = true }
 tokio-metrics = { version = "0.1.0", optional = true }
diff --git a/poem/README.md b/poem/README.md
index 1356656285..c19bd7e77c 100644
--- a/poem/README.md
+++ b/poem/README.md
@@ -72,6 +72,7 @@ which are disabled by default:
 | eyre06        | Integrate with version 0.6.x of the [`eyre`](https://crates.io/crates/eyre) crate.        |
 | i18n          | Support for internationalization                                                          |
 | acme          | Support for ACME(Automatic Certificate Management Environment)                            |
+| acme-webpki-roots | Support for ACME using webpki TLS roots rather than native TLS roots                  |
 | tokio-metrics | Integrate with [`tokio-metrics`](https://crates.io/crates/tokio-metrics) crate.           |
 | embed         | Integrate with [`rust-embed`](https://crates.io/crates/rust-embed) crate.                 |
 | xml           | Integrate with [`quick-xml`](https://crates.io/crates/quick-xml) crate.                   |
diff --git a/poem/src/listener/acme/client.rs b/poem/src/listener/acme/client.rs
index 407107b0e8..d6db243cac 100644
--- a/poem/src/listener/acme/client.rs
+++ b/poem/src/listener/acme/client.rs
@@ -35,13 +35,13 @@ impl AcmeClient {
         key_pair: Arc<KeyPair>,
         contacts: Vec<String>,
     ) -> IoResult<Self> {
-        let client = Client::builder().build(
-            HttpsConnectorBuilder::new()
-                .with_native_roots()
-                .https_or_http()
-                .enable_http1()
-                .build(),
-        );
+        let client_builder = HttpsConnectorBuilder::new();
+        #[cfg(feature = "acme-native-roots")]
+        let client_builder1 = client_builder.with_native_roots();
+        #[cfg(feature = "acme-webpki-roots")]
+        let client_builder1 = client_builder.with_webpki_roots();
+        let client =
+            Client::builder().build(client_builder1.https_or_http().enable_http1().build());
         let directory = get_directory(&client, directory_url).await?;
         Ok(Self {
             client,
diff --git a/poem/src/listener/mod.rs b/poem/src/listener/mod.rs
index 2efdae4d2f..06552939da 100644
--- a/poem/src/listener/mod.rs
+++ b/poem/src/listener/mod.rs
@@ -1,7 +1,7 @@
 //! Commonly used listeners.
 
-#[cfg(feature = "acme")]
-#[cfg_attr(docsrs, doc(cfg(feature = "acme")))]
+#[cfg(feature = "acme-base")]
+#[cfg_attr(docsrs, doc(cfg(feature = "acme-base")))]
 pub mod acme;
 mod combined;
 #[cfg(any(feature = "native-tls", feature = "rustls", feature = "openssl-tls"))]
@@ -29,7 +29,7 @@ use futures_util::{future::BoxFuture, FutureExt, TryFutureExt};
 use http::uri::Scheme;
 use tokio::io::{AsyncRead, AsyncWrite, ReadBuf, Result as IoResult};
 
-#[cfg(feature = "acme")]
+#[cfg(feature = "acme-base")]
 use self::acme::{AutoCert, AutoCertListener};
 #[cfg(any(feature = "native-tls", feature = "rustls", feature = "openssl-tls"))]
 pub use self::handshake_stream::HandshakeStream;
@@ -213,8 +213,8 @@ pub trait Listener: Send {
     ///         .unwrap(),
     /// );
     /// ```
-    #[cfg(feature = "acme")]
-    #[cfg_attr(docsrs, doc(cfg(feature = "acme")))]
+    #[cfg(feature = "acme-base")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "acme-base")))]
     #[must_use]
     fn acme(self, auto_cert: AutoCert) -> AutoCertListener<Self>
     where


Test patch: