neon_arch commited on
Commit
9d3a8e0
2 Parent(s): cad5307 c4a2d87

Merge branch 'rolling' into patch-csrf-security-with-cors

Browse files
src/bin/websurfx.rs CHANGED
@@ -4,7 +4,6 @@
4
  //! stdout and handles the command line arguments provided and launches the `websurfx` server.
5
 
6
  use std::net::TcpListener;
7
-
8
  use websurfx::{config::parser::Config, run};
9
 
10
  /// The function that launches the main server and registers all the routes of the website.
@@ -16,15 +15,18 @@ use websurfx::{config::parser::Config, run};
16
  #[actix_web::main]
17
  async fn main() -> std::io::Result<()> {
18
  // Initialize the parsed config file.
19
- let config = Config::parse().unwrap();
20
-
21
- // Initializing logging middleware with level set to default or info.
22
- if config.logging || config.debug {
23
- use env_logger::Env;
24
- env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
25
- }
26
 
27
- log::info!("started server on port {}", config.port);
 
 
 
 
 
 
 
 
 
28
 
29
  let listener = TcpListener::bind((config.binding_ip.clone(), config.port))?;
30
 
 
4
  //! stdout and handles the command line arguments provided and launches the `websurfx` server.
5
 
6
  use std::net::TcpListener;
 
7
  use websurfx::{config::parser::Config, run};
8
 
9
  /// The function that launches the main server and registers all the routes of the website.
 
15
  #[actix_web::main]
16
  async fn main() -> std::io::Result<()> {
17
  // Initialize the parsed config file.
18
+ let config = Config::parse(true).unwrap();
 
 
 
 
 
 
19
 
20
+ log::info!(
21
+ "started server on port {} and IP {}",
22
+ config.port,
23
+ config.binding_ip
24
+ );
25
+ log::info!(
26
+ "Open http://{}:{}/ in your browser",
27
+ config.port,
28
+ config.binding_ip
29
+ );
30
 
31
  let listener = TcpListener::bind((config.binding_ip.clone(), config.port))?;
32
 
src/config/parser.rs CHANGED
@@ -2,8 +2,9 @@
2
  //! into rust readable form.
3
 
4
  use super::parser_models::Style;
 
5
  use rlua::Lua;
6
- use std::{collections::HashMap, format, fs, path::Path};
7
 
8
  // ------- Constants --------
9
  static COMMON_DIRECTORY_NAME: &str = "websurfx";
@@ -23,6 +24,7 @@ static CONFIG_FILE_NAME: &str = "config.lua";
23
  /// * `debug` - It stores the option to whether enable or disable debug mode.
24
  /// * `upstream_search_engines` - It stores all the engine names that were enabled by the user.
25
  /// * `request_timeout` - It stores the time (secs) which controls the server request timeout.
 
26
  #[derive(Clone)]
27
  pub struct Config {
28
  pub port: u16,
@@ -34,6 +36,7 @@ pub struct Config {
34
  pub debug: bool,
35
  pub upstream_search_engines: Vec<String>,
36
  pub request_timeout: u8,
 
37
  }
38
 
39
  /// Configuration options for the aggregator.
@@ -51,12 +54,17 @@ impl Config {
51
  /// A function which parses the config.lua file and puts all the parsed options in the newly
52
  /// constructed Config struct and returns it.
53
  ///
 
 
 
 
 
54
  /// # Error
55
  ///
56
  /// Returns a lua parse error if parsing of the config.lua file fails or has a syntax error
57
  /// or io error if the config.lua file doesn't exists otherwise it returns a newly constructed
58
  /// Config struct with all the parsed config options from the parsed config file.
59
- pub fn parse() -> Result<Self, Box<dyn std::error::Error>> {
60
  Lua::new().context(|context| -> Result<Self, Box<dyn std::error::Error>> {
61
  let globals = context.globals();
62
 
@@ -64,6 +72,38 @@ impl Config {
64
  .load(&fs::read_to_string(Config::config_path()?)?)
65
  .exec()?;
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  Ok(Config {
68
  port: globals.get::<_, u16>("port")?,
69
  binding_ip: globals.get::<_, String>("binding_ip")?,
@@ -75,14 +115,15 @@ impl Config {
75
  aggregator: AggregatorConfig {
76
  random_delay: globals.get::<_, bool>("production_use")?,
77
  },
78
- logging: globals.get::<_, bool>("logging")?,
79
- debug: globals.get::<_, bool>("debug")?,
80
  upstream_search_engines: globals
81
  .get::<_, HashMap<String, bool>>("upstream_search_engines")?
82
  .into_iter()
83
  .filter_map(|(key, value)| value.then_some(key))
84
  .collect(),
85
  request_timeout: globals.get::<_, u8>("request_timeout")?,
 
86
  })
87
  })
88
  }
 
2
  //! into rust readable form.
3
 
4
  use super::parser_models::Style;
5
+ use log::LevelFilter;
6
  use rlua::Lua;
7
+ use std::{collections::HashMap, format, fs, io::Write, path::Path, thread::available_parallelism};
8
 
9
  // ------- Constants --------
10
  static COMMON_DIRECTORY_NAME: &str = "websurfx";
 
24
  /// * `debug` - It stores the option to whether enable or disable debug mode.
25
  /// * `upstream_search_engines` - It stores all the engine names that were enabled by the user.
26
  /// * `request_timeout` - It stores the time (secs) which controls the server request timeout.
27
+ /// * `threads` - It stores the number of threads which controls the app will use to run.
28
  #[derive(Clone)]
29
  pub struct Config {
30
  pub port: u16,
 
36
  pub debug: bool,
37
  pub upstream_search_engines: Vec<String>,
38
  pub request_timeout: u8,
39
+ pub threads: u8,
40
  }
41
 
42
  /// Configuration options for the aggregator.
 
54
  /// A function which parses the config.lua file and puts all the parsed options in the newly
55
  /// constructed Config struct and returns it.
56
  ///
57
+ /// # Arguments
58
+ ///
59
+ /// * `logging_initialized` - It takes a boolean which ensures that the logging doesn't get
60
+ /// initialized twice.
61
+ ///
62
  /// # Error
63
  ///
64
  /// Returns a lua parse error if parsing of the config.lua file fails or has a syntax error
65
  /// or io error if the config.lua file doesn't exists otherwise it returns a newly constructed
66
  /// Config struct with all the parsed config options from the parsed config file.
67
+ pub fn parse(logging_initialized: bool) -> Result<Self, Box<dyn std::error::Error>> {
68
  Lua::new().context(|context| -> Result<Self, Box<dyn std::error::Error>> {
69
  let globals = context.globals();
70
 
 
72
  .load(&fs::read_to_string(Config::config_path()?)?)
73
  .exec()?;
74
 
75
+ let parsed_threads: u8 = globals.get::<_, u8>("threads")?;
76
+
77
+ let debug: bool = globals.get::<_, bool>("debug")?;
78
+ let logging:bool= globals.get::<_, bool>("logging")?;
79
+
80
+ // Check whether logging has not been initialized before.
81
+ if logging_initialized {
82
+ // Initializing logging middleware with level set to default or info.
83
+ let mut log_level: LevelFilter = LevelFilter::Off;
84
+ if logging && debug == false {
85
+ log_level = LevelFilter::Info;
86
+ } else if debug {
87
+ log_level = LevelFilter::Trace;
88
+ };
89
+ env_logger::Builder::new().filter(None, log_level).init();
90
+ }
91
+
92
+ let threads: u8 = if parsed_threads == 0 {
93
+ let total_num_of_threads:usize = available_parallelism()?.get() /2;
94
+ if debug || logging {
95
+ log::error!("Config Error: The value of `threads` option should be a non zero positive integer");
96
+ log::info!("Falling back to using {} threads", total_num_of_threads)
97
+ } else {
98
+ std::io::stdout()
99
+ .lock()
100
+ .write_all(&format!("Config Error: The value of `threads` option should be a non zero positive integer\nFalling back to using {} threads\n", total_num_of_threads).into_bytes())?;
101
+ };
102
+ total_num_of_threads as u8
103
+ } else {
104
+ parsed_threads
105
+ };
106
+
107
  Ok(Config {
108
  port: globals.get::<_, u16>("port")?,
109
  binding_ip: globals.get::<_, String>("binding_ip")?,
 
115
  aggregator: AggregatorConfig {
116
  random_delay: globals.get::<_, bool>("production_use")?,
117
  },
118
+ logging,
119
+ debug,
120
  upstream_search_engines: globals
121
  .get::<_, HashMap<String, bool>>("upstream_search_engines")?
122
  .into_iter()
123
  .filter_map(|(key, value)| value.then_some(key))
124
  .collect(),
125
  request_timeout: globals.get::<_, u8>("request_timeout")?,
126
+ threads,
127
  })
128
  })
129
  }
src/lib.rs CHANGED
@@ -35,7 +35,7 @@ use handler::public_paths::public_path;
35
  /// use std::net::TcpListener;
36
  /// use websurfx::{config::parser::Config, run};
37
  ///
38
- /// let config = Config::parse().unwrap();
39
  /// let listener = TcpListener::bind("127.0.0.1:8080").expect("Failed to bind address");
40
  /// let server = run(listener,config).expect("Failed to start server");
41
  /// ```
@@ -50,6 +50,8 @@ pub fn run(listener: TcpListener, config: Config) -> std::io::Result<Server> {
50
 
51
  let handlebars_ref: web::Data<Handlebars> = web::Data::new(handlebars);
52
 
 
 
53
  let server = HttpServer::new(move || {
54
  let cors: Cors = Cors::default()
55
  .allow_any_origin()
@@ -82,6 +84,7 @@ pub fn run(listener: TcpListener, config: Config) -> std::io::Result<Server> {
82
  .service(routes::settings) // settings page
83
  .default_service(web::route().to(routes::not_found)) // error page
84
  })
 
85
  // Start server on 127.0.0.1 with the user provided port number. for example 127.0.0.1:8080.
86
  .listen(listener)?
87
  .run();
 
35
  /// use std::net::TcpListener;
36
  /// use websurfx::{config::parser::Config, run};
37
  ///
38
+ /// let config = Config::parse(true).unwrap();
39
  /// let listener = TcpListener::bind("127.0.0.1:8080").expect("Failed to bind address");
40
  /// let server = run(listener,config).expect("Failed to start server");
41
  /// ```
 
50
 
51
  let handlebars_ref: web::Data<Handlebars> = web::Data::new(handlebars);
52
 
53
+ let cloned_config_threads_opt: u8 = config.threads;
54
+
55
  let server = HttpServer::new(move || {
56
  let cors: Cors = Cors::default()
57
  .allow_any_origin()
 
84
  .service(routes::settings) // settings page
85
  .default_service(web::route().to(routes::not_found)) // error page
86
  })
87
+ .workers(cloned_config_threads_opt as usize)
88
  // Start server on 127.0.0.1 with the user provided port number. for example 127.0.0.1:8080.
89
  .listen(listener)?
90
  .run();
tests/index.rs CHANGED
@@ -8,7 +8,7 @@ fn spawn_app() -> String {
8
  // Binding to port 0 will trigger the OS to assign a port for us.
9
  let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
10
  let port = listener.local_addr().unwrap().port();
11
- let config = Config::parse().unwrap();
12
  let server = run(listener, config).expect("Failed to bind address");
13
 
14
  tokio::spawn(server);
@@ -36,7 +36,7 @@ async fn test_index() {
36
  assert_eq!(res.status(), 200);
37
 
38
  let handlebars = handlebars();
39
- let config = Config::parse().unwrap();
40
  let template = handlebars.render("index", &config.style).unwrap();
41
  assert_eq!(res.text().await.unwrap(), template);
42
  }
 
8
  // Binding to port 0 will trigger the OS to assign a port for us.
9
  let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
10
  let port = listener.local_addr().unwrap().port();
11
+ let config = Config::parse(true).unwrap();
12
  let server = run(listener, config).expect("Failed to bind address");
13
 
14
  tokio::spawn(server);
 
36
  assert_eq!(res.status(), 200);
37
 
38
  let handlebars = handlebars();
39
+ let config = Config::parse(false).unwrap();
40
  let template = handlebars.render("index", &config.style).unwrap();
41
  assert_eq!(res.text().await.unwrap(), template);
42
  }
websurfx/config.lua CHANGED
@@ -1,6 +1,7 @@
1
  -- ### General ###
2
  logging = true -- an option to enable or disable logs.
3
  debug = false -- an option to enable or disable debug mode.
 
4
 
5
  -- ### Server ###
6
  port = "8080" -- port on which server should be launched
 
1
  -- ### General ###
2
  logging = true -- an option to enable or disable logs.
3
  debug = false -- an option to enable or disable debug mode.
4
+ threads = 10 -- the amount of threads that the app will use to run (the value should be greater than 0).
5
 
6
  -- ### Server ###
7
  port = "8080" -- port on which server should be launched