Update to latest actix-web
This commit is contained in:
parent
f739f6729b
commit
58b4eb3681
10
Cargo.toml
10
Cargo.toml
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "actix-webfinger"
|
name = "actix-webfinger"
|
||||||
description = "Types and helpers to create and fetch Webfinger resources"
|
description = "Types and helpers to create and fetch Webfinger resources"
|
||||||
version = "0.1.0"
|
version = "0.2.0-beta.1"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["asonix <asonix@asonix.dog>"]
|
authors = ["asonix <asonix@asonix.dog>"]
|
||||||
repository = "https://git.asonix.dog/asonix/actix-webfinger"
|
repository = "https://git.asonix.dog/asonix/actix-webfinger"
|
||||||
|
@ -9,14 +9,16 @@ readme = "README.md"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix = "0.7"
|
actix-http = "0.1.5"
|
||||||
actix-web = "0.7"
|
actix-service = "0.3.0"
|
||||||
|
actix-web = "1.0.0-beta.3"
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-web = { version = "0.7", features = ["ssl"] }
|
actix = "0.8"
|
||||||
|
actix-web = { version = "1.0.0-beta.3", features = ["ssl"] }
|
||||||
openssl = "0.10"
|
openssl = "0.10"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
use actix::{Actor, System};
|
use actix::System;
|
||||||
use actix_web::client::ClientConnector;
|
use actix_web::client::Connector;
|
||||||
use actix_webfinger::Webfinger;
|
use actix_webfinger::Webfinger;
|
||||||
use futures::Future;
|
use futures::{future::lazy, Future};
|
||||||
use openssl::ssl::{SslConnector, SslMethod};
|
use openssl::ssl::{SslConnector, SslMethod};
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let sys = System::new("sir-boops");
|
let sys = System::new("sir-boops");
|
||||||
|
|
||||||
let ssl_conn = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
let ssl_conn = SslConnector::builder(SslMethod::tls())?.build();
|
||||||
let conn = ClientConnector::with_connector(ssl_conn).start();
|
let conn = Connector::new().ssl(ssl_conn).finish();
|
||||||
|
|
||||||
let fut = Webfinger::fetch(conn, "asonix@asonix.dog", "localhost:8000", false)
|
let fut = lazy(move || {
|
||||||
.map(move |w: Webfinger| {
|
Webfinger::fetch(conn, "asonix@asonix.dog", "localhost:8000", false)
|
||||||
println!("asonix's webfinger:\n{:#?}", w);
|
.map(move |w: Webfinger| {
|
||||||
|
println!("asonix's webfinger:\n{:#?}", w);
|
||||||
|
|
||||||
System::current().stop();
|
System::current().stop();
|
||||||
})
|
})
|
||||||
.map_err(|e| eprintln!("Error: {}", e));
|
.map_err(|e| eprintln!("Error: {}", e))
|
||||||
|
});
|
||||||
|
|
||||||
actix::spawn(fut);
|
actix::spawn(fut);
|
||||||
|
|
||||||
let _ = sys.run();
|
sys.run()?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use actix_web::server;
|
use actix_web::{web::Data, App, HttpServer};
|
||||||
use actix_webfinger::{Resolver, Webfinger};
|
use actix_webfinger::{Resolver, Webfinger};
|
||||||
use futures::{future::IntoFuture, Future};
|
use futures::{future::IntoFuture, Future};
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MyState {
|
pub struct MyState {
|
||||||
|
@ -9,13 +10,13 @@ pub struct MyState {
|
||||||
|
|
||||||
pub struct MyResolver;
|
pub struct MyResolver;
|
||||||
|
|
||||||
impl Resolver<MyState> for MyResolver {
|
impl Resolver<Data<MyState>> for MyResolver {
|
||||||
type Error = actix_web::error::JsonPayloadError;
|
type Error = actix_web::error::JsonPayloadError;
|
||||||
|
|
||||||
fn find(
|
fn find(
|
||||||
account: &str,
|
account: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
state: &MyState,
|
state: &Data<MyState>,
|
||||||
) -> Box<dyn Future<Item = Option<Webfinger>, Error = Self::Error>> {
|
) -> Box<dyn Future<Item = Option<Webfinger>, Error = Self::Error>> {
|
||||||
let w = if domain == state.domain {
|
let w = if domain == state.domain {
|
||||||
Some(Webfinger::new(&format!("{}@{}", account, domain)))
|
Some(Webfinger::new(&format!("{}@{}", account, domain)))
|
||||||
|
@ -27,13 +28,16 @@ impl Resolver<MyState> for MyResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
server::new(|| {
|
HttpServer::new(|| {
|
||||||
actix_webfinger::app::<MyState, MyResolver>(MyState {
|
App::new()
|
||||||
domain: "asonix.dog".to_owned(),
|
.data(MyState {
|
||||||
})
|
domain: "asonix.dog".to_owned(),
|
||||||
|
})
|
||||||
|
.service(actix_webfinger::resource::<_, MyResolver>())
|
||||||
})
|
})
|
||||||
.bind("127.0.0.1:8000")
|
.bind("127.0.0.1:8000")?
|
||||||
.unwrap()
|
.run()?;
|
||||||
.run();
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
238
src/lib.rs
238
src/lib.rs
|
@ -9,106 +9,117 @@
|
||||||
//!
|
//!
|
||||||
//! ```toml
|
//! ```toml
|
||||||
//! [dependencies]
|
//! [dependencies]
|
||||||
//! actix = "0.7"
|
//! actix = "0.8"
|
||||||
//! actix-web = "0.7"
|
//! actix-web = "1.0.0-beta.3"
|
||||||
//! actix-webfinger = "0.1"
|
//! actix-webfinger = "0.2.0-beta.1"
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! Then use it in your application
|
//! Then use it in your application
|
||||||
//!
|
//!
|
||||||
//! #### Client Example
|
//! #### Client Example
|
||||||
//! ```rust,ignore
|
//! ```rust,ignore
|
||||||
//! use actix::{Actor, System};
|
//! use actix::System;
|
||||||
//! use actix_web::client::ClientConnector;
|
//! use actix_web::client::Connector;
|
||||||
//! use actix_webfinger::Webfinger;
|
//! use actix_webfinger::Webfinger;
|
||||||
//! use futures::Future;
|
//! use futures::{future::lazy, Future};
|
||||||
//! use openssl::ssl::{SslConnector, SslMethod};
|
//! use openssl::ssl::{SslConnector, SslMethod};
|
||||||
//!
|
//! use std::error::Error;
|
||||||
//! fn main() {
|
//!
|
||||||
|
//! fn main() -> Result<(), Box<dyn Error>> {
|
||||||
//! let sys = System::new("asonix");
|
//! let sys = System::new("asonix");
|
||||||
//!
|
//!
|
||||||
//! let ssl_conn = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
//! let ssl_conn = SslConnector::builder(SslMethod::tls())?.build();
|
||||||
//! let conn = ClientConnector::with_connector(ssl_conn).start();
|
//! let conn = Connector::new().ssl(ssl_conn).finish();
|
||||||
//!
|
//!
|
||||||
//! let fut = Webfinger::fetch(conn, "asonix@asonix.dog", "localhost:8000", false)
|
//! let fut = lazy(move || {
|
||||||
//! .map(move |w: Webfinger| {
|
//! Webfinger::fetch(conn, "asonix@asonix.dog", "localhost:8000", false)
|
||||||
//! println!("asonix's webfinger:\n{:#?}", w);
|
//! .map(move |w: Webfinger| {
|
||||||
//!
|
//! println!("asonix's webfinger:\n{:#?}", w);
|
||||||
//! System::current().stop();
|
//!
|
||||||
//! })
|
//! System::current().stop();
|
||||||
//! .map_err(|e| eprintln!("Error: {}", e));
|
//! })
|
||||||
//!
|
//! .map_err(|e| eprintln!("Error: {}", e))
|
||||||
|
//! });
|
||||||
|
//!
|
||||||
//! actix::spawn(fut);
|
//! actix::spawn(fut);
|
||||||
//!
|
//!
|
||||||
//! let _ = sys.run();
|
//! sys.run()?;
|
||||||
|
//! Ok(())
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! #### Server Example
|
//! #### Server Example
|
||||||
//! ```rust,ignore
|
//! ```rust,ignore
|
||||||
//! use actix_web::server;
|
//! use actix_web::{web::Data, App, HttpServer};
|
||||||
//! use actix_webfinger::{Resolver, Webfinger};
|
//! use actix_webfinger::{Resolver, Webfinger};
|
||||||
//! use futures::{future::IntoFuture, Future};
|
//! use futures::{future::IntoFuture, Future};
|
||||||
//!
|
//! use std::error::Error;
|
||||||
|
//!
|
||||||
//! #[derive(Clone, Debug)]
|
//! #[derive(Clone, Debug)]
|
||||||
//! pub struct MyState {
|
//! pub struct MyState {
|
||||||
//! domain: String,
|
//! domain: String,
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! pub struct MyResolver;
|
//! pub struct MyResolver;
|
||||||
//!
|
//!
|
||||||
//! impl Resolver<MyState> for MyResolver {
|
//! impl Resolver<Data<MyState>> for MyResolver {
|
||||||
//! type Error = actix_web::error::JsonPayloadError;
|
//! type Error = actix_web::error::JsonPayloadError;
|
||||||
//!
|
//!
|
||||||
//! fn find(
|
//! fn find(
|
||||||
//! account: &str,
|
//! account: &str,
|
||||||
//! domain: &str,
|
//! domain: &str,
|
||||||
//! state: &MyState,
|
//! state: &Data<MyState>,
|
||||||
//! ) -> Box<dyn Future<Item = Option<Webfinger>, Error = Self::Error>> {
|
//! ) -> Box<dyn Future<Item = Option<Webfinger>, Error = Self::Error>> {
|
||||||
//! let w = if domain == state.domain {
|
//! let w = if domain == state.domain {
|
||||||
//! Some(Webfinger::new(&format!("{}@{}", account, domain)))
|
//! Some(Webfinger::new(&format!("{}@{}", account, domain)))
|
||||||
//! } else {
|
//! } else {
|
||||||
//! None
|
//! None
|
||||||
//! };
|
//! };
|
||||||
//!
|
//!
|
||||||
//! Box::new(Ok(w).into_future())
|
//! Box::new(Ok(w).into_future())
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! fn main() {
|
//! fn main() -> Result<(), Box<dyn Error>> {
|
||||||
//! server::new(|| {
|
//! HttpServer::new(|| {
|
||||||
//! actix_webfinger::app::<MyState, MyResolver>(MyState {
|
//! App::new()
|
||||||
//! domain: "asonix.dog".to_owned(),
|
//! .data(MyState {
|
||||||
//! })
|
//! domain: "asonix.dog".to_owned(),
|
||||||
|
//! })
|
||||||
|
//! .service(actix_webfinger::resource::<_, MyResolver>())
|
||||||
//! })
|
//! })
|
||||||
//! .bind("127.0.0.1:8000")
|
//! .bind("127.0.0.1:8000")?
|
||||||
//! .unwrap()
|
//! .run()?;
|
||||||
//! .run();
|
//!
|
||||||
|
//! Ok(())
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ### Contributing
|
//! ### Contributing
|
||||||
//! Feel free to open issues for anything you find an issue with. Please note that any contributed code will be licensed under the GPLv3.
|
//! Feel free to open issues for anything you find an issue with. Please note that any contributed code will be licensed under the GPLv3.
|
||||||
//!
|
//!
|
||||||
//! ### License
|
//! ### License
|
||||||
//!
|
//!
|
||||||
//! Copyright © 2019 Riley Trautman
|
//! Copyright © 2019 Riley Trautman
|
||||||
//!
|
//!
|
||||||
//! Actix Webfinger is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
//! Actix Webfinger is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
//!
|
//!
|
||||||
//! Actix Webfinger is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. This file is part of Tokio ZMQ.
|
//! Actix Webfinger is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. This file is part of Tokio ZMQ.
|
||||||
//!
|
//!
|
||||||
//! You should have received a copy of the GNU General Public License along with Actix Webfinger. If not, see [http://www.gnu.org/licenses/](http://www.gnu.org/licenses/).
|
//! You should have received a copy of the GNU General Public License along with Actix Webfinger. If not, see [http://www.gnu.org/licenses/](http://www.gnu.org/licenses/).
|
||||||
use actix::Addr;
|
use actix_http::client::{Connect, ConnectError, Connection};
|
||||||
|
use actix_service::Service;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
client::{self, ClientConnector},
|
client::Client,
|
||||||
|
dev::RequestHead,
|
||||||
error::ResponseError,
|
error::ResponseError,
|
||||||
|
guard::Guard,
|
||||||
http::Method,
|
http::Method,
|
||||||
pred::Predicate,
|
web::{get, Query},
|
||||||
App, HttpMessage, HttpResponse, Query, Request, State,
|
FromRequest, HttpResponse, Resource,
|
||||||
};
|
};
|
||||||
use failure::Fail;
|
use failure::Fail;
|
||||||
use futures::{future::IntoFuture, Future};
|
use futures::Future;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A predicate for Actix Web route filters
|
/// A predicate for Actix Web route filters
|
||||||
|
@ -124,21 +135,21 @@ use serde_derive::{Deserialize, Serialize};
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// use actix_web::App;
|
/// use actix_web::App;
|
||||||
/// use actix_webfinger::WebfingerPredicate;
|
/// use actix_webfinger::WebfingerGuard;
|
||||||
///
|
///
|
||||||
/// let app = App::new()
|
/// let app = App::new()
|
||||||
/// .resource("/.well-known/webfinger", |r| {
|
/// .resource("/.well-known/webfinger", |r| {
|
||||||
/// r.route()
|
/// r.route()
|
||||||
/// .filter(WebfingerPredicate)
|
/// .filter(WebfingerGuard)
|
||||||
/// .with(your_route_handler)
|
/// .with(your_route_handler)
|
||||||
/// })
|
/// })
|
||||||
/// .finish();
|
/// .finish();
|
||||||
/// ```
|
/// ```
|
||||||
pub struct WebfingerPredicate;
|
pub struct WebfingerGuard;
|
||||||
|
|
||||||
impl<S> Predicate<S> for WebfingerPredicate {
|
impl Guard for WebfingerGuard {
|
||||||
fn check(&self, req: &Request, _: &S) -> bool {
|
fn check(&self, request: &RequestHead) -> bool {
|
||||||
if let Some(val) = req.headers().get("Accept") {
|
if let Some(val) = request.headers().get("Accept") {
|
||||||
if let Ok(s) = val.to_str() {
|
if let Ok(s) = val.to_str() {
|
||||||
return s.split(",").any(|v| {
|
return s.split(",").any(|v| {
|
||||||
let v = if let Some(index) = v.find(';') {
|
let v = if let Some(index) = v.find(';') {
|
||||||
|
@ -152,7 +163,7 @@ impl<S> Predicate<S> for WebfingerPredicate {
|
||||||
|| trimmed == "application/json"
|
|| trimmed == "application/json"
|
||||||
|| trimmed == "application/*"
|
|| trimmed == "application/*"
|
||||||
|| trimmed == "*/*"
|
|| trimmed == "*/*"
|
||||||
}) && req.method() == Method::GET;
|
}) && request.method == Method::GET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,26 +171,53 @@ impl<S> Predicate<S> for WebfingerPredicate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A simple way to mount the webfinger app to your Actix Web application
|
/// A simple way to mount the webfinger service to your Actix Web application
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// use actix_web::server;
|
/// use actix_web::HttpServer;
|
||||||
/// use actix_webfinger::app;
|
|
||||||
///
|
///
|
||||||
/// server::new(|| {
|
/// HttpServer::new(|| {
|
||||||
/// app::<_, MyResolver>(my_state)
|
/// App::new()
|
||||||
|
/// .service(actix_webfinger::resource::<_, MyResolver>())
|
||||||
/// })
|
/// })
|
||||||
/// .bind("127.0.0.1:8000")?
|
/// .bind("127.0.0.1:8000")?
|
||||||
/// .run();
|
/// .start();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn app<S, R>(state: S) -> App<S>
|
pub fn resource<S, R>() -> Resource
|
||||||
where
|
where
|
||||||
R: Resolver<S> + 'static,
|
R: Resolver<S> + 'static,
|
||||||
S: 'static,
|
S: FromRequest + 'static,
|
||||||
{
|
{
|
||||||
App::with_state(state).resource("/.well-known/webfinger", |r| {
|
actix_web::web::resource("/.well-known/webfinger")
|
||||||
r.route().filter(WebfingerPredicate).with(R::endpoint)
|
.guard(WebfingerGuard)
|
||||||
})
|
.route(get().to(R::endpoint))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A simple way to mount the webfinger service inside the /.well-known scope
|
||||||
|
///
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// use actix_web::{App, HttpServer, web::scope};
|
||||||
|
/// use actix_webfinger::resource;
|
||||||
|
///
|
||||||
|
/// HttpServer::new(|| {
|
||||||
|
/// App::new()
|
||||||
|
/// .data(())
|
||||||
|
/// .service(
|
||||||
|
/// scope("/")
|
||||||
|
/// .service(resource::<(), MyResolver>())
|
||||||
|
/// )
|
||||||
|
/// })
|
||||||
|
/// .bind("127.0.0.1:8000")
|
||||||
|
/// .start();
|
||||||
|
/// ```
|
||||||
|
pub fn scoped<S, R>() -> Resource
|
||||||
|
where
|
||||||
|
R: Resolver<S> + 'static,
|
||||||
|
S: FromRequest + 'static,
|
||||||
|
{
|
||||||
|
actix_web::web::resource("/webfinger")
|
||||||
|
.guard(WebfingerGuard)
|
||||||
|
.route(get().to(R::endpoint))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The error created if the webfinger resource query is malformed
|
/// The error created if the webfinger resource query is malformed
|
||||||
|
@ -290,7 +328,10 @@ pub struct WebfingerQuery {
|
||||||
///
|
///
|
||||||
/// struct MyResolver;
|
/// struct MyResolver;
|
||||||
///
|
///
|
||||||
/// impl<S> Resolver<S> for MyResolver {
|
/// impl<S> Resolver<S> for MyResolver
|
||||||
|
/// where
|
||||||
|
/// S: FromRequest,
|
||||||
|
/// {
|
||||||
/// type Error = CustomError;
|
/// type Error = CustomError;
|
||||||
///
|
///
|
||||||
/// fn find(
|
/// fn find(
|
||||||
|
@ -308,19 +349,27 @@ pub struct WebfingerQuery {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
/// server::new(|| {
|
/// let sys = System::new("asonix");
|
||||||
|
///
|
||||||
|
/// HttpServer::new(|| {
|
||||||
/// App::new()
|
/// App::new()
|
||||||
/// .resource("/.well-known/webfinger", |r| {
|
/// .data(())
|
||||||
/// r.with(<MyResolver as Resolver<()>>::endpoint)
|
/// .service(resource::<Data<()>, MyResolver>())
|
||||||
/// })
|
|
||||||
/// })
|
/// })
|
||||||
/// .bind("127.0.0.1:8000")?
|
/// .bind("127.0.0.1:8000")?
|
||||||
/// .run();
|
/// .start();
|
||||||
|
///
|
||||||
|
/// sys.run()?;
|
||||||
|
///
|
||||||
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub trait Resolver<S> {
|
pub trait Resolver<S>
|
||||||
type Error: ResponseError;
|
where
|
||||||
|
S: FromRequest,
|
||||||
|
{
|
||||||
|
type Error: ResponseError + 'static;
|
||||||
|
|
||||||
fn find(
|
fn find(
|
||||||
account: &str,
|
account: &str,
|
||||||
|
@ -329,7 +378,7 @@ pub trait Resolver<S> {
|
||||||
) -> Box<dyn Future<Item = Option<Webfinger>, Error = Self::Error>>;
|
) -> Box<dyn Future<Item = Option<Webfinger>, Error = Self::Error>>;
|
||||||
|
|
||||||
fn endpoint(
|
fn endpoint(
|
||||||
(query, state): (Query<WebfingerQuery>, State<S>),
|
(query, state): (Query<WebfingerQuery>, S),
|
||||||
) -> Box<dyn Future<Item = HttpResponse, Error = Self::Error>> {
|
) -> Box<dyn Future<Item = HttpResponse, Error = Self::Error>> {
|
||||||
let WebfingerResource { account, domain } = query.into_inner().resource;
|
let WebfingerResource { account, domain } = query.into_inner().resource;
|
||||||
|
|
||||||
|
@ -547,14 +596,19 @@ impl Webfinger {
|
||||||
|
|
||||||
/// Fetch a webfinger with subject `user` from a given `domain`
|
/// Fetch a webfinger with subject `user` from a given `domain`
|
||||||
///
|
///
|
||||||
/// This method takes an `Addr<ClientConnector>` so derivative works can provide their own SSL
|
/// This method takes an `Service` so derivative works can provide their own SSL
|
||||||
/// connector implemenation (currently with OpenSSL or Rustls)
|
/// connector implemenation (currently with OpenSSL or Rustls)
|
||||||
pub fn fetch(
|
pub fn fetch<T>(
|
||||||
conn: Addr<ClientConnector>,
|
conn: T,
|
||||||
user: &str,
|
user: &str,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
https: bool,
|
https: bool,
|
||||||
) -> Box<dyn Future<Item = Self, Error = actix_web::Error>> {
|
) -> Box<dyn Future<Item = Self, Error = FetchError>>
|
||||||
|
where
|
||||||
|
T: Service<Request = Connect, Error = ConnectError> + Clone + 'static,
|
||||||
|
<T as Service>::Response: Connection,
|
||||||
|
<T as Service>::Future: 'static,
|
||||||
|
{
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}://{}/.well-known/webfinger?resource=acct:{}",
|
"{}://{}/.well-known/webfinger?resource=acct:{}",
|
||||||
if https { "https" } else { "http" },
|
if https { "https" } else { "http" },
|
||||||
|
@ -562,21 +616,27 @@ impl Webfinger {
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
let fut = client::get(url)
|
let fut = Client::build()
|
||||||
.with_connector(conn)
|
.connector(conn)
|
||||||
.header("Accept", "application/jrd+json")
|
.header("Accept", "application/jrd+json")
|
||||||
.finish()
|
.finish()
|
||||||
.into_future()
|
.get(url)
|
||||||
.and_then(|r| {
|
.send()
|
||||||
r.send()
|
.map_err(|_| FetchError::Send)
|
||||||
.from_err()
|
.and_then(|mut res| res.json::<Webfinger>().map_err(|_| FetchError::Parse));
|
||||||
.and_then(|res| res.json::<Webfinger>().from_err())
|
|
||||||
});
|
|
||||||
|
|
||||||
Box::new(fut)
|
Box::new(fut)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Fail)]
|
||||||
|
pub enum FetchError {
|
||||||
|
#[fail(display = "Failed to send request")]
|
||||||
|
Send,
|
||||||
|
#[fail(display = "Failed to parse response JSON")]
|
||||||
|
Parse,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{Webfinger, WebfingerQuery};
|
use crate::{Webfinger, WebfingerQuery};
|
||||||
|
|
Loading…
Reference in a new issue