Skip to content

Commit

Permalink
Add Location::uri constructor
Browse files Browse the repository at this point in the history
As far as I know, all URI characters should be valid Header value
characters, so we can have an infallible constructor for Location
from an `Uri`.

This doesn't cover all uses of the Location header, since it allows
URI-references like `/People.html#tim`, but it's an ergonomic win
already, as mentioned in hyperium#48
  • Loading branch information
fasterthanlime committed Mar 15, 2022
1 parent ffca4a9 commit 9e81b92
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/common/location.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use http::Uri;
use HeaderValue;

/// `Location` header, defined in
Expand Down Expand Up @@ -28,6 +29,18 @@ derive_header! {
name: LOCATION
}

impl Location {
/// Creates a `Location` header from a uri
pub fn uri(uri: Uri) -> Self {
let uri = uri.to_string();
// cf. https://www.rfc-editor.org/rfc/rfc3986#section-2
Self(
HeaderValue::from_str(&uri)
.expect("All URI characters should be valid HTTP header value characters"),
)
}
}

#[cfg(test)]
mod tests {
use super::super::test_decode;
Expand All @@ -48,4 +61,20 @@ mod tests {

assert_eq!(loc, Location(HeaderValue::from_static(s)));
}

#[test]
fn uri_constructor() {
let s = "https://www.rust-lang.org/tools";
let uri: Uri = s.parse().unwrap();
let loc = Location::uri(uri);

assert_eq!(loc, Location(HeaderValue::from_static(s)));
}

#[test]
fn uri_constructor_invalid_chars() {
let s = "https://www.rust-lang.org/hélas";
let uri: Result<Uri, _> = s.parse();
assert!(uri.is_err());
}
}

0 comments on commit 9e81b92

Please sign in to comment.