diff --git a/lib/src/http/uri.rs b/lib/src/http/uri.rs index c8cf5306..a38630ff 100644 --- a/lib/src/http/uri.rs +++ b/lib/src/http/uri.rs @@ -239,6 +239,23 @@ impl<'a> URI<'a> { decoder.decode_utf8_lossy() } + /// Returns a URL-encoded version of the string. Any characters outside of + /// visible ASCII-range are encoded as well as ' ', '"', '#', '<', '>', '`', + /// '?', '{', '}', '%', and '/'. + /// + /// # Examples + /// + /// ```rust + /// use rocket::http::uri::URI; + /// + /// let encoded = URI::percent_encode("hello?a=hi"); + /// assert_eq!(encoded, "hello%3Fa=%3Cb%3Ehi%3C%2Fb%3E"); + /// ``` + pub fn percent_encode(string: &str) -> Cow { + let set = url::percent_encoding::PATH_SEGMENT_ENCODE_SET; + url::percent_encoding::utf8_percent_encode(string, set).into() + } + /// Returns the inner string of this URI. /// /// The returned string is in raw form. It contains empty segments. If you'd @@ -275,7 +292,7 @@ impl From for URI<'static> { impl<'a> fmt::Display for URI<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // If this is the root path, then there are "zero" segments. - if self.as_str().starts_with('/') && self.segment_count() == 0 { + if self.segment_count() == 0 { write!(f, "/")?; } else { for segment in self.segments() {