Skip to content

Commit 20f177a

Browse files
committed
fix(headers): Allow IPv6 Addresses in Host header
1 parent 15fe605 commit 20f177a

File tree

1 file changed

+36
-8
lines changed

1 file changed

+36
-8
lines changed

src/header/common/host.rs

+36-8
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)