Merge pull request #12 from Keivan-sf/5-improve-vless-parser-and-headers

sync
This commit is contained in:
Keivan
2025-07-26 19:27:00 +03:30
committed by GitHub
8 changed files with 56 additions and 38 deletions

View File

@@ -12,7 +12,8 @@ Arguments:
<URI>
Options:
-s, --socksport <socksport>
--socksport <socksport>
--httpport <httpport>
-h, --help Print help
-V, --version Print version
```

View File

@@ -109,7 +109,7 @@ pub struct WsSettings {
#[derive(Serialize, Deserialize)]
pub struct TlsSettings {
pub alpn: Option<Vec<String>>,
pub allowInsecure: Option<bool>,
pub allowInsecure: bool,
pub serverName: Option<String>,
pub enableSessionResumption: Option<bool>,
pub disableSystemRoot: Option<bool>,
@@ -165,7 +165,7 @@ pub struct Inbound {
pub listen: String,
pub port: u16,
pub protocol: String,
pub settings: InboundSettings,
pub settings: Option<InboundSettings>,
pub sniffing: Option<SniffingSettings>,
pub tag: String,
}

View File

@@ -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<u16>,
#[arg(long, value_name = "httpport")]
httpport: Option<u16>,
}
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);
}

View File

@@ -5,17 +5,22 @@ use std::process::exit;
mod uri_identifier;
mod vless;
pub fn create_json_config(uri: &str, socks_port: Option<u16>) -> String {
let config = create_config(uri, socks_port);
pub fn create_json_config(uri: &str, socks_port: Option<u16>, http_port: Option<u16>) -> 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<u16>) -> config_models::Config {
pub fn create_config(
uri: &str,
socks_port: Option<u16>,
http_port: Option<u16>,
) -> 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],

View File

@@ -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;
}

View File

@@ -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

View File

@@ -1,3 +1,4 @@
#[allow(non_snake_case)]
pub struct VlessQuery {
pub security: Option<String>,
pub sni: Option<String>,
@@ -20,6 +21,7 @@ pub struct VlessQuery {
pub spx: Option<String>,
pub alpn: Option<String>,
pub extra: Option<String>,
pub allowInsecure: Option<String>,
}
pub struct VlessAddress {

View File

@@ -2,6 +2,7 @@ use crate::config_models;
pub struct InboundGenerationOptions {
pub socks_port: Option<u16>,
pub http_port: Option<u16>,
}
pub fn generate_inbound_config(options: InboundGenerationOptions) -> Vec<config_models::Inbound> {
@@ -12,16 +13,24 @@ pub fn generate_inbound_config(options: InboundGenerationOptions) -> Vec<config_
}
None => {}
}
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"),
])
);
}
]),
}),
};
}