diff --git a/src/main.rs b/src/main.rs index 3cc13f9..0548f2e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -125,11 +125,11 @@ fn parse_start_line(input: &str) -> Result> { .for_each(|byte| response_body.push(*byte)); response_field_lines.insert( - String::from("Content-Length"), + String::from("content-length"), vec![response_body.len().to_string()], ); response_field_lines.insert( - String::from("Content-Type"), + String::from("content-type"), vec![String::from("text/plain")], ); @@ -168,11 +168,11 @@ fn parse_start_line(input: &str) -> Result> { .for_each(|byte| response_body.push(*byte)); response_field_lines.insert( - String::from("Content-Length"), + String::from("content-length"), vec![response_body.len().to_string()], ); response_field_lines.insert( - String::from("Content-Type"), + String::from("content-type"), vec![String::from("text/plain")], ); @@ -204,13 +204,13 @@ fn parse_start_line(input: &str) -> Result> { Ok(start_line) } -//TODO: Be able to parse this -// Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8 -// Be careful of optional whitespace (OWS) -// q=x.yyy is basically a which I want most value the closer to 1 the better. If no q=x.yyy was specified, then q=1 is implied. +// Example -> Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8 +// Be careful of optional whitespace (OWS) and CRLF +// q=x.yyy is basically a value which says, what the client wants most. +// The closer to 1 the better. If no q=x.yyy was specified, then q=1 is implied. // This basically mean I should sort the vector by qvalue. So that the one it wants most, is at the beginning. fn parse_field_line(field_line: (&str, &str)) -> (String, Vec) { - let field_name = field_line.0.to_owned(); + let field_name = field_line.0.to_ascii_lowercase(); let mut fuck: HashMap> = HashMap::new(); if !field_line.1.contains(",") { @@ -290,11 +290,11 @@ fn parse_field_lines( .for_each(|byte| response_body.push(*byte)); response_field_lines.insert( - String::from("Content-Length"), + String::from("content-length"), vec![response_body.len().to_string()], ); response_field_lines.insert( - String::from("Content-Type"), + String::from("content-type"), vec![String::from("text/plain")], ); @@ -319,11 +319,11 @@ fn parse_field_lines( .for_each(|byte| response_body.push(*byte)); response_field_lines.insert( - String::from("Content-Length"), + String::from("content-length"), vec![response_body.len().to_string()], ); response_field_lines.insert( - String::from("Content-Type"), + String::from("content-type"), vec![String::from("text/plain")], ); @@ -339,18 +339,18 @@ fn parse_field_lines( field_lines.insert(field_line.0, field_line.1); } - if !field_lines.contains_key(&String::from("Host")) { - "field-line with key HOST is missing" + if !field_lines.contains_key(&String::from("host")) { + "field-line with field-name -> host is missing" .as_bytes() .iter() .for_each(|byte| response_body.push(*byte)); response_field_lines.insert( - String::from("Content-Length"), + String::from("content-length"), vec![response_body.len().to_string()], ); response_field_lines.insert( - String::from("Content-Type"), + String::from("content-type"), vec![String::from("text/plain")], ); @@ -415,7 +415,7 @@ fn response_builder( response } -fn try_get_file(start_line: &StartLine, _field_lines: &HashMap>) -> Vec { +fn try_get_file(start_line: &StartLine, field_lines: &HashMap>) -> Vec { let mut response_field_lines: HashMap> = HashMap::new(); let mut response_body: Vec = vec![]; @@ -424,28 +424,45 @@ fn try_get_file(start_line: &StartLine, _field_lines: &HashMap PathBuf::from(format!("/www{}", start_line.target)), }; - // TODO: Check if wanted file is contained in the optional Accept field-line - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept for reference - // let mime_type = match MimeGuess::from_path(&path).first_raw() { - // Some(val) => val, - // _ => { - // return response_builder(RequestMethods::HEAD, "HTTP/1.1 500 ", None, None); - // } - // } - match fs::read(&path) { Ok(val) => { val.iter().for_each(|byte| response_body.push(*byte)); response_field_lines.insert( - String::from("Content-Length"), + String::from("content-length"), vec![response_body.len().to_string()], ); let mime_type = mime_guess::from_path(&path) - .first_raw() + .first() .expect("Could not guess mime-type from path"); - response_field_lines.insert(String::from("Content-Type"), vec![mime_type.to_string()]); + + if let Some(vector) = field_lines.get("accept") { + for value in vector { + if mime_type.to_string() == *value { + response_field_lines + .insert(String::from("content-type"), vec![mime_type.to_string()]); + } + + if format!("{}/*", mime_type.type_()) == *value { + response_field_lines + .insert(String::from("content-type"), vec![mime_type.to_string()]); + } + + if "*/*" == *value { + response_field_lines + .insert(String::from("content-type"), vec![mime_type.to_string()]); + } + } + } else { + response_field_lines + .insert(String::from("content-type"), vec![mime_type.to_string()]); + } + + if !response_field_lines.contains_key("content-type") { + // TODO: make better according to https://datatracker.ietf.org/doc/html/rfc9110#status.406 + return response_builder(start_line.method, "HTTP/1.1 406 ", None, None); + } response_builder( start_line.method, @@ -478,11 +495,11 @@ fn handle_request(mut stream: TcpStream) -> Result<(), Box> { .for_each(|byte| response_body.push(*byte)); response_field_lines.insert( - String::from("Content-Length"), + String::from("content-length"), vec![response_body.len().to_string()], ); response_field_lines.insert( - String::from("Content-Type"), + String::from("content-type"), vec![String::from("text/plain")], ); @@ -503,7 +520,7 @@ fn handle_request(mut stream: TcpStream) -> Result<(), Box> { return Ok(()); } }; - dbg!(&start_line); + // dbg!(&start_line); let field_lines = match parse_field_lines(&mut reader) { Ok(val) => val, @@ -512,7 +529,7 @@ fn handle_request(mut stream: TcpStream) -> Result<(), Box> { return Ok(()); } }; - dbg!(&field_lines); + // dbg!(&field_lines); // let mut request_body: Vec = vec![]; // reader.read_to_end(&mut request_body)?;