feat: v1.0 — am serve : API HTTP + WebSocket authentifiée pour piloter am à distance (closes #80)
- src/serve.rs : tiny_http (zéro dépendance runtime) — token Bearer obligatoire (comptime-ish), rate limiting fenêtre 60s par IP, routes réutilisant les contrats --json (stats/sessions/ps/providers/run/start/stop/ask) en re-spawnant le binaire (pattern web #54), WebSocket RFC 6455 (handshake 101 + accept sha1, broadcast des events du journal par polling 500ms, première passe = indexation), TLS délégué au reverse proxy (documenté) - am serve --token <TOKEN> [--host] [--port 8080] [--rate-limit 120] + REPL + help + man - 9 tests : auth (sans/mauvais/bon token), routes (runner mocké), run args, 404, rate limit, handshake RFC 6455 (vecteur connu), broadcast journal, comparaison token - E2E réel : curl 401/health/stats + POST run exécutant un agent, client WS brut recevant l'event run en temps réel - version 1.0.0 (milestone v1.0 terminé) ; test version_table suit Cargo.toml (major plus hardcodé)
This commit is contained in:
+3
-1
@@ -30,10 +30,11 @@ pub mod registry_cmd;
|
||||
pub mod run_cmd;
|
||||
pub mod schedule_cmd;
|
||||
pub mod search_cmd;
|
||||
pub mod service_cmd;
|
||||
pub mod secret_cmd;
|
||||
pub mod self_uninstall;
|
||||
pub mod self_update;
|
||||
pub mod serve_cmd;
|
||||
pub mod service_cmd;
|
||||
pub mod sessions_cmd;
|
||||
pub mod stats_cmd;
|
||||
pub mod status_cmd;
|
||||
@@ -124,6 +125,7 @@ pub fn execute_command(app: &App, cmd: &Command) -> Result<i32> {
|
||||
monitor_cmd::run(app, *interval, *json)
|
||||
}
|
||||
Command::Web(args) => web_cmd::run(app, args.port, args.no_open),
|
||||
Command::Serve(args) => serve_cmd::run(app, args),
|
||||
Command::Sync { message } => sync_cmd::run(app, message.as_deref()),
|
||||
Command::Migrate { export, output, bundle } => {
|
||||
migrate_cmd::run(app, *export, output.as_deref(), bundle.as_deref())
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//! am serve — authenticated HTTP + WebSocket API (issue #80).
|
||||
|
||||
use super::*;
|
||||
use crate::cli::ServeArgs;
|
||||
|
||||
pub fn run(app: &App, args: &ServeArgs) -> Result<i32> {
|
||||
let Some(token) = args.token.clone() else {
|
||||
anyhow::bail!("am serve exige --token <token> — le serveur refuse toute requête sans ce token");
|
||||
};
|
||||
crate::serve::run(
|
||||
app,
|
||||
&token,
|
||||
args.host.as_deref().unwrap_or("127.0.0.1"),
|
||||
args.port.unwrap_or(crate::serve::DEFAULT_PORT),
|
||||
args.rate_limit.unwrap_or(crate::serve::DEFAULT_RATE_LIMIT),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user