feat: adjust fetch profile url

This commit is contained in:
GyDi 2022-02-19 00:09:36 +08:00
parent 3a9a392a77
commit c60578f5b5
No known key found for this signature in database
GPG Key ID: 1C95E0D3467B3084
3 changed files with 46 additions and 54 deletions

View File

@ -34,13 +34,9 @@ pub async fn import_profile(
with_proxy: bool,
profiles_state: State<'_, ProfilesState>,
) -> Result<(), String> {
match fetch_profile(&url, with_proxy).await {
Some(result) => {
let mut profiles = profiles_state.0.lock().unwrap();
profiles.import_from_url(url, result)
}
None => Err(format!("failed to fetch profile from `{}`", url)),
}
let result = fetch_profile(&url, with_proxy).await?;
let mut profiles = profiles_state.0.lock().unwrap();
profiles.import_from_url(url, result)
}
/// new a profile
@ -82,23 +78,22 @@ pub async fn update_profile(
Err(_) => return Err("failed to get profiles lock".into()),
};
match fetch_profile(&url, with_proxy).await {
Some(result) => match profiles_state.0.lock() {
Ok(mut profiles) => {
profiles.update_item(index, result)?;
let result = fetch_profile(&url, with_proxy).await?;
// reactivate the profile
let current = profiles.current.clone().unwrap_or(0);
if current == index {
let clash = clash_state.0.lock().unwrap();
profiles.activate(&clash)
} else {
Ok(())
}
match profiles_state.0.lock() {
Ok(mut profiles) => {
profiles.update_item(index, result)?;
// reactivate the profile
let current = profiles.current.clone().unwrap_or(0);
if current == index {
let clash = clash_state.0.lock().unwrap();
profiles.activate(&clash)
} else {
Ok(())
}
Err(_) => Err("failed to get profiles lock".into()),
},
None => Err(format!("failed to fetch profile from `{}`", url)),
}
Err(_) => Err("failed to get profiles lock".into()),
}
}

View File

@ -60,7 +60,7 @@ pub struct ProfileResponse {
pub name: String,
pub file: String,
pub data: String,
pub extra: ProfileExtra,
pub extra: Option<ProfileExtra>,
}
static PROFILE_YAML: &str = "profiles.yaml";
@ -117,7 +117,7 @@ impl Profiles {
mode: Some(format!("rule")),
url: Some(url),
selected: Some(vec![]),
extra: Some(result.extra),
extra: result.extra,
updated: Some(now as usize),
});
@ -194,7 +194,7 @@ impl Profiles {
File::create(file_path).unwrap().write(file_data).unwrap();
items[index].name = Some(result.name);
items[index].extra = Some(result.extra);
items[index].extra = result.extra;
items[index].updated = Some(now);
self.items = Some(items);

View File

@ -22,36 +22,35 @@ fn parse_string<T: FromStr>(target: &str, key: &str) -> Option<T> {
}
}
/// fetch and parse the profile
pub async fn fetch_profile(url: &str, with_proxy: bool) -> Option<ProfileResponse> {
/// fetch and parse the profile url
/// maybe it contains some Subscription infomations, maybe not
pub async fn fetch_profile(url: &str, with_proxy: bool) -> Result<ProfileResponse, String> {
let builder = reqwest::ClientBuilder::new();
let client = match with_proxy {
true => builder.build(),
false => builder.no_proxy().build(),
};
let resp = match client {
Ok(client) => match client.get(url).send().await {
Ok(res) => res,
Err(_) => return None,
},
Err(_) => return None,
let resp = match client.unwrap().get(url).send().await {
Ok(res) => res,
Err(_) => return Err("failed to create https client".into()),
};
let header = resp.headers();
// parse the Subscription Userinfo
let extra = {
let sub_info = match header.get("Subscription-Userinfo") {
Some(value) => value.to_str().unwrap_or(""),
None => "",
};
let extra = match header.get("Subscription-Userinfo") {
Some(value) => {
let sub_info = value.to_str().unwrap_or("");
ProfileExtra {
upload: parse_string(sub_info, "upload=").unwrap_or(0),
download: parse_string(sub_info, "download=").unwrap_or(0),
total: parse_string(sub_info, "total=").unwrap_or(0),
expire: parse_string(sub_info, "expire=").unwrap_or(0),
Some(ProfileExtra {
upload: parse_string(sub_info, "upload=").unwrap_or(0),
download: parse_string(sub_info, "download=").unwrap_or(0),
total: parse_string(sub_info, "total=").unwrap_or(0),
expire: parse_string(sub_info, "expire=").unwrap_or(0),
})
}
None => None,
};
let file = {
@ -71,17 +70,15 @@ pub async fn fetch_profile(url: &str, with_proxy: bool) -> Option<ProfileRespons
};
// get the data
let data = match resp.text_with_charset("utf-8").await {
Ok(d) => d,
Err(_) => return None,
};
Some(ProfileResponse {
file,
name,
data,
extra,
})
match resp.text_with_charset("utf-8").await {
Ok(data) => Ok(ProfileResponse {
file,
name,
data,
extra,
}),
Err(_) => Err("failed to parse the response data".into()),
}
}
#[test]