mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-01 18:53:38 -07:00
global: snapshot
This commit is contained in:
@@ -1,17 +1,12 @@
|
||||
use std::time::Instant;
|
||||
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Query as AxumQuery, State},
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
http::{HeaderMap, StatusCode},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_query::{Format, Index, Output, Params};
|
||||
|
||||
use crate::{
|
||||
log_result,
|
||||
traits::{HeaderMapExtended, ModifiedState, ResponseExtended},
|
||||
};
|
||||
use crate::traits::{HeaderMapExtended, ModifiedState, ResponseExtended};
|
||||
|
||||
use super::AppState;
|
||||
|
||||
@@ -21,21 +16,14 @@ pub use dts::*;
|
||||
|
||||
pub async fn handler(
|
||||
headers: HeaderMap,
|
||||
uri: Uri,
|
||||
query: AxumQuery<Params>,
|
||||
State(app_state): State<AppState>,
|
||||
) -> Response {
|
||||
let instant = Instant::now();
|
||||
|
||||
match req_to_response_res(headers, query, app_state) {
|
||||
Ok(response) => {
|
||||
log_result(response.status(), &uri, instant);
|
||||
response
|
||||
}
|
||||
Ok(response) => response,
|
||||
Err(error) => {
|
||||
let mut response =
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response();
|
||||
log_result(response.status(), &uri, instant);
|
||||
response.headers_mut().insert_cors();
|
||||
response
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use std::{fs, path::Path, time::Instant};
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use axum::{
|
||||
body::Body,
|
||||
extract::{self, State},
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
http::{HeaderMap, StatusCode},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use log::{error, info};
|
||||
|
||||
use crate::{
|
||||
AppState, log_result,
|
||||
AppState,
|
||||
traits::{HeaderMapExtended, ModifiedState, ResponseExtended},
|
||||
};
|
||||
|
||||
@@ -18,24 +18,18 @@ use super::minify::minify_js;
|
||||
pub async fn file_handler(
|
||||
headers: HeaderMap,
|
||||
State(app_state): State<AppState>,
|
||||
uri: Uri,
|
||||
path: extract::Path<String>,
|
||||
) -> Response {
|
||||
any_handler(headers, app_state, uri, Some(path))
|
||||
any_handler(headers, app_state, Some(path))
|
||||
}
|
||||
|
||||
pub async fn index_handler(
|
||||
headers: HeaderMap,
|
||||
State(app_state): State<AppState>,
|
||||
uri: Uri,
|
||||
) -> Response {
|
||||
any_handler(headers, app_state, uri, None)
|
||||
pub async fn index_handler(headers: HeaderMap, State(app_state): State<AppState>) -> Response {
|
||||
any_handler(headers, app_state, None)
|
||||
}
|
||||
|
||||
fn any_handler(
|
||||
headers: HeaderMap,
|
||||
app_state: AppState,
|
||||
uri: Uri,
|
||||
path: Option<extract::Path<String>>,
|
||||
) -> Response {
|
||||
let website_path = app_state
|
||||
@@ -44,8 +38,6 @@ fn any_handler(
|
||||
.expect("Should never reach here is websites_path is None")
|
||||
.join(app_state.website.to_folder_name());
|
||||
|
||||
let instant = Instant::now();
|
||||
|
||||
let response = if let Some(path) = path.as_ref() {
|
||||
let path = path.0.replace("..", "").replace("\\", "");
|
||||
|
||||
@@ -72,8 +64,6 @@ fn any_handler(
|
||||
path_to_response(&headers, &website_path.join("index.html"))
|
||||
};
|
||||
|
||||
log_result(response.status(), &uri, instant);
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,15 @@ use std::{
|
||||
fs,
|
||||
io::Cursor,
|
||||
path::{Path, PathBuf},
|
||||
time::Instant,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use api::{ApiRoutes, DTS};
|
||||
use axum::{
|
||||
Json, Router,
|
||||
http::{StatusCode, Uri},
|
||||
body::Body,
|
||||
http::{Request, Response, StatusCode, Uri},
|
||||
middleware::Next,
|
||||
routing::get,
|
||||
serve,
|
||||
};
|
||||
@@ -26,13 +28,14 @@ use files::FilesRoutes;
|
||||
use log::{error, info};
|
||||
pub use tokio;
|
||||
use tokio::net::TcpListener;
|
||||
use tower_http::compression::CompressionLayer;
|
||||
use tower_http::{compression::CompressionLayer, trace::TraceLayer};
|
||||
|
||||
mod api;
|
||||
mod files;
|
||||
mod traits;
|
||||
|
||||
pub use files::Website;
|
||||
use tracing::Span;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
@@ -63,14 +66,16 @@ impl Server {
|
||||
} else {
|
||||
let downloads_path = dot_brk_path().join(DOWNLOADS);
|
||||
|
||||
let downloaded_websites_path = downloads_path.join("brk-main").join(WEBSITES);
|
||||
let version = format!("v{}", env!("CARGO_PKG_VERSION"));
|
||||
|
||||
let downloaded_websites_path = downloads_path.join(&version).join(WEBSITES);
|
||||
|
||||
if !fs::exists(&downloaded_websites_path)? {
|
||||
info!("Downloading websites from Github...");
|
||||
|
||||
let url = format!(
|
||||
"https://github.com/bitcoinresearchkit/brk/archive/refs/tags/v{}.zip",
|
||||
env!("CARGO_PKG_VERSION")
|
||||
"https://github.com/bitcoinresearchkit/brk/archive/refs/tags/{}.zip",
|
||||
version
|
||||
);
|
||||
|
||||
let response = minreq::get(url).send()?;
|
||||
@@ -108,12 +113,47 @@ impl Server {
|
||||
.gzip(true)
|
||||
.zstd(true);
|
||||
|
||||
let response_uri_layer = axum::middleware::from_fn(
|
||||
async |request: Request<Body>, next: Next| -> Response<Body> {
|
||||
let uri = request.uri().clone();
|
||||
let mut response = next.run(request).await;
|
||||
response.extensions_mut().insert(uri);
|
||||
response
|
||||
},
|
||||
);
|
||||
|
||||
let trace_layer = TraceLayer::new_for_http()
|
||||
.on_request(())
|
||||
.on_response(
|
||||
|response: &Response<Body>, latency: Duration, _span: &Span| {
|
||||
let latency = latency.bright_black();
|
||||
let status = response.status();
|
||||
let uri = response.extensions().get::<Uri>().unwrap();
|
||||
match status {
|
||||
StatusCode::INTERNAL_SERVER_ERROR => {
|
||||
error!("{} {} {:?}", status.as_u16().red(), uri, latency)
|
||||
}
|
||||
StatusCode::NOT_MODIFIED => {
|
||||
info!("{} {} {:?}", status.as_u16().bright_black(), uri, latency)
|
||||
}
|
||||
StatusCode::OK => {
|
||||
info!("{} {} {:?}", status.as_u16().green(), uri, latency)
|
||||
}
|
||||
_ => error!("{} {} {:?}", status.as_u16().red(), uri, latency),
|
||||
}
|
||||
},
|
||||
)
|
||||
.on_body_chunk(())
|
||||
.on_eos(());
|
||||
|
||||
let router = Router::new()
|
||||
.add_api_routes()
|
||||
.add_website_routes(state.website)
|
||||
.route("/version", get(Json(env!("CARGO_PKG_VERSION"))))
|
||||
.with_state(state)
|
||||
.layer(compression_layer);
|
||||
.layer(compression_layer)
|
||||
.layer(response_uri_layer)
|
||||
.layer(trace_layer);
|
||||
|
||||
let mut port = 3110;
|
||||
|
||||
@@ -135,14 +175,3 @@ impl Server {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn log_result(code: StatusCode, uri: &Uri, instant: Instant) {
|
||||
let time = format!("{}µs", instant.elapsed().as_micros());
|
||||
let time = time.bright_black();
|
||||
match code {
|
||||
StatusCode::INTERNAL_SERVER_ERROR => error!("{} {} {}", code.as_u16().red(), uri, time),
|
||||
StatusCode::NOT_MODIFIED => info!("{} {} {}", code.as_u16().bright_black(), uri, time),
|
||||
StatusCode::OK => info!("{} {} {}", code.as_u16().green(), uri, time),
|
||||
_ => error!("{} {} {}", code.as_u16().red(), uri, time),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ pub enum ModifiedState {
|
||||
}
|
||||
|
||||
pub trait HeaderMapExtended {
|
||||
fn get_scheme(&self) -> &str;
|
||||
fn _get_scheme(&self) -> &str;
|
||||
fn get_host(&self) -> &str;
|
||||
fn check_if_host_is_any_local(&self) -> bool;
|
||||
fn check_if_host_is_local(&self) -> bool;
|
||||
fn check_if_host_is_0000(&self) -> bool;
|
||||
fn check_if_host_is_localhost(&self) -> bool;
|
||||
|
||||
@@ -30,8 +30,7 @@ pub trait HeaderMapExtended {
|
||||
-> color_eyre::Result<(ModifiedState, DateTime)>;
|
||||
|
||||
fn insert_cache_control_immutable(&mut self);
|
||||
#[allow(unused)]
|
||||
fn insert_cache_control_revalidate(&mut self, max_age: u64, stale_while_revalidate: u64);
|
||||
fn _insert_cache_control_revalidate(&mut self, max_age: u64, stale_while_revalidate: u64);
|
||||
fn insert_last_modified(&mut self, date: DateTime);
|
||||
|
||||
fn insert_content_disposition_attachment(&mut self);
|
||||
@@ -53,8 +52,8 @@ pub trait HeaderMapExtended {
|
||||
}
|
||||
|
||||
impl HeaderMapExtended for HeaderMap {
|
||||
fn get_scheme(&self) -> &str {
|
||||
if self.check_if_host_is_any_local() {
|
||||
fn _get_scheme(&self) -> &str {
|
||||
if self.check_if_host_is_local() {
|
||||
"http"
|
||||
} else {
|
||||
"https"
|
||||
@@ -65,7 +64,7 @@ impl HeaderMapExtended for HeaderMap {
|
||||
self[HOST].to_str().unwrap()
|
||||
}
|
||||
|
||||
fn check_if_host_is_any_local(&self) -> bool {
|
||||
fn check_if_host_is_local(&self) -> bool {
|
||||
self.check_if_host_is_localhost() || self.check_if_host_is_0000()
|
||||
}
|
||||
|
||||
@@ -95,7 +94,7 @@ impl HeaderMapExtended for HeaderMap {
|
||||
self.insert(header::CONTENT_DISPOSITION, "attachment".parse().unwrap());
|
||||
}
|
||||
|
||||
fn insert_cache_control_revalidate(&mut self, max_age: u64, stale_while_revalidate: u64) {
|
||||
fn _insert_cache_control_revalidate(&mut self, max_age: u64, stale_while_revalidate: u64) {
|
||||
self.insert(
|
||||
header::CACHE_CONTROL,
|
||||
format!(
|
||||
|
||||
Reference in New Issue
Block a user