repeated headers

This commit is contained in:
Martin Algesten
2018-06-11 22:45:09 +02:00
parent 9852960bd7
commit 8bc8559c22
5 changed files with 75 additions and 6 deletions

View File

@@ -10,8 +10,9 @@
- [x] Transfer-Encoding: chunked - [x] Transfer-Encoding: chunked
- [x] Ergonomic JSON handling - [x] Ergonomic JSON handling
- [x] Test harness for end-to-end tests - [x] Test harness for end-to-end tests
- [ ] Limit read length on Content-Size - [x] Limit read length on Content-Size
- [ ] Auth headers - [x] Auth headers
- [x] Repeated headers
- [ ] Cookie jar in agent - [ ] Cookie jar in agent
- [ ] Forms with application/x-www-form-urlencoded - [ ] Forms with application/x-www-form-urlencoded
- [ ] multipart/form-data - [ ] multipart/form-data

View File

@@ -53,7 +53,9 @@ impl Agent {
K: Into<String>, K: Into<String>,
V: Into<String>, V: Into<String>,
{ {
add_agent_header(self, header.into(), value.into()); let s = format!("{}: {}", header.into(), value.into());
let header = s.parse::<Header>().expect("Failed to parse header");
add_header(header, &mut self.headers);
self self
} }
@@ -87,7 +89,9 @@ impl Agent {
I: IntoIterator<Item = (K, V)>, I: IntoIterator<Item = (K, V)>,
{ {
for (k, v) in headers.into_iter() { for (k, v) in headers.into_iter() {
add_agent_header(self, k.into(), v.into()); let s = format!("{}: {}", k.into(), v.into());
let header = s.parse::<Header>().expect("Failed to parse header");
add_header(header, &mut self.headers);
} }
self self
} }

View File

@@ -56,3 +56,11 @@ impl FromStr for Header {
Ok(Header { line, index }) Ok(Header { line, index })
} }
} }
pub fn add_header(header: Header, headers: &mut Vec<Header>) {
if !header.name().to_lowercase().starts_with("x-") {
let name = header.name();
headers.retain(|h| h.name() != name);
}
headers.push(header);
}

View File

@@ -177,7 +177,9 @@ impl Request {
K: Into<String>, K: Into<String>,
V: Into<String>, V: Into<String>,
{ {
add_request_header(self, header.into(), value.into()); let s = format!("{}: {}", header.into(), value.into());
let header = s.parse::<Header>().expect("Failed to parse header");
add_header(header, &mut self.headers);
self self
} }
@@ -208,6 +210,26 @@ impl Request {
self.get(name).is_some() self.get(name).is_some()
} }
/// All headers corresponding values for the give name, or empty vector.
///
/// ```
/// let req = ureq::get("/my_page")
/// .set("X-Forwarded-For", "1.2.3.4")
/// .set("X-Forwarded-For", "2.3.4.5")
/// .build();
/// assert_eq!(req.get_all("x-forwarded-for"), vec![
/// "1.2.3.4",
/// "2.3.4.5",
/// ]);
/// ```
pub fn get_all<'a>(&self, name: &'a str) -> Vec<&str> {
self.headers
.iter()
.filter(|h| h.is_name(name))
.map(|h| h.value())
.collect()
}
/// Set many headers. /// Set many headers.
/// ///
/// ``` /// ```
@@ -234,7 +256,9 @@ impl Request {
I: IntoIterator<Item = (K, V)>, I: IntoIterator<Item = (K, V)>,
{ {
for (k, v) in headers.into_iter() { for (k, v) in headers.into_iter() {
add_request_header(self, k.into(), v.into()); let s = format!("{}: {}", k.into(), v.into());
let header = s.parse::<Header>().expect("Failed to parse header");
add_header(header, &mut self.headers);
} }
self self
} }

View File

@@ -16,6 +16,38 @@ fn header_passing() {
assert_eq!(resp.get("X-Bar").unwrap(), "foo"); assert_eq!(resp.get("X-Bar").unwrap(), "foo");
} }
#[test]
fn repeat_non_x_header() {
test::set_handler("/repeat_non_x_header", |req, _url| {
assert!(req.has("Accept"));
assert_eq!(req.get("Accept").unwrap(), "baz");
test::make_stream(200, "OK", vec![], vec![])
});
let resp = get("test://host/repeat_non_x_header")
.set("Accept", "bar")
.set("Accept", "baz")
.call();
assert_eq!(*resp.status(), 200);
}
#[test]
fn repeat_x_header() {
test::set_handler("/repeat_x_header", |req, _url| {
assert!(req.has("X-Forwarded-For"));
assert_eq!(req.get("X-Forwarded-For").unwrap(), "130.240.19.2");
assert_eq!(req.get_all("X-Forwarded-For"), vec![
"130.240.19.2",
"130.240.19.3",
]);
test::make_stream(200, "OK", vec![], vec![])
});
let resp = get("test://host/repeat_x_header")
.set("X-Forwarded-For", "130.240.19.2")
.set("X-Forwarded-For", "130.240.19.3")
.call();
assert_eq!(*resp.status(), 200);
}
#[test] #[test]
fn body_as_text() { fn body_as_text() {
test::set_handler("/body_as_text", |_req, _url| { test::set_handler("/body_as_text", |_req, _url| {