Skip to content

Commit 911a505

Browse files
committed
fix(uri): allow empty paths in uri::Builder
1 parent bb8705b commit 911a505

3 files changed

Lines changed: 48 additions & 1 deletion

File tree

src/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ impl fmt::Display for Error {
4747
}
4848

4949
impl Error {
50+
pub(crate) fn is_empty_uri(&self) -> bool {
51+
match self.inner {
52+
ErrorKind::Uri(ref err) => err.is_empty(),
53+
_ => false,
54+
}
55+
}
56+
5057
/// Return true if the underlying error has the same type as T.
5158
pub fn is<T: error::Error + 'static>(&self) -> bool {
5259
self.get_ref().is::<T>()

src/uri/builder.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,17 @@ impl Builder {
9696
<T as TryInto<PathAndQuery>>::Error: Into<crate::Error>,
9797
{
9898
self.map(move |mut parts| {
99-
let p_and_q = p_and_q.try_into().map_err(Into::into)?;
99+
let p_and_q = match p_and_q.try_into() {
100+
Ok(p_and_q) => p_and_q,
101+
Err(err) => {
102+
let err = err.into();
103+
if err.is_empty_uri() {
104+
PathAndQuery::empty()
105+
} else {
106+
return Err(err);
107+
}
108+
}
109+
};
100110
parts.path_and_query = Some(p_and_q);
101111
Ok(parts)
102112
})
@@ -202,6 +212,32 @@ mod tests {
202212
}
203213
}
204214

215+
#[test]
216+
fn build_from_empty_path_and_query() {
217+
let uri = Builder::new()
218+
.scheme(Scheme::HTTP)
219+
.authority("localhost:8080")
220+
.path_and_query("")
221+
.build()
222+
.unwrap();
223+
224+
assert_eq!(uri, "http://localhost:8080");
225+
assert_eq!(uri.path(), "/");
226+
}
227+
228+
#[test]
229+
fn empty_path_and_query_remains_strict() {
230+
assert!(PathAndQuery::try_from("").is_err());
231+
}
232+
233+
#[test]
234+
fn authority_form_path_and_query_remains_strict() {
235+
assert!(Builder::new()
236+
.path_and_query("localhost:8080")
237+
.build()
238+
.is_err());
239+
}
240+
205241
#[test]
206242
fn build_from_uri() {
207243
let original_uri = Uri::default();

src/uri/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,10 @@ impl From<ErrorKind> for InvalidUriParts {
10681068
}
10691069

10701070
impl InvalidUri {
1071+
pub(crate) fn is_empty(&self) -> bool {
1072+
self.0 == ErrorKind::Empty
1073+
}
1074+
10711075
fn s(&self) -> &str {
10721076
match self.0 {
10731077
ErrorKind::InvalidUriChar => "invalid uri character",

0 commit comments

Comments
 (0)