Reworked http

This commit is contained in:
2021-05-20 20:15:06 +02:00
parent 2699ddc5f8
commit fb4a78f23f
2 changed files with 48 additions and 34 deletions

View File

@ -145,6 +145,10 @@ pub struct HeaderField {
value: String,
}
pub struct Header {
fields: Vec<HeaderField>,
}
impl std::fmt::Display for HeaderField {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "[{}: {}]", self.name, self.value)
@ -155,28 +159,50 @@ pub struct Request {
version: String,
pub method: Method,
pub uri: String,
header_fields: Vec<HeaderField>,
header: Header,
}
pub struct Response {
version: String,
status: Status,
header_fields: Vec<HeaderField>,
header: Header,
}
impl Request {
pub fn find_header(&self, header_name: &str) -> Option<String> {
for field in &self.header_fields {
if field
.name
.to_lowercase()
.eq(header_name.to_ascii_lowercase().as_str())
{
impl Header {
pub fn new() -> Self {
Header { fields: Vec::new() }
}
pub fn from(fields: Vec<HeaderField>) -> Self {
Header { fields }
}
pub fn find_field(&self, field_name: &str) -> Option<String> {
let field_name = field_name.to_lowercase();
for field in &self.fields {
if field.name.to_lowercase().eq(field_name.as_str()) {
return Some(field.value.clone());
}
}
return None;
}
pub fn add_field(&mut self, name: &str, value: &str) {
self.fields.push(HeaderField {
name: String::from(name),
value: String::from(value),
})
}
}
impl Request {
pub fn find_header(&self, name: &str) -> Option<String> {
self.header.find_field(name)
}
pub fn add_header(&mut self, name: &str, value: &str) {
self.header.add_field(name, value)
}
}
impl Response {
@ -184,7 +210,7 @@ impl Response {
let mut res = Response {
version: "1.1".to_string(),
status: Status::from_code(200).unwrap(),
header_fields: Vec::new(),
header: Header::new(),
};
res.add_header("Server", "Locutus");
res.add_header(
@ -197,6 +223,14 @@ impl Response {
res
}
pub fn find_header(&self, name: &str) -> Option<String> {
self.header.find_field(name)
}
pub fn add_header(&mut self, name: &str, value: &str) {
self.header.add_field(name, value)
}
pub fn status(&mut self, status_code: u16) {
self.status = Status::from_code(status_code).unwrap()
}
@ -205,26 +239,6 @@ impl Response {
self.status.info = Some(info);
}
pub fn add_header(&mut self, name: &str, value: &str) {
self.header_fields.push(HeaderField {
name: String::from(name),
value: String::from(value),
});
}
pub fn find_header(&self, header_name: &str) -> Option<String> {
for field in &self.header_fields {
if field
.name
.to_lowercase()
.eq(header_name.to_ascii_lowercase().as_str())
{
return Some(field.value.clone());
}
}
return None;
}
pub fn send(&mut self, stream: &mut Stream) -> Result<(), std::io::Error> {
let mut buf = None;
if let None = self.find_header("Content-Length") {
@ -241,7 +255,7 @@ impl Response {
"HTTP/{} {:03} {}\r\n",
self.version, self.status.code, self.status.message
);
for header_field in &self.header_fields {
for header_field in &self.header.fields {
header.push_str(format!("{}: {}\r\n", header_field.name, header_field.value).as_str());
}
header.push_str("\r\n");

View File

@ -24,7 +24,7 @@ pub fn parse_request(stream: &mut http::Stream) -> Result<Option<http::Request>,
version: String::from(parser.http_version.unwrap()),
method: http::Method::from_str(parser.method.unwrap()),
uri: String::from(parser.uri.unwrap()),
header_fields,
header: http::Header::from(header_fields),
};
stream.read_exact(&mut buf[..header_size])?;
@ -59,7 +59,7 @@ pub fn parse_response(stream: &mut http::Stream) -> Result<http::Response, Error
let response = http::Response {
version: String::from(parser.http_version.unwrap()),
status: Status::new_custom(status_code, parser.status_message.unwrap()),
header_fields,
header: http::Header::from(header_fields),
};
stream.read_exact(&mut buf[..header_size])?;