forked from mirrors/relay
Do a bit of reorganizing
This commit is contained in:
parent
f44df38ea1
commit
9925e41673
14 changed files with 123 additions and 110 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::{error::MyError, requests::Requests, verifier::MyVerify};
|
||||
use crate::{error::MyError, middleware::MyVerify, requests::Requests};
|
||||
use config::Environment;
|
||||
use http_signature_normalization_actix::prelude::{VerifyDigest, VerifySignature};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
|
69
src/main.rs
69
src/main.rs
|
@ -1,77 +1,29 @@
|
|||
use actix::Arbiter;
|
||||
use actix_web::{
|
||||
http::header::{ContentType, Expires},
|
||||
middleware::Logger,
|
||||
web, App, HttpResponse, HttpServer,
|
||||
};
|
||||
use log::error;
|
||||
use std::{
|
||||
io::BufWriter,
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
use actix_web::{middleware::Logger, web, App, HttpServer};
|
||||
|
||||
mod actor;
|
||||
mod apub;
|
||||
mod args;
|
||||
mod config;
|
||||
mod db;
|
||||
mod error;
|
||||
mod inbox;
|
||||
mod jobs;
|
||||
mod middleware;
|
||||
mod node;
|
||||
mod nodeinfo;
|
||||
mod notify;
|
||||
mod rehydrate;
|
||||
mod requests;
|
||||
mod responses;
|
||||
mod routes;
|
||||
mod state;
|
||||
mod verifier;
|
||||
mod webfinger;
|
||||
|
||||
use self::{
|
||||
args::Args,
|
||||
config::Config,
|
||||
db::Db,
|
||||
error::MyError,
|
||||
jobs::{create_server, create_workers},
|
||||
middleware::RelayResolver,
|
||||
routes::{actor, inbox, index, nodeinfo, nodeinfo_meta, statics},
|
||||
state::State,
|
||||
templates::statics::StaticFile,
|
||||
webfinger::RelayResolver,
|
||||
};
|
||||
|
||||
async fn index(
|
||||
state: web::Data<State>,
|
||||
config: web::Data<Config>,
|
||||
) -> Result<HttpResponse, MyError> {
|
||||
let nodes = state.node_cache().nodes().await;
|
||||
|
||||
let mut buf = BufWriter::new(Vec::new());
|
||||
|
||||
templates::index(&mut buf, &nodes, &config)?;
|
||||
let buf = buf.into_inner().map_err(|e| {
|
||||
error!("Error rendering template, {}", e.error());
|
||||
MyError::FlushBuffer
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Ok().content_type("text/html").body(buf))
|
||||
}
|
||||
|
||||
static FAR: Duration = Duration::from_secs(60 * 60 * 24);
|
||||
|
||||
async fn static_file(filename: web::Path<String>) -> HttpResponse {
|
||||
if let Some(data) = StaticFile::get(&filename.into_inner()) {
|
||||
let far_expires = SystemTime::now() + FAR;
|
||||
HttpResponse::Ok()
|
||||
.set(Expires(far_expires.into()))
|
||||
.set(ContentType(data.mime.clone()))
|
||||
.body(data.content)
|
||||
} else {
|
||||
HttpResponse::NotFound()
|
||||
.reason("No such static file.")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> Result<(), anyhow::Error> {
|
||||
dotenv::dotenv().ok();
|
||||
|
@ -114,7 +66,6 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
let state = State::hydrate(config.clone(), &db).await?;
|
||||
let job_server = create_server(db.clone());
|
||||
|
||||
rehydrate::spawn(db.clone(), state.clone());
|
||||
notify::spawn(state.clone(), job_server.clone(), &config)?;
|
||||
|
||||
if args.jobs_only() {
|
||||
|
@ -150,16 +101,16 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
web::resource("/inbox")
|
||||
.wrap(config.digest_middleware())
|
||||
.wrap(config.signature_middleware(state.requests()))
|
||||
.route(web::post().to(inbox::inbox)),
|
||||
.route(web::post().to(inbox)),
|
||||
)
|
||||
.service(web::resource("/actor").route(web::get().to(actor::route)))
|
||||
.service(web::resource("/nodeinfo/2.0.json").route(web::get().to(nodeinfo::route)))
|
||||
.service(web::resource("/actor").route(web::get().to(actor)))
|
||||
.service(web::resource("/nodeinfo/2.0.json").route(web::get().to(nodeinfo)))
|
||||
.service(
|
||||
web::scope("/.well-known")
|
||||
.service(actix_webfinger::scoped::<_, RelayResolver>())
|
||||
.service(web::resource("/nodeinfo").route(web::get().to(nodeinfo::well_known))),
|
||||
.service(web::resource("/nodeinfo").route(web::get().to(nodeinfo_meta))),
|
||||
)
|
||||
.service(web::resource("/static/{filename}").route(web::get().to(static_file)))
|
||||
.service(web::resource("/static/{filename}").route(web::get().to(statics)))
|
||||
})
|
||||
.bind(bind_address)?
|
||||
.run()
|
||||
|
|
5
src/middleware/mod.rs
Normal file
5
src/middleware/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod verifier;
|
||||
mod webfinger;
|
||||
|
||||
pub use verifier::MyVerify;
|
||||
pub use webfinger::RelayResolver;
|
|
@ -1,24 +0,0 @@
|
|||
use crate::{db::Db, state::State};
|
||||
use actix::{
|
||||
clock::{interval_at, Duration, Instant},
|
||||
Arbiter,
|
||||
};
|
||||
use log::error;
|
||||
|
||||
pub fn spawn(db: Db, state: State) {
|
||||
Arbiter::spawn(async move {
|
||||
let start = Instant::now();
|
||||
let duration = Duration::from_secs(60 * 10);
|
||||
|
||||
let mut interval = interval_at(start, duration);
|
||||
|
||||
loop {
|
||||
interval.tick().await;
|
||||
|
||||
match state.rehydrate(&db).await {
|
||||
Err(e) => error!("Error rehydrating, {}", e),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
use actix_web::HttpResponse;
|
||||
use serde::ser::Serialize;
|
||||
|
||||
static CONTENT_TYPE: &str = "application/activity+json";
|
||||
|
||||
pub fn ok<T>(item: T) -> HttpResponse
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
HttpResponse::Ok().content_type(CONTENT_TYPE).json(item)
|
||||
}
|
||||
|
||||
pub fn accepted<T>(item: T) -> HttpResponse
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
HttpResponse::Accepted()
|
||||
.content_type(CONTENT_TYPE)
|
||||
.json(item)
|
||||
}
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
apub::PublicKey,
|
||||
config::{Config, UrlKind},
|
||||
error::MyError,
|
||||
responses::ok,
|
||||
routes::ok,
|
||||
state::State,
|
||||
};
|
||||
use activitystreams::{
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
jobs::JobServer,
|
||||
jobs::{Deliver, DeliverMany},
|
||||
requests::Requests,
|
||||
responses::accepted,
|
||||
routes::accepted,
|
||||
state::State,
|
||||
};
|
||||
use activitystreams::{
|
||||
|
@ -22,7 +22,7 @@ use http_signature_normalization_actix::prelude::{DigestVerified, SignatureVerif
|
|||
use log::error;
|
||||
use std::convert::TryInto;
|
||||
|
||||
pub async fn inbox(
|
||||
pub async fn route(
|
||||
db: web::Data<Db>,
|
||||
state: web::Data<State>,
|
||||
config: web::Data<Config>,
|
21
src/routes/index.rs
Normal file
21
src/routes/index.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use crate::{config::Config, error::MyError, state::State};
|
||||
use actix_web::{web, HttpResponse};
|
||||
use log::error;
|
||||
use std::io::BufWriter;
|
||||
|
||||
pub async fn route(
|
||||
state: web::Data<State>,
|
||||
config: web::Data<Config>,
|
||||
) -> Result<HttpResponse, MyError> {
|
||||
let nodes = state.node_cache().nodes().await;
|
||||
|
||||
let mut buf = BufWriter::new(Vec::new());
|
||||
|
||||
crate::templates::index(&mut buf, &nodes, &config)?;
|
||||
let buf = buf.into_inner().map_err(|e| {
|
||||
error!("Error rendering template, {}", e.error());
|
||||
MyError::FlushBuffer
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Ok().content_type("text/html").body(buf))
|
||||
}
|
34
src/routes/mod.rs
Normal file
34
src/routes/mod.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
mod actor;
|
||||
mod inbox;
|
||||
mod index;
|
||||
mod nodeinfo;
|
||||
mod statics;
|
||||
|
||||
pub use self::{
|
||||
actor::route as actor,
|
||||
inbox::route as inbox,
|
||||
index::route as index,
|
||||
nodeinfo::{route as nodeinfo, well_known as nodeinfo_meta},
|
||||
statics::route as statics,
|
||||
};
|
||||
|
||||
use actix_web::HttpResponse;
|
||||
use serde::ser::Serialize;
|
||||
|
||||
static CONTENT_TYPE: &str = "application/activity+json";
|
||||
|
||||
fn ok<T>(item: T) -> HttpResponse
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
HttpResponse::Ok().content_type(CONTENT_TYPE).json(item)
|
||||
}
|
||||
|
||||
fn accepted<T>(item: T) -> HttpResponse
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
HttpResponse::Accepted()
|
||||
.content_type(CONTENT_TYPE)
|
||||
.json(item)
|
||||
}
|
22
src/routes/statics.rs
Normal file
22
src/routes/statics.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use crate::templates::statics::StaticFile;
|
||||
use actix_web::{
|
||||
http::header::{ContentType, Expires},
|
||||
web, HttpResponse,
|
||||
};
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
static FAR: Duration = Duration::from_secs(60 * 60 * 24);
|
||||
|
||||
pub async fn route(filename: web::Path<String>) -> HttpResponse {
|
||||
if let Some(data) = StaticFile::get(&filename.into_inner()) {
|
||||
let far_expires = SystemTime::now() + FAR;
|
||||
HttpResponse::Ok()
|
||||
.set(Expires(far_expires.into()))
|
||||
.set(ContentType(data.mime.clone()))
|
||||
.body(data.content)
|
||||
} else {
|
||||
HttpResponse::NotFound()
|
||||
.reason("No such static file.")
|
||||
.finish()
|
||||
}
|
||||
}
|
30
src/state.rs
30
src/state.rs
|
@ -7,9 +7,10 @@ use crate::{
|
|||
requests::Requests,
|
||||
};
|
||||
use activitystreams::primitives::XsdAnyUri;
|
||||
use actix::clock::{interval_at, Duration, Instant};
|
||||
use actix_web::web;
|
||||
use futures::{join, try_join};
|
||||
use log::info;
|
||||
use log::{error, info};
|
||||
use lru::LruCache;
|
||||
use rand::thread_rng;
|
||||
use rsa::{RSAPrivateKey, RSAPublicKey};
|
||||
|
@ -199,7 +200,7 @@ impl State {
|
|||
let public_key = private_key.to_public_key();
|
||||
let listeners = Arc::new(RwLock::new(listeners));
|
||||
|
||||
Ok(State {
|
||||
let state = State {
|
||||
public_key,
|
||||
private_key,
|
||||
config,
|
||||
|
@ -209,6 +210,29 @@ impl State {
|
|||
whitelists: Arc::new(RwLock::new(whitelists)),
|
||||
listeners: listeners.clone(),
|
||||
node_cache: NodeCache::new(listeners),
|
||||
})
|
||||
};
|
||||
|
||||
state.spawn_rehydrate(db.clone());
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
fn spawn_rehydrate(&self, db: Db) {
|
||||
let state = self.clone();
|
||||
actix::spawn(async move {
|
||||
let start = Instant::now();
|
||||
let duration = Duration::from_secs(60 * 10);
|
||||
|
||||
let mut interval = interval_at(start, duration);
|
||||
|
||||
loop {
|
||||
interval.tick().await;
|
||||
|
||||
match state.rehydrate(&db).await {
|
||||
Err(e) => error!("Error rehydrating, {}", e),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue