Use const for header names that matters.

This commit is contained in:
jcamiel 2024-02-06 18:28:29 +01:00 committed by hurl-bot
parent 4662c65902
commit fb85c5083b
No known key found for this signature in database
GPG Key ID: 1283A2B4A0DCAF8D
6 changed files with 34 additions and 20 deletions

View File

@ -522,15 +522,16 @@ impl Client {
list.append(format!("{}: {}", header.name, header.value).as_str())?;
}
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())?;
// If request has no Content-Type header, we set it if the content type has been set explicitly on this request.
if request.get_header_values(Header::CONTENT_TYPE).is_empty() {
if let Some(s) = &request.content_type {
list.append(&format!("{}: {s}", Header::CONTENT_TYPE))?;
} else {
// We remove default Content-Type headers added by curl because we want
// to explicitly manage this header.
// For instance, with --data option, curl will send a 'Content-type: application/x-www-form-urlencoded'
// header.
list.append("Content-Type:")?;
list.append(&format!("{}:", Header::CONTENT_TYPE))?;
}
}
@ -538,18 +539,18 @@ impl Client {
// libcurl will generate `SignedHeaders` that include `expect` even though the header is not
// present, causing some APIs to reject the request.
// Therefore we only remove this header when not in aws_sigv4 mode.
if request.get_header_values("Expect").is_empty() && options.aws_sigv4.is_none() {
if request.get_header_values(Header::EXPECT).is_empty() && options.aws_sigv4.is_none() {
// We remove default Expect headers added by curl because we want
// to explicitly manage this header.
list.append("Expect:")?; // remove header Expect
list.append(&format!("{}:", Header::EXPECT))?;
}
if request.get_header_values("User-Agent").is_empty() {
if request.get_header_values(Header::USER_AGENT).is_empty() {
let user_agent = match options.user_agent {
Some(ref u) => u.clone(),
None => format!("hurl/{}", clap::crate_version!()),
};
list.append(format!("User-Agent: {user_agent}").as_str())?;
list.append(&format!("{}: {user_agent}", Header::USER_AGENT))?;
}
if let Some(ref user) = options.user {
@ -564,13 +565,17 @@ impl Client {
} else {
let user = user.as_bytes();
let authorization = general_purpose::STANDARD.encode(user);
if request.get_header_values("Authorization").is_empty() {
list.append(format!("Authorization: Basic {authorization}").as_str())?;
if request.get_header_values(Header::AUTHORIZATION).is_empty() {
list.append(&format!("{}: Basic {authorization}", Header::AUTHORIZATION))?;
}
}
}
if options.compressed && request.get_header_values("Accept-Encoding").is_empty() {
list.append("Accept-Encoding: gzip, deflate, br")?;
if options.compressed
&& request
.get_header_values(Header::ACCEPT_ENCODING)
.is_empty()
{
list.append(&format!("{}: gzip, deflate, br", Header::ACCEPT_ENCODING))?;
}
self.handle.http_headers(list)?;

View File

@ -31,6 +31,12 @@ impl fmt::Display for Header {
}
impl Header {
pub const ACCEPT_ENCODING: &'static str = "Accept-Encoding";
pub const AUTHORIZATION: &'static str = "Authorization";
pub const CONTENT_TYPE: &'static str = "Content-Type";
pub const EXPECT: &'static str = "Expect";
pub const USER_AGENT: &'static str = "User-Agent";
pub fn new(name: &str, value: &str) -> Self {
Header {
name: name.to_string(),

View File

@ -104,7 +104,7 @@ impl Request {
/// Returns optional Content-type header value.
pub fn content_type(&self) -> Option<String> {
header::get_values(&self.headers, "Content-Type")
header::get_values(&self.headers, Header::CONTENT_TYPE)
.first()
.cloned()
}

View File

@ -39,28 +39,31 @@ impl RequestSpec {
.headers
.iter()
.map(|h| &h.name)
.any(|n| n.as_str() == "Content-Type");
.any(|n| n.as_str() == Header::CONTENT_TYPE);
if !has_explicit_content_type {
if let Some(content_type) = &self.content_type {
if content_type.as_str() != "application/x-www-form-urlencoded"
&& content_type.as_str() != "multipart/form-data"
{
arguments.push("--header".to_string());
arguments.push(format!("'Content-Type: {content_type}'"));
arguments.push(format!("'{}: {content_type}'", Header::CONTENT_TYPE));
}
} else if !self.body.bytes().is_empty() {
match self.body {
Body::Text(_) => {
arguments.push("--header".to_string());
arguments.push("'Content-Type:'".to_string())
arguments.push(format!("'{}:'", Header::CONTENT_TYPE))
}
Body::Binary(_) => {
arguments.push("--header".to_string());
arguments.push("'Content-Type: application/octet-stream'".to_string())
arguments.push(format!(
"'{}: application/octet-stream'",
Header::CONTENT_TYPE
))
}
Body::File(_, _) => {
arguments.push("--header".to_string());
arguments.push("'Content-Type:'".to_string())
arguments.push(format!("'{}:'", Header::CONTENT_TYPE))
}
}
}

View File

@ -78,7 +78,7 @@ impl Response {
/// Returns optional Content-type header value.
pub fn content_type(&self) -> Option<String> {
header::get_values(&self.headers, "Content-Type")
header::get_values(&self.headers, Header::CONTENT_TYPE)
.first()
.cloned()
}

View File

@ -55,7 +55,7 @@ pub fn eval_request(
let user_password = user_password.as_bytes();
let authorization = general_purpose::STANDARD.encode(user_password);
let value = format!("Basic {authorization}");
let header = http::Header::new("Authorization", &value);
let header = http::Header::new(http::Header::AUTHORIZATION, &value);
headers.push(header);
}