@@ -822,11 +822,13 @@ impl<'a> Parser<'a> {
822822 self . serialization . push ( '/' ) ;
823823 self . serialization . push ( '/' ) ;
824824 // authority state
825+ let before_authority = self . serialization . len ( ) ;
825826 let ( username_end, remaining) = self . parse_userinfo ( input, scheme_type) ?;
827+ let has_authority = before_authority != self . serialization . len ( ) ;
826828 // host state
827829 let host_start = to_u32 ( self . serialization . len ( ) ) ?;
828830 let ( host_end, host, port, remaining) =
829- self . parse_host_and_port ( remaining, scheme_end, scheme_type) ?;
831+ self . parse_host_and_port ( remaining, scheme_end, scheme_type, has_authority ) ?;
830832 // path state
831833 let path_start = to_u32 ( self . serialization . len ( ) ) ?;
832834 let remaining = self . parse_path_start ( scheme_type, & mut true , remaining) ;
@@ -912,18 +914,26 @@ impl<'a> Parser<'a> {
912914 input : Input < ' i > ,
913915 scheme_end : u32 ,
914916 scheme_type : SchemeType ,
917+ has_authority : bool ,
915918 ) -> ParseResult < ( u32 , HostInternal , Option < u16 > , Input < ' i > ) > {
916919 let ( host, remaining) = Parser :: parse_host ( input, scheme_type) ?;
917920 write ! ( & mut self . serialization, "{}" , host) . unwrap ( ) ;
918921 let host_end = to_u32 ( self . serialization . len ( ) ) ?;
919- if remaining. starts_with ( ":" ) {
920- // Port with an empty host
921- if let Host :: Domain ( h) = & host {
922- if h. is_empty ( ) {
922+ if let Host :: Domain ( h) = & host {
923+ if h. is_empty ( ) {
924+ // Port with an empty host
925+ if remaining. starts_with ( ":" ) {
926+ return Err ( ParseError :: EmptyHost ) ;
927+ }
928+ if scheme_type. is_special ( ) {
929+ return Err ( ParseError :: EmptyHost ) ;
930+ }
931+ if !scheme_type. is_special ( ) && has_authority {
923932 return Err ( ParseError :: EmptyHost ) ;
924933 }
925934 }
926- }
935+ } ;
936+
927937 let ( port, remaining) = if let Some ( remaining) = remaining. split_prefix ( ':' ) {
928938 let scheme = || default_port ( & self . serialization [ ..scheme_end as usize ] ) ;
929939 Parser :: parse_port ( remaining, scheme, self . context ) ?
0 commit comments