@@ -822,11 +822,13 @@ impl<'a> Parser<'a> {
822
822
self . serialization . push ( '/' ) ;
823
823
self . serialization . push ( '/' ) ;
824
824
// authority state
825
+ let before_authority = self . serialization . len ( ) ;
825
826
let ( username_end, remaining) = self . parse_userinfo ( input, scheme_type) ?;
827
+ let has_authority = before_authority != self . serialization . len ( ) ;
826
828
// host state
827
829
let host_start = to_u32 ( self . serialization . len ( ) ) ?;
828
830
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 ) ?;
830
832
// path state
831
833
let path_start = to_u32 ( self . serialization . len ( ) ) ?;
832
834
let remaining = self . parse_path_start ( scheme_type, & mut true , remaining) ;
@@ -912,18 +914,26 @@ impl<'a> Parser<'a> {
912
914
input : Input < ' i > ,
913
915
scheme_end : u32 ,
914
916
scheme_type : SchemeType ,
917
+ has_authority : bool ,
915
918
) -> ParseResult < ( u32 , HostInternal , Option < u16 > , Input < ' i > ) > {
916
919
let ( host, remaining) = Parser :: parse_host ( input, scheme_type) ?;
917
920
write ! ( & mut self . serialization, "{}" , host) . unwrap ( ) ;
918
921
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 {
923
932
return Err ( ParseError :: EmptyHost ) ;
924
933
}
925
934
}
926
- }
935
+ } ;
936
+
927
937
let ( port, remaining) = if let Some ( remaining) = remaining. split_prefix ( ':' ) {
928
938
let scheme = || default_port ( & self . serialization [ ..scheme_end as usize ] ) ;
929
939
Parser :: parse_port ( remaining, scheme, self . context ) ?
0 commit comments