mirror of
https://github.com/phantomptr/ps5upload.git
synced 2026-10-21 11:23:35 -05:00
Fix round 2. The helper refused a request under 500 ms after the last one (429),
which caught the final batch sent as Controls closes, right after a regular one,
so ○ was still lost. The gate is now a pure, host-tested function: one request
marked {"final":true} is admitted inside the window, once per window, each body
still at most 4 KiB. The page marks its final batch (keepalive, cut to fit with
the flag) and sends it only after a regular send still on the wire, so the two
never arrive out of order.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RxCGb8Asp1A1AQYiv1kbgS
53 lines
3.3 KiB
C
53 lines
3.3 KiB
C
/* The console page's input log: what the PS5 browser delivers for each controller button,
|
|
* measured on the console. POST /api/input-log {"events":["<line>",...]} (webui_api.c) appends
|
|
* one line per event to WEBUI_INPUTLOG_PATH, a ring that never grows past WEBUI_INPUTLOG_CAP.
|
|
* The page (client/src/console/inputLog.ts) sends only while its Controls screen asks for it, at
|
|
* most one request a second, each body at most WEBUI_INPUTLOG_BODY_MAX bytes.
|
|
*
|
|
* Pure file I/O and parsing, no globals, no allocation (host-tested in
|
|
* payload/tests/webui_inputlog_selftest.c). Callers serialize appends to one path themselves. */
|
|
#ifndef PS5UPLOAD_WEBUI_INPUTLOG_H
|
|
#define PS5UPLOAD_WEBUI_INPUTLOG_H
|
|
|
|
#include <stddef.h>
|
|
|
|
#define WEBUI_INPUTLOG_PATH "/data/ps5upload/webui-input.log"
|
|
#define WEBUI_INPUTLOG_CAP (64u * 1024u) /* the file's ceiling */
|
|
#define WEBUI_INPUTLOG_BODY_MAX 4096u /* one request's body */
|
|
#define WEBUI_INPUTLOG_LINE_MAX 160u /* one event's line, newline excluded */
|
|
#define WEBUI_INPUTLOG_EVENTS_MAX 256u /* events in one request */
|
|
|
|
/* `arr` (n bytes, not NUL-terminated) is a JSON array as webui_json_array returns it. Every
|
|
* element must be a plain string: 1..WEBUI_INPUTLOG_LINE_MAX bytes of printable ASCII (0x20-0x7e)
|
|
* without a quote or backslash (so no escapes: a line can never carry a newline and forge
|
|
* another), at most WEBUI_INPUTLOG_EVENTS_MAX of them. Writes each as "<string>\n" to `out`.
|
|
* Returns the bytes written (0 for an empty array), or -1: an element breaks a rule, the array
|
|
* is malformed or has trailing bytes, or `out` (cap bytes) is too small. */
|
|
long webui_inputlog_lines(const char *arr, size_t n, char *out, size_t cap);
|
|
|
|
/* Appends `add` (whole lines) to the ring file `path`. While the result stays within `cap` it is
|
|
* a plain O_APPEND write. Otherwise the file is rewritten to its newest whole lines plus `add`,
|
|
* totalling at most cap - cap/4 (the slack makes rewrites rare), through `<path>.tmp` in the same
|
|
* directory, fsync, then rename() over `path` within that directory (never across mounts); when
|
|
* `add` alone is that large only its own newest whole lines are kept. `work` (work_cap bytes, at
|
|
* least `cap`) is the scratch for a rewrite; a smaller one refuses the rewrite. A failure leaves
|
|
* the previous file whole and no temp file behind. 0, or -1. */
|
|
int webui_inputlog_append(const char *path, const char *add, size_t add_len, size_t cap, char *work, size_t work_cap);
|
|
|
|
/* The route's rate gate. A request is admitted when at least `gap_ms` passed since the last
|
|
* admitted one. A request the page marks final ({"final":true}: the last batch as the Controls
|
|
* screen closes or the page is hidden) may come sooner, but only one final per `gap_ms` window,
|
|
* so the mark cannot be used to flood: at most two appends per window, each body still capped at
|
|
* WEBUI_INPUTLOG_BODY_MAX. Pure (the caller holds its lock and passes a monotonic clock).
|
|
* 1 = admitted (the gate is updated), 0 = refused (429; the gate is unchanged). */
|
|
typedef struct {
|
|
long long last_ms; /* last admitted request */
|
|
long long last_final_ms; /* last admitted request that used the final exemption */
|
|
} webui_inputlog_gate;
|
|
|
|
#define WEBUI_INPUTLOG_GATE_INIT { -1000000, -1000000 }
|
|
|
|
int webui_inputlog_gate_admit(webui_inputlog_gate *g, long long now_ms, int final, long long gap_ms);
|
|
|
|
#endif
|