1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;
use actix::prelude::*;
use actix_web::middleware::{errhandlers::ErrorHandlers, Logger};
use actix_identity::{CookieIdentityPolicy, IdentityService};
use actix_web::{http, web, App, HttpServer};
use chrono::Duration;
use diesel::mysql::MysqlConnection;
use dotenv::dotenv;
use r2d2_diesel::ConnectionManager;
mod public;
mod error;
mod error_handlers;
mod schema;
mod model;
use crate::model::DbExecutor;
embed_migrations!();
pub struct Secret(String);
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
dotenv().ok();
std::env::set_var(
"RUST_LOG",
"rgit=debug,actix_web=trace,actix_server=debug",
);
env_logger::init();
let bind_host: String =
std::env::var("BIND_HOST").unwrap_or_else(|_| "127.0.0.1:8000".to_string());
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let manager = ConnectionManager::<MysqlConnection>::new(database_url);
let pool = r2d2::Pool::builder()
.build(manager)
.expect("Can to build connection pool");
embedded_migrations::run(&*pool.get().expect("Can connect to mysql"))
.expect("Can run migrations");
let db_addr: Addr<DbExecutor> = SyncArbiter::start(4, move || DbExecutor(pool.clone()));
HttpServer::new(move || {
let secret: String = std::env::var("SECRET_KEY").expect("SECRET_KEY env var should be set");
let domain: String = std::env::var("DOMAIN").unwrap_or_else(|_| "localhost".to_string());
let secure_cookies = &domain != "localhost";
let error_handlers = ErrorHandlers::new()
.handler(
http::StatusCode::INTERNAL_SERVER_ERROR,
error_handlers::internal_server_error,
)
.handler(http::StatusCode::BAD_REQUEST, error_handlers::bad_request)
.handler(http::StatusCode::NOT_FOUND, error_handlers::not_found);
App::new()
.data(db_addr.clone())
.data(Secret(secret.clone()))
.wrap(error_handlers)
.wrap(IdentityService::new(
CookieIdentityPolicy::new(secret.as_bytes())
.name("rgit-session")
.domain(domain.as_str())
.max_age_time(Duration::days(30))
.secure(secure_cookies), // this has to reflect the usage of https
))
.wrap(Logger::default())
.route("/", web::get().to(public::index))
.service(actix_files::Files::new("/static", "static/"))
})
.bind(&bind_host)?
.run()
.await?;
Ok(())
}
|