Some checks failed
Quality gates / quality (pull_request) Failing after 2m39s
Closes the PR 63 hostile-review blockers: 1. Immutable pinned Python/Pillow runtime (TIMMY_PYTHON absolute, --verify-pin), deployment/runtime re-encode smoke gate in build_release + deploy_staging. 2. Header-only width/height/total-pixel/bomb rejection before full decode; proves 6000x6000 and 12000x12000 stay resource bounded (RSS + address-space caps). 3. Fail-fast decoder concurrency ceiling; tests count actual spawned children. 4. Rate-limiter key cardinality hard-bounded under 20k+ unexpired identities, trusted-loopback-proxy identity, no spoofable forwarded headers, fixed-window boundary burst smoothed by two-window sliding count. 5. build_release explicitly syntax/gates every new JS module + Python re-encoder + production-runtime smoke; CI runs reencode-image test and the runtime pin smoke. 6. Robust polyglot contract via canonical container parsing; rejects uppercase/mixed script, appended HTML, ZIP local/EOCD and archive tails, data after canonical JPEG/PNG/WebP end; no naive compressed-byte scans (false-positive controls pass). 7. Canonical base64 data-URL grammar with byte-exact round trip; rejects missing/excess padding, whitespace/CRLF, malformed and noncanonical encodings; exact MIME policy. 8. Missing Pillow / runtime-unavailable maps to sanitized 503 + manual fallback. 9. Inbound body-read timeout and stop-on-oversize; preserves sanitized 413, base path, provider suppression, and temp cleanup; socket torn down on rejection. Audited prior partial edits: reused the sound source modules, re-wired new tests into the unit/syntax gates, fixed a non-canonical readJson that destroyed the socket before delivering 413/408, and hardened test flakiness (port reuse, EPIPE, startup races).
32 lines
1.5 KiB
JavaScript
32 lines
1.5 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import { createRateLimiter } from '../src/rate-limiter.js';
|
|
|
|
test('rate limiter blocks after the configured burst and recovers once the window drains', () => {
|
|
const limiter = createRateLimiter({ windowMs: 1000, maxRequests: 3 });
|
|
const t0 = 1_000_000;
|
|
assert.equal(limiter.take('k', t0).allowed, true);
|
|
assert.equal(limiter.take('k', t0 + 1).allowed, true);
|
|
assert.equal(limiter.take('k', t0 + 2).allowed, true);
|
|
const blocked = limiter.take('k', t0 + 3);
|
|
assert.equal(blocked.allowed, false);
|
|
assert.ok(blocked.retryAfterMs > 0 && blocked.retryAfterMs <= 1000);
|
|
// Crossing the window boundary must NOT immediately grant a fresh full
|
|
// budget: that is the boundary-doubling burst. The trailing count decays, so
|
|
// capacity returns only once the earlier requests have actually aged out.
|
|
assert.equal(limiter.take('k', t0 + 1001).allowed, false,
|
|
'a 1ms boundary straddle must not reset the budget');
|
|
assert.equal(limiter.take('k', t0 + 2001).allowed, true,
|
|
'capacity must return once the window has genuinely drained');
|
|
});
|
|
|
|
test('rate limiter keys are isolated and never expose payload data', () => {
|
|
const limiter = createRateLimiter({ windowMs: 60_000, maxRequests: 1 });
|
|
assert.equal(limiter.take('a').allowed, true);
|
|
assert.equal(limiter.take('b').allowed, true);
|
|
const blocked = limiter.take('a');
|
|
assert.equal(blocked.allowed, false);
|
|
assert.doesNotMatch(blocked.reason, /image|base64|byte/i);
|
|
});
|