Files
timmy ba9afe0a1d feat(ingress): decide photo validity from bytes, budget, and header before any provider work (#16)
The declared data-URL MIME was a claim the boundary believed. Every image decision now comes from
the bytes: the container is sniffed, walked to its own end marker, refused when metadata segments
remain, and refused above a 4096px edge or 16MP. The request path adds a per-caller sliding-window
budget (429 + Retry-After) and a body deadline (408), so a flood, a stalled body, or a decode bomb
fails before a provider call.

Log hygiene is part of the contract: refusal copy is fixed prose, the bucket key is a salted hash
kept in memory only, and the acceptance test asserts no image bytes reach the process log.
2026-10-20 08:21:20 +00:00

59 lines
1.9 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { PassThrough } from 'node:stream';
import { BodyError, readJsonBody } from '../src/http-body.js';
const bodyStream = chunks => {
const stream = new PassThrough();
for (const chunk of chunks) stream.write(chunk);
stream.end();
return stream;
};
test('reads a bounded JSON request body', async () => {
const parsed = await readJsonBody(bodyStream([Buffer.from('{"consent":'), Buffer.from('true}')]), { maxBytes: 1024 });
assert.deepEqual(parsed, { consent: true });
});
test('refuses a body above the byte limit instead of buffering it', async () => {
await assert.rejects(
() => readJsonBody(bodyStream([Buffer.alloc(64, 0x61)]), { maxBytes: 16 }),
error => {
assert.ok(error instanceof BodyError);
assert.equal(error.code, 'too_large');
assert.equal(error.status, 413);
return true;
},
);
});
test('refuses malformed JSON with a client error', async () => {
await assert.rejects(
() => readJsonBody(bodyStream([Buffer.from('{not json')]), { maxBytes: 1024 }),
error => {
assert.ok(error instanceof BodyError);
assert.equal(error.code, 'invalid_json');
assert.equal(error.status, 400);
return true;
},
);
});
test('gives up on a body that never finishes and stops reading it', async () => {
const stalled = new PassThrough();
stalled.write(Buffer.from('{"consent":true'));
const started = Date.now();
await assert.rejects(
() => readJsonBody(stalled, { maxBytes: 1024, timeoutMs: 40 }),
error => {
assert.ok(error instanceof BodyError);
assert.equal(error.code, 'body_timeout');
assert.equal(error.status, 408);
return true;
},
);
assert.ok(Date.now() - started < 2_000, 'the deadline must fire promptly');
assert.equal(stalled.isPaused(), true, 'the stalled body must stop being read after the deadline');
});