Skip to content

Commit 264d08d

Browse files
committed
Add redirect handling to AcmeClient and including relevant error reporting.
1 parent a508f09 commit 264d08d

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

src/acme.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ const MAX_SERVER_RETRY_INTERVAL: Duration = Duration::from_secs(60);
4343

4444
static REPLAY_NONCE: http::HeaderName = http::HeaderName::from_static("replay-nonce");
4545

46+
// Maximum number of redirects to follow for a single request.
47+
const MAX_REDIRECTS: usize = 10;
48+
4649
pub enum NewAccountOutput<'a> {
4750
Created(&'a str),
4851
Found(&'a str),
@@ -170,12 +173,29 @@ where
170173
}
171174

172175
pub async fn get(&self, url: &Uri) -> Result<http::Response<Bytes>, RequestError> {
173-
let req = http::Request::builder()
174-
.uri(url)
175-
.method(http::Method::GET)
176-
.header(http::header::CONTENT_LENGTH, 0)
177-
.body(String::new())?;
178-
Ok(self.http.request(req).await?)
176+
let mut u = url.clone();
177+
178+
for _ in 0..MAX_REDIRECTS {
179+
let req = http::Request::builder()
180+
.uri(&u)
181+
.method(http::Method::GET)
182+
.header(http::header::CONTENT_LENGTH, 0)
183+
.body(String::new())?;
184+
let res = self.http.request(req).await?;
185+
186+
if res.status().is_redirection() {
187+
if let Some(location) = try_get_header(res.headers(), http::header::LOCATION) {
188+
u = Uri::try_from(location).map_err(RequestError::UrlParse)?;
189+
continue;
190+
} else {
191+
return Err(RequestError::RedirectNoLocation);
192+
}
193+
}
194+
195+
return Ok(res);
196+
}
197+
198+
Err(RequestError::TooManyRedirects)
179199
}
180200

181201
pub async fn post<P: AsRef<[u8]>>(

src/acme/error.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,15 @@ pub enum RequestError {
145145

146146
#[error("cannot sign request body ({0})")]
147147
Sign(#[from] crate::jws::Error),
148+
149+
#[error("cannot parse URL ({0})")]
150+
UrlParse(#[from] http::uri::InvalidUri),
151+
152+
#[error("redirect response missing Location header")]
153+
RedirectNoLocation,
154+
155+
#[error("too many redirects")]
156+
TooManyRedirects,
148157
}
149158

150159
impl From<HttpClientError> for RequestError {

0 commit comments

Comments
 (0)