fix(routes): fix handle_request ABI, 429 status code, soul_boot_ts write
Neuron Soul CI / build (pull_request) Has been cancelled
Neuron Soul CI / build (pull_request) Has been cancelled
This commit is contained in:
@@ -18,6 +18,13 @@ import "soul.elh"
|
|||||||
// minute). Falls back to 60 req/min if not set. The /health endpoint is
|
// minute). Falls back to 60 req/min if not set. The /health endpoint is
|
||||||
// exempt so monitoring does not consume quota.
|
// exempt so monitoring does not consume quota.
|
||||||
//
|
//
|
||||||
|
// State growth: each unique source IP accumulates exactly 2 state keys
|
||||||
|
// (count + window) for the lifetime of the process. Per-IP storage is
|
||||||
|
// bounded and constant; values reset on window expiry. In aggregate, state
|
||||||
|
// grows linearly with distinct IPs — typical for a trusted-client service.
|
||||||
|
// EL has no state_delete builtin, so keys from inactive IPs persist.
|
||||||
|
// TODO: add state_delete sweep when the EL runtime exposes that primitive.
|
||||||
|
//
|
||||||
// Returns "" when the request is allowed, or a 429 JSON body when rejected.
|
// Returns "" when the request is allowed, or a 429 JSON body when rejected.
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
fn rate_limit_check(ip: String, path: String) -> String {
|
fn rate_limit_check(ip: String, path: String) -> String {
|
||||||
@@ -54,7 +61,7 @@ fn rate_limit_check(ip: String, path: String) -> String {
|
|||||||
if new_count > limit {
|
if new_count > limit {
|
||||||
let retry_after: Int = 60 - (now - eff_win)
|
let retry_after: Int = 60 - (now - eff_win)
|
||||||
let eff_retry: Int = if retry_after < 0 { 0 } else { retry_after }
|
let eff_retry: Int = if retry_after < 0 { 0 } else { retry_after }
|
||||||
return "{\"error\":\"rate limit exceeded\",\"code\":\"rate_limited\",\"retry_after_secs\":" + int_to_str(eff_retry) + "}"
|
return "{\"__status__\":429,\"error\":\"rate limit exceeded\",\"code\":\"rate_limited\",\"retry_after_secs\":" + int_to_str(eff_retry) + "}"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -331,11 +338,13 @@ fn handle_connectors(method: String, clean: String, body: String) -> String {
|
|||||||
return "{\"ok\":false,\"error\":\"unknown connectors route\"}"
|
return "{\"ok\":false,\"error\":\"unknown connectors route\"}"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_request(method: String, path: String, body: String, ip: String) -> String {
|
fn handle_request(method: String, path: String, body: String) -> String {
|
||||||
let clean: String = strip_query(path)
|
let clean: String = strip_query(path)
|
||||||
|
|
||||||
// Rate limit check. ip may be empty (e.g. loopback/unix socket callers) — skip
|
// Rate limit check. Extract caller IP from REMOTE_ADDR env var (set by the
|
||||||
// enforcement when no address is available so internal tooling is never blocked.
|
// EL HTTP runtime for each request). Skip enforcement when empty so
|
||||||
|
// loopback/internal callers are never blocked.
|
||||||
|
let ip: String = env("REMOTE_ADDR")
|
||||||
if !str_eq(ip, "") {
|
if !str_eq(ip, "") {
|
||||||
let rl_result: String = rate_limit_check(ip, clean)
|
let rl_result: String = rate_limit_check(ip, clean)
|
||||||
if !str_eq(rl_result, "") {
|
if !str_eq(rl_result, "") {
|
||||||
|
|||||||
@@ -369,6 +369,7 @@ load_identity_context()
|
|||||||
seed_persona_from_env()
|
seed_persona_from_env()
|
||||||
let boot_num: Int = mem_boot_count_inc()
|
let boot_num: Int = mem_boot_count_inc()
|
||||||
state_set("soul_boot_count", int_to_str(boot_num))
|
state_set("soul_boot_count", int_to_str(boot_num))
|
||||||
|
state_set("soul_boot_ts", int_to_str(time_now()))
|
||||||
println("[soul] boot #" + int_to_str(boot_num))
|
println("[soul] boot #" + int_to_str(boot_num))
|
||||||
emit_session_start_event()
|
emit_session_start_event()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user