perf: fix memory leaks, optimize tracing logs, fix networking eof fragmentation bug in nvim-core and stub, and deduplicate json-rpc handlers
This commit is contained in:
1 parent
ce88bef45e
commit
f76d8ccce8
23 files changed
+1373
-803
No files matched your search
@@ -0,0 +1,107 @@
|
||||
use crate::AppState;
|
||||
use crate::error::AppError;
|
||||
use crate::models::GateRecord;
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Query, State},
|
||||
response::IntoResponse,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct GateVerifyReq {
|
||||
pub action: String,
|
||||
pub target: String,
|
||||
pub namespace: Option<String>,
|
||||
#[serde(default)]
|
||||
pub params: HashMap<String, String>,
|
||||
#[serde(default)]
|
||||
pub consume: bool,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct GateSetReq {
|
||||
pub action: String,
|
||||
pub target: String,
|
||||
pub namespace: Option<String>,
|
||||
#[serde(default)]
|
||||
pub params: HashMap<String, String>,
|
||||
pub authorize: Option<bool>,
|
||||
pub block: Option<bool>,
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn gate_verify_handler(
|
||||
State(app_state): State<Arc<AppState>>,
|
||||
Query(q): Query<GateVerifyReq>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
let mut found = None;
|
||||
let mut to_remove = None;
|
||||
app_state.handler.state.gates.modify(|gates| {
|
||||
if let Some(idx) = gates.iter().position(|g| {
|
||||
g.action == q.action
|
||||
&& g.target == q.target
|
||||
&& g.namespace == q.namespace
|
||||
&& g.params == q.params
|
||||
}) {
|
||||
found = Some(gates[idx].clone());
|
||||
if q.consume {
|
||||
to_remove = Some(idx);
|
||||
}
|
||||
}
|
||||
if let Some(idx) = to_remove {
|
||||
gates.remove(idx);
|
||||
}
|
||||
});
|
||||
|
||||
match found {
|
||||
Some(record) => {
|
||||
if record.status == "authorized" {
|
||||
Ok((axum::http::StatusCode::OK, "Authorized"))
|
||||
} else {
|
||||
let msg = if let Some(r) = record.reason {
|
||||
format!("Action blocked. Reason: {}", r)
|
||||
} else {
|
||||
"Action blocked.".to_string()
|
||||
};
|
||||
Err(AppError::Forbidden(msg))
|
||||
}
|
||||
}
|
||||
None => Err(AppError::NotFound("Action not yet authorized (no gate record found).".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn gate_set_handler(
|
||||
State(app_state): State<Arc<AppState>>,
|
||||
Json(body): Json<GateSetReq>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
let status = if body.block.unwrap_or(false) {
|
||||
"blocked".to_string()
|
||||
} else if body.authorize.unwrap_or(false) {
|
||||
"authorized".to_string()
|
||||
} else {
|
||||
"pending".to_string()
|
||||
};
|
||||
|
||||
let record = GateRecord {
|
||||
id: uuid::Uuid::new_v4().to_string(),
|
||||
action: body.action.clone(),
|
||||
target: body.target.clone(),
|
||||
namespace: body.namespace.clone(),
|
||||
params: body.params.clone(),
|
||||
status,
|
||||
reason: body.reason.clone(),
|
||||
timestamp: crate::handlers::utils::now_secs(),
|
||||
};
|
||||
app_state.handler.state.gates.modify(|gates| {
|
||||
gates.retain(|g| !(g.action == record.action && g.target == record.target));
|
||||
gates.push(record);
|
||||
});
|
||||
|
||||
Ok((axum::http::StatusCode::OK, "Gate state updated."))
|
||||
}
|
||||
|
||||
pub async fn health_handler() -> &'static str {
|
||||
"OK"
|
||||
}
|
||||
Reference in new issue
Block a user