@@ -1659,8 +1659,13 @@ impl Url {
1659
1659
self . set_host_internal ( Host :: parse_opaque ( host_substr) ?, None ) ;
1660
1660
}
1661
1661
} else if self . has_host ( ) {
1662
- if SchemeType :: from ( self . scheme ( ) ) . is_special ( ) {
1662
+ let scheme_type = SchemeType :: from ( self . scheme ( ) ) ;
1663
+ if scheme_type. is_special ( ) {
1663
1664
return Err ( ParseError :: EmptyHost ) ;
1665
+ } else {
1666
+ if self . serialization . len ( ) == self . path_start as usize {
1667
+ self . serialization . push ( '/' ) ;
1668
+ }
1664
1669
}
1665
1670
debug_assert ! ( self . byte_at( self . scheme_end) == b':' ) ;
1666
1671
debug_assert ! ( self . byte_at( self . path_start) == b'/' ) ;
@@ -1963,14 +1968,28 @@ impl Url {
1963
1968
///
1964
1969
/// # fn run() -> Result<(), ParseError> {
1965
1970
/// let mut url = Url::parse("https://example.net")?;
1966
- /// let result = url.set_scheme("foo ");
1967
- /// assert_eq!(url.as_str(), "foo ://example.net/");
1971
+ /// let result = url.set_scheme("http ");
1972
+ /// assert_eq!(url.as_str(), "http ://example.net/");
1968
1973
/// assert!(result.is_ok());
1969
1974
/// # Ok(())
1970
1975
/// # }
1971
1976
/// # run().unwrap();
1972
1977
/// ```
1978
+ /// Change the URL’s scheme from `foo` to `bar`:
1973
1979
///
1980
+ /// ```
1981
+ /// use url::Url;
1982
+ /// # use url::ParseError;
1983
+ ///
1984
+ /// # fn run() -> Result<(), ParseError> {
1985
+ /// let mut url = Url::parse("foo://example.net")?;
1986
+ /// let result = url.set_scheme("bar");
1987
+ /// assert_eq!(url.as_str(), "bar://example.net");
1988
+ /// assert!(result.is_ok());
1989
+ /// # Ok(())
1990
+ /// # }
1991
+ /// # run().unwrap();
1992
+ /// ```
1974
1993
///
1975
1994
/// Cannot change URL’s scheme from `https` to `foõ`:
1976
1995
///
@@ -2003,14 +2022,49 @@ impl Url {
2003
2022
/// # }
2004
2023
/// # run().unwrap();
2005
2024
/// ```
2025
+ /// Cannot change the URL’s scheme from `foo` to `https`:
2026
+ ///
2027
+ /// ```
2028
+ /// use url::Url;
2029
+ /// # use url::ParseError;
2030
+ ///
2031
+ /// # fn run() -> Result<(), ParseError> {
2032
+ /// let mut url = Url::parse("foo://example.net")?;
2033
+ /// let result = url.set_scheme("https");
2034
+ /// assert_eq!(url.as_str(), "foo://example.net");
2035
+ /// assert!(result.is_err());
2036
+ /// # Ok(())
2037
+ /// # }
2038
+ /// # run().unwrap();
2039
+ /// ```
2040
+ /// Cannot change the URL’s scheme from `http` to `foo`:
2041
+ ///
2042
+ /// ```
2043
+ /// use url::Url;
2044
+ /// # use url::ParseError;
2045
+ ///
2046
+ /// # fn run() -> Result<(), ParseError> {
2047
+ /// let mut url = Url::parse("http://example.net")?;
2048
+ /// let result = url.set_scheme("foo");
2049
+ /// assert_eq!(url.as_str(), "http://example.net/");
2050
+ /// assert!(result.is_err());
2051
+ /// # Ok(())
2052
+ /// # }
2053
+ /// # run().unwrap();
2054
+ /// ```
2006
2055
pub fn set_scheme ( & mut self , scheme : & str ) -> Result < ( ) , ( ) > {
2007
2056
let mut parser = Parser :: for_setter ( String :: new ( ) ) ;
2008
2057
let remaining = parser. parse_scheme ( parser:: Input :: new ( scheme) ) ?;
2009
2058
let new_scheme_type = SchemeType :: from ( & parser. serialization ) ;
2010
2059
let old_scheme_type = SchemeType :: from ( self . scheme ( ) ) ;
2011
- // Switching from special scheme to non special scheme
2012
- // and switching from file to non file is not allowed
2013
- if old_scheme_type != new_scheme_type {
2060
+ // If url’s scheme is a special scheme and buffer is not a special scheme, then return.
2061
+ if new_scheme_type. is_special ( ) && !old_scheme_type. is_special ( ) ||
2062
+ // If url’s scheme is not a special scheme and buffer is a special scheme, then return.
2063
+ !new_scheme_type. is_special ( ) && old_scheme_type. is_special ( ) ||
2064
+ // If url includes credentials or has a non-null port, and buffer is "file", then return.
2065
+ // If url’s scheme is "file" and its host is an empty host or null, then return.
2066
+ new_scheme_type. is_file ( ) && self . has_authority ( )
2067
+ {
2014
2068
return Err ( ( ) ) ;
2015
2069
}
2016
2070
0 commit comments