|
| 1 | +use std::time::Duration; |
| 2 | + |
| 3 | +use wreq::{ |
| 4 | + Client, |
| 5 | + tls::{CertStore, TlsInfo}, |
| 6 | +}; |
| 7 | + |
| 8 | +/// Certificate Store Example |
| 9 | +/// |
| 10 | +/// In most cases, you don't need to manually configure certificate stores. wreq automatically |
| 11 | +/// uses appropriate default certificates: |
| 12 | +/// - With `webpki-roots` feature enabled: Uses Mozilla's maintained root certificate collection |
| 13 | +/// - Without this feature: Uses system default certificate store paths |
| 14 | +/// |
| 15 | +/// Manual certificate store configuration is only needed in the following special cases: |
| 16 | +/// |
| 17 | +/// ## Scenarios requiring custom certificate store: |
| 18 | +/// |
| 19 | +/// ### 1. Self-signed Certificates |
| 20 | +/// - Connect to internal services using self-signed certificates |
| 21 | +/// - Test servers in development environments |
| 22 | +/// |
| 23 | +/// ### 2. Enterprise Internal CA |
| 24 | +/// - Add root certificates from enterprise internal certificate authorities |
| 25 | +/// - Access HTTPS services on corporate intranets |
| 26 | +/// |
| 27 | +/// ### 3. Certificate Updates and Management |
| 28 | +/// - Dynamically update certificates in the certificate store |
| 29 | +/// - Remove revoked or expired certificates |
| 30 | +/// |
| 31 | +/// ### 4. Compliance Requirements |
| 32 | +/// - Special compliance requirements for certain industries or regions |
| 33 | +/// - Need to use specific certificate collections |
| 34 | +/// |
| 35 | +/// ### 5. Performance Optimization |
| 36 | +/// - Reduce certificate store size to improve TLS handshake performance |
| 37 | +/// - Include only necessary root certificates |
| 38 | +#[tokio::main] |
| 39 | +async fn main() -> wreq::Result<()> { |
| 40 | + tracing_subscriber::fmt() |
| 41 | + .with_max_level(tracing::Level::INFO) |
| 42 | + .init(); |
| 43 | + |
| 44 | + // Create a client with a custom certificate store using webpki-roots |
| 45 | + let client = Client::builder() |
| 46 | + .cert_store(CertStore::from_der_certs( |
| 47 | + webpki_root_certs::TLS_SERVER_ROOT_CERTS, |
| 48 | + )?) |
| 49 | + .build()?; |
| 50 | + |
| 51 | + // Use the API you're already familiar with |
| 52 | + client.get("https://www.google.com").send().await?; |
| 53 | + |
| 54 | + // Self-signed certificate Client |
| 55 | + // Skip certificate verification for self-signed certificates |
| 56 | + let client = Client::builder() |
| 57 | + .tls_info(true) |
| 58 | + .cert_verification(false) |
| 59 | + .build()?; |
| 60 | + |
| 61 | + // Use the API you're already familiar with |
| 62 | + let resp = client.get("https://self-signed.badssl.com/").send().await?; |
| 63 | + if let Some(val) = resp.extensions().get::<TlsInfo>() { |
| 64 | + if let Some(peer_cert_der) = val.peer_certificate() { |
| 65 | + // Create self-signed certificate Store |
| 66 | + let self_signed_store = CertStore::from_der_certs(&[peer_cert_der])?; |
| 67 | + |
| 68 | + // Create a client with self-signed certificate store |
| 69 | + let client = Client::builder() |
| 70 | + .cert_store(self_signed_store) |
| 71 | + .connect_timeout(Duration::from_secs(10)) |
| 72 | + .build()?; |
| 73 | + |
| 74 | + // Use the API you're already familiar with |
| 75 | + let resp = client.get("https://self-signed.badssl.com/").send().await?; |
| 76 | + println!("{}", resp.text().await?); |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + Ok(()) |
| 81 | +} |
0 commit comments