This repository has been archived on 2023-11-08. You can view files and clone it, but cannot push or open issues or pull requests.
fiddle/src/main.rs

127 lines
3.3 KiB
Rust

use actix_cors::Cors;
use actix_web::{http::header, middleware, web, App, HttpRequest, HttpResponse, HttpServer};
use anyhow::Result;
use diesel::prelude::*;
use std::fs;
use std::thread;
use std::time::Duration;
#[cfg(not(target_env = "msvc"))]
use tikv_jemallocator::Jemalloc;
use uuidv7::Uuid;
use juniper_actix::graphql_handler;
use fiddle::{api, db, init, prune_job, prune_many, CONFIG};
#[cfg(not(target_env = "msvc"))]
#[global_allocator]
static GLOBAL: Jemalloc = Jemalloc;
fn tamper_prune() -> Result<()> {
let db_conn = &mut db::POOL.get()?;
let entries = fs::read_dir(&CONFIG.data_dir)?;
let allowed: Vec<String> = db::schema::directories::table
.select(db::schema::directories::id)
.load::<Uuid>(db_conn)?
.iter()
.map(|id| id.to_string())
.collect();
let mut prunes: Vec<String> = vec![];
for p in entries {
let path = match p {
Ok(x) => x.path(),
Err(e) => {
log::error!("{:?}", e);
continue;
}
};
let relative = match path.strip_prefix(&CONFIG.data_dir) {
Ok(x) => x.to_string_lossy().to_string(),
Err(e) => {
log::error!("{:?}", e);
continue;
}
};
if path.is_file() || (path.is_dir() && !allowed.contains(&relative)) {
log::warn!("Invalid entry found: {}", relative);
prunes.push(relative);
}
}
prune_many(&prunes)?;
Ok(())
}
async fn not_found() -> &'static str {
"Not found!"
}
async fn graphql_route(
req: HttpRequest,
payload: web::Payload,
schema: web::Data<api::Schema>,
) -> Result<HttpResponse, actix_web::Error> {
let context = api::Context {
db_pool: db::POOL.clone(),
loaders: api::context::Loaders::default(),
};
graphql_handler(&schema, &context, req, payload).await
}
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();
init();
thread::spawn(move || {
let sleep_dur = Duration::from_secs(CONFIG.auto_prune_sleep);
loop {
prune_job();
thread::sleep(sleep_dur);
}
});
thread::spawn(move || {
let sleep_dur = Duration::from_secs(CONFIG.tamper_sleep);
loop {
if let Err(e) = tamper_prune() {
log::error!("{:?}", e);
}
thread::sleep(sleep_dur);
}
});
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(api::schema()))
.wrap(middleware::Logger::default())
.wrap(middleware::Compress::default())
.wrap(
Cors::default()
.allow_any_origin()
.allowed_methods(["POST", "GET"])
.allowed_headers([header::ACCEPT])
.allowed_header(header::CONTENT_TYPE)
.supports_credentials()
.max_age(3600),
)
.service(
web::resource("/graphql")
.route(web::post().to(graphql_route))
.route(web::get().to(graphql_route)),
)
.default_service(web::to(not_found))
})
.bind(("0.0.0.0", 80))?
.run()
.await?;
Ok(())
}