Files
quoter/src/main.rs

91 lines
3.3 KiB
Rust
Raw Normal View History

2024-08-31 03:32:37 +03:00
mod app_state;
mod auth;
mod handlers;
2025-08-02 00:18:09 +03:00
mod lookup;
2024-08-31 03:32:37 +03:00
mod s3_utils;
mod security;
2024-08-31 03:32:37 +03:00
mod thumbnail;
2024-04-08 10:17:14 +03:00
2025-06-02 22:20:37 +03:00
use actix_cors::Cors;
2025-08-02 00:18:09 +03:00
use actix_web::{
2025-09-01 22:58:03 +03:00
App, HttpServer,
http::header,
middleware::{Logger, DefaultHeaders},
2025-09-01 22:58:03 +03:00
web,
2025-08-02 00:18:09 +03:00
};
2024-08-31 03:32:37 +03:00
use app_state::AppState;
use security::{SecurityConfig, security_middleware};
2025-08-12 14:13:35 +03:00
use handlers::universal_handler;
use log::{warn, info};
2024-10-02 18:56:52 +03:00
use std::env;
2025-08-02 00:18:09 +03:00
use tokio::task::spawn_blocking;
2023-09-28 02:08:48 +03:00
#[actix_web::main]
async fn main() -> std::io::Result<()> {
2024-10-02 18:56:52 +03:00
env_logger::init();
2024-10-23 16:21:18 +03:00
warn!("Started");
2024-08-30 22:11:21 +03:00
2024-10-22 13:18:57 +03:00
let port = env::var("PORT").unwrap_or_else(|_| "8080".to_string());
let addr = format!("0.0.0.0:{}", port);
let app_state = AppState::new().await;
2024-08-30 23:27:01 +03:00
let app_state_clone = app_state.clone();
2024-09-23 18:16:47 +03:00
2024-09-23 16:32:54 +03:00
// Используем spawn_blocking для работы, которая не совместима с Send
spawn_blocking(move || {
let rt = tokio::runtime::Handle::current();
rt.block_on(async move {
2024-10-22 19:34:08 +03:00
app_state_clone.cache_filelist().await;
2024-09-23 16:32:54 +03:00
});
2024-08-30 23:27:01 +03:00
});
// Конфигурация безопасности
let security_config = SecurityConfig::default();
info!("Security config: max_payload={} MB, upload_rate_limit={}/{}s",
security_config.max_payload_size / (1024 * 1024),
security_config.upload_rate_limit.max_requests,
security_config.upload_rate_limit.window_seconds);
2023-09-28 02:08:48 +03:00
HttpServer::new(move || {
// Настройка CORS middleware - ограничиваем в продакшене
2025-06-02 22:20:37 +03:00
let cors = Cors::default()
.allowed_origin("https://discours.io")
.allowed_origin("https://new.discours.io")
.allowed_origin("https://testing.discours.io")
.allowed_origin("https://testing3.discours.io")
.allowed_origin("http://localhost:3000") // для разработки
.allowed_methods(vec!["GET", "POST", "OPTIONS"])
2025-06-02 22:20:37 +03:00
.allowed_headers(vec![
header::CONTENT_TYPE,
header::AUTHORIZATION,
header::IF_NONE_MATCH,
header::CACHE_CONTROL,
2025-06-02 22:20:37 +03:00
])
.expose_headers(vec![header::CONTENT_LENGTH, header::ETAG])
2025-06-02 22:20:37 +03:00
.supports_credentials()
.max_age(86400); // 1 день вместо 20
// Заголовки безопасности
let security_headers = DefaultHeaders::new()
.add(("X-Content-Type-Options", "nosniff"))
.add(("X-Frame-Options", "DENY"))
.add(("X-XSS-Protection", "1; mode=block"))
.add(("Referrer-Policy", "strict-origin-when-cross-origin"))
.add(("Content-Security-Policy", "default-src 'self'; img-src 'self' data: https:; object-src 'none';"))
.add(("Strict-Transport-Security", "max-age=31536000; includeSubDomains"));
2025-06-02 22:20:37 +03:00
2023-09-28 02:08:48 +03:00
App::new()
2024-08-30 22:11:21 +03:00
.app_data(web::Data::new(app_state.clone()))
.app_data(web::PayloadConfig::new(security_config.max_payload_size))
.app_data(web::JsonConfig::default().limit(1024 * 1024)) // 1MB для JSON
.wrap(actix_web::middleware::from_fn(security_middleware))
.wrap(security_headers)
2025-06-02 22:20:37 +03:00
.wrap(cors)
2023-10-11 23:03:12 +03:00
.wrap(Logger::default())
.default_service(web::to(universal_handler))
2023-09-28 02:08:48 +03:00
})
2024-10-02 18:56:52 +03:00
.bind(addr)?
2023-09-28 02:08:48 +03:00
.run()
.await
2024-09-23 18:16:47 +03:00
}