fedimovies/src/main.rs

170 lines
7 KiB
Rust
Raw Normal View History

2021-04-09 00:22:17 +00:00
use actix_cors::Cors;
use actix_web::{
2023-04-24 15:35:32 +00:00
dev::Service, http::Method, middleware::Logger as ActixLogger, web, App, HttpResponse,
HttpServer,
2021-04-09 00:22:17 +00:00
};
use tokio::sync::Mutex;
2021-04-09 00:22:17 +00:00
2023-04-25 13:49:35 +00:00
use fedimovies::activitypub::views as activitypub;
use fedimovies::atom::views::atom_scope;
use fedimovies::http::{
2023-04-24 15:35:32 +00:00
create_auth_error_handler, create_default_headers_middleware, json_error_handler,
};
2023-04-25 13:49:35 +00:00
use fedimovies::job_queue::scheduler;
use fedimovies::logger::configure_logger;
use fedimovies::mastodon_api::accounts::views::account_api_scope;
use fedimovies::mastodon_api::apps::views::application_api_scope;
use fedimovies::mastodon_api::custom_emojis::views::custom_emoji_api_scope;
use fedimovies::mastodon_api::directory::views::directory_api_scope;
use fedimovies::mastodon_api::instance::views::instance_api_scope;
use fedimovies::mastodon_api::markers::views::marker_api_scope;
use fedimovies::mastodon_api::media::views::media_api_scope;
use fedimovies::mastodon_api::notifications::views::notification_api_scope;
use fedimovies::mastodon_api::oauth::views::oauth_api_scope;
use fedimovies::mastodon_api::search::views::search_api_scope;
use fedimovies::mastodon_api::settings::views::settings_api_scope;
use fedimovies::mastodon_api::statuses::views::status_api_scope;
use fedimovies::mastodon_api::subscriptions::views::subscription_api_scope;
use fedimovies::mastodon_api::timelines::views::timeline_api_scope;
use fedimovies::nodeinfo::views as nodeinfo;
use fedimovies::web_client::views as web_client;
use fedimovies::webfinger::views as webfinger;
use fedimovies_config::{parse_config, Environment, REEF_VERSION};
use fedimovies_models::database::migrate::apply_migrations;
use fedimovies_models::database::{create_pool, get_database_client};
2021-04-09 00:22:17 +00:00
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let (config, config_warnings) = parse_config();
configure_logger(config.log_level);
log::info!("config loaded from {}", config.config_path);
for warning in config_warnings {
log::warn!("{}", warning);
2023-04-24 15:35:32 +00:00
}
2022-06-14 10:29:14 +00:00
// https://wiki.postgresql.org/wiki/Number_Of_Database_Connections
let db_pool_size = num_cpus::get() * 2;
let db_pool = create_pool(
&config.database_url,
2023-04-27 22:01:24 +00:00
config.tls_ca_file.as_deref(),
db_pool_size,
);
let mut db_client = get_database_client(&db_pool).await.unwrap();
2022-11-06 21:20:14 +00:00
apply_migrations(&mut db_client).await;
if !config.media_dir().exists() {
2023-04-24 15:35:32 +00:00
std::fs::create_dir(config.media_dir()).expect("failed to create media directory");
};
std::mem::drop(db_client);
log::info!(
"app initialized; version {}, environment = '{:?}'",
2023-04-08 23:34:07 +00:00
REEF_VERSION,
config.environment,
);
2023-04-08 19:20:12 +00:00
scheduler::run(config.clone(), db_pool.clone());
2021-04-09 00:22:17 +00:00
log::info!("scheduler started");
let num_workers = std::cmp::max(num_cpus::get(), 4);
2023-04-24 15:35:32 +00:00
let http_socket_addr = format!("{}:{}", config.http_host, config.http_port,);
// Mutex is used to make server process incoming activities sequentially
let inbox_mutex = web::Data::new(Mutex::new(()));
let http_server = HttpServer::new(move || {
2021-04-09 00:22:17 +00:00
let cors_config = match config.environment {
2023-04-24 15:35:32 +00:00
Environment::Development => Cors::permissive(),
2021-04-09 00:22:17 +00:00
Environment::Production => {
let mut cors_config = Cors::default();
for origin in config.http_cors_allowlist.iter() {
cors_config = cors_config.allowed_origin(origin);
2023-04-24 15:35:32 +00:00
}
cors_config
.allowed_origin(&config.instance_url())
2022-10-27 15:48:54 +00:00
.allowed_origin_fn(|origin, req_head| {
2023-04-24 15:35:32 +00:00
req_head.method == Method::GET
|| origin.as_bytes().starts_with(b"http://localhost:")
})
2021-04-09 00:22:17 +00:00
.allow_any_method()
.allow_any_header()
2022-08-18 18:05:18 +00:00
.expose_any_header()
2023-04-24 15:35:32 +00:00
}
2021-04-09 00:22:17 +00:00
};
2023-03-14 15:17:56 +00:00
let payload_size_limit = 2 * config.limits.media.file_size_limit;
let mut app = App::new()
2021-04-09 00:22:17 +00:00
.wrap(cors_config)
2022-06-02 20:00:56 +00:00
.wrap(ActixLogger::new("%r : %s : %{r}a"))
.wrap_fn(|req, srv| {
// Always log server errors (500-599)
let fut = srv.call(req);
async {
let res = fut.await?;
if let Some(error) = res.response().error() {
if error.as_response_error().status_code().is_server_error() {
log::warn!(
"{} {} : {}",
res.request().method(),
res.request().path(),
error,
);
};
};
Ok(res)
}
})
2021-10-01 00:35:52 +00:00
.wrap(create_auth_error_handler())
.wrap(create_default_headers_middleware())
2023-03-14 15:17:56 +00:00
.app_data(web::PayloadConfig::default().limit(payload_size_limit))
2023-04-24 15:35:32 +00:00
.app_data(
web::JsonConfig::default()
.limit(payload_size_limit)
.error_handler(json_error_handler),
)
2022-04-08 18:52:13 +00:00
.app_data(web::Data::new(config.clone()))
.app_data(web::Data::new(db_pool.clone()))
.app_data(web::Data::clone(&inbox_mutex))
2023-04-24 15:35:32 +00:00
.service(actix_files::Files::new("/media", config.media_dir()))
2021-10-01 00:35:52 +00:00
.service(oauth_api_scope())
2021-04-09 00:22:17 +00:00
.service(account_api_scope())
2023-02-10 23:29:42 +00:00
.service(application_api_scope())
2023-02-02 12:38:02 +00:00
.service(custom_emoji_api_scope())
2021-11-07 08:52:57 +00:00
.service(directory_api_scope())
.service(instance_api_scope())
.service(marker_api_scope())
2021-04-09 00:22:17 +00:00
.service(media_api_scope())
2021-10-12 16:11:47 +00:00
.service(notification_api_scope())
2021-11-07 08:52:57 +00:00
.service(search_api_scope())
.service(settings_api_scope())
.service(status_api_scope())
.service(subscription_api_scope())
2021-11-07 08:52:57 +00:00
.service(timeline_api_scope())
2023-01-12 21:38:36 +00:00
.service(webfinger::webfinger_view)
2021-11-18 00:51:56 +00:00
.service(activitypub::actor_scope())
.service(activitypub::instance_actor_scope())
2021-11-18 00:51:56 +00:00
.service(activitypub::object_view)
2023-01-21 00:23:15 +00:00
.service(activitypub::emoji_view)
.service(activitypub::tag_view)
.service(atom_scope())
2023-03-06 19:49:45 +00:00
.service(nodeinfo::get_nodeinfo_jrd)
.service(nodeinfo::get_nodeinfo_2_0)
2023-03-06 19:49:45 +00:00
.service(nodeinfo::get_nodeinfo_2_1)
.service(web_client::profile_page_redirect())
.service(web_client::profile_acct_page_redirect())
.service(web_client::post_page_redirect())
.service(
// Fallback for well-known paths
2023-04-24 15:35:32 +00:00
web::resource("/.well-known/{path}").to(HttpResponse::NotFound),
);
if let Some(ref web_client_dir) = config.web_client_dir {
app = app.service(web_client::static_service(web_client_dir));
};
app
});
log::info!("listening on {}", http_socket_addr);
http_server
.workers(num_workers)
.bind(http_socket_addr)?
.run()
.await
2021-04-09 00:22:17 +00:00
}