diff --git a/json-api/src/http.rs b/json-api/src/http.rs index 329aed8..98428ca 100644 --- a/json-api/src/http.rs +++ b/json-api/src/http.rs @@ -16,11 +16,34 @@ pub fn set_json_body(response: &mut Response, values: Value) { *response.body_mut() = Body::from(values.to_string()); } +fn percent_decode(url: &str) -> String { + // completely ripped from: https://docs.rs/urldecode/0.1.1/src/urldecode/lib.rs.html#1-21 + let url = String::from(url); + let mut decoded = String::from(""); + let mut skip = 0; + for i in 0..url.len() { + if skip != 0 { + skip -= 1; + continue; + } + let c: char = url.chars().nth(i).unwrap(); + if c == '%' { + let left = url.chars().nth(i + 1).unwrap(); + let right = url.chars().nth(i + 2).unwrap(); + let byte = u8::from_str_radix(&format!("{}{}", left, right), 16).unwrap(); + decoded += &(byte as char).to_string(); + skip = 2; + } else { + decoded += &c.to_string(); + } + } + decoded +} -pub fn parse_query_string<'qs>(string: &'qs str) - -> HashMap<&str, &str> { +pub fn parse_query_string<'qs>(string: &str) + -> HashMap { - let mut map: HashMap<&str, &str> = HashMap::new(); + let mut map: HashMap = HashMap::new(); // get pairs of [key1=value1, key2=value2, ...] for pair in string.split('&') { @@ -30,7 +53,7 @@ pub fn parse_query_string<'qs>(string: &'qs str) match (kv.get(0), kv.get(1)) { // only if the format is some_key=some_value do we actually care about it (Some(key), Some(value)) => { - map.insert(key, value); + map.insert(percent_decode(&key), percent_decode(&value)); }, // ignore all non-pairs _ => continue @@ -75,4 +98,4 @@ mod tests { assert_eq!(qs_param!(map, "asdf", u64).is_some(), true); assert_eq!(qs_param!(map, "asdf", bool).is_some(), false); } -} \ No newline at end of file +}