mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-12-23 19:12:06 +03:00
Create http::header module.
This commit is contained in:
parent
3b801a782a
commit
451f6e8200
@ -28,7 +28,7 @@ use super::options::ClientOptions;
|
||||
use super::request::*;
|
||||
use super::request_spec::*;
|
||||
use super::response::*;
|
||||
use crate::http::{HttpError, Verbosity};
|
||||
use super::{Header, HttpError, Verbosity};
|
||||
use std::str::FromStr;
|
||||
use url::Url;
|
||||
|
||||
@ -310,7 +310,7 @@ impl Client {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
if get_header_values(&request.headers, "Content-Type").is_empty() {
|
||||
if request.get_header_values("Content-Type").is_empty() {
|
||||
if let Some(ref s) = request.content_type {
|
||||
list.append(format!("Content-Type: {}", s).as_str())
|
||||
.unwrap();
|
||||
@ -319,11 +319,11 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
if get_header_values(&request.headers, "Expect").is_empty() {
|
||||
if request.get_header_values("Expect").is_empty() {
|
||||
list.append("Expect:").unwrap(); // remove header Expect
|
||||
}
|
||||
|
||||
if get_header_values(&request.headers, "User-Agent").is_empty() {
|
||||
if request.get_header_values("User-Agent").is_empty() {
|
||||
let user_agent = match self.options.user_agent {
|
||||
Some(ref u) => u.clone(),
|
||||
None => format!("hurl/{}", clap::crate_version!()),
|
||||
@ -334,14 +334,12 @@ impl Client {
|
||||
|
||||
if let Some(ref user) = self.options.user {
|
||||
let authorization = base64::encode(user.as_bytes());
|
||||
if get_header_values(&request.headers, "Authorization").is_empty() {
|
||||
if request.get_header_values("Authorization").is_empty() {
|
||||
list.append(format!("Authorization: Basic {}", authorization).as_str())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
if self.options.compressed
|
||||
&& get_header_values(&request.headers, "Accept-Encoding").is_empty()
|
||||
{
|
||||
if self.options.compressed && request.get_header_values("Accept-Encoding").is_empty() {
|
||||
list.append("Accept-Encoding: gzip, deflate, br").unwrap();
|
||||
}
|
||||
|
||||
@ -468,7 +466,7 @@ impl Client {
|
||||
if !(300..400).contains(&response_code) {
|
||||
return None;
|
||||
}
|
||||
let location = match get_header_values(&response.headers, "Location").get(0) {
|
||||
let location = match response.get_header_values("Location").get(0) {
|
||||
None => return None,
|
||||
Some(value) => value.clone(),
|
||||
};
|
||||
|
@ -19,12 +19,6 @@
|
||||
use core::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Header {
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Cookie {
|
||||
pub domain: String,
|
||||
@ -49,12 +43,6 @@ pub struct Param {
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for Header {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}: {}", self.name, self.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Cookie {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
@ -144,22 +132,6 @@ impl FromStr for Cookie {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Return a list of headers values for the given header name.
|
||||
///
|
||||
pub fn get_header_values(headers: &[Header], expected_name: &str) -> Vec<String> {
|
||||
headers
|
||||
.iter()
|
||||
.filter_map(|Header { name, value }| {
|
||||
if name.to_lowercase() == expected_name.to_lowercase() {
|
||||
Some(value.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
50
packages/hurl/src/http/header.rs
Normal file
50
packages/hurl/src/http/header.rs
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Hurl (https://hurl.dev)
|
||||
* Copyright (C) 2022 Orange
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
use core::fmt;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Header {
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for Header {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}: {}", self.name, self.value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all header values for given name
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `headers` - A list of HTTP headers
|
||||
/// * `name` - A name to filter header (case insensitively)
|
||||
pub fn get_values(headers: &[Header], name: &str) -> Vec<String> {
|
||||
headers
|
||||
.iter()
|
||||
.filter_map(|Header { name: key, value }| {
|
||||
if key.to_lowercase() == name.to_lowercase() {
|
||||
Some(value.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
@ -18,8 +18,9 @@
|
||||
|
||||
pub use self::client::Client;
|
||||
pub use self::cookie::{CookieAttribute, ResponseCookie};
|
||||
pub use self::core::{Cookie, Header, Param, RequestCookie};
|
||||
pub use self::core::{Cookie, Param, RequestCookie};
|
||||
pub use self::error::HttpError;
|
||||
pub use self::header::Header;
|
||||
pub use self::options::{ClientOptions, Verbosity};
|
||||
pub use self::request::Request;
|
||||
#[cfg(test)]
|
||||
@ -34,6 +35,7 @@ mod client;
|
||||
mod cookie;
|
||||
mod core;
|
||||
mod error;
|
||||
mod header;
|
||||
mod options;
|
||||
mod request;
|
||||
mod request_spec;
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
use super::core::*;
|
||||
use super::Header;
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -16,6 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
use super::{header, Header};
|
||||
use core::fmt;
|
||||
|
||||
use super::core::*;
|
||||
@ -77,6 +78,13 @@ impl Body {
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestSpec {
|
||||
/// Returns all header values.
|
||||
pub fn get_header_values(&self, name: &str) -> Vec<String> {
|
||||
header::get_values(&self.headers, name)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Method {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let value = match self {
|
||||
|
@ -16,11 +16,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
use super::{header, Header};
|
||||
use core::fmt;
|
||||
use std::time::Duration;
|
||||
|
||||
use super::core::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Response {
|
||||
pub version: Version,
|
||||
@ -49,34 +48,16 @@ impl fmt::Display for Version {
|
||||
}
|
||||
|
||||
impl Response {
|
||||
///
|
||||
/// return a list of headers values for the given header name
|
||||
///
|
||||
pub fn get_header_values(&self, expected_name: String) -> Vec<String> {
|
||||
get_header_values(&self.headers, &expected_name)
|
||||
/// Returns all header values.
|
||||
pub fn get_header_values(&self, name: &str) -> Vec<String> {
|
||||
header::get_values(&self.headers, name)
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
pub fn get_header(&self, name: String) -> Vec<String> {
|
||||
self.headers
|
||||
.iter()
|
||||
.filter(|&h| h.name.to_lowercase() == name.to_lowercase())
|
||||
.map(|h| h.value.clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
///
|
||||
/// Return optional Content-type header value
|
||||
///
|
||||
/// Returns optional Content-type header value.
|
||||
pub fn content_type(&self) -> Option<String> {
|
||||
for header in self.headers.clone() {
|
||||
if header.name.to_lowercase().as_str() == "content-type" {
|
||||
return Some(header.value);
|
||||
}
|
||||
}
|
||||
None
|
||||
header::get_values(&self.headers, "Content-Type")
|
||||
.get(0)
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,9 +234,9 @@ xxx
|
||||
duration: Default::default(),
|
||||
};
|
||||
assert_eq!(
|
||||
response.get_header_values("Content-Length".to_string()),
|
||||
response.get_header_values("Content-Length"),
|
||||
vec!["12".to_string()]
|
||||
);
|
||||
assert!(response.get_header_values("Unknown".to_string()).is_empty());
|
||||
assert!(response.get_header_values("Unknown").is_empty());
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use crate::http::Response;
|
||||
use crate::http::ResponseCookie;
|
||||
use super::Response;
|
||||
use super::ResponseCookie;
|
||||
|
||||
impl Response {
|
||||
pub fn cookies(&self) -> Vec<ResponseCookie> {
|
||||
|
@ -60,7 +60,7 @@ pub fn eval_query_value(
|
||||
QueryValue::Status {} => Ok(Some(Value::Integer(i64::from(http_response.status)))),
|
||||
QueryValue::Header { name, .. } => {
|
||||
let header_name = eval_template(&name, variables)?;
|
||||
let values = http_response.get_header(header_name);
|
||||
let values = http_response.get_header_values(&header_name);
|
||||
if values.is_empty() {
|
||||
Ok(None)
|
||||
} else if values.len() == 1 {
|
||||
|
@ -72,7 +72,7 @@ pub fn eval_asserts(
|
||||
}
|
||||
Ok(expected) => {
|
||||
let header_name = header.key.value.clone();
|
||||
let actuals = http_response.get_header(header_name);
|
||||
let actuals = http_response.get_header_values(&header_name);
|
||||
if actuals.is_empty() {
|
||||
asserts.push(AssertResult::Header {
|
||||
actual: Err(Error {
|
||||
|
@ -67,7 +67,7 @@ fn test_hello() {
|
||||
name: "Content-Type".to_string(),
|
||||
value: "text/html; charset=utf-8".to_string(),
|
||||
}));
|
||||
assert_eq!(response.get_header_values("Date".to_string()).len(), 1);
|
||||
assert_eq!(response.get_header_values("Date").len(), 1);
|
||||
}
|
||||
|
||||
// endregion
|
||||
@ -337,10 +337,7 @@ fn test_redirect() {
|
||||
|
||||
assert_eq!(response.status, 302);
|
||||
assert_eq!(
|
||||
response
|
||||
.get_header_values("Location".to_string())
|
||||
.get(0)
|
||||
.unwrap(),
|
||||
response.get_header_values("Location").get(0).unwrap(),
|
||||
"http://localhost:8000/redirected"
|
||||
);
|
||||
assert_eq!(client.redirect_count, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user