chore (backend-rs): more documents on NodeInfo
This commit is contained in:
parent
c1255ef965
commit
8293ed8e87
4 changed files with 27 additions and 7 deletions
|
@ -1,10 +1,13 @@
|
||||||
//! NodeInfo fetcher
|
//! NodeInfo fetcher
|
||||||
|
//!
|
||||||
|
//! ref: <https://nodeinfo.diaspora.software/protocol.html>
|
||||||
|
|
||||||
use crate::federation::nodeinfo::schema::*;
|
use crate::federation::nodeinfo::schema::*;
|
||||||
use crate::util::http_client;
|
use crate::util::http_client;
|
||||||
use isahc::AsyncReadResponseExt;
|
use isahc::AsyncReadResponseExt;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
/// Errors that can occur while fetching NodeInfo from a remote server
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("HTTP client aquisition error: {0}")]
|
#[error("HTTP client aquisition error: {0}")]
|
||||||
|
@ -21,25 +24,23 @@ pub enum Error {
|
||||||
MissingNodeinfo,
|
MissingNodeinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the schema of `/.well-known/nodeinfo`.
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct NodeinfoLinks {
|
pub struct NodeinfoLinks {
|
||||||
links: Vec<NodeinfoLink>,
|
links: Vec<NodeinfoLink>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents one entry of `/.well-known/nodeinfo`.
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct NodeinfoLink {
|
pub struct NodeinfoLink {
|
||||||
rel: String,
|
rel: String,
|
||||||
href: String,
|
href: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
/// Fetches `/.well-known/nodeinfo` and parses the result.
|
||||||
fn wellknown_nodeinfo_url(host: &str) -> String {
|
|
||||||
format!("https://{}/.well-known/nodeinfo", host)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn fetch_nodeinfo_links(host: &str) -> Result<NodeinfoLinks, Error> {
|
async fn fetch_nodeinfo_links(host: &str) -> Result<NodeinfoLinks, Error> {
|
||||||
let client = http_client::client()?;
|
let client = http_client::client()?;
|
||||||
let wellknown_url = wellknown_nodeinfo_url(host);
|
let wellknown_url = format!("https://{}/.well-known/nodeinfo", host);
|
||||||
let mut wellknown_response = client.get_async(&wellknown_url).await?;
|
let mut wellknown_response = client.get_async(&wellknown_url).await?;
|
||||||
|
|
||||||
if !wellknown_response.status().is_success() {
|
if !wellknown_response.status().is_success() {
|
||||||
|
@ -54,6 +55,9 @@ async fn fetch_nodeinfo_links(host: &str) -> Result<NodeinfoLinks, Error> {
|
||||||
Ok(serde_json::from_str(&wellknown_response.text().await?)?)
|
Ok(serde_json::from_str(&wellknown_response.text().await?)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if any of the following relations is present in the given [NodeinfoLinks].
|
||||||
|
/// * <http://nodeinfo.diaspora.software/ns/schema/2.0>
|
||||||
|
/// * <http://nodeinfo.diaspora.software/ns/schema/2.1>
|
||||||
fn check_nodeinfo_link(links: NodeinfoLinks) -> Result<String, Error> {
|
fn check_nodeinfo_link(links: NodeinfoLinks) -> Result<String, Error> {
|
||||||
for link in links.links {
|
for link in links.links {
|
||||||
if link.rel == "http://nodeinfo.diaspora.software/ns/schema/2.1"
|
if link.rel == "http://nodeinfo.diaspora.software/ns/schema/2.1"
|
||||||
|
@ -66,6 +70,7 @@ fn check_nodeinfo_link(links: NodeinfoLinks) -> Result<String, Error> {
|
||||||
Err(Error::MissingNodeinfo)
|
Err(Error::MissingNodeinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetches the nodeinfo from the given URL and parses the result.
|
||||||
async fn fetch_nodeinfo_impl(nodeinfo_link: &str) -> Result<Nodeinfo20, Error> {
|
async fn fetch_nodeinfo_impl(nodeinfo_link: &str) -> Result<Nodeinfo20, Error> {
|
||||||
let client = http_client::client()?;
|
let client = http_client::client()?;
|
||||||
let mut response = client.get_async(nodeinfo_link).await?;
|
let mut response = client.get_async(nodeinfo_link).await?;
|
||||||
|
@ -85,7 +90,7 @@ async fn fetch_nodeinfo_impl(nodeinfo_link: &str) -> Result<Nodeinfo20, Error> {
|
||||||
// for napi export
|
// for napi export
|
||||||
type Nodeinfo = Nodeinfo20;
|
type Nodeinfo = Nodeinfo20;
|
||||||
|
|
||||||
/// Fetches and returns the NodeInfo of a remote server.
|
/// Fetches and returns the NodeInfo (version 2.0) of a remote server.
|
||||||
#[crate::export]
|
#[crate::export]
|
||||||
pub async fn fetch_nodeinfo(host: &str) -> Result<Nodeinfo, Error> {
|
pub async fn fetch_nodeinfo(host: &str) -> Result<Nodeinfo, Error> {
|
||||||
tracing::info!("fetching from {}", host);
|
tracing::info!("fetching from {}", host);
|
||||||
|
|
|
@ -9,6 +9,7 @@ use sea_orm::{ColumnTrait, DbErr, EntityTrait, PaginatorTrait, QueryFilter};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
/// Errors that can occur while generating NodeInfo of the local server
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("Database error: {0}")]
|
#[error("Database error: {0}")]
|
||||||
|
@ -19,6 +20,14 @@ pub enum Error {
|
||||||
Json(#[from] serde_json::Error),
|
Json(#[from] serde_json::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetches the number of total/active local users and local posts.
|
||||||
|
///
|
||||||
|
/// # Return value
|
||||||
|
/// A tuple containing the following information in this order:
|
||||||
|
/// * the total number of local users
|
||||||
|
/// * the total number of local users active in the last 6 months
|
||||||
|
/// * the total number of local users active in the last month (MAU)
|
||||||
|
/// * the total number of posts from local users
|
||||||
async fn statistics() -> Result<(u64, u64, u64, u64), DbErr> {
|
async fn statistics() -> Result<(u64, u64, u64, u64), DbErr> {
|
||||||
let db = db_conn().await?;
|
let db = db_conn().await?;
|
||||||
|
|
||||||
|
@ -49,6 +58,8 @@ async fn statistics() -> Result<(u64, u64, u64, u64), DbErr> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates NodeInfo (version 2.1) of the local server.
|
||||||
|
/// This function doesn't use caches and returns the latest information.
|
||||||
async fn generate_nodeinfo_2_1() -> Result<Nodeinfo21, Error> {
|
async fn generate_nodeinfo_2_1() -> Result<Nodeinfo21, Error> {
|
||||||
let (local_users, local_active_halfyear, local_active_month, local_posts) =
|
let (local_users, local_active_halfyear, local_active_month, local_posts) =
|
||||||
statistics().await?;
|
statistics().await?;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
//! NodeInfo handler
|
//! NodeInfo handler
|
||||||
|
//!
|
||||||
|
//! ref: <https://nodeinfo.diaspora.software/>
|
||||||
|
|
||||||
pub mod fetch;
|
pub mod fetch;
|
||||||
pub mod generate;
|
pub mod generate;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
//! Schema definitions of NodeInfo version 2.0 and 2.1
|
//! Schema definitions of NodeInfo version 2.0 and 2.1
|
||||||
|
//!
|
||||||
|
//! ref: <https://nodeinfo.diaspora.software/schema.html>
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
Loading…
Reference in a new issue