66 lines
2.3 KiB
Rust
66 lines
2.3 KiB
Rust
use crate::{
|
|
auth::Session,
|
|
runtime::{ApiError, App},
|
|
settings::PanelCompression,
|
|
};
|
|
use axum::{
|
|
extract::{rejection::JsonRejection, State},
|
|
response::{Html, IntoResponse, Response},
|
|
Extension,
|
|
};
|
|
use http::{HeaderMap, StatusCode};
|
|
use std::sync::{Arc, OnceLock};
|
|
|
|
use super::panel_content::PanelContent;
|
|
|
|
static ADMIN_INDEX: OnceLock<PanelContent> = OnceLock::new();
|
|
|
|
fn panel_response(headers: &HeaderMap, compression: &PanelCompression) -> Response {
|
|
let content = ADMIN_INDEX.get_or_init(|| {
|
|
let (metrics, web_metrics) = include_str!("../web/partials/overview-metrics.html")
|
|
.split_once("<!-- RP_METRICS_SPLIT -->")
|
|
.expect("invalid Overview metrics partial");
|
|
let (charts, web_charts) = include_str!("../web/partials/overview-charts.html")
|
|
.split_once("<!-- RP_CHARTS_SPLIT -->")
|
|
.expect("invalid Overview charts partial");
|
|
let html = include_str!("../web/index.html")
|
|
.replace("<!-- RP_METRICS_MAIN -->", metrics)
|
|
.replace("<!-- RP_CHARTS_MAIN -->", charts)
|
|
.replace("<!-- RP_METRICS_WEB -->", web_metrics)
|
|
.replace("<!-- RP_CHARTS_WEB -->", web_charts)
|
|
.replace("__RUSTPROXY_ASSET_ID__", super::asset_build_id())
|
|
.replace("__RUSTPROXY_VERSION__", env!("CARGO_PKG_VERSION"));
|
|
PanelContent::new(Box::leak(html.into_boxed_str()))
|
|
});
|
|
content.response(headers, compression, "text/html; charset=utf-8")
|
|
}
|
|
|
|
pub(super) async fn index(
|
|
State(state): State<Arc<App>>,
|
|
session: Option<Extension<Session>>,
|
|
headers: HeaderMap,
|
|
) -> Response {
|
|
if session.is_none() {
|
|
let html = include_str!("../web/login.html")
|
|
.replace("__RUSTPROXY_ASSET_ID__", super::asset_build_id());
|
|
return Html(html).into_response();
|
|
}
|
|
let snapshot = state.config.load();
|
|
panel_response(
|
|
&headers,
|
|
&snapshot.envelope.config.administration.panel_compression,
|
|
)
|
|
}
|
|
|
|
pub(super) fn invalid_json(error: JsonRejection) -> ApiError {
|
|
let status = match error.status() {
|
|
StatusCode::PAYLOAD_TOO_LARGE => StatusCode::PAYLOAD_TOO_LARGE,
|
|
StatusCode::UNSUPPORTED_MEDIA_TYPE => StatusCode::UNSUPPORTED_MEDIA_TYPE,
|
|
_ => StatusCode::BAD_REQUEST,
|
|
};
|
|
ApiError(status, "auth.invalid_request".into())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|