diff --git a/src/http/mod.rs b/src/http/mod.rs index ab56729..ce0a5fb 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -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"); diff --git a/src/http/parser.rs b/src/http/parser.rs index 22a3046..c80aab2 100644 --- a/src/http/parser.rs +++ b/src/http/parser.rs @@ -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])?;