mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-29 03:38:10 -07:00
global: snapshot
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use std::{fs, path::Path};
|
||||
use std::{fs, path::Path, time::Duration};
|
||||
|
||||
use axum::{
|
||||
body::Body,
|
||||
@@ -6,13 +6,11 @@ use axum::{
|
||||
http::{HeaderMap, StatusCode},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_error::{Error, Result};
|
||||
use log::{error, info};
|
||||
use quick_cache::sync::GuardResult;
|
||||
|
||||
use crate::{
|
||||
AppState,
|
||||
traits::{HeaderMapExtended, ModifiedState, ResponseExtended},
|
||||
};
|
||||
use crate::{AppState, HeaderMapExtended, ModifiedState, ResponseExtended};
|
||||
|
||||
pub async fn file_handler(
|
||||
headers: HeaderMap,
|
||||
@@ -31,12 +29,12 @@ fn any_handler(
|
||||
app_state: AppState,
|
||||
path: Option<extract::Path<String>>,
|
||||
) -> Response {
|
||||
let dist_path = app_state.dist_path();
|
||||
let files_path = app_state.path.as_ref().unwrap();
|
||||
|
||||
if let Some(path) = path.as_ref() {
|
||||
let path = path.0.replace("..", "").replace("\\", "");
|
||||
|
||||
let mut path = dist_path.join(&path);
|
||||
let mut path = files_path.join(&path);
|
||||
|
||||
if !path.exists() || path.is_dir() {
|
||||
if path.extension().is_some() {
|
||||
@@ -50,18 +48,18 @@ fn any_handler(
|
||||
|
||||
return response;
|
||||
} else {
|
||||
path = dist_path.join("index.html");
|
||||
path = files_path.join("index.html");
|
||||
}
|
||||
}
|
||||
|
||||
path_to_response(&headers, &path)
|
||||
path_to_response(&headers, &app_state, &path)
|
||||
} else {
|
||||
path_to_response(&headers, &dist_path.join("index.html"))
|
||||
path_to_response(&headers, &app_state, &files_path.join("index.html"))
|
||||
}
|
||||
}
|
||||
|
||||
fn path_to_response(headers: &HeaderMap, path: &Path) -> Response {
|
||||
match path_to_response_(headers, path) {
|
||||
fn path_to_response(headers: &HeaderMap, app_state: &AppState, path: &Path) -> Response {
|
||||
match path_to_response_(headers, app_state, path) {
|
||||
Ok(response) => response,
|
||||
Err(error) => {
|
||||
let mut response =
|
||||
@@ -74,32 +72,51 @@ fn path_to_response(headers: &HeaderMap, path: &Path) -> Response {
|
||||
}
|
||||
}
|
||||
|
||||
fn path_to_response_(headers: &HeaderMap, path: &Path) -> Result<Response> {
|
||||
fn path_to_response_(headers: &HeaderMap, app_state: &AppState, path: &Path) -> Result<Response> {
|
||||
let (modified, date) = headers.check_if_modified_since(path)?;
|
||||
if modified == ModifiedState::NotModifiedSince {
|
||||
return Ok(Response::new_not_modified());
|
||||
}
|
||||
|
||||
let content = fs::read(path).unwrap_or_else(|error| {
|
||||
error!("{error}");
|
||||
let path = path.to_str().unwrap();
|
||||
info!("Can't read file {path}");
|
||||
panic!("")
|
||||
});
|
||||
let serialized_path = path.to_str().unwrap();
|
||||
|
||||
let mut response = Response::new(content.into());
|
||||
let must_revalidate = path
|
||||
.extension()
|
||||
.is_some_and(|extension| extension == "html")
|
||||
|| serialized_path.ends_with("service-worker.js");
|
||||
|
||||
let guard_res = if !must_revalidate {
|
||||
Some(app_state.cache.get_value_or_guard(
|
||||
&path.to_str().unwrap().to_owned(),
|
||||
Some(Duration::from_millis(500)),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut response = if let Some(GuardResult::Value(v)) = guard_res {
|
||||
Response::new(Body::from(v))
|
||||
} else {
|
||||
let content = fs::read(path).unwrap_or_else(|error| {
|
||||
error!("{error}");
|
||||
let path = path.to_str().unwrap();
|
||||
info!("Can't read file {path}");
|
||||
panic!("")
|
||||
});
|
||||
|
||||
if let Some(GuardResult::Guard(g)) = guard_res {
|
||||
g.insert(content.clone().into())
|
||||
.map_err(|_| Error::QuickCacheError)?;
|
||||
}
|
||||
|
||||
Response::new(content.into())
|
||||
};
|
||||
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_content_type(path);
|
||||
|
||||
let serialized_path = path.to_str().unwrap();
|
||||
|
||||
if path
|
||||
.extension()
|
||||
.is_some_and(|extension| extension == "html")
|
||||
|| serialized_path.ends_with("service-worker.js")
|
||||
{
|
||||
if must_revalidate {
|
||||
headers.insert_cache_control_must_revalidate();
|
||||
} else if path.extension().is_some_and(|extension| {
|
||||
extension == "jpg"
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use axum::{Router, routing::get};
|
||||
|
||||
use super::AppState;
|
||||
|
||||
mod file;
|
||||
mod website;
|
||||
|
||||
use file::{file_handler, index_handler};
|
||||
pub use website::Website;
|
||||
|
||||
pub trait FilesRoutes {
|
||||
fn add_website_routes(self, website: Website) -> Self;
|
||||
fn add_files_routes(self, path: Option<&PathBuf>) -> Self;
|
||||
}
|
||||
|
||||
impl FilesRoutes for Router<AppState> {
|
||||
fn add_website_routes(self, website: Website) -> Self {
|
||||
if website.is_some() {
|
||||
fn add_files_routes(self, path: Option<&PathBuf>) -> Self {
|
||||
if path.is_some() {
|
||||
self.route("/{*path}", get(file_handler))
|
||||
.route("/", get(index_handler))
|
||||
} else {
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
use clap_derive::ValueEnum;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, ValueEnum)]
|
||||
pub enum Website {
|
||||
None,
|
||||
Default,
|
||||
Custom,
|
||||
}
|
||||
|
||||
impl Website {
|
||||
pub fn is_none(&self) -> bool {
|
||||
self == &Self::None
|
||||
}
|
||||
|
||||
pub fn is_some(&self) -> bool {
|
||||
!self.is_none()
|
||||
}
|
||||
|
||||
pub fn to_folder_name(&self) -> &str {
|
||||
match self {
|
||||
Self::Custom => "custom",
|
||||
Self::Default => "default",
|
||||
Self::None => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user