29 _middleware[_middleware_count++] = mw;
34bool PC::run_middleware(uint8_t slot_id,
HttpReq *req)
36 for (uint8_t i = 0; i < _middleware_count; i++)
51 _rl_max = max_requests;
52 _rl_window_ms = window_ms;
53 _rl_window_start = millis();
59bool PC::rate_limit_check(uint8_t slot_id)
61 if (_rl_max == 0 || _rl_window_ms == 0)
66 uint32_t now = millis();
67 if ((uint32_t)(now - _rl_window_start) >= _rl_window_ms)
69 _rl_window_start = now;
74 if (_rl_count <= _rl_max)
80 uint32_t elapsed = (uint32_t)(now - _rl_window_start);
84 uint32_t remain_ms = (_rl_window_ms > elapsed) ? (_rl_window_ms - elapsed) : 0;
86 pc_sb sb_secs = {secs,
sizeof(secs), 0,
true};
87 pc_sb_u32(&sb_secs, (uint32_t)((
unsigned long)((remain_ms + 999) / 1000)));
93 send(slot_id, 429, PC_MIME_TEXT_PLAIN,
"Too Many Requests");
void enable_rate_limit(uint16_t max_requests, uint32_t window_ms)
Enable a built-in fixed-window request rate limiter.
void use(Middleware mw)
Register a middleware to run before every request is dispatched.
void add_response_header(uint8_t slot_id, const char *name, const char *value)
Queue a custom response header for the next send on this slot.
void send(uint8_t slot_id, int code, const char *content_type, const char *payload)
Send an HTTP response with a body and close the connection.
Shared HTTP Content-Type ("MIME") string constants (one source of truth).
Layer 7 (Application) - public HTTP routing API.
MwResult(* Middleware)(uint8_t slot_id, HttpReq *request)
Composable pre-dispatch middleware (see PC::use()).
@ MW_HALT
Stop dispatch; the middleware already sent a response.
#define MAX_MIDDLEWARE
Maximum globally-registered middleware functions.
Bounded no-heap string builder that fails closed on overflow (one shared copy).
size_t pc_sb_finish(pc_sb *b)
NUL-terminate and return the built length, or 0 if the build overflowed.
void pc_sb_u32(pc_sb *b, uint32_t v)
Append v as decimal (no leading zeros; "0" for zero).
Fully-parsed HTTP/1.1 request.
Bump-append target; ok latches false once an append would overflow cap.