mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-05-01 09:59:57 -07:00
On-demand analysis of past recordings
* rayhunter-daemon: API for triggering and reading analysis * rayhunter-daemon: rename readonly mode to debug mode * rayhunter-daemon: debug mode allows live-loading frontend files * rayhunter-check: rework to handle directories * rayhunter-check: better output * CI: build rayhunter-check
This commit is contained in:
committed by
Cooper Quintin
parent
c59fb7c013
commit
df84faa1f9
@@ -4,6 +4,7 @@ use axum::extract::State;
|
||||
use axum::http::{StatusCode, HeaderValue};
|
||||
use axum::response::{Response, IntoResponse};
|
||||
use axum::extract::Path;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use std::sync::Arc;
|
||||
@@ -12,20 +13,23 @@ use tokio_util::io::ReaderStream;
|
||||
use include_dir::{include_dir, Dir};
|
||||
|
||||
use crate::{framebuffer, DiagDeviceCtrlMessage};
|
||||
use crate::analysis::{AnalysisCtrlMessage, AnalysisStatus};
|
||||
use crate::qmdl_store::RecordingStore;
|
||||
|
||||
pub struct ServerState {
|
||||
pub qmdl_store_lock: Arc<RwLock<RecordingStore>>,
|
||||
pub diag_device_ctrl_sender: Sender<DiagDeviceCtrlMessage>,
|
||||
pub ui_update_sender: Sender<framebuffer::DisplayState>,
|
||||
pub readonly_mode: bool
|
||||
pub analysis_status_lock: Arc<RwLock<AnalysisStatus>>,
|
||||
pub analysis_sender: Sender<AnalysisCtrlMessage>,
|
||||
pub debug_mode: bool
|
||||
}
|
||||
|
||||
pub async fn get_qmdl(State(state): State<Arc<ServerState>>, Path(qmdl_name): Path<String>) -> Result<Response, (StatusCode, String)> {
|
||||
let qmdl_store = state.qmdl_store_lock.read().await;
|
||||
let entry = qmdl_store.entry_for_name(&qmdl_name)
|
||||
let (entry_index, entry) = qmdl_store.entry_for_name(&qmdl_name)
|
||||
.ok_or((StatusCode::NOT_FOUND, format!("couldn't find qmdl file with name {}", qmdl_name)))?;
|
||||
let qmdl_file = qmdl_store.open_entry_qmdl(&entry).await
|
||||
let qmdl_file = qmdl_store.open_entry_qmdl(entry_index).await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("error opening QMDL file: {}", e)))?;
|
||||
let limited_qmdl_file = qmdl_file.take(entry.qmdl_size_bytes as u64);
|
||||
let qmdl_stream = ReaderStream::new(limited_qmdl_file);
|
||||
@@ -38,10 +42,39 @@ pub async fn get_qmdl(State(state): State<Arc<ServerState>>, Path(qmdl_name): Pa
|
||||
// Bundles the server's static files (html/css/js) into the binary for easy distribution
|
||||
static STATIC_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/static");
|
||||
|
||||
pub async fn serve_static(Path(path): Path<String>) -> impl IntoResponse {
|
||||
pub async fn serve_static(State(state): State<Arc<ServerState>>, Path(path): Path<String>) -> impl IntoResponse {
|
||||
let path = path.trim_start_matches('/');
|
||||
let mime_type = mime_guess::from_path(path).first_or_text_plain();
|
||||
|
||||
// if we're in debug mode, return the files from the build directory so we
|
||||
// don't have to rebuild every time the JS/HTML change
|
||||
if state.debug_mode {
|
||||
let mut build_path = std::path::PathBuf::new();
|
||||
build_path.push("bin");
|
||||
build_path.push("static");
|
||||
for part in path.split("/") {
|
||||
build_path.push(part);
|
||||
}
|
||||
return match File::open(build_path).await {
|
||||
Ok(mut file) => {
|
||||
let mut body = String::new();
|
||||
file.read_to_string(&mut body).await.expect("failed to read file");
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_str(mime_type.as_ref()).unwrap(),
|
||||
)
|
||||
.body(Body::from(body))
|
||||
.unwrap()
|
||||
},
|
||||
Err(_) => Response::builder()
|
||||
.status(StatusCode::NOT_FOUND)
|
||||
.body(Body::empty())
|
||||
.unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
match STATIC_DIR.get_file(path) {
|
||||
None => Response::builder()
|
||||
.status(StatusCode::NOT_FOUND)
|
||||
|
||||
Reference in New Issue
Block a user