neon_arch commited on
Commit
a8b6a9b
2 Parent(s): 9d32f4a b299766

Merge branch 'rolling' into patch-searx-results-on-first-page

Browse files
docs/configuration.md CHANGED
@@ -29,6 +29,7 @@ Some of the configuration options provided in the file are stated below. These a
29
  - **port:** Port number on which server should be launched.
30
  - **binding_ip_addr:** IP address on the which server should be launched.
31
  - **production_use:** Whether to use production mode or not (in other words this option should be used if it is to be used to host it on the server to provide a service to a large number of users). If production_use is set to true. There will be a random delay before sending the request to the search engines, this is to prevent DDoSing the upstream search engines from a large number of simultaneous requests. This is newly added option and hence is only available in the **edge version**.
 
32
 
33
  ## Website
34
 
 
29
  - **port:** Port number on which server should be launched.
30
  - **binding_ip_addr:** IP address on the which server should be launched.
31
  - **production_use:** Whether to use production mode or not (in other words this option should be used if it is to be used to host it on the server to provide a service to a large number of users). If production_use is set to true. There will be a random delay before sending the request to the search engines, this is to prevent DDoSing the upstream search engines from a large number of simultaneous requests. This is newly added option and hence is only available in the **edge version**.
32
+ - **request_timeout:** Timeout for the search requests sent to the upstream search engines to be fetched (value in seconds).
33
 
34
  ## Website
35
 
docs/installation.md CHANGED
@@ -86,6 +86,7 @@ binding_ip_addr = "0.0.0.0" --ip address on the which server should be launched.
86
  production_use = false -- whether to use production mode or not (in other words this option should be used if it is to be used to host it on the server to provide a service to a large number of users)
87
  -- if production_use is set to true
88
  -- There will be a random delay before sending the request to the search engines, this is to prevent DDoSing the upstream search engines from a large number of simultaneous requests.
 
89
 
90
  -- ### Website ###
91
  -- The different colorschemes provided are:
 
86
  production_use = false -- whether to use production mode or not (in other words this option should be used if it is to be used to host it on the server to provide a service to a large number of users)
87
  -- if production_use is set to true
88
  -- There will be a random delay before sending the request to the search engines, this is to prevent DDoSing the upstream search engines from a large number of simultaneous requests.
89
+ request_timeout = 60 -- timeout for the search requests sent to the upstream search engines to be fetched (value in seconds).
90
 
91
  -- ### Website ###
92
  -- The different colorschemes provided are:
src/config/parser.rs CHANGED
@@ -22,6 +22,7 @@ static CONFIG_FILE_NAME: &str = "config.lua";
22
  /// * `logging` - It stores the option to whether enable or disable logs.
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
  #[derive(Clone)]
26
  pub struct Config {
27
  pub port: u16,
@@ -32,6 +33,7 @@ pub struct Config {
32
  pub logging: bool,
33
  pub debug: bool,
34
  pub upstream_search_engines: Vec<String>,
 
35
  }
36
 
37
  /// Configuration options for the aggregator.
@@ -80,6 +82,7 @@ impl Config {
80
  .into_iter()
81
  .filter_map(|(key, value)| value.then_some(key))
82
  .collect(),
 
83
  })
84
  })
85
  }
 
22
  /// * `logging` - It stores the option to whether enable or disable logs.
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,
 
33
  pub logging: bool,
34
  pub debug: bool,
35
  pub upstream_search_engines: Vec<String>,
36
+ pub request_timeout: u8,
37
  }
38
 
39
  /// Configuration options for the aggregator.
 
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
  }
src/engines/duckduckgo.rs CHANGED
@@ -29,6 +29,7 @@ impl SearchEngine for DuckDuckGo {
29
  /// * `query` - Takes the user provided query to query to the upstream search engine with.
30
  /// * `page` - Takes an u32 as an argument.
31
  /// * `user_agent` - Takes a random user agent string as an argument.
 
32
  ///
33
  /// # Errors
34
  ///
@@ -41,6 +42,7 @@ impl SearchEngine for DuckDuckGo {
41
  query: String,
42
  page: u32,
43
  user_agent: String,
 
44
  ) -> Result<HashMap<String, RawSearchResult>, EngineError> {
45
  // Page number can be missing or empty string and so appropriate handling is required
46
  // so that upstream server recieves valid page number.
@@ -90,7 +92,7 @@ impl SearchEngine for DuckDuckGo {
90
  );
91
 
92
  let document: Html = Html::parse_document(
93
- &DuckDuckGo::fetch_html_from_upstream(self, url, header_map).await?,
94
  );
95
 
96
  let no_result: Selector = Selector::parse(".no-results")
 
29
  /// * `query` - Takes the user provided query to query to the upstream search engine with.
30
  /// * `page` - Takes an u32 as an argument.
31
  /// * `user_agent` - Takes a random user agent string as an argument.
32
+ /// * `request_timeout` - Takes a time (secs) as a value which controls the server request timeout.
33
  ///
34
  /// # Errors
35
  ///
 
42
  query: String,
43
  page: u32,
44
  user_agent: String,
45
+ request_timeout: u8,
46
  ) -> Result<HashMap<String, RawSearchResult>, EngineError> {
47
  // Page number can be missing or empty string and so appropriate handling is required
48
  // so that upstream server recieves valid page number.
 
92
  );
93
 
94
  let document: Html = Html::parse_document(
95
+ &DuckDuckGo::fetch_html_from_upstream(self, url, header_map, request_timeout).await?,
96
  );
97
 
98
  let no_result: Selector = Selector::parse(".no-results")
src/engines/engine_models.rs CHANGED
@@ -50,11 +50,12 @@ pub trait SearchEngine {
50
  &self,
51
  url: String,
52
  header_map: reqwest::header::HeaderMap,
 
53
  ) -> Result<String, EngineError> {
54
  // fetch the html from upstream search engine
55
  Ok(reqwest::Client::new()
56
  .get(url)
57
- .timeout(Duration::from_secs(30)) // Add timeout to request to avoid DDOSing the server
58
  .headers(header_map) // add spoofed headers to emulate human behaviour
59
  .send()
60
  .await
@@ -71,5 +72,6 @@ pub trait SearchEngine {
71
  query: String,
72
  page: u32,
73
  user_agent: String,
 
74
  ) -> Result<HashMap<String, RawSearchResult>, EngineError>;
75
  }
 
50
  &self,
51
  url: String,
52
  header_map: reqwest::header::HeaderMap,
53
+ request_timeout: u8,
54
  ) -> Result<String, EngineError> {
55
  // fetch the html from upstream search engine
56
  Ok(reqwest::Client::new()
57
  .get(url)
58
+ .timeout(Duration::from_secs(request_timeout as u64)) // Add timeout to request to avoid DDOSing the server
59
  .headers(header_map) // add spoofed headers to emulate human behaviour
60
  .send()
61
  .await
 
72
  query: String,
73
  page: u32,
74
  user_agent: String,
75
+ request_timeout: u8,
76
  ) -> Result<HashMap<String, RawSearchResult>, EngineError>;
77
  }
src/engines/searx.rs CHANGED
@@ -27,6 +27,7 @@ impl SearchEngine for Searx {
27
  /// * `query` - Takes the user provided query to query to the upstream search engine with.
28
  /// * `page` - Takes an u32 as an argument.
29
  /// * `user_agent` - Takes a random user agent string as an argument.
 
30
  ///
31
  /// # Errors
32
  ///
@@ -40,6 +41,7 @@ impl SearchEngine for Searx {
40
  query: String,
41
  page: u32,
42
  user_agent: String,
 
43
  ) -> Result<HashMap<String, RawSearchResult>, EngineError> {
44
  // Page number can be missing or empty string and so appropriate handling is required
45
  // so that upstream server recieves valid page number.
@@ -73,8 +75,9 @@ impl SearchEngine for Searx {
73
  );
74
  header_map.insert(COOKIE, "categories=general; language=auto; locale=en; autocomplete=duckduckgo; image_proxy=1; method=POST; safesearch=2; theme=simple; results_on_new_tab=1; doi_resolver=oadoi.org; simple_style=auto; center_alignment=1; query_in_title=1; infinite_scroll=0; disabled_engines=; enabled_engines=\"archive is__general\\054yep__general\\054curlie__general\\054currency__general\\054ddg definitions__general\\054wikidata__general\\054duckduckgo__general\\054tineye__general\\054lingva__general\\054startpage__general\\054yahoo__general\\054wiby__general\\054marginalia__general\\054alexandria__general\\054wikibooks__general\\054wikiquote__general\\054wikisource__general\\054wikiversity__general\\054wikivoyage__general\\054dictzone__general\\054seznam__general\\054mojeek__general\\054naver__general\\054wikimini__general\\054brave__general\\054petalsearch__general\\054goo__general\"; disabled_plugins=; enabled_plugins=\"searx.plugins.hostname_replace\\054searx.plugins.oa_doi_rewrite\\054searx.plugins.vim_hotkeys\"; tokens=; maintab=on; enginetab=on".parse().into_report().change_context(EngineError::UnexpectedError)?);
75
 
76
- let document: Html =
77
- Html::parse_document(&Searx::fetch_html_from_upstream(self, url, header_map).await?);
 
78
 
79
  let no_result: Selector = Selector::parse("#urls>.dialog-error>p")
80
  .map_err(|_| Report::new(EngineError::UnexpectedError))
 
27
  /// * `query` - Takes the user provided query to query to the upstream search engine with.
28
  /// * `page` - Takes an u32 as an argument.
29
  /// * `user_agent` - Takes a random user agent string as an argument.
30
+ /// * `request_timeout` - Takes a time (secs) as a value which controls the server request timeout.
31
  ///
32
  /// # Errors
33
  ///
 
41
  query: String,
42
  page: u32,
43
  user_agent: String,
44
+ request_timeout: u8,
45
  ) -> Result<HashMap<String, RawSearchResult>, EngineError> {
46
  // Page number can be missing or empty string and so appropriate handling is required
47
  // so that upstream server recieves valid page number.
 
75
  );
76
  header_map.insert(COOKIE, "categories=general; language=auto; locale=en; autocomplete=duckduckgo; image_proxy=1; method=POST; safesearch=2; theme=simple; results_on_new_tab=1; doi_resolver=oadoi.org; simple_style=auto; center_alignment=1; query_in_title=1; infinite_scroll=0; disabled_engines=; enabled_engines=\"archive is__general\\054yep__general\\054curlie__general\\054currency__general\\054ddg definitions__general\\054wikidata__general\\054duckduckgo__general\\054tineye__general\\054lingva__general\\054startpage__general\\054yahoo__general\\054wiby__general\\054marginalia__general\\054alexandria__general\\054wikibooks__general\\054wikiquote__general\\054wikisource__general\\054wikiversity__general\\054wikivoyage__general\\054dictzone__general\\054seznam__general\\054mojeek__general\\054naver__general\\054wikimini__general\\054brave__general\\054petalsearch__general\\054goo__general\"; disabled_plugins=; enabled_plugins=\"searx.plugins.hostname_replace\\054searx.plugins.oa_doi_rewrite\\054searx.plugins.vim_hotkeys\"; tokens=; maintab=on; enginetab=on".parse().into_report().change_context(EngineError::UnexpectedError)?);
77
 
78
+ let document: Html = Html::parse_document(
79
+ &Searx::fetch_html_from_upstream(self, url, header_map, request_timeout).await?,
80
+ );
81
 
82
  let no_result: Selector = Selector::parse("#urls>.dialog-error>p")
83
  .map_err(|_| Report::new(EngineError::UnexpectedError))
src/results/aggregator.rs CHANGED
@@ -51,6 +51,7 @@ type FutureVec = Vec<JoinHandle<Result<HashMap<String, RawSearchResult>, Report<
51
  /// * `random_delay` - Accepts a boolean value to add a random delay before making the request.
52
  /// * `debug` - Accepts a boolean value to enable or disable debug mode option.
53
  /// * `upstream_search_engines` - Accepts a vector of search engine names which was selected by the
 
54
  /// user through the UI or the config file.
55
  ///
56
  /// # Error
@@ -64,6 +65,7 @@ pub async fn aggregate(
64
  random_delay: bool,
65
  debug: bool,
66
  upstream_search_engines: Vec<String>,
 
67
  ) -> Result<SearchResults, Box<dyn std::error::Error>> {
68
  let user_agent: String = random_user_agent();
69
  let mut result_map: HashMap<String, RawSearchResult> = HashMap::new();
@@ -92,9 +94,11 @@ pub async fn aggregate(
92
  .map(|search_engine| {
93
  let query: String = query.clone();
94
  let user_agent: String = user_agent.clone();
95
- tokio::spawn(
96
- async move { search_engine.results(query, page, user_agent.clone()).await },
97
- )
 
 
98
  })
99
  .collect();
100
 
 
51
  /// * `random_delay` - Accepts a boolean value to add a random delay before making the request.
52
  /// * `debug` - Accepts a boolean value to enable or disable debug mode option.
53
  /// * `upstream_search_engines` - Accepts a vector of search engine names which was selected by the
54
+ /// * `request_timeout` - Accepts a time (secs) as a value which controls the server request timeout.
55
  /// user through the UI or the config file.
56
  ///
57
  /// # Error
 
65
  random_delay: bool,
66
  debug: bool,
67
  upstream_search_engines: Vec<String>,
68
+ request_timeout: u8,
69
  ) -> Result<SearchResults, Box<dyn std::error::Error>> {
70
  let user_agent: String = random_user_agent();
71
  let mut result_map: HashMap<String, RawSearchResult> = HashMap::new();
 
94
  .map(|search_engine| {
95
  let query: String = query.clone();
96
  let user_agent: String = user_agent.clone();
97
+ tokio::spawn(async move {
98
+ search_engine
99
+ .results(query, page, user_agent.clone(), request_timeout)
100
+ .await
101
+ })
102
  })
103
  .collect();
104
 
src/server/routes.rs CHANGED
@@ -146,6 +146,7 @@ async fn results(
146
  config.aggregator.random_delay,
147
  config.debug,
148
  cookie_value.engines,
 
149
  )
150
  .await?
151
  }
@@ -156,6 +157,7 @@ async fn results(
156
  config.aggregator.random_delay,
157
  config.debug,
158
  config.upstream_search_engines.clone(),
 
159
  )
160
  .await?
161
  }
 
146
  config.aggregator.random_delay,
147
  config.debug,
148
  cookie_value.engines,
149
+ config.request_timeout,
150
  )
151
  .await?
152
  }
 
157
  config.aggregator.random_delay,
158
  config.debug,
159
  config.upstream_search_engines.clone(),
160
+ config.request_timeout,
161
  )
162
  .await?
163
  }
websurfx/config.lua CHANGED
@@ -8,6 +8,7 @@ binding_ip = "127.0.0.1" --ip address on the which server should be launched.
8
  production_use = false -- whether to use production mode or not (in other words this option should be used if it is to be used to host it on the server to provide a service to a large number of users (more than one))
9
  -- if production_use is set to true
10
  -- There will be a random delay before sending the request to the search engines, this is to prevent DDoSing the upstream search engines from a large number of simultaneous requests.
 
11
 
12
  -- ### Website ###
13
  -- The different colorschemes provided are:
 
8
  production_use = false -- whether to use production mode or not (in other words this option should be used if it is to be used to host it on the server to provide a service to a large number of users (more than one))
9
  -- if production_use is set to true
10
  -- There will be a random delay before sending the request to the search engines, this is to prevent DDoSing the upstream search engines from a large number of simultaneous requests.
11
+ request_timeout = 30 -- timeout for the search requests sent to the upstream search engines to be fetched (value in seconds).
12
 
13
  -- ### Website ###
14
  -- The different colorschemes provided are: