File size: 3,549 Bytes
cb1edad
 
 
c170de8
4402168
15fc415
dc3308c
4402168
137c62e
12bb0ee
 
 
 
 
bef8956
12bb0ee
51937a0
bef8956
4402168
12bb0ee
b170574
12bb0ee
 
137c62e
12bb0ee
 
 
 
 
 
 
 
 
137c62e
cb1edad
12bb0ee
4cb38b1
12bb0ee
e02fafd
12bb0ee
4a505fb
12bb0ee
137c62e
12bb0ee
 
fd6cb46
2945665
12bb0ee
dc3308c
12bb0ee
 
 
 
d8bd2fe
 
12bb0ee
bef8956
 
 
 
 
 
 
 
 
 
12bb0ee
51937a0
12bb0ee
137c62e
bef8956
51937a0
 
0132a63
 
51937a0
 
 
12bb0ee
2945665
dc3308c
2945665
 
 
dc3308c
2945665
 
12bb0ee
 
 
 
 
 
 
d8bd2fe
12bb0ee
 
 
 
 
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
96
97
98
99
100
101
//! This main library module provides the functionality to provide and handle the Tcp server
//! and register all the routes for the `websurfx` meta search engine website.

pub mod cache;
pub mod config;
pub mod engines;
pub mod handler;
pub mod results;
pub mod server;

use std::net::TcpListener;

use crate::server::routes;

use actix_cors::Cors;
use actix_files as fs;
use actix_governor::{Governor, GovernorConfigBuilder};
use actix_web::{dev::Server, http::header, middleware::Logger, web, App, HttpServer};
use config::parser::Config;
use handlebars::Handlebars;
use handler::paths::{file_path, FileType};

/// Runs the web server on the provided TCP listener and returns a `Server` instance.
///
/// # Arguments
///
/// * `listener` - A `TcpListener` instance representing the address and port to listen on.
///
/// # Returns
///
/// Returns a `Result` containing a `Server` instance on success, or an `std::io::Error` on failure.
///
/// # Example
///
/// ```rust
/// use std::net::TcpListener;
/// use websurfx::{config::parser::Config, run};
///
/// let config = Config::parse(true).unwrap();
/// let listener = TcpListener::bind("127.0.0.1:8080").expect("Failed to bind address");
/// let server = run(listener,config).expect("Failed to start server");
/// ```
pub fn run(listener: TcpListener, config: Config) -> std::io::Result<Server> {
    let mut handlebars: Handlebars = Handlebars::new();

    let public_folder_path: &str = file_path(FileType::Theme)?;

    handlebars
        .register_templates_directory(".html", format!("{}/templates", public_folder_path))
        .unwrap();

    let handlebars_ref: web::Data<Handlebars> = web::Data::new(handlebars);

    let cloned_config_threads_opt: u8 = config.threads;

    let server = HttpServer::new(move || {
        let cors: Cors = Cors::default()
            .allow_any_origin()
            .allowed_methods(vec!["GET"])
            .allowed_headers(vec![
                header::ORIGIN,
                header::CONTENT_TYPE,
                header::REFERER,
                header::COOKIE,
            ]);

        App::new()
            .wrap(Logger::default()) // added logging middleware for logging.
            .app_data(handlebars_ref.clone())
            .app_data(web::Data::new(config.clone()))
            .wrap(cors)
            .wrap(Governor::new(
                &GovernorConfigBuilder::default()
                    .per_second(config.rate_limiter.time_limit as u64)
                    .burst_size(config.rate_limiter.number_of_requests as u32)
                    .finish()
                    .unwrap(),
            ))
            // Serve images and static files (css and js files).
            .service(
                fs::Files::new("/static", format!("{}/static", public_folder_path))
                    .show_files_listing(),
            )
            .service(
                fs::Files::new("/images", format!("{}/images", public_folder_path))
                    .show_files_listing(),
            )
            .service(routes::robots_data) // robots.txt
            .service(routes::index) // index page
            .service(routes::search) // search page
            .service(routes::about) // about page
            .service(routes::settings) // settings page
            .default_service(web::route().to(routes::not_found)) // error page
    })
    .workers(cloned_config_threads_opt as usize)
    // Start server on 127.0.0.1 with the user provided port number. for example 127.0.0.1:8080.
    .listen(listener)?
    .run();
    Ok(server)
}