Clean up build_update_instance_form in scheduled_tasks.rs

This commit is contained in:
dullbananas 2024-06-03 15:38:17 -07:00 committed by GitHub
parent aefb41b551
commit d2e82ffcb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -30,6 +30,7 @@ use lemmy_db_schema::{
}; };
use lemmy_routes::nodeinfo::{NodeInfo, NodeInfoWellKnown}; use lemmy_routes::nodeinfo::{NodeInfo, NodeInfoWellKnown};
use lemmy_utils::error::LemmyResult; use lemmy_utils::error::LemmyResult;
use reqwest::Response;
use reqwest_middleware::ClientWithMiddleware; use reqwest_middleware::ClientWithMiddleware;
use std::time::Duration; use std::time::Duration;
use tracing::{error, info, warn}; use tracing::{error, info, warn};
@ -484,9 +485,6 @@ async fn update_instance_software(
/// This builds an instance update form, for a given domain. /// This builds an instance update form, for a given domain.
/// If the instance sends a response, but doesn't have a well-known or nodeinfo, /// If the instance sends a response, but doesn't have a well-known or nodeinfo,
/// Then return a default form with only the updated field. /// Then return a default form with only the updated field.
///
/// TODO This function is a bit of a nightmare with its embedded matches, but the only other way
/// would be to extract the fetches into functions which return the default_form on errors.
async fn build_update_instance_form( async fn build_update_instance_form(
domain: &str, domain: &str,
client: &ClientWithMiddleware, client: &ClientWithMiddleware,
@ -504,55 +502,51 @@ async fn build_update_instance_form(
// First, fetch their /.well-known/nodeinfo, then extract the correct nodeinfo link from it // First, fetch their /.well-known/nodeinfo, then extract the correct nodeinfo link from it
let well_known_url = format!("https://{}/.well-known/nodeinfo", domain); let well_known_url = format!("https://{}/.well-known/nodeinfo", domain);
match client.get(&well_known_url).send().await { let Ok(res) = client.get(&well_known_url).send().await else {
Ok(res) if res.status().is_client_error() => { // This is the only kind of error that means the instance is dead
// Instance doesn't have well-known but sent a response, consider it alive return None;
Some(instance_form) };
// In this block, returning `None` is ignored, and only means not writing nodeinfo to db
async {
if res.status().is_client_error() {
return None;
} }
Ok(res) => match res.json::<NodeInfoWellKnown>().await {
Ok(well_known) => { let node_info_url = res
// Find the first link where the rel contains the allowed rels above .json::<NodeInfoWellKnown>()
match well_known.links.into_iter().find(|links| { .await
.ok()?
.links
.into_iter()
.find(|links| {
links links
.rel .rel
.as_str() .as_str()
.starts_with("http://nodeinfo.diaspora.software/ns/schema/2.") .starts_with("http://nodeinfo.diaspora.software/ns/schema/2.")
}) { })?
Some(well_known_link) => { .href;
let node_info_url = well_known_link.href;
// Fetch the node_info from the well known href let software = client
match client.get(node_info_url).send().await { .get(node_info_url)
Ok(node_info_res) => match node_info_res.json::<NodeInfo>().await { .send()
Ok(node_info) => { .await
// Instance sent valid nodeinfo, write it to db .ok()?
// Set the instance form fields. .json::<NodeInfo>()
if let Some(software) = node_info.software.as_ref() { .await
instance_form.software.clone_from(&software.name); .ok()?
instance_form.version.clone_from(&software.version); .software?;
instance_form.software = software.name;
instance_form.version = software.version;
Some(())
} }
.await;
Some(instance_form) Some(instance_form)
} }
Err(_) => Some(instance_form),
},
Err(_) => Some(instance_form),
}
}
// If none is found, use the default form above
None => Some(instance_form),
}
}
Err(_) => {
// No valid nodeinfo but valid HTTP response, consider instance alive
Some(instance_form)
}
},
Err(_) => {
// dead instance, do nothing
None
}
}
}
#[cfg(test)] #[cfg(test)]
#[allow(clippy::indexing_slicing)] #[allow(clippy::indexing_slicing)]
mod tests { mod tests {