2020-03-17 17:15:16 +00:00
|
|
|
use crate::{
|
|
|
|
apub::AcceptedActors,
|
|
|
|
error::MyError,
|
|
|
|
state::{State, UrlKind},
|
|
|
|
};
|
|
|
|
use activitystreams::primitives::XsdAnyUri;
|
|
|
|
use actix_web::{client::Client, web};
|
|
|
|
use log::error;
|
|
|
|
|
|
|
|
pub async fn fetch_actor(
|
|
|
|
state: std::sync::Arc<State>,
|
|
|
|
client: std::sync::Arc<Client>,
|
|
|
|
actor_id: &XsdAnyUri,
|
|
|
|
) -> Result<AcceptedActors, MyError> {
|
2020-03-17 21:36:53 +00:00
|
|
|
use http_signature_normalization_actix::prelude::*;
|
|
|
|
|
2020-03-17 17:15:16 +00:00
|
|
|
if let Some(actor) = state.get_actor(actor_id).await {
|
|
|
|
return Ok(actor);
|
|
|
|
}
|
|
|
|
|
2020-03-17 21:36:53 +00:00
|
|
|
let key_id = state.generate_url(UrlKind::MainKey);
|
|
|
|
|
2020-03-17 21:53:31 +00:00
|
|
|
let mut res = client
|
2020-03-17 17:15:16 +00:00
|
|
|
.get(actor_id.as_str())
|
|
|
|
.header("Accept", "application/activity+json")
|
2020-03-18 00:02:33 +00:00
|
|
|
.signature(
|
|
|
|
&Config::default().dont_use_created_field(),
|
|
|
|
key_id,
|
|
|
|
|signing_string| state.sign(signing_string),
|
|
|
|
)?
|
2020-03-17 17:15:16 +00:00
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
.map_err(|e| {
|
|
|
|
error!("Couldn't send request to {} for actor, {}", actor_id, e);
|
|
|
|
MyError::SendRequest
|
|
|
|
})?;
|
|
|
|
|
2020-03-17 21:53:31 +00:00
|
|
|
if !res.status().is_success() {
|
|
|
|
error!("Invalid status code for actor fetch, {}", res.status());
|
|
|
|
if let Ok(bytes) = res.body().await {
|
|
|
|
if let Ok(s) = String::from_utf8(bytes.as_ref().to_vec()) {
|
|
|
|
error!("Response, {}", s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Err(MyError::Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
let actor: AcceptedActors = res.json().await.map_err(|e| {
|
|
|
|
error!("Coudn't fetch actor from {}, {}", actor_id, e);
|
|
|
|
MyError::ReceiveResponse
|
|
|
|
})?;
|
|
|
|
|
2020-03-17 17:15:16 +00:00
|
|
|
state.cache_actor(actor_id.to_owned(), actor.clone()).await;
|
|
|
|
|
|
|
|
Ok(actor)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn deliver_many<T>(
|
2020-03-18 02:16:09 +00:00
|
|
|
state: &web::Data<State>,
|
|
|
|
client: &web::Data<Client>,
|
2020-03-17 17:15:16 +00:00
|
|
|
inboxes: Vec<XsdAnyUri>,
|
|
|
|
item: T,
|
|
|
|
) where
|
|
|
|
T: serde::ser::Serialize + 'static,
|
|
|
|
{
|
2020-03-18 02:16:09 +00:00
|
|
|
let client = client.clone().into_inner();
|
|
|
|
let state = state.clone().into_inner();
|
2020-03-17 17:15:16 +00:00
|
|
|
|
|
|
|
actix::Arbiter::spawn(async move {
|
|
|
|
use futures::stream::StreamExt;
|
|
|
|
|
|
|
|
let mut unordered = futures::stream::FuturesUnordered::new();
|
|
|
|
|
|
|
|
for inbox in inboxes {
|
|
|
|
unordered.push(deliver(&state, &client, inbox, &item));
|
|
|
|
}
|
|
|
|
|
|
|
|
while let Some(_) = unordered.next().await {}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn deliver<T>(
|
|
|
|
state: &std::sync::Arc<State>,
|
|
|
|
client: &std::sync::Arc<Client>,
|
|
|
|
inbox: XsdAnyUri,
|
|
|
|
item: &T,
|
|
|
|
) -> Result<(), MyError>
|
|
|
|
where
|
|
|
|
T: serde::ser::Serialize,
|
|
|
|
{
|
|
|
|
use http_signature_normalization_actix::prelude::*;
|
|
|
|
use sha2::{Digest, Sha256};
|
|
|
|
|
|
|
|
let mut digest = Sha256::new();
|
|
|
|
|
2020-03-17 21:36:53 +00:00
|
|
|
let key_id = state.generate_url(UrlKind::MainKey);
|
2020-03-17 17:15:16 +00:00
|
|
|
|
|
|
|
let item_string = serde_json::to_string(item)?;
|
|
|
|
|
2020-03-17 21:53:31 +00:00
|
|
|
let mut res = client
|
2020-03-17 17:15:16 +00:00
|
|
|
.post(inbox.as_str())
|
|
|
|
.header("Accept", "application/activity+json")
|
|
|
|
.header("Content-Type", "application/activity+json")
|
|
|
|
.header("User-Agent", "Aode Relay v0.1.0")
|
|
|
|
.signature_with_digest(
|
2020-03-18 00:02:33 +00:00
|
|
|
&Config::default().dont_use_created_field(),
|
2020-03-17 17:15:16 +00:00
|
|
|
&key_id,
|
|
|
|
&mut digest,
|
|
|
|
item_string,
|
|
|
|
|signing_string| state.sign(signing_string),
|
|
|
|
)?
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
.map_err(|e| {
|
|
|
|
error!("Couldn't send deliver request to {}, {}", inbox, e);
|
|
|
|
MyError::SendRequest
|
|
|
|
})?;
|
|
|
|
|
|
|
|
if !res.status().is_success() {
|
|
|
|
error!("Invalid response status from {}, {}", inbox, res.status());
|
2020-03-17 21:53:31 +00:00
|
|
|
if let Ok(bytes) = res.body().await {
|
|
|
|
if let Ok(s) = String::from_utf8(bytes.as_ref().to_vec()) {
|
|
|
|
error!("Response, {}", s);
|
|
|
|
}
|
|
|
|
}
|
2020-03-17 17:15:16 +00:00
|
|
|
return Err(MyError::Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|