Skip to content

Commit 8e2fcd7

Browse files
renewal_info() yields retry-after header
1 parent 1e68826 commit 8e2fcd7

File tree

3 files changed

+13
-6
lines changed

3 files changed

+13
-6
lines changed

src/account.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use std::sync::Arc;
2+
#[cfg(feature = "time")]
3+
use std::time::SystemTime;
24

35
use base64::prelude::{BASE64_URL_SAFE_NO_PAD, Engine};
46
use http::header::LOCATION;
@@ -143,16 +145,18 @@ impl Account {
143145
/// uniformly random point between the window start/end should be selected and used to
144146
/// schedule a renewal in the future.
145147
///
148+
/// The `SystemTime` is a hint from the ACME server when to again fetch the renewal window.
149+
/// See <https://www.rfc-editor.org/rfc/rfc9773.html#section-4.3.2> for details.
150+
///
146151
/// This is only supported by some ACME servers. If the server does not support this feature,
147152
/// this method will return `Error::Unsupported`.
148153
///
149-
/// See <https://www.rfc-editor.org/rfc/rfc9773.html#section-4.2-4> for more
150-
/// information.
154+
/// See <https://www.rfc-editor.org/rfc/rfc9773.html#section-4.2-4> for more information.
151155
#[cfg(feature = "time")]
152156
pub async fn renewal_info(
153157
&self,
154158
certificate_id: &CertificateIdentifier<'_>,
155-
) -> Result<RenewalInfo, Error> {
159+
) -> Result<(RenewalInfo, SystemTime), Error> {
156160
let renewal_info_url = match self.inner.client.directory.renewal_info.as_deref() {
157161
Some(url) => url,
158162
None => return Err(Error::Unsupported("ACME renewal information (ARI)")),
@@ -166,7 +170,10 @@ impl Account {
166170
.body(Full::default())?;
167171

168172
let rsp = self.inner.client.http.request(request).await?;
169-
Problem::check::<RenewalInfo>(rsp).await
173+
let retry_after =
174+
crate::order::retry_after(&rsp).ok_or(Error::Str("Missing Retry-After header"))?;
175+
176+
Ok((Problem::check::<RenewalInfo>(rsp).await?, retry_after))
170177
}
171178

172179
/// Update the account's authentication key

src/order.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ impl RetryState {
622622
///
623623
/// Retry-After = HTTP-date / delay-seconds
624624
/// delay-seconds = 1*DIGIT
625-
fn retry_after(rsp: &BytesResponse) -> Option<SystemTime> {
625+
pub(crate) fn retry_after(rsp: &BytesResponse) -> Option<SystemTime> {
626626
let value = rsp.parts.headers.get(RETRY_AFTER)?.to_str().ok()?.trim();
627627
if value.is_empty() {
628628
return None;

tests/pebble.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ async fn replacement_order() -> Result<(), Box<dyn StdError>> {
229229
.expect("failed to fetch renewal window");
230230

231231
// Since we revoked the initial certificate, the window start should be in the past.
232-
assert!(renewal_info.suggested_window.start < OffsetDateTime::now_utc());
232+
assert!(renewal_info.0.suggested_window.start < OffsetDateTime::now_utc());
233233

234234
// So, let's go ahead and issue a replacement certificate.
235235
env.test::<Http01>(&NewOrder::new(&dns_identifiers(names)).replaces(initial_cert_id))

0 commit comments

Comments
 (0)