pub struct AcmeProvider<S: Storage> { /* private fields */ }Expand description
ACME certificate provider for automatic TLS provisioning.
Manages the full ACME lifecycle: account creation, order placement, HTTP-01 challenge fulfillment, certificate download, and storage.
§Type Parameter
S: The platform storage backend (e.g.,InMemoryStorage,SqliteStorage).
§DNS-01 Alternative
For environments where port 80 is unavailable (NAT, shared hosting), DNS-01 challenges can be used instead. The operator configures DNS TXT records manually or via DNS API. This is not implemented in this module but is documented here per spec section 18.6.3.
Implementations§
Source§impl<S: Storage + 'static> AcmeProvider<S>
impl<S: Storage + 'static> AcmeProvider<S>
Sourcepub fn new(domain: &str, storage: Arc<ProtocolStore<S>>) -> Self
pub fn new(domain: &str, storage: Arc<ProtocolStore<S>>) -> Self
Create a new ACME provider for the given domain.
Uses the Let’s Encrypt production directory by default. Call
with_directory_url to change.
Sourcepub fn with_email(self, email: &str) -> Self
pub fn with_email(self, email: &str) -> Self
Set the contact email for the ACME account.
Sourcepub fn with_directory_url(self, url: &str) -> Self
pub fn with_directory_url(self, url: &str) -> Self
Set a custom ACME directory URL (e.g., staging environment).
Sourcepub fn with_cert_resolver(self, resolver: Arc<CertResolver>) -> Self
pub fn with_cert_resolver(self, resolver: Arc<CertResolver>) -> Self
Set a cert resolver for hot-reloading on renewal.
Sourcepub fn challenges(&self) -> Arc<RwLock<HashMap<String, String>>>
pub fn challenges(&self) -> Arc<RwLock<HashMap<String, String>>>
Returns a handle to the shared ACME challenge map.
Pass this to acme_challenge_router so the HTTP server can serve
GET /.well-known/acme-challenge/{token} responses during ACME
provisioning.
Sourcepub async fn provision(&self) -> Result<CertificateData, TlsError>
pub async fn provision(&self) -> Result<CertificateData, TlsError>
Provision a new certificate via ACME HTTP-01.
This performs the full ACME flow:
- Create an ACME account.
- Place a new order for the domain.
- Retrieve the HTTP-01 challenge.
- Respond to the challenge (caller must serve the challenge token).
- Wait for the order to become ready.
- Finalize the order with a CSR.
- Download the certificate.
- Store in platform storage.
§Errors
Returns TlsError::Acme if any ACME protocol step fails.
Returns TlsError::Storage if certificate storage fails.
Sourcepub async fn load_or_provision(&self) -> Result<CertificateData, TlsError>
pub async fn load_or_provision(&self) -> Result<CertificateData, TlsError>
Sourcepub fn start_renewal_loop(self: Arc<Self>) -> JoinHandle<()>
pub fn start_renewal_loop(self: Arc<Self>) -> JoinHandle<()>
Start a background renewal loop that checks certificate expiry every 12 hours and renews when within 30 days of expiry.
The task runs until the returned tokio::task::JoinHandle is
aborted or the process exits.
Trait Implementations§
Source§impl<S: Storage> Debug for AcmeProvider<S>
impl<S: Storage> Debug for AcmeProvider<S>
Source§impl<S: Storage + 'static> TlsProvider for AcmeProvider<S>
Blanket TlsProvider for AcmeProvider.
impl<S: Storage + 'static> TlsProvider for AcmeProvider<S>
Blanket TlsProvider for AcmeProvider.
Source§fn provision(
&self,
) -> Pin<Box<dyn Future<Output = Result<CertificateData, TlsError>> + Send + '_>>
fn provision( &self, ) -> Pin<Box<dyn Future<Output = Result<CertificateData, TlsError>> + Send + '_>>
Source§fn challenges(&self) -> Arc<RwLock<HashMap<String, String>>>
fn challenges(&self) -> Arc<RwLock<HashMap<String, String>>>
Source§fn needs_challenge_listener(&self) -> bool
fn needs_challenge_listener(&self) -> bool
Auto Trait Implementations§
impl<S> Freeze for AcmeProvider<S>
impl<S> !RefUnwindSafe for AcmeProvider<S>
impl<S> Send for AcmeProvider<S>
impl<S> Sync for AcmeProvider<S>
impl<S> Unpin for AcmeProvider<S>
impl<S> UnsafeUnpin for AcmeProvider<S>
impl<S> !UnwindSafe for AcmeProvider<S>
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Declassify for T
impl<T> Declassify for T
type Declassified = T
fn declassify(self) -> T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more