@@ -840,11 +840,13 @@ impl<'a> Parser<'a> {
840
840
self . serialization . push ( '/' ) ;
841
841
self . serialization . push ( '/' ) ;
842
842
// authority state
843
+ let before_authority = self . serialization . len ( ) ;
843
844
let ( username_end, remaining) = self . parse_userinfo ( input, scheme_type) ?;
845
+ let has_authority = before_authority != self . serialization . len ( ) ;
844
846
// host state
845
847
let host_start = to_u32 ( self . serialization . len ( ) ) ?;
846
848
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 ) ?;
848
850
// path state
849
851
let path_start = to_u32 ( self . serialization . len ( ) ) ?;
850
852
let remaining = self . parse_path_start ( scheme_type, & mut true , remaining) ;
@@ -930,18 +932,26 @@ impl<'a> Parser<'a> {
930
932
input : Input < ' i > ,
931
933
scheme_end : u32 ,
932
934
scheme_type : SchemeType ,
935
+ has_authority : bool ,
933
936
) -> ParseResult < ( u32 , HostInternal , Option < u16 > , Input < ' i > ) > {
934
937
let ( host, remaining) = Parser :: parse_host ( input, scheme_type) ?;
935
938
write ! ( & mut self . serialization, "{}" , host) . unwrap ( ) ;
936
939
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 {
941
950
return Err ( ParseError :: EmptyHost ) ;
942
951
}
943
952
}
944
- }
953
+ } ;
954
+
945
955
let ( port, remaining) = if let Some ( remaining) = remaining. split_prefix ( ':' ) {
946
956
let scheme = || default_port ( & self . serialization [ ..scheme_end as usize ] ) ;
947
957
Parser :: parse_port ( remaining, scheme, self . context ) ?
0 commit comments