Support xhttp

This commit is contained in:
Keivan-sf
2025-07-26 16:32:53 +03:30
parent 763169e04b
commit ae36a180f7
3 changed files with 33 additions and 2 deletions

View File

@@ -60,6 +60,15 @@ pub struct KCPSettings {
pub seed: Option<String>, pub seed: Option<String>,
} }
#[allow(non_snake_case)]
#[derive(Serialize, Deserialize)]
pub struct XHTTPSettings {
pub host: Option<String>,
pub path: Option<String>,
pub mode: Option<String>,
pub extra: Option<serde_json::Value>,
}
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct RealitySettings { pub struct RealitySettings {
@@ -124,6 +133,7 @@ pub struct StreamSettings {
pub grpcSettings: Option<GRPCSettings>, pub grpcSettings: Option<GRPCSettings>,
pub quicSettings: Option<QuicSettings>, pub quicSettings: Option<QuicSettings>,
pub kcpSettings: Option<KCPSettings>, pub kcpSettings: Option<KCPSettings>,
pub xhttpSettings: Option<XHTTPSettings>,
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]

View File

@@ -31,8 +31,8 @@ pub fn create_outbound_object(data: models::VlessData) -> Outbound {
}, },
wsSettings: if network_type == String::from("ws") { wsSettings: if network_type == String::from("ws") {
Some(WsSettings { Some(WsSettings {
Host: data.query.host, Host: data.query.host.clone(),
path: data.query.path, path: data.query.path.clone(),
acceptProxyProtocol: None, acceptProxyProtocol: None,
}) })
} else { } else {
@@ -93,6 +93,16 @@ pub fn create_outbound_object(data: models::VlessData) -> Outbound {
} else { } else {
None None
}, },
xhttpSettings: if network_type == String::from("xhttp") {
Some(XHTTPSettings {
host: data.query.host.clone(),
path: data.query.path.clone(),
mode: data.query.mode,
extra: data.query.extra.and_then(|e| parse_raw_json(e.as_str())),
})
} else {
None
},
}, },
settings: OutboundSettings::Vless(VlessOutboundSettings { settings: OutboundSettings::Vless(VlessOutboundSettings {
vnext: vec![VlessServerObject { vnext: vec![VlessServerObject {
@@ -167,6 +177,7 @@ fn parse_vless_query(raw_query: &str) -> models::VlessQuery {
service_name: url_decode(get_parameter_value(&query, "serviceName")), service_name: url_decode(get_parameter_value(&query, "serviceName")),
slpn: get_parameter_value(&query, "slpn"), slpn: get_parameter_value(&query, "slpn"),
spx: url_decode(get_parameter_value(&query, "spx")), spx: url_decode(get_parameter_value(&query, "spx")),
extra: url_decode(get_parameter_value(&query, "extra")),
}; };
return a; return a;
} }
@@ -179,6 +190,15 @@ fn url_decode(value: Option<String>) -> Option<String> {
}); });
} }
fn parse_raw_json(input: &str) -> Option<serde_json::Value> {
serde_json::from_str::<serde_json::Value>(input)
.ok()
.and_then(|v| match v {
serde_json::Value::Object(_) => Some(v),
_ => None,
})
}
fn get_parameter_value(query: &Vec<(&str, &str)>, param: &str) -> Option<String> { fn get_parameter_value(query: &Vec<(&str, &str)>, param: &str) -> Option<String> {
return query return query
.iter() .iter()

View File

@@ -19,6 +19,7 @@ pub struct VlessQuery {
pub slpn: Option<String>, pub slpn: Option<String>,
pub spx: Option<String>, pub spx: Option<String>,
pub alpn: Option<String>, pub alpn: Option<String>,
pub extra: Option<String>,
} }
pub struct VlessAddress { pub struct VlessAddress {