use crate::compression;
use crate::enums::header::http_header::HttpHeader;
use crate::enums::http_body::HttpBody;
use crate::enums::http_request_method::HttpRequestMethod;
use crate::enums::http_version::HttpVersion;
use crate::structures::header::header_list::HttpHeaderList;
use crate::structures::http_message::HttpMessage;
use crate::utils::http_header_field_name::{self, USER_AGENT};
use std::fmt::Write;
pub struct HttpRequestBuilder {
pub headers: HttpHeaderList,
pub http_version: HttpVersion,
pub host: String,
}
impl HttpRequestBuilder {
pub fn new(
http_version: HttpVersion,
headers: HttpHeaderList,
host: impl Into<String>,
) -> HttpRequestBuilder {
let host: String = host.into();
let supported = compression::supported_encodings();
let mut encoding_str = String::with_capacity(64);
let mut first = true;
for enc in &supported {
if !first {
encoding_str.push_str(", ");
}
let _ = write!(encoding_str, "{}", enc);
first = false;
}
let mut default_headers: HttpHeaderList = vec![
HttpHeader::new(http_header_field_name::HOST, &host),
HttpHeader::new(http_header_field_name::USER_AGENT, USER_AGENT),
HttpHeader::new(http_header_field_name::ACCEPT, "text/html;q=0.9,*/*;q=0.8"),
]
.into();
if !encoding_str.is_empty() {
default_headers.add(HttpHeader::new(
http_header_field_name::ACCEPT_ENCODING,
&encoding_str,
));
default_headers.add(HttpHeader::new(http_header_field_name::TE, &encoding_str));
}
default_headers.merge_items(headers.into_iter().map(|(_, header)| header));
HttpRequestBuilder {
headers: default_headers,
http_version,
host,
}
}
pub fn build_request<T: Into<HttpHeaderList>>(
&self,
method: HttpRequestMethod,
path_query: &str,
headers: T,
body: HttpBody,
) -> HttpMessage {
let start_line = format!(
"{} {} {}",
method.to_string(),
path_query,
self.http_version.to_string()
);
let mut headers: HttpHeaderList = headers.into();
headers.merge_items(self.headers.iter().map(|(_, header)| header).cloned());
HttpMessage::new(start_line, headers, body)
}
}