#[cfg(test)]
mod tests;
use std::sync::atomic::{AtomicBool, Ordering};
use crate::application::Application;
use crate::middleware::Middleware;
use crate::request::Request;
use crate::response::{Response, STATUS_CODE_REASON_PHRASE};
use crate::server::ConnectionInfo;
pub static MAINTENANCE_MODE: AtomicBool = AtomicBool::new(false);
fn service_unavailable() -> Response {
crate::error::problem::problem_with_text(STATUS_CODE_REASON_PHRASE.n503_service_unavailable, "maintenance", "Service Temporarily Unavailable")
}
pub struct MaintenanceLayer;
impl Middleware for MaintenanceLayer {
fn accepts_streamed_body(&self, _request: &Request, _connection: &ConnectionInfo) -> bool {
true
}
fn handle(
&self,
request: &Request,
connection: &ConnectionInfo,
next: &dyn Application,
) -> Result<Response, String> {
if MAINTENANCE_MODE.load(Ordering::Relaxed) {
let path = request.request_uri.split('?').next().unwrap_or(&request.request_uri);
if path != "/healthz" && path != "/readyz" {
return Ok(service_unavailable());
}
}
next.execute(request, connection)
}
fn runs_inline(&self, _request: &Request, _connection: &ConnectionInfo) -> bool {
true
}
fn is_passthrough(&self, _request: &Request, _connection: &ConnectionInfo) -> bool {
!MAINTENANCE_MODE.load(Ordering::Relaxed)
}
}