FIX: Avoid stack overflow triggered by addition of new Actor::auth_error field by flattening out chained async API handler invocation. This avoids deep recursive .or_else() macro expansion of calls that pass the large Request value (of which Actor is part) resulting in stack overflow. This fix also removes the need for the boosted recursion_limit compiler setting.

This commit is contained in:
Ximon Eighteen
2020-12-31 15:57:02 +01:00
parent 1b1d7f9a5d
commit dd7d3f41b2
14 changed files with 23 additions and 46 deletions
-8
View File
@@ -1,11 +1,3 @@
// Added so that the call chain from http/auth.rs through to Authorizer doesn't
// exceed the recursion limit within future macro expansion. Possibly related to
// this:
// "Note that select! relies on proc-macro-hack, and may require to set the
// compiler's recursion limit very high, e.g. #![recursion_limit="1024"]."
// From: https://docs.rs/futures/0.3.6/futures/macro.select.html
#![recursion_limit = "155"]
extern crate krill;
use std::env;
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
extern crate krill;
use krill::cli::options::Options;
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
extern crate krill;
use krill::cli::options::KrillPubcOptions;
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
extern crate krill;
use std::sync::Arc;
+23 -14
View File
@@ -201,20 +201,29 @@ async fn map_requests(req: hyper::Request<hyper::Body>, state: State) -> Result<
// just make the trace log unusable.
let logger = ApiCallLogger::new(&req);
let res = api(req)
.or_else(auth)
.or_else(health)
.or_else(metrics)
.or_else(stats)
.or_else(rfc8181)
.or_else(rfc6492)
.or_else(statics)
.or_else(ta)
.or_else(rrdp)
.or_else(testbed)
.or_else(render_not_found)
.map_err(|_| Error::custom("should have received not found response"))
.await;
// We used to use .or_else() here but that causes a large recursive call
// tree due to these calls being to async functions, large enough with the
// given Request object passed each time that it eventually resulted in
// stack overflow. By doing it by hand like this we avoid the use of the
// macros that cause the recursion. We could also look at putting less data
// on the stack.
let mut res = api(req).await;
if let Err(req) = res { res = auth(req).await; }
if let Err(req) = res { res = health(req).await; }
if let Err(req) = res { res = metrics(req).await; }
if let Err(req) = res { res = stats(req).await; }
if let Err(req) = res { res = rfc8181(req).await; }
if let Err(req) = res { res = rfc6492(req).await; }
if let Err(req) = res { res = statics(req).await; }
if let Err(req) = res { res = ta(req).await; }
if let Err(req) = res { res = rrdp(req).await; }
if let Err(req) = res { res = testbed(req).await; }
if let Err(req) = res { res = render_not_found(req).await; }
let res = match res {
Ok(res) => Ok(res),
Err(_) => Err(Error::custom("should have received not found response")),
};
// Augment the response with any updated auth details that were determined
// above.
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
extern crate base64;
#[macro_use]
extern crate bcder;
-2
View File
@@ -1,7 +1,5 @@
//! Perform functional tests on a Krill instance, using the API
//!
#![recursion_limit = "155"]
use std::fs;
use std::str::FromStr;
use std::time::Duration;
-3
View File
@@ -1,6 +1,3 @@
#![type_length_limit = "5000000"]
#![recursion_limit = "155"]
extern crate krill;
/// This tests regressions for the Command history and details as exposed through the
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
#[cfg(feature = "ui-tests")]
mod ui;
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
#[cfg(feature = "ui-tests")]
mod ui;
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
#[cfg(feature = "ui-tests")]
mod ui;
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
#[cfg(feature = "ui-tests")]
mod ui;
-2
View File
@@ -1,5 +1,3 @@
#![recursion_limit = "155"]
#[cfg(feature = "ui-tests")]
mod ui;
-1
View File
@@ -1,5 +1,4 @@
#![type_length_limit = "5000000"]
#![recursion_limit = "155"]
extern crate krill;