@@ -840,11 +840,13 @@ impl<'a> Parser<'a> {
840840 self . serialization . push ( '/' ) ;
841841 self . serialization . push ( '/' ) ;
842842 // authority state
843+ let before_authority = self . serialization . len ( ) ;
843844 let ( username_end, remaining) = self . parse_userinfo ( input, scheme_type) ?;
845+ let has_authority = before_authority != self . serialization . len ( ) ;
844846 // host state
845847 let host_start = to_u32 ( self . serialization . len ( ) ) ?;
846848 let ( host_end, host, port, remaining) =
847- self . parse_host_and_port ( remaining, scheme_end, scheme_type) ?;
849+ self . parse_host_and_port ( remaining, scheme_end, scheme_type, has_authority ) ?;
848850 // path state
849851 let path_start = to_u32 ( self . serialization . len ( ) ) ?;
850852 let remaining = self . parse_path_start ( scheme_type, & mut true , remaining) ;
@@ -930,18 +932,26 @@ impl<'a> Parser<'a> {
930932 input : Input < ' i > ,
931933 scheme_end : u32 ,
932934 scheme_type : SchemeType ,
935+ has_authority : bool ,
933936 ) -> ParseResult < ( u32 , HostInternal , Option < u16 > , Input < ' i > ) > {
934937 let ( host, remaining) = Parser :: parse_host ( input, scheme_type) ?;
935938 write ! ( & mut self . serialization, "{}" , host) . unwrap ( ) ;
936939 let host_end = to_u32 ( self . serialization . len ( ) ) ?;
937- if remaining. starts_with ( ":" ) {
938- // Port with an empty host
939- if let Host :: Domain ( h) = & host {
940- if h. is_empty ( ) {
940+ if let Host :: Domain ( h) = & host {
941+ if h. is_empty ( ) {
942+ // Port with an empty host
943+ if remaining. starts_with ( ":" ) {
944+ return Err ( ParseError :: EmptyHost ) ;
945+ }
946+ if scheme_type. is_special ( ) {
947+ return Err ( ParseError :: EmptyHost ) ;
948+ }
949+ if !scheme_type. is_special ( ) && has_authority {
941950 return Err ( ParseError :: EmptyHost ) ;
942951 }
943952 }
944- }
953+ } ;
954+
945955 let ( port, remaining) = if let Some ( remaining) = remaining. split_prefix ( ':' ) {
946956 let scheme = || default_port ( & self . serialization [ ..scheme_end as usize ] ) ;
947957 Parser :: parse_port ( remaining, scheme, self . context ) ?
0 commit comments