hostbasket/actix_mvc_app/src/main.rs

115 lines
3.6 KiB
Rust

use actix_files as fs;
use actix_web::{App, HttpServer, web};
use actix_web::middleware::Logger;
use tera::Tera;
use std::io;
use std::env;
use lazy_static::lazy_static;
mod config;
mod controllers;
mod middleware;
mod models;
mod routes;
mod utils;
// Import middleware components
use middleware::{RequestTimer, SecurityHeaders, JwtAuth};
use utils::redis_service;
use models::initialize_mock_data;
// Initialize lazy_static for in-memory storage
extern crate lazy_static;
// Create a consistent session key
lazy_static! {
pub static ref SESSION_KEY: actix_web::cookie::Key = {
// In production, this should be a proper secret key from environment variables
let secret = std::env::var("SESSION_SECRET").unwrap_or_else(|_| {
// Create a key that's at least 64 bytes long
"my_secret_session_key_that_is_at_least_64_bytes_long_for_security_reasons_1234567890abcdef".to_string()
});
// Ensure the key is at least 64 bytes
let mut key_bytes = secret.as_bytes().to_vec();
while key_bytes.len() < 64 {
key_bytes.extend_from_slice(b"0123456789abcdef");
}
actix_web::cookie::Key::from(&key_bytes[0..64])
};
}
#[actix_web::main]
async fn main() -> io::Result<()> {
// Initialize environment
dotenv::dotenv().ok();
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
// Load configuration
let config = config::get_config();
// Check for port override from command line arguments
let args: Vec<String> = env::args().collect();
let mut port = config.server.port;
for i in 1..args.len() {
if args[i] == "--port" && i + 1 < args.len() {
if let Ok(p) = args[i + 1].parse::<u16>() {
port = p;
break;
}
}
}
let bind_address = format!("{}:{}", config.server.host, port);
// Initialize Redis client
let redis_url = std::env::var("REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string());
if let Err(e) = redis_service::init_redis_client(&redis_url) {
log::error!("Failed to initialize Redis client: {}", e);
log::warn!("Calendar functionality will not work properly without Redis");
} else {
log::info!("Redis client initialized successfully");
}
// Initialize mock data for DeFi operations
initialize_mock_data();
log::info!("DeFi mock data initialized successfully");
log::info!("Starting server at http://{}", bind_address);
// Create and configure the HTTP server
HttpServer::new(move || {
// Initialize Tera templates
let mut tera = match Tera::new(&format!("{}/**/*.html", config.templates.dir)) {
Ok(t) => t,
Err(e) => {
log::error!("Parsing error(s): {}", e);
::std::process::exit(1);
}
};
// Register custom Tera functions
utils::register_tera_functions(&mut tera);
App::new()
// Enable logger middleware
.wrap(Logger::default())
// Add custom middleware
.wrap(RequestTimer)
.wrap(SecurityHeaders)
.wrap(JwtAuth)
// Configure static files
.service(fs::Files::new("/static", "./src/static"))
// Add Tera template engine
.app_data(web::Data::new(tera))
// Configure routes
.configure(routes::configure_routes)
})
.bind(bind_address)?
.workers(num_cpus::get())
.run()
.await
}