@@ -72,18 +72,28 @@ impl FromStr for Host {
7272 type Err = :: Error ;
7373
7474 fn from_str ( s : & str ) -> :: Result < Host > {
75- let ( host_port, res) = domain_to_unicode ( s) ;
76- if res. is_err ( ) {
77- return Err ( :: Error :: Header )
78- }
79- let idx = host_port. rfind ( ':' ) ;
75+ let idx = s. rfind ( ':' ) ;
8076 let port = idx. and_then (
8177 |idx| s[ idx + 1 ..] . parse ( ) . ok ( )
8278 ) ;
83- let hostname = match idx {
84- None => host_port,
85- Some ( idx) => host_port[ ..idx] . to_owned ( )
79+ let hostname_encoded = match port {
80+ None => s,
81+ Some ( _) => & s[ ..idx. unwrap ( ) ]
82+ } ;
83+
84+ let hostname = if hostname_encoded. starts_with ( "[" ) {
85+ if !hostname_encoded. ends_with ( "]" ) {
86+ return Err ( :: Error :: Header )
87+ }
88+ hostname_encoded. to_owned ( )
89+ } else {
90+ let ( hostname, res) = domain_to_unicode ( hostname_encoded) ;
91+ if res. is_err ( ) {
92+ return Err ( :: Error :: Header )
93+ }
94+ hostname
8695 } ;
96+
8797 Ok ( Host {
8898 hostname : hostname,
8999 port : port
@@ -111,6 +121,24 @@ mod tests {
111121 hostname: "foo.com" . to_owned( ) ,
112122 port: Some ( 8080 )
113123 } ) ) ;
124+
125+ let host = Header :: parse_header ( [ b"foo.com" . to_vec ( ) ] . as_ref ( ) ) ;
126+ assert_eq ! ( host. ok( ) , Some ( Host {
127+ hostname: "foo.com" . to_owned( ) ,
128+ port: None
129+ } ) ) ;
130+
131+ let host = Header :: parse_header ( [ b"[::1]:8080" . to_vec ( ) ] . as_ref ( ) ) ;
132+ assert_eq ! ( host. ok( ) , Some ( Host {
133+ hostname: "[::1]" . to_owned( ) ,
134+ port: Some ( 8080 )
135+ } ) ) ;
136+
137+ let host = Header :: parse_header ( [ b"[::1]" . to_vec ( ) ] . as_ref ( ) ) ;
138+ assert_eq ! ( host. ok( ) , Some ( Host {
139+ hostname: "[::1]" . to_owned( ) ,
140+ port: None
141+ } ) ) ;
114142 }
115143}
116144
0 commit comments