@@ -1603,8 +1603,13 @@ impl Url {
1603
1603
self . set_host_internal ( Host :: parse_opaque ( host_substr) ?, None ) ;
1604
1604
}
1605
1605
} else if self . has_host ( ) {
1606
- if SchemeType :: from ( self . scheme ( ) ) . is_special ( ) {
1606
+ let scheme_type = SchemeType :: from ( self . scheme ( ) ) ;
1607
+ if scheme_type. is_special ( ) {
1607
1608
return Err ( ParseError :: EmptyHost ) ;
1609
+ } else {
1610
+ if self . serialization . len ( ) == self . path_start as usize {
1611
+ self . serialization . push ( '/' ) ;
1612
+ }
1608
1613
}
1609
1614
debug_assert ! ( self . byte_at( self . scheme_end) == b':' ) ;
1610
1615
debug_assert ! ( self . byte_at( self . path_start) == b'/' ) ;
@@ -1907,14 +1912,28 @@ impl Url {
1907
1912
///
1908
1913
/// # fn run() -> Result<(), ParseError> {
1909
1914
/// let mut url = Url::parse("https://example.net")?;
1910
- /// let result = url.set_scheme("foo ");
1911
- /// assert_eq!(url.as_str(), "foo ://example.net/");
1915
+ /// let result = url.set_scheme("http ");
1916
+ /// assert_eq!(url.as_str(), "http ://example.net/");
1912
1917
/// assert!(result.is_ok());
1913
1918
/// # Ok(())
1914
1919
/// # }
1915
1920
/// # run().unwrap();
1916
1921
/// ```
1922
+ /// Change the URL’s scheme from `foo` to `bar`:
1917
1923
///
1924
+ /// ```
1925
+ /// use url::Url;
1926
+ /// # use url::ParseError;
1927
+ ///
1928
+ /// # fn run() -> Result<(), ParseError> {
1929
+ /// let mut url = Url::parse("foo://example.net")?;
1930
+ /// let result = url.set_scheme("bar");
1931
+ /// assert_eq!(url.as_str(), "bar://example.net");
1932
+ /// assert!(result.is_ok());
1933
+ /// # Ok(())
1934
+ /// # }
1935
+ /// # run().unwrap();
1936
+ /// ```
1918
1937
///
1919
1938
/// Cannot change URL’s scheme from `https` to `foõ`:
1920
1939
///
@@ -1947,14 +1966,49 @@ impl Url {
1947
1966
/// # }
1948
1967
/// # run().unwrap();
1949
1968
/// ```
1969
+ /// Cannot change the URL’s scheme from `foo` to `https`:
1970
+ ///
1971
+ /// ```
1972
+ /// use url::Url;
1973
+ /// # use url::ParseError;
1974
+ ///
1975
+ /// # fn run() -> Result<(), ParseError> {
1976
+ /// let mut url = Url::parse("foo://example.net")?;
1977
+ /// let result = url.set_scheme("https");
1978
+ /// assert_eq!(url.as_str(), "foo://example.net");
1979
+ /// assert!(result.is_err());
1980
+ /// # Ok(())
1981
+ /// # }
1982
+ /// # run().unwrap();
1983
+ /// ```
1984
+ /// Cannot change the URL’s scheme from `http` to `foo`:
1985
+ ///
1986
+ /// ```
1987
+ /// use url::Url;
1988
+ /// # use url::ParseError;
1989
+ ///
1990
+ /// # fn run() -> Result<(), ParseError> {
1991
+ /// let mut url = Url::parse("http://example.net")?;
1992
+ /// let result = url.set_scheme("foo");
1993
+ /// assert_eq!(url.as_str(), "http://example.net/");
1994
+ /// assert!(result.is_err());
1995
+ /// # Ok(())
1996
+ /// # }
1997
+ /// # run().unwrap();
1998
+ /// ```
1950
1999
pub fn set_scheme ( & mut self , scheme : & str ) -> Result < ( ) , ( ) > {
1951
2000
let mut parser = Parser :: for_setter ( String :: new ( ) ) ;
1952
2001
let remaining = parser. parse_scheme ( parser:: Input :: new ( scheme) ) ?;
1953
2002
let new_scheme_type = SchemeType :: from ( & parser. serialization ) ;
1954
2003
let old_scheme_type = SchemeType :: from ( self . scheme ( ) ) ;
1955
- // Switching from special scheme to non special scheme
1956
- // and switching from file to non file is not allowed
1957
- if old_scheme_type != new_scheme_type {
2004
+ // If url’s scheme is a special scheme and buffer is not a special scheme, then return.
2005
+ if new_scheme_type. is_special ( ) && !old_scheme_type. is_special ( ) ||
2006
+ // If url’s scheme is not a special scheme and buffer is a special scheme, then return.
2007
+ !new_scheme_type. is_special ( ) && old_scheme_type. is_special ( ) ||
2008
+ // If url includes credentials or has a non-null port, and buffer is "file", then return.
2009
+ // If url’s scheme is "file" and its host is an empty host or null, then return.
2010
+ new_scheme_type. is_file ( ) && self . has_authority ( )
2011
+ {
1958
2012
return Err ( ( ) ) ;
1959
2013
}
1960
2014
0 commit comments