aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2023-04-06 08:01:52 +0000
committerFuwn <[email protected]>2023-04-06 08:01:52 +0000
commitfff207d3cb41c5a76db234196f16d28952dfd91c (patch)
treed19f70410c049b25ce579fdaa1cf1ac984d847f7 /src
parentfeat(context): bring back peer address (diff)
downloadwindmark-fff207d3cb41c5a76db234196f16d28952dfd91c.tar.xz
windmark-fff207d3cb41c5a76db234196f16d28952dfd91c.zip
feat(response): async error handler
Diffstat (limited to 'src')
-rw-r--r--src/handler/response/error.rs19
-rw-r--r--src/handler/response/route.rs4
-rw-r--r--src/router.rs40
3 files changed, 43 insertions, 20 deletions
diff --git a/src/handler/response/error.rs b/src/handler/response/error.rs
index c433a46..a1a7885 100644
--- a/src/handler/response/error.rs
+++ b/src/handler/response/error.rs
@@ -16,10 +16,23 @@
// Copyright (C) 2022-2022 Fuwn <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only
+use async_trait::async_trait;
+
use crate::{context::ErrorContext, Response};
#[allow(clippy::module_name_repetitions)]
-pub trait ErrorResponse: FnMut(ErrorContext) -> Response + Send + Sync {}
+#[async_trait]
+pub trait ErrorResponse: Send + Sync {
+ async fn call(&mut self, context: ErrorContext) -> Response;
+}
-impl<T> ErrorResponse for T where T: FnMut(ErrorContext) -> Response + Send + Sync
-{}
+#[async_trait]
+impl<T, F> ErrorResponse for T
+where
+ T: FnMut(ErrorContext) -> F + Send + Sync,
+ F: std::future::Future<Output = Response> + Send + 'static,
+{
+ async fn call(&mut self, context: ErrorContext) -> Response {
+ (*self)(context).await
+ }
+}
diff --git a/src/handler/response/route.rs b/src/handler/response/route.rs
index 0196363..a65b889 100644
--- a/src/handler/response/route.rs
+++ b/src/handler/response/route.rs
@@ -16,8 +16,6 @@
// Copyright (C) 2022-2022 Fuwn <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only
-use std::future::Future;
-
use async_trait::async_trait;
use crate::{context::RouteContext, Response};
@@ -32,7 +30,7 @@ pub trait RouteResponse: Send + Sync {
impl<T, F> RouteResponse for T
where
T: FnMut(RouteContext<'_>) -> F + Send + Sync,
- F: Future<Output = Response> + Send + 'static,
+ F: std::future::Future<Output = Response> + Send + 'static,
{
async fn call(&mut self, context: RouteContext<'_>) -> Response {
(*self)(context).await
diff --git a/src/router.rs b/src/router.rs
index c865fa9..030ffb8 100644
--- a/src/router.rs
+++ b/src/router.rs
@@ -75,7 +75,7 @@ macro_rules! or_error {
#[derive(Clone)]
pub struct Router {
routes: matchit::Router<Arc<AsyncMutex<Box<dyn RouteResponse>>>>,
- error_handler: Arc<Mutex<Box<dyn ErrorResponse<Output = Response>>>>,
+ error_handler: Arc<AsyncMutex<Box<dyn ErrorResponse>>>,
private_key_file_name: String,
ca_file_name: String,
headers: Arc<Mutex<Vec<Box<dyn Partial<Output = String>>>>>,
@@ -190,11 +190,17 @@ impl Router {
/// windmark::success!("You have encountered an error!")
/// });
/// ```
- pub fn set_error_handler(
+ pub fn set_error_handler<R>(
&mut self,
- handler: impl ErrorResponse + 'static,
- ) -> &mut Self {
- self.error_handler = Arc::new(Mutex::new(Box::new(handler)));
+ mut handler: impl FnMut(ErrorContext) -> R + Send + Sync + 'static,
+ ) -> &mut Self
+ where
+ R: IntoFuture<Output = Response> + Send + 'static,
+ <R as IntoFuture>::IntoFuture: Send,
+ {
+ self.error_handler = Arc::new(AsyncMutex::new(Box::new(move |context| {
+ handler(context).into_future()
+ })));
self
}
@@ -398,11 +404,15 @@ impl Router {
handler.await
} else {
- (*self.error_handler).lock().unwrap()(ErrorContext::new(
- stream.get_ref().peer_addr(),
- url.clone(),
- peer_certificate,
- ))
+ (*self.error_handler)
+ .lock()
+ .await
+ .call(ErrorContext::new(
+ stream.get_ref().peer_addr(),
+ url.clone(),
+ peer_certificate,
+ ))
+ .await
};
for module in &mut *self.async_modules.lock().await {
@@ -855,10 +865,12 @@ impl Default for Router {
fn default() -> Self {
Self {
routes: matchit::Router::new(),
- error_handler: Arc::new(Mutex::new(Box::new(|_| {
- Response::not_found(
- "This capsule has not implemented an error handler...",
- )
+ error_handler: Arc::new(AsyncMutex::new(Box::new(|_| {
+ async {
+ Response::not_found(
+ "This capsule has not implemented an error handler...",
+ )
+ }
}))),
private_key_file_name: String::new(),
ca_file_name: String::new(),