    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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95

    /*
     * Copyright (C) 2021  Aravinth Manivannan <realaravinth@batsense.net>
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU Affero General Public License as
     * published by the Free Software Foundation, either version 3 of the
     * License, or (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Affero General Public License for more details.
     *
     * You should have received a copy of the GNU Affero General Public License
     * along with this program.  If not, see <https://www.gnu.org/licenses/>.
     */
    use std::env;

    use actix_web::{
        error::InternalError, http::StatusCode, middleware as actix_middleware, web::JsonConfig, App,
        HttpServer,
    };
    use lazy_static::lazy_static;
    use log::info;

    mod data;
    mod meta;
    mod post;
    mod proxy;
    mod render_html;
    mod routes;
    mod settings;

    pub use data::AppData;
    pub use data::Data;
    pub use routes::ROUTES as V1_API_ROUTES;
    pub use settings::Settings;

    lazy_static! {
        pub static ref SETTINGS: Settings = Settings::new().unwrap();
    }

    pub const CACHE_AGE: u32 = 604800;

    pub const GIT_COMMIT_HASH: &str = env!("GIT_HASH");
    pub const VERSION: &str = env!("CARGO_PKG_VERSION");
    pub const PKG_NAME: &str = env!("CARGO_PKG_NAME");
    pub const PKG_DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
    pub const PKG_HOMEPAGE: &str = env!("CARGO_PKG_HOMEPAGE");

    #[cfg(not(tarpaulin_include))]
    #[actix_web::main]
    async fn main() -> std::io::Result<()> {
        env::set_var("RUST_LOG", "info");

        pretty_env_logger::init();

        info!(
            "{}: {}.\nFor more information, see: {}\nBuild info:\nVersion: {} commit: {}",
            PKG_NAME, PKG_DESCRIPTION, PKG_HOMEPAGE, VERSION, GIT_COMMIT_HASH
        );

        println!("Starting server on: http://{}", SETTINGS.server.get_ip());

        let data = Data::new();

        HttpServer::new(move || {
            App::new()
                .wrap(actix_middleware::Logger::default())
                .wrap(actix_middleware::Compress::default())
                .app_data(get_json_err())
                .wrap(
                    actix_middleware::DefaultHeaders::new()
                        .add(("Permissions-Policy", "interest-cohort=()")),
                )
                .wrap(actix_middleware::NormalizePath::new(
                    actix_middleware::TrailingSlash::Trim,
                ))
                .app_data(data.clone())
                .configure(routes::services)
        })
        .workers(SETTINGS.server.workers.unwrap_or_else(num_cpus::get))
        .bind(SETTINGS.server.get_ip())
        .unwrap()
        .run()
        .await
    }

    #[cfg(not(tarpaulin_include))]
    pub fn get_json_err() -> JsonConfig {
        JsonConfig::default().error_handler(|err, _| {
            //debug!("JSON deserialization error: {:?}", &err);
            InternalError::new(err, StatusCode::BAD_REQUEST).into()
        })
    }