diff --git a/examples/resolver.rs b/examples/resolver.rs index 5814d20..da58b65 100644 --- a/examples/resolver.rs +++ b/examples/resolver.rs @@ -1,5 +1,5 @@ use actix_web::{server, App}; -use actix_webfinger::{Resolver, Webfinger}; +use actix_webfinger::{Resolver, Webfinger, WebfingerPredicate}; use futures::{future::IntoFuture, Future}; #[derive(Clone, Debug)] @@ -33,7 +33,9 @@ fn main() { domain: "asonix.dog".to_owned(), }) .resource("/.well-known/webfinger", |r| { - r.with(>::endpoint) + r.route() + .filter(WebfingerPredicate) + .with(>::endpoint) }) }) .bind("127.0.0.1:8000") diff --git a/src/lib.rs b/src/lib.rs index f3b11f7..6ed6a0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,12 +2,40 @@ use actix::Addr; use actix_web::{ client::{self, ClientConnector}, error::ResponseError, - HttpMessage, HttpResponse, Query, State, + http::Method, + pred::Predicate, + HttpMessage, HttpResponse, Query, Request, State, }; use failure::Fail; use futures::{future::IntoFuture, Future}; use serde_derive::{Deserialize, Serialize}; +pub struct WebfingerPredicate; + +impl Predicate for WebfingerPredicate { + fn check(&self, req: &Request, _: &S) -> bool { + if let Some(val) = req.headers().get("Accept") { + if let Ok(s) = val.to_str() { + return s.split(",").any(|v| { + let v = if let Some(index) = v.find(';') { + v.split_at(index).0 + } else { + v + }; + let trimmed = v.trim(); + + trimmed == "application/jrd+json" + || trimmed == "application/json" + || trimmed == "application/*" + || trimmed == "*/*" + }) && req.method() == Method::GET; + } + } + + false + } +} + #[derive(Clone, Debug, Fail)] #[fail(display = "Resource {} is invalid", _0)] pub struct InvalidResource(String); @@ -239,17 +267,14 @@ impl Webfinger { ) -> Box> { let url = format!( "{}://{}/.well-known/webfinger?resource=acct:{}", - if https { - "https" - } else { - "http" - }, - domain, user + if https { "https" } else { "http" }, + domain, + user ); let fut = client::get(url) .with_connector(conn) - .header("Accept", "application/json") + .header("Accept", "application/jrd+json") .finish() .into_future() .and_then(|r| {