diff --git a/Cargo.lock b/Cargo.lock index c9c23fd..178daf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +[[package]] +name = "querystring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9318ead08c799aad12a55a3e78b82e0b6167271ffd1f627b758891282f739187" + [[package]] name = "regex" version = "1.9.6" @@ -50,5 +56,6 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" name = "v2parser" version = "0.1.0" dependencies = [ + "querystring", "regex", ] diff --git a/Cargo.toml b/Cargo.toml index 44a8072..1bbc517 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +querystring = "1.1.0" regex = "1.9.6" diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 79076bd..f0099f9 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,5 +1,6 @@ use std::process::exit; mod uri_identifier; +mod vless; pub fn parse(uri: &str) { let protocol = uri_identifier::get_uri_protocol(uri); diff --git a/src/parser/vless.rs b/src/parser/vless.rs new file mode 100644 index 0000000..b062349 --- /dev/null +++ b/src/parser/vless.rs @@ -0,0 +1,95 @@ +use querystring; + +#[derive(PartialEq, Eq)] +pub struct Vless_Query { + security: String, + sni: String, + fp: String, + pbk: String, + sid: String, + r#type: String, + flow: String, +} + +pub fn get_vless_data(uri: &str) { + let data = uri.split_once("vless://").unwrap().1; + let query = uri.split_once("?").unwrap().1; + let query_parsed = querystring::querify(query); + for i in query_parsed { + println!("{0} : {1}", i.0, i.1); + } +} + +pub fn get_vless_query_data(raw_query: &str) -> Vless_Query { + let query = querystring::querify(raw_query); + let a = Vless_Query { + pbk: query + .iter() + .find(|q| String::from(q.0) == String::from("pbk")) + .unwrap_or(&("", "")) + .1 + .to_string(), + security: query + .iter() + .find(|q| String::from(q.0) == String::from("security")) + .unwrap_or(&("", "")) + .1 + .to_string(), + sid: query + .iter() + .find(|q| String::from(q.0) == String::from("sid")) + .unwrap_or(&("", "")) + .1 + .to_string(), + flow: query + .iter() + .find(|q| String::from(q.0) == String::from("flow")) + .unwrap_or(&("", "")) + .1 + .to_string(), + sni: query + .iter() + .find(|q| String::from(q.0) == String::from("sni")) + .unwrap_or(&("", "")) + .1 + .to_string(), + fp: query + .iter() + .find(|q| String::from(q.0) == String::from("fp")) + .unwrap_or(&("", "")) + .1 + .to_string(), + r#type: query + .iter() + .find(|q| String::from(q.0) == String::from("type")) + .unwrap_or(&("", "")) + .1 + .to_string(), + }; + return a; +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn vless_test() { + let v = "vless://4d2c3e35-749d-52e3-bdb6-3f3f4950c183@tre.test.one:2053?security=reality&sni=bench.sh&fp=chrome&pbk=7xhH4b_VkliBxGulljcyPOH-bYUA2dl-XAdZAsfhk04&sid=6ba85179e30d4fc2&type=tcp&flow=xtls-rprx-vision#test-name"; + get_vless_data(v); + } + #[test] + fn should_return_vless_query() { + let query = "security=reality&sni=bench.sh&fp=chrome&pbk=7xhH4b_VkliBxGulljcyPOH-bYUA2dl-XAdZAsfhk04&sid=6ba85179e30d4fc2&type=tcp&flow=xtls-rprx-vision"; + let parsed_query = get_vless_query_data(query); + assert_eq!(parsed_query.sni, "bench.sh"); + assert_eq!(parsed_query.security, "reality"); + assert_eq!(parsed_query.fp, "chrome"); + assert_eq!( + parsed_query.pbk, + "7xhH4b_VkliBxGulljcyPOH-bYUA2dl-XAdZAsfhk04" + ); + assert_eq!(parsed_query.sid, "6ba85179e30d4fc2"); + assert_eq!(parsed_query.r#type, "tcp"); + assert_eq!(parsed_query.r#flow, "xtls-rprx-vision"); + } +}