mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-17 12:16:21 +02:00
Lot 4 (socle) : store accessible à Rust, routeur /api côté façade
Le Go expose sa base à la façade par l'API interne : lecture, écriture, suppression d'une clé et lecture d'un bucket entier. Il reste l'unique propriétaire du fichier bbolt ; les écritures passent par putBytes/update et invalident son cache comme une écriture locale. Base illisible : 503, pour que Rust distingue « rien » de « pas pu lire ». Côté Rust : client du store (seul point de passage, que la migration finale de la base ne touchera qu'ici), routeur /api avec contexte partagé et garde d'authentification réutilisable ; /api/ping y emménage. Modules réservés aux aides portées ensuite (système, état du moteur, presets, chemins, GGUF). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a672760f3c
commit
bea29bc6a9
14 files changed
+401
-22
No files matched your search
+16
-22
@@ -1,5 +1,5 @@
|
||||
//! Façade HTTP : reçoit tout le trafic public. Les routes déjà réécrites en
|
||||
//! Rust sont servies ici (lot 2 : UI statique, `/api/ping`) ; tout le reste
|
||||
//! Rust sont servies ici (UI statique, routes de `api.rs`) ; tout le reste
|
||||
//! est relayé au serveur Go (`loki web` sur 127.0.0.1).
|
||||
//!
|
||||
//! Règles, héritées de `web_server.go` :
|
||||
@@ -27,7 +27,10 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use crate::auth::{self, HostEnv, INTERNAL_HEADER, InternalClient};
|
||||
use crate::api;
|
||||
use crate::auth::{HostEnv, INTERNAL_HEADER, InternalClient};
|
||||
use crate::engine;
|
||||
use crate::store::Store;
|
||||
use crate::ui;
|
||||
|
||||
pub type Body = BoxBody<Bytes, hyper::Error>;
|
||||
@@ -53,13 +56,14 @@ pub struct Config {
|
||||
/// Jeton de l'API interne du Go (`LOKI_INTERNAL_TOKEN`).
|
||||
pub internal_token: String,
|
||||
pub host_env: HostEnv,
|
||||
/// `$LOKI_HOME` et service moteur, pour les routes portées.
|
||||
pub engine: engine::Paths,
|
||||
}
|
||||
|
||||
struct Proxy {
|
||||
client: Client<HttpConnector, Incoming>,
|
||||
backend: SocketAddr,
|
||||
internal: InternalClient,
|
||||
host_env: HostEnv,
|
||||
ctx: api::Ctx,
|
||||
}
|
||||
|
||||
/// Sert la façade sur `listener` jusqu'à ce que `shutdown` se termine.
|
||||
@@ -72,8 +76,12 @@ pub async fn serve(
|
||||
let proxy = Arc::new(Proxy {
|
||||
client,
|
||||
backend: cfg.backend,
|
||||
internal: InternalClient::new(cfg.backend, cfg.internal_token),
|
||||
host_env: cfg.host_env,
|
||||
ctx: api::Ctx {
|
||||
store: Store::new(cfg.backend, cfg.internal_token.clone()),
|
||||
internal: InternalClient::new(cfg.backend, cfg.internal_token),
|
||||
host_env: cfg.host_env,
|
||||
engine: cfg.engine,
|
||||
},
|
||||
});
|
||||
tokio::pin!(shutdown);
|
||||
loop {
|
||||
@@ -123,26 +131,12 @@ impl Proxy {
|
||||
if let Some(resp) = ui::serve(req.method(), path, req.headers()) {
|
||||
return resp;
|
||||
}
|
||||
if path == "/api/ping" {
|
||||
return self.ping(req.headers()).await;
|
||||
if api::handles(req.method(), path) {
|
||||
return api::serve(&self.ctx, req).await;
|
||||
}
|
||||
self.forward(req).await
|
||||
}
|
||||
|
||||
/// `/api/ping` : vérifie la connectivité ET la clé (200 = bonne clé,
|
||||
/// 401 = mauvaise clé), comme `handlePing`.
|
||||
async fn ping(&self, headers: &HeaderMap) -> Response<Body> {
|
||||
let info = self.internal.auth().await;
|
||||
if let Some(refus) = auth::authorize(headers, &info, &self.host_env) {
|
||||
return refus;
|
||||
}
|
||||
let version = info.map(|i| i.version).unwrap_or_default();
|
||||
auth::json(
|
||||
StatusCode::OK,
|
||||
&serde_json::json!({ "ok": true, "service": "loki", "version": version }),
|
||||
)
|
||||
}
|
||||
|
||||
/// Relais vers le Go (HTTP, SSE, WebSocket).
|
||||
async fn forward(&self, mut req: Request<Incoming>) -> Response<Body> {
|
||||
let upgrade = upgrade_protocol(req.headers());
|
||||
|
||||
Reference in new issue
Block a user