diff --git a/src/lib.rs b/src/lib.rs index f7fffee..71a4b5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -490,6 +490,39 @@ impl Client { } async fn post( + &self, + payload: Option<&impl Serialize>, + mut nonce: Option, + signer: &impl Signer, + url: &str, + ) -> Result { + let mut retries = 3; + loop { + let mut response = self + .post_attempt(payload, nonce.clone(), signer, url) + .await?; + if response.parts.status != StatusCode::BAD_REQUEST { + return Ok(response); + } + let body = response.body.into_bytes().await.map_err(Error::Other)?; + let problem = serde_json::from_slice::(&body)?; + if let Some("urn:ietf:params:acme:error:badNonce") = problem.r#type.as_deref() { + retries -= 1; + if retries != 0 { + // Set to `None` so on the next run it'll get regenerated. + nonce = None; + continue; + } + } + + return Ok(BytesResponse { + parts: response.parts, + body: Box::new(body), + }); + } + } + + async fn post_attempt( &self, payload: Option<&impl Serialize>, nonce: Option, @@ -789,6 +822,13 @@ where } } +#[async_trait] +impl BytesBody for Bytes { + async fn into_bytes(&mut self) -> Result> { + Ok(self.to_owned()) + } +} + /// Object safe body trait #[async_trait] pub trait BytesBody: Send {