Link shortener in Rust.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.4 KiB

extern crate lazy_static;
extern crate serde_derive;
extern crate diesel;
extern crate diesel_migrations;
extern crate base64;
extern crate captcha;
extern crate url;
mod database;
mod db_schema;
mod handlers;
mod error_handlers;
mod init;
mod routes;
mod spam;
mod cache;
mod structs;
mod templates;
use actix_files as fs;
use actix_session::CookieSession;
use actix_web::{web, App, HttpServer, guard, HttpResponse};
use diesel::prelude::*;
use diesel::r2d2::{self, ConnectionManager};
use chrono::DateTime;
use chrono::Utc;
use crate::handlers::*;
use crate::error_handlers::*;
use crate::init::*;
use crate::database::Link;
use base64::decode as base64_decode;
use std::collections::HashMap;
use std::sync::Mutex;
type DbPool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
// see the watch_visits function for more details on the watcher
type SuspiciousWatcher = Mutex<HashMap<String, Vec<(DateTime<Utc>, String)>>>;
// Failsafe preventing 500 Internal Server Errors because of db locks
type LinkCache = Mutex<Vec<Link>>;
async fn main() -> std::io::Result<()> {
println!("rs-short, starting.");
println!("Opening database {}", CONFIG.general.database_path);
// connecting the sqlite database
let manager = ConnectionManager::<SqliteConnection>::new(&CONFIG.general.database_path);
let pool = r2d2::Pool::builder()
.expect("Failed to create pool.");
let conn = pool.get().expect("ERROR: main: DB connection failed");
println!("Running migrations");
embedded_migrations::run(&*conn).expect("Failed to run database migrations");
// for verbose_suspicious option
let suspicious_watch = web::Data::new(Mutex::new(HashMap::<
Vec<(DateTime<Utc>, String)>,
let link_cache = web::Data::new(Mutex::new(Vec::<Link>::new()));
// check configuration version
// and panic if it doesn't match CONFIG_VERSION
// starting the http server
println!("Server listening at {}", CONFIG.general.listening_address);
HttpServer::new(move || {
.expect("Couldn't read the specified cookie_key"),
.service(fs::Files::new("/assets", "./assets"))
// 404 for GET request
// all requests that are not `GET`