feat: add query string parser

This commit is contained in:
2020-08-09 17:28:09 +08:00
parent 28c14d2ca8
commit 7d99300a3c
3 changed files with 50 additions and 6 deletions

1
Cargo.lock generated
View File

@@ -1362,6 +1362,7 @@ dependencies = [
"clap",
"futures-core",
"linked-hash-map",
"percent-encoding",
"reqwest",
"rust_util",
"serde",

View File

@@ -19,3 +19,4 @@ actix-rt = "1"
bytes = "0.5"
futures-core = "0.3"
linked-hash-map = "0.5"
percent-encoding = "2.1"

View File

@@ -36,11 +36,22 @@ impl futures_core::Stream for ProxyStream {
}
async fn get_file(req: HttpRequest) -> HttpResponse {
println!("{:?}", req);
let query_string = req.query_string();
println!("Q: {}", query_string);
// TODO parse url
let resp = reqwest::get("http://example.com/").await.unwrap();
let parsed_query_string = parse_query_string(query_string);
information!("Parsed query string: {:?}", parsed_query_string);
let url = match parsed_query_string.get("url") {
None => None,
Some(v) => v.iter().next().clone(),
};
let url = match url {
Some(u) => u, None => {
return HttpResponse::BadRequest().content_type("text/plain").body("No url!");
},
};
let resp = reqwest::get(url.as_str()).await.unwrap();
// TODO ...
HttpResponse::Ok()
.content_type("text/plain")
.streaming(ProxyStream{ inner: Box::new(resp.bytes_stream()) })
@@ -71,7 +82,38 @@ async fn main() -> std::io::Result<()> {
}
fn parse_query_string(query_string: &str) -> LinkedHashMap<String, Vec<String>> {
let map = LinkedHashMap::new();
// TODO ...
let mut map = LinkedHashMap::new();
query_string.split('&').for_each(|kv| {
let mut meet_equal = false;
let mut k = String::new();
let mut v = String::new();
kv.chars().for_each(|c| {
if meet_equal {
v.push(c);
} else if c == '=' {
meet_equal = true;
} else {
k.push(c);
}
});
let k = percent_encoding::percent_decode_str(&k).decode_utf8_lossy().into_owned();
let v = percent_encoding::percent_decode_str(&v).decode_utf8_lossy().into_owned();
match map.get_mut(&k) {
None => { map.insert(k, vec![v]); },
Some(values) => { values.push(v); },
}
});
map
}
#[test]
fn test_parse_query_string() {
let mut e = LinkedHashMap::new();
e.insert("a".to_string(), vec!["b".to_string()]);
let m = parse_query_string("a=b");
assert_eq!(e, m);
let mut e = LinkedHashMap::new();
e.insert("a".to_string(), vec!["b".to_string(), "c".to_string()]);
let m = parse_query_string("a=b&a=c");
assert_eq!(e, m);
}