Skip to content

Commit

Permalink
fix: service hoops can not get status code correctly (#925)
Browse files Browse the repository at this point in the history
* fix service hoops can not get status code correctly

* Format Rust code using rustfmt

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
chrislearn and github-actions[bot] authored Sep 24, 2024
1 parent bae02e3 commit 494fb5c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
8 changes: 0 additions & 8 deletions crates/core/src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,14 +540,6 @@ fn decode_url_path_safely(path: &str) -> String {
.to_string()
}

#[doc(hidden)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[non_exhaustive]
pub enum FlowCtrlStage {
Routing,
Catching,
}

/// Control the flow of execute handlers.
///
/// When a request is coming, [`Router`] will detect it and get the matched router.
Expand Down
43 changes: 41 additions & 2 deletions crates/core/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::handler::{Handler, WhenHoop};
use crate::http::body::{ReqBody, ResBody};
use crate::http::{Mime, Request, Response, StatusCode};
use crate::routing::{FlowCtrl, PathState, Router};
use crate::Depot;
use crate::{async_trait, Depot};

/// Service http request.
#[non_exhaustive]
Expand Down Expand Up @@ -172,6 +172,22 @@ where
}
}

struct DefaultStatusOK;
#[async_trait]
impl Handler for DefaultStatusOK {
async fn handle(
&self,
_req: &mut Request,
_depot: &mut Depot,
res: &mut Response,
_ctrl: &mut FlowCtrl,
) {
if res.status_code.is_none() {
res.status_code = Some(StatusCode::OK);
}
}
}

#[doc(hidden)]
#[derive(Clone)]
pub struct HyperHandler {
Expand Down Expand Up @@ -209,15 +225,38 @@ impl HyperHandler {
async move {
if let Some(dm) = router.detect(&mut req, &mut path_state) {
req.params = path_state.params;
let mut ctrl = FlowCtrl::new([&hoops[..], &dm.hoops[..], &[dm.goal]].concat());
// Set default status code before service hoops executed.
// We hope all hoops in service can get the correct status code.
let mut ctrl = if !hoops.is_empty() {
FlowCtrl::new(
[
&hoops[..],
&[Arc::new(DefaultStatusOK)],
&dm.hoops[..],
&[dm.goal],
]
.concat(),
)
} else {
FlowCtrl::new([&dm.hoops[..], &[dm.goal]].concat())
};
ctrl.call_next(&mut req, &mut depot, &mut res).await;
// Set it to default status code again if any hoop set status code to None.
if res.status_code.is_none() {
res.status_code = Some(StatusCode::OK);
}
} else if !hoops.is_empty() {
req.params = path_state.params;
// Set default status code before service hoops executed.
// We hope all hoops in service can get the correct status code.
if path_state.has_any_goal {
res.status_code = Some(StatusCode::METHOD_NOT_ALLOWED);
} else {
res.status_code = Some(StatusCode::NOT_FOUND);
}
let mut ctrl = FlowCtrl::new(hoops);
ctrl.call_next(&mut req, &mut depot, &mut res).await;
// Set it to default status code again if any hoop set status code to None.
if res.status_code.is_none() && path_state.has_any_goal {
res.status_code = Some(StatusCode::METHOD_NOT_ALLOWED);
}
Expand Down

0 comments on commit 494fb5c

Please sign in to comment.