@@ -72,18 +72,28 @@ impl FromStr for Host {
72
72
type Err = :: Error ;
73
73
74
74
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 ( ':' ) ;
80
76
let port = idx. and_then (
81
77
|idx| s[ idx + 1 ..] . parse ( ) . ok ( )
82
78
) ;
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
86
95
} ;
96
+
87
97
Ok ( Host {
88
98
hostname : hostname,
89
99
port : port
@@ -111,6 +121,24 @@ mod tests {
111
121
hostname: "foo.com" . to_owned( ) ,
112
122
port: Some ( 8080 )
113
123
} ) ) ;
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
+ } ) ) ;
114
142
}
115
143
}
116
144
0 commit comments