feat: add query string parser
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1362,6 +1362,7 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"linked-hash-map",
|
"linked-hash-map",
|
||||||
|
"percent-encoding",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rust_util",
|
"rust_util",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -19,3 +19,4 @@ actix-rt = "1"
|
|||||||
bytes = "0.5"
|
bytes = "0.5"
|
||||||
futures-core = "0.3"
|
futures-core = "0.3"
|
||||||
linked-hash-map = "0.5"
|
linked-hash-map = "0.5"
|
||||||
|
percent-encoding = "2.1"
|
||||||
|
|||||||
54
src/main.rs
54
src/main.rs
@@ -36,11 +36,22 @@ impl futures_core::Stream for ProxyStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn get_file(req: HttpRequest) -> HttpResponse {
|
async fn get_file(req: HttpRequest) -> HttpResponse {
|
||||||
println!("{:?}", req);
|
|
||||||
let query_string = req.query_string();
|
let query_string = req.query_string();
|
||||||
println!("Q: {}", query_string);
|
let parsed_query_string = parse_query_string(query_string);
|
||||||
// TODO parse url
|
information!("Parsed query string: {:?}", parsed_query_string);
|
||||||
let resp = reqwest::get("http://example.com/").await.unwrap();
|
|
||||||
|
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()
|
HttpResponse::Ok()
|
||||||
.content_type("text/plain")
|
.content_type("text/plain")
|
||||||
.streaming(ProxyStream{ inner: Box::new(resp.bytes_stream()) })
|
.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>> {
|
fn parse_query_string(query_string: &str) -> LinkedHashMap<String, Vec<String>> {
|
||||||
let map = LinkedHashMap::new();
|
let mut map = LinkedHashMap::new();
|
||||||
// TODO ...
|
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
|
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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user