@@ -19,9 +19,24 @@ use host::{Host, HostInternal};
1919use percent_encoding:: {
2020 utf8_percent_encode, percent_encode,
2121 SIMPLE_ENCODE_SET , DEFAULT_ENCODE_SET , USERINFO_ENCODE_SET , QUERY_ENCODE_SET ,
22- PATH_SEGMENT_ENCODE_SET
22+ PATH_SEGMENT_ENCODE_SET , EncodeSet
2323} ;
2424
25+ // The backslash (\) character is treated as a path separator in special URLs
26+ // so it needs to be additionally escaped in that case.
27+ #[ derive( Clone ) ]
28+ struct SPECIAL_PATH_SEGMENT_ENCODE_SET ;
29+
30+ impl EncodeSet for SPECIAL_PATH_SEGMENT_ENCODE_SET {
31+ #[ inline]
32+ fn contains ( & self , byte : u8 ) -> bool {
33+ match byte {
34+ b'\\' => true ,
35+ _ => PATH_SEGMENT_ENCODE_SET . contains ( byte)
36+ }
37+ }
38+ }
39+
2540pub type ParseResult < T > = Result < T , ParseError > ;
2641
2742macro_rules! simple_enum_error {
@@ -1011,8 +1026,13 @@ impl<'a> Parser<'a> {
10111026 _ => {
10121027 self . check_url_code_point ( c, & input) ;
10131028 if self . context == Context :: PathSegmentSetter {
1014- self . serialization . extend ( utf8_percent_encode (
1015- utf8_c, PATH_SEGMENT_ENCODE_SET ) ) ;
1029+ if scheme_type. is_special ( ) {
1030+ self . serialization . extend ( utf8_percent_encode (
1031+ utf8_c, SPECIAL_PATH_SEGMENT_ENCODE_SET ) ) ;
1032+ } else {
1033+ self . serialization . extend ( utf8_percent_encode (
1034+ utf8_c, PATH_SEGMENT_ENCODE_SET ) ) ;
1035+ }
10161036 } else {
10171037 self . serialization . extend ( utf8_percent_encode (
10181038 utf8_c, DEFAULT_ENCODE_SET ) ) ;
0 commit comments