Skip to content

Commit d8d7a08

Browse files
committed
Add redirect error handling and new IRI dependency.
1 parent 264d08d commit d8d7a08

File tree

4 files changed

+42
-12
lines changed

4 files changed

+42
-12
lines changed

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ http-body = "1.0.1"
1818
http-body-util = "0.1.3"
1919
http-serde = "2.1.1"
2020
hyper = { version = "1.6.0", features = ["client", "http1"] }
21+
iri-string = "0.7.9"
2122
libc = "0.2.174"
2223
nginx-sys = "0.5.0"
2324
ngx = { version = "0.5.0", features = ["async", "serde", "std"] }

src/acme.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ use std::collections::VecDeque;
1010
use std::string::{String, ToString};
1111

1212
use bytes::Bytes;
13-
use error::{NewAccountError, NewCertificateError, RequestError};
13+
use error::{NewAccountError, NewCertificateError, RedirectError, RequestError};
1414
use http::Uri;
15+
use iri_string::types::{UriAbsoluteString, UriReferenceStr};
1516
use ngx::allocator::{Allocator, Box};
1617
use ngx::async_::sleep;
1718
use ngx::collections::Vec;
@@ -185,17 +186,22 @@ where
185186

186187
if res.status().is_redirection() {
187188
if let Some(location) = try_get_header(res.headers(), http::header::LOCATION) {
188-
u = Uri::try_from(location).map_err(RequestError::UrlParse)?;
189+
let base = UriAbsoluteString::try_from(u.to_string())
190+
.map_err(RedirectError::InvalidBase)?;
191+
let location_ref =
192+
UriReferenceStr::new(location).map_err(RedirectError::InvalidLocation)?;
193+
let resolved = location_ref.resolve_against(&base).to_string();
194+
u = Uri::try_from(resolved).map_err(RedirectError::InvalidUri)?;
189195
continue;
190196
} else {
191-
return Err(RequestError::RedirectNoLocation);
197+
return Err(RedirectError::MissingLocation.into());
192198
}
193199
}
194200

195201
return Ok(res);
196202
}
197203

198-
Err(RequestError::TooManyRedirects)
204+
Err(RedirectError::TooManyRedirects.into())
199205
}
200206

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

src/acme/error.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,24 @@ impl NewCertificateError {
114114
}
115115
}
116116

117+
#[derive(Debug, Error)]
118+
pub enum RedirectError {
119+
#[error("missing Location header")]
120+
MissingLocation,
121+
122+
#[error("too many redirects")]
123+
TooManyRedirects,
124+
125+
#[error("invalid base URI (IRI creation)")]
126+
InvalidBase(#[source] iri_string::types::CreationError<std::string::String>),
127+
128+
#[error("invalid redirect location (IRI validation)")]
129+
InvalidLocation(#[source] iri_string::validate::Error),
130+
131+
#[error("invalid resolved redirect URI")]
132+
InvalidUri(#[source] http::uri::InvalidUri),
133+
}
134+
117135
#[derive(Debug, Error)]
118136
pub enum RequestError {
119137
#[error(transparent)]
@@ -146,14 +164,8 @@ pub enum RequestError {
146164
#[error("cannot sign request body ({0})")]
147165
Sign(#[from] crate::jws::Error),
148166

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,
167+
#[error("redirect failed: {0}")]
168+
Redirect(#[from] RedirectError),
157169
}
158170

159171
impl From<HttpClientError> for RequestError {

0 commit comments

Comments
 (0)