Support arbitrary schemes
This commit is contained in:
parent
b42225d3e5
commit
9f214fbbff
|
@ -5,7 +5,14 @@ use std::error::Error;
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> Result<(), Box<dyn Error>> {
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let client = Client::default();
|
let client = Client::default();
|
||||||
let wf = Webfinger::fetch(&client, "asonix@localhost:8000", "localhost:8000", false).await?;
|
let wf = Webfinger::fetch(
|
||||||
|
&client,
|
||||||
|
Some("acct:"),
|
||||||
|
"asonix@localhost:8000",
|
||||||
|
"localhost:8000",
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
println!("asonix's webfinger:\n{:#?}", wf);
|
println!("asonix's webfinger:\n{:#?}", wf);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -14,11 +14,12 @@ impl Resolver for MyResolver {
|
||||||
type Error = actix_web::error::JsonPayloadError;
|
type Error = actix_web::error::JsonPayloadError;
|
||||||
|
|
||||||
fn find(
|
fn find(
|
||||||
|
scheme: Option<&str>,
|
||||||
account: &str,
|
account: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
state: Data<MyState>,
|
state: Data<MyState>,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Option<Webfinger>, Self::Error>>>> {
|
) -> Pin<Box<dyn Future<Output = Result<Option<Webfinger>, Self::Error>>>> {
|
||||||
let w = if domain == state.domain {
|
let w = if scheme == Some("acct:") && domain == state.domain {
|
||||||
Some(Webfinger::new(&format!("{}@{}", account, domain)))
|
Some(Webfinger::new(&format!("{}@{}", account, domain)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
30
src/lib.rs
30
src/lib.rs
|
@ -29,7 +29,7 @@
|
||||||
//! #[actix_rt::main]
|
//! #[actix_rt::main]
|
||||||
//! async fn main() -> Result<(), Box<dyn Error>> {
|
//! async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
//! let client = Client::default();
|
//! let client = Client::default();
|
||||||
//! let wf = Webfinger::fetch(&client, "asonix@asonix.dog", "localhost:8000", false).await?;
|
//! let wf = Webfinger::fetch(&client, None, "asonix@asonix.dog", "localhost:8000", false).await?;
|
||||||
//!
|
//!
|
||||||
//! println!("asonix's webfinger:\n{:#?}", wf);
|
//! println!("asonix's webfinger:\n{:#?}", wf);
|
||||||
//! Ok(())
|
//! Ok(())
|
||||||
|
@ -249,6 +249,7 @@ pub struct InvalidResource(String);
|
||||||
/// formatting before the request reaches the route handler.
|
/// formatting before the request reaches the route handler.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct WebfingerResource {
|
pub struct WebfingerResource {
|
||||||
|
pub scheme: Option<String>,
|
||||||
pub account: String,
|
pub account: String,
|
||||||
pub domain: String,
|
pub domain: String,
|
||||||
}
|
}
|
||||||
|
@ -257,12 +258,24 @@ impl std::str::FromStr for WebfingerResource {
|
||||||
type Err = InvalidResource;
|
type Err = InvalidResource;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let trimmed = s.trim_start_matches("acct:").trim_start_matches('@');
|
let (scheme, trimmed) = s
|
||||||
|
.find(':')
|
||||||
|
.map(|index| {
|
||||||
|
let (scheme, trimmed) = s.split_at(index);
|
||||||
|
(
|
||||||
|
Some(scheme.to_owned() + ":"),
|
||||||
|
trimmed.trim_start_matches(':'),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap_or((None, s));
|
||||||
|
|
||||||
|
let trimmed = trimmed.trim_start_matches('@');
|
||||||
|
|
||||||
if let Some(index) = trimmed.find('@') {
|
if let Some(index) = trimmed.find('@') {
|
||||||
let (account, domain) = trimmed.split_at(index);
|
let (account, domain) = trimmed.split_at(index);
|
||||||
|
|
||||||
Ok(WebfingerResource {
|
Ok(WebfingerResource {
|
||||||
|
scheme,
|
||||||
account: account.to_owned(),
|
account: account.to_owned(),
|
||||||
domain: domain.trim_start_matches('@').to_owned(),
|
domain: domain.trim_start_matches('@').to_owned(),
|
||||||
})
|
})
|
||||||
|
@ -353,6 +366,7 @@ pub trait Resolver {
|
||||||
type Error: ResponseError + 'static;
|
type Error: ResponseError + 'static;
|
||||||
|
|
||||||
fn find(
|
fn find(
|
||||||
|
scheme: Option<&str>,
|
||||||
account: &str,
|
account: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
state: Self::State,
|
state: Self::State,
|
||||||
|
@ -366,10 +380,14 @@ pub fn endpoint<R>(
|
||||||
where
|
where
|
||||||
R: Resolver,
|
R: Resolver,
|
||||||
{
|
{
|
||||||
let WebfingerResource { account, domain } = query.into_inner().resource;
|
let WebfingerResource {
|
||||||
|
scheme,
|
||||||
|
account,
|
||||||
|
domain,
|
||||||
|
} = query.into_inner().resource;
|
||||||
|
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
match R::find(&account, &domain, state).await? {
|
match R::find(scheme.as_deref(), &account, &domain, state).await? {
|
||||||
Some(w) => Ok(w.respond()),
|
Some(w) => Ok(w.respond()),
|
||||||
None => Ok(HttpResponse::NotFound().finish()),
|
None => Ok(HttpResponse::NotFound().finish()),
|
||||||
}
|
}
|
||||||
|
@ -611,14 +629,16 @@ impl Webfinger {
|
||||||
/// rather this library generating it's own http clients.
|
/// rather this library generating it's own http clients.
|
||||||
pub async fn fetch(
|
pub async fn fetch(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
|
scheme: Option<&str>,
|
||||||
user: &str,
|
user: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
https: bool,
|
https: bool,
|
||||||
) -> Result<Self, FetchError> {
|
) -> Result<Self, FetchError> {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}://{}/.well-known/webfinger?resource=acct:{}",
|
"{}://{}/.well-known/webfinger?resource={}{}",
|
||||||
if https { "https" } else { "http" },
|
if https { "https" } else { "http" },
|
||||||
domain,
|
domain,
|
||||||
|
scheme.unwrap_or("acct:"),
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue