diff --git a/README.md b/README.md index 96f5e7b..809eab1 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,11 @@ V2ray URI parser Usage: v2parser [OPTIONS] Arguments: - + Options: - -s, --socksport + --socksport + --httpport -h, --help Print help -V, --version Print version ``` diff --git a/src/config_models/mod.rs b/src/config_models/mod.rs index ce2ad9c..c4d6d28 100644 --- a/src/config_models/mod.rs +++ b/src/config_models/mod.rs @@ -109,7 +109,7 @@ pub struct WsSettings { #[derive(Serialize, Deserialize)] pub struct TlsSettings { pub alpn: Option>, - pub allowInsecure: Option, + pub allowInsecure: bool, pub serverName: Option, pub enableSessionResumption: Option, pub disableSystemRoot: Option, @@ -165,7 +165,7 @@ pub struct Inbound { pub listen: String, pub port: u16, pub protocol: String, - pub settings: InboundSettings, + pub settings: Option, pub sniffing: Option, pub tag: String, } diff --git a/src/main.rs b/src/main.rs index ef374ad..e4ae9c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,12 +7,14 @@ pub mod utils; #[command(author ,version = "0.1.1", about = "V2ray URI parser", long_about = None)] struct Cli { uri: String, - #[arg(short, long, value_name = "socksport")] + #[arg(long, value_name = "socksport")] socksport: Option, + #[arg(long, value_name = "httpport")] + httpport: Option, } fn main() { let cli = Cli::parse(); - let json_config = parser::create_json_config(&cli.uri, cli.socksport); + let json_config = parser::create_json_config(&cli.uri, cli.socksport, cli.httpport); println!("{}", json_config); } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index d4fb81d..ad0ff87 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5,17 +5,22 @@ use std::process::exit; mod uri_identifier; mod vless; -pub fn create_json_config(uri: &str, socks_port: Option) -> String { - let config = create_config(uri, socks_port); +pub fn create_json_config(uri: &str, socks_port: Option, http_port: Option) -> String { + let config = create_config(uri, socks_port, http_port); let serialized = serde_json::to_string(&config).unwrap(); return serialized; } -pub fn create_config(uri: &str, socks_port: Option) -> config_models::Config { +pub fn create_config( + uri: &str, + socks_port: Option, + http_port: Option, +) -> config_models::Config { let outbound_object = create_outbound_object(uri); let inbound_config = inbound_generator::generate_inbound_config(inbound_generator::InboundGenerationOptions { socks_port, + http_port, }); let config = config_models::Config { outbounds: vec![outbound_object], diff --git a/src/parser/vless/data.rs b/src/parser/vless/data.rs index bd03a36..21916f2 100644 --- a/src/parser/vless/data.rs +++ b/src/parser/vless/data.rs @@ -60,6 +60,7 @@ fn parse_vless_query(raw_query: &str) -> models::VlessQuery { slpn: get_parameter_value(&query, "slpn"), spx: url_decode(get_parameter_value(&query, "spx")), extra: url_decode(get_parameter_value(&query, "extra")), + allowInsecure: get_parameter_value(&query, "allowInsecure"), }; return a; } diff --git a/src/parser/vless/mod.rs b/src/parser/vless/mod.rs index 1ac1b00..3dcb4ba 100644 --- a/src/parser/vless/mod.rs +++ b/src/parser/vless/mod.rs @@ -4,13 +4,17 @@ use crate::{config_models::*, utils::parse_raw_json}; pub fn create_outbound_object(data: models::VlessData) -> Outbound { let network_type = data.query.r#type.clone().unwrap_or(String::from("")); + + let allow_insecure = data.query.allowInsecure == Some(String::from("true")) + || data.query.allowInsecure == Some(String::from("1")); + return Outbound { protocol: String::from("vless"), tag: String::from("proxy"), streamSettings: StreamSettings { network: data.query.r#type.clone(), security: data.query.security.clone(), - tlsSettings: if network_type == String::from("tls") { + tlsSettings: if data.query.security == Some(String::from("tls")) { Some(TlsSettings { alpn: data.query.alpn.map(|alpn| vec![alpn]), rejectUnknownSni: None, @@ -22,7 +26,7 @@ pub fn create_outbound_object(data: models::VlessData) -> Outbound { preferServerCipherSuites: None, fingerprint: data.query.fp.clone(), serverName: data.query.sni.clone(), - allowInsecure: Some(false), + allowInsecure: allow_insecure, }) } else { None diff --git a/src/parser/vless/models.rs b/src/parser/vless/models.rs index c287a3f..363927f 100644 --- a/src/parser/vless/models.rs +++ b/src/parser/vless/models.rs @@ -1,3 +1,4 @@ +#[allow(non_snake_case)] pub struct VlessQuery { pub security: Option, pub sni: Option, @@ -20,6 +21,7 @@ pub struct VlessQuery { pub spx: Option, pub alpn: Option, pub extra: Option, + pub allowInsecure: Option, } pub struct VlessAddress { diff --git a/src/utils/inbound_generator.rs b/src/utils/inbound_generator.rs index ec7bde2..3808dfb 100644 --- a/src/utils/inbound_generator.rs +++ b/src/utils/inbound_generator.rs @@ -2,6 +2,7 @@ use crate::config_models; pub struct InboundGenerationOptions { pub socks_port: Option, + pub http_port: Option, } pub fn generate_inbound_config(options: InboundGenerationOptions) -> Vec { @@ -12,16 +13,24 @@ pub fn generate_inbound_config(options: InboundGenerationOptions) -> Vec {} } + + match options.http_port { + Some(port) => { + inbounds.push(generate_http_inbound(port)); + } + None => {} + } + return inbounds; } -pub fn generate_socks_inbound(socks_port: u16) -> config_models::Inbound { +pub fn generate_http_inbound(http_port: u16) -> config_models::Inbound { return config_models::Inbound { - protocol: String::from("socks"), - port: socks_port, - tag: String::from("socks-in"), + protocol: String::from("http"), + port: http_port, + tag: String::from("http-in"), + settings: None, listen: String::from("127.0.0.1"), - settings: config_models::InboundSettings { udp: true }, sniffing: Some(config_models::SniffingSettings { enabled: Some(true), routeOnly: Some(true), @@ -36,29 +45,23 @@ pub fn generate_socks_inbound(socks_port: u16) -> config_models::Inbound { }; } -#[cfg(test)] -mod test { - use super::*; - #[test] - fn test_generate_socks_inboud() { - let socks_inbound = generate_socks_inbound(2080); - assert_eq!(socks_inbound.protocol, String::from("socks")); - assert_eq!(socks_inbound.listen, String::from("127.0.0.1")); - assert_eq!(socks_inbound.tag, String::from("socks-in")); - assert_eq!(socks_inbound.port, 2080); - assert_eq!(socks_inbound.settings.udp, true); - - let sniffing_obj = socks_inbound.sniffing.unwrap(); - assert_eq!(sniffing_obj.enabled, Some(true)); - assert_eq!(sniffing_obj.routeOnly, Some(true)); - assert_eq!(sniffing_obj.domainsExcluded, None); - assert_eq!( - sniffing_obj.destOverride, - Some(vec![ +pub fn generate_socks_inbound(socks_port: u16) -> config_models::Inbound { + return config_models::Inbound { + protocol: String::from("socks"), + port: socks_port, + tag: String::from("socks-in"), + listen: String::from("127.0.0.1"), + settings: Some(config_models::InboundSettings { udp: true }), + sniffing: Some(config_models::SniffingSettings { + enabled: Some(true), + routeOnly: Some(true), + metadataOnly: Some(false), + domainsExcluded: None, + destOverride: Some(vec![ String::from("http"), String::from("tls"), String::from("quic"), - ]) - ); - } + ]), + }), + }; }