diff --git a/src/main.rs b/src/main.rs index ea7cb5a..3cc13f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -204,6 +204,73 @@ 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. +// 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 mut fuck: HashMap> = HashMap::new(); + + if !field_line.1.contains(",") { + return (field_name, vec![field_line.1.trim().to_owned()]); + } + let temp_field_values = field_line.1.split(",").collect::>(); + + for field_value in temp_field_values { + if field_value.contains(";") { + let temp_field_value = field_value.split(";").collect::>(); + if temp_field_value.len() != 2 { + // TODO: return with an http_response + continue; + } + if !temp_field_value[1].starts_with("q=") && !temp_field_value[1].starts_with("Q=") { + // TODO: return with an http_response + continue; + } + let qvalue = temp_field_value[1] + .trim() + .trim_start_matches("q=") + .trim_start_matches("Q="); + + if qvalue == "0" { + continue; + } + + if let Some(val) = fuck.get_mut(qvalue) { + val.push(temp_field_value[0].trim().to_owned()); + continue; + } + + fuck.insert( + qvalue.to_owned(), + vec![temp_field_value[0].trim().to_owned()], + ); + } else { + if let Some(val) = fuck.get_mut("1") { + val.push(field_value.trim().to_owned()); + continue; + } + + fuck.insert("1".to_owned(), vec![field_value.trim().to_owned()]); + } + } + + let fuck_keys = fuck.keys(); + let mut keys = fuck_keys.collect::>(); + keys.sort_by(|a, b| b.cmp(a)); + + let mut field_values: Vec = vec![]; + for key in keys { + if let Some(value) = fuck.get(key) { + value.iter().for_each(|val| field_values.push(val.clone())); + } + } + + (field_name, field_values) +} + fn parse_field_lines( reader: &mut BufReader<&mut TcpStream>, ) -> Result>, Vec> { @@ -243,8 +310,8 @@ fn parse_field_lines( break; } - let field_line = match line.split_once(":") { - Some(val) => val, + let field_line: (String, Vec) = match line.split_once(":") { + Some(val) => parse_field_line(val), None => { "Invalid field-line" .as_bytes() @@ -269,10 +336,7 @@ fn parse_field_lines( } }; - field_lines.insert( - field_line.0.to_owned(), - vec![field_line.1.trim().to_owned()], - ); + field_lines.insert(field_line.0, field_line.1); } if !field_lines.contains_key(&String::from("Host")) {