Spaces:
Runtime error
Runtime error
File size: 2,246 Bytes
077865a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import type { Express } from 'express';
import { createApp } from '../../app.js';
import { initDb } from '../../db/index.js';
async function request(app: Express, headers: Record<string, string> = {}) {
const server = app.listen(0);
const addr = server.address() as any;
const url = `http://127.0.0.1:${addr.port}/v1/chat/completions`;
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...headers },
body: JSON.stringify({ messages: [{ role: 'user', content: 'hi' }] }),
});
const text = await res.text();
server.close();
let json: any = null;
try { json = JSON.parse(text); } catch {}
return { status: res.status, body: json, headers: res.headers };
}
describe('Proxy per-IP rate limiting (#35 item #6)', () => {
const originalRpm = process.env.PROXY_RATE_LIMIT_RPM;
beforeAll(() => {
process.env.ENCRYPTION_KEY = '0'.repeat(64);
initDb(':memory:');
});
afterAll(() => {
if (originalRpm === undefined) delete process.env.PROXY_RATE_LIMIT_RPM;
else process.env.PROXY_RATE_LIMIT_RPM = originalRpm;
});
it('returns 429 once the per-minute cap is exceeded', async () => {
// Limiter reads the env at createApp() time, so set it before building.
process.env.PROXY_RATE_LIMIT_RPM = '3';
const app = createApp();
// First 3 requests pass the limiter (they 401 on auth, but the limiter is
// upstream of auth, so each one still counts against the window).
for (let i = 0; i < 3; i++) {
const res = await request(app);
expect(res.status).not.toBe(429);
}
// The 4th trips the limit.
const limited = await request(app);
expect(limited.status).toBe(429);
expect(limited.body.error.type).toBe('rate_limit_error');
expect(limited.headers.get('retry-after')).toBeTruthy();
expect(limited.headers.get('x-ratelimit-limit')).toBe('3');
});
it('does not rate-limit when PROXY_RATE_LIMIT_RPM=0', async () => {
process.env.PROXY_RATE_LIMIT_RPM = '0';
const app = createApp();
for (let i = 0; i < 5; i++) {
const res = await request(app);
expect(res.status).not.toBe(429);
}
});
});
|