fix(server): declare the method contract on the three read-only query proxies

/api/opensky, /api/adsblol/mil and /api/route answered any verb with the same
body while ignoring the request entirely. Measured against a running server
before the change: POST /api/opensky returned 200 with 833,759 bytes of live
state vectors, POST /api/adsblol/mil returned 47,372 bytes. Their siblings do
not: /api/geocode, /api/weather and /api/transit answer 405, and /api/overpass
is deliberately POST-only.

These three are read-only query proxies, so they now answer 405 to anything but
GET, using the wording and shape /api/geocode already uses. The refusal comes
first, before rate limiting and before any upstream call, which the tests
assert by stubbing fetch to throw.

Scope, stated plainly: this is a consistency and intent fix. No rate limiter
was being bypassed — /api/route already limits every request regardless of
verb, and the two aircraft routes have no limiter at all, only 9s and 12s
server-side caches that bound upstream cost for any method.

One existing fixture in src/search/geospatial.test.mjs built a request without
a method, which a real Node request always has; it now sets GET.

Verified on a running server after the change: GET still 200 on all three,
POST 405 on all three, /api/overpass and the other proxies unchanged.
Suite goes from 5090 to 5092 tests, 0 failures.
This commit is contained in:
daikaginza committed 2026-09-29 10:52:26 +07:00
1 parent e7707d9a0f
commit b09db55149
7 files changed
+70 -1

No files matched your search

+1
View File
@@ -4072,6 +4072,7 @@ are omitted rather than framing the wrong part of the globe.
- `/api/overpass` is bounded by body/response caps, per-client/global rate limits, concurrency limits, operator-configured upstreams, in-flight dedupe, cache bounds, and static validation that every selector is spatially bounded.
- `/api/military-installations` uses an independent limiter with the same 90-per-client/300-global one-minute bounds, so viewport installation refreshes never consume `/api/overpass` annotation capacity.
- `/api/route` proxies bounded OSRM route requests for annotation routes, with profile allowlisting, distance caps, response caps, caching, and sanitized "no route found" errors.
- `/api/opensky`, `/api/adsblol/mil`, and `/api/route` are read-only query proxies and answer `405 Method Not Allowed` to anything but `GET`, as `/api/geocode` and the other query proxies already did. The refusal precedes rate limiting and any upstream call.
- Track endpoints: `/api/ais-live/track?mmsi=` (server-accumulated ring buffers; sub-route handled before the rows snapshot), `/api/opensky-track?icao24=` (OAuth, 60s cache, sanitized errors, independent OpenSky credit bucket), `/api/adsblol/trace?hex=` (60s cache, 5MB cap, ODbL attribution required in UI).
- Realtime debug logs redact API keys, bearer tokens, client secrets, and image data URLs before writing to disk; request bodies are size-capped.
- `/api/realtime/debug-log` enforces an always-on 120-per-client/400-global one-minute limiter (not the opt-in `GEV_RATELIMIT_OPENAI_PER_MIN` bucket the cost-bearing OpenAI routes share), appends asynchronously through a serialized queue, and rotates `realtime-conversations.jsonl` at 32 MB keeping one prior generation, so the sink is bounded at twice that regardless of session length. A malformed record answers 400 and a failed write 500, both with a fixed message.