Files
MikrotikManager/tests/integration/next-proxy-timeout.mjs

47 lines
2.4 KiB
JavaScript

import assert from 'node:assert/strict';
import http from 'node:http';
import url from 'node:url';
import configExports from 'next/dist/server/config.js';
import constants from 'next/constants.js';
import proxyExports from 'next/dist/server/lib/router-utils/proxy-request.js';
const loadConfig = configExports.default;
const { PHASE_DEVELOPMENT_SERVER } = constants;
const { proxyRequest } = proxyExports;
// Exercise the installed Next proxy with the project's loaded config and real sockets.
// A delayed structured failure must reach the caller beyond Next's default 30s.
(async () => {
const config = await loadConfig(PHASE_DEVELOPMENT_SERVER, process.cwd());
const pending = new Set();
const backend = http.createServer((request, response) => {
request.resume();
const timer = setTimeout(() => {
pending.delete(timer);
response.writeHead(502, { 'content-type': 'application/json' });
response.end(JSON.stringify({ error: 'Backend timeout receipt', outcome: 'unknown' }));
}, 31_000);
pending.add(timer);
});
const proxy = http.createServer((request, response) => {
const target = url.parse(`http://127.0.0.1:${backend.address().port}${request.url}`, true);
proxyRequest(request, response, target, undefined, undefined, config.experimental.proxyTimeout)
.catch(() => { if (!response.headersSent) response.writeHead(500); response.end(); });
});
const listen = server => new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
try {
await listen(backend); await listen(proxy);
const started = Date.now();
const response = await fetch(`http://127.0.0.1:${proxy.address().port}/api/uptime/speed-test`, {
method: 'POST', body: '{}', headers: { 'content-type': 'application/json' }, signal: AbortSignal.timeout(60_000),
});
assert.equal(response.status, 502, 'Next must preserve the backend failure receipt after 30s');
assert.deepEqual(await response.json(), { error: 'Backend timeout receipt', outcome: 'unknown' });
assert(Date.now() - started >= 31_000);
console.log('Next proxy: delayed 502 JSON preserved beyond 30s');
} finally {
for (const timer of pending) clearTimeout(timer);
proxy.closeAllConnections(); backend.closeAllConnections();
await Promise.all([proxy, backend].map(server => new Promise(resolve => server.close(resolve))));
}
})().catch(error => { console.error(error.message); process.exitCode = 1; });