mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-12-23 02:52:34 +03:00
Merge pull request #15 from Orange-OpenSource/feature/add-http-response-version
Add http version in response
This commit is contained in:
commit
84586c9ec1
@ -48,7 +48,6 @@ pub struct ClientOptions {
|
||||
|
||||
|
||||
impl Client {
|
||||
|
||||
///
|
||||
/// Init HTTP hurl client
|
||||
///
|
||||
@ -107,7 +106,7 @@ impl Client {
|
||||
}
|
||||
}
|
||||
easy::InfoType::HeaderIn => {
|
||||
eprint!("< {}", str::from_utf8(data).unwrap());
|
||||
eprint!("< {}", str::from_utf8(data).unwrap());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -147,8 +146,11 @@ impl Client {
|
||||
}
|
||||
|
||||
let status = self.handle.response_code().unwrap();
|
||||
let first_line = lines.remove(0); // remove the status line
|
||||
let version = self.parse_response_version(first_line)?;
|
||||
let headers = self.parse_response_headers(&mut lines);
|
||||
|
||||
|
||||
if let Some(url) = self.get_follow_location(headers.clone()) {
|
||||
let request = Request {
|
||||
method: Method::Get,
|
||||
@ -173,6 +175,7 @@ impl Client {
|
||||
self.redirect_count = redirect_count;
|
||||
|
||||
Ok(Response {
|
||||
version,
|
||||
status,
|
||||
headers,
|
||||
body,
|
||||
@ -203,7 +206,7 @@ impl Client {
|
||||
///
|
||||
fn set_method(&mut self, method: &Method) {
|
||||
match method {
|
||||
Method::Get => self.handle.custom_request("GET").unwrap(),
|
||||
Method::Get => self.handle.custom_request("GET").unwrap(),
|
||||
Method::Post => self.handle.custom_request("POST").unwrap(),
|
||||
Method::Put => self.handle.custom_request("PUT").unwrap(),
|
||||
Method::Head => self.handle.custom_request("HEAD").unwrap(),
|
||||
@ -308,12 +311,27 @@ impl Client {
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// parse response version
|
||||
///
|
||||
fn parse_response_version(&mut self, line: String) -> Result<Version, HttpError> {
|
||||
if line.starts_with("HTTP/1.0") {
|
||||
Ok(Version::Http10)
|
||||
} else if line.starts_with("HTTP/1.1") {
|
||||
Ok(Version::Http11)
|
||||
} else if line.starts_with("HTTP/2") {
|
||||
Ok(Version::Http2)
|
||||
} else {
|
||||
Err(HttpError::CouldNotParseResponse)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// parse headers from libcurl responses
|
||||
///
|
||||
fn parse_response_headers(&mut self, lines: &mut Vec<String>) -> Vec<Header> {
|
||||
let mut headers: Vec<Header> = vec![];
|
||||
lines.remove(0); // remove the status line
|
||||
lines.pop(); // remove the blank line between headers and body
|
||||
for line in lines {
|
||||
if let Some(header) = Header::parse(line.to_string()) {
|
||||
@ -398,7 +416,6 @@ impl Header {
|
||||
}
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// Split an array of bytes into http lines (\r\n separator)
|
||||
///
|
||||
@ -448,6 +465,5 @@ mod tests {
|
||||
assert_eq!(lines.get(0).unwrap().as_str(), "GET /hello HTTP/1.1");
|
||||
assert_eq!(lines.get(1).unwrap().as_str(), "Host: localhost:8000");
|
||||
assert_eq!(lines.get(2).unwrap().as_str(), "");
|
||||
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ pub struct Request {
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Response {
|
||||
pub version: Version,
|
||||
pub status: u32,
|
||||
pub headers: Vec<Header>,
|
||||
pub body: Vec<u8>,
|
||||
@ -51,6 +52,13 @@ pub enum Method {
|
||||
Patch,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Version {
|
||||
Http10,
|
||||
Http11,
|
||||
Http2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Header {
|
||||
pub name: String,
|
||||
@ -96,12 +104,9 @@ pub struct Cookie {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
impl fmt::Display for RequestCookie {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}={}", self.name, self.value)
|
||||
write!(f, "{}={}", self.name, self.value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,22 +116,18 @@ pub enum HttpError {
|
||||
CouldNotResolveProxyName,
|
||||
CouldNotResolveHost,
|
||||
FailToConnect,
|
||||
TooManyRedirect
|
||||
TooManyRedirect,
|
||||
CouldNotParseResponse,
|
||||
}
|
||||
|
||||
|
||||
impl Response {
|
||||
|
||||
///
|
||||
/// return a list of headers values for the given header name
|
||||
///
|
||||
pub fn get_header_values(&self, expected_name: String) -> Vec<String> {
|
||||
self.headers
|
||||
.iter()
|
||||
.filter_map(|Header{ name, value}| if name.clone() == expected_name { Some(value.to_string())} else { None })
|
||||
.collect()
|
||||
get_header_values(self.headers.clone(), expected_name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -136,27 +137,38 @@ impl Response {
|
||||
pub fn get_header_values(headers: Vec<Header>, expected_name: String) -> Vec<String> {
|
||||
headers
|
||||
.iter()
|
||||
.filter_map(|Header{ name, value}| if name.clone() == expected_name { Some(value.to_string())} else { None })
|
||||
.filter_map(|Header { name, value }| if name.clone() == expected_name { Some(value.to_string()) } else { None })
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn get_header_values() {
|
||||
let response = Response {
|
||||
version: Version::Http10,
|
||||
status: 200,
|
||||
headers: vec![
|
||||
Header { name: "Content-Length".to_string(), value: "12".to_string() }
|
||||
],
|
||||
body: vec![]
|
||||
body: vec![],
|
||||
};
|
||||
assert_eq!(response.get_header_values("Content-Length".to_string()), vec!["12".to_string()]);
|
||||
assert!(response.get_header_values("Unknown".to_string()).is_empty());
|
||||
|
||||
}
|
||||
|
||||
pub fn hello_http_request() -> Request {
|
||||
Request {
|
||||
method: Method::Get,
|
||||
url: "http://localhost:8000/hello".to_string(),
|
||||
querystring: vec![],
|
||||
headers: vec![],
|
||||
cookies: vec![],
|
||||
body: vec![],
|
||||
multipart: vec![],
|
||||
form: vec![],
|
||||
}
|
||||
}
|
||||
}
|
@ -88,6 +88,7 @@ fn test_hello() {
|
||||
let mut client = default_client();
|
||||
let request = default_get_request("http://localhost:8000/hello".to_string());
|
||||
let response = client.execute(&request, 0).unwrap();
|
||||
assert_eq!(response.version, Version::Http10);
|
||||
assert_eq!(response.status, 200);
|
||||
assert_eq!(response.body, b"Hello World!".to_vec());
|
||||
|
||||
@ -95,7 +96,6 @@ fn test_hello() {
|
||||
assert!(response.headers.contains(&Header { name: "Content-Length".to_string(), value: "12".to_string() }));
|
||||
assert!(response.headers.contains(&Header { name: "Content-Type".to_string(), value: "text/html; charset=utf-8".to_string() }));
|
||||
assert_eq!(response.get_header_values("Date".to_string()).len(), 1);
|
||||
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
Loading…
Reference in New Issue
Block a user