/
nayvok
/
livecoding
Обзор
Документация
Войти
/
nayvok
/
livecoding
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
runner/src/server.ts
86 строк
3 KB
nayvok
fix: harden sessions and WebRTC recovery
17 июн 2026, 22:02
17 июн 2026, 22:02
37b9a92
Код
Авторство
О чём код?
import express, { type Request, type Response } from 'express' import { executeNode } from './executors/node.js' import { executePython } from './executors/python.js' import { getLocalAddresses, isLocalSourceAddress } from './networkGuard.js' import { createExecutionGate } from './executionGate.js' import { DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS, type RunLanguage, type RunRequest, type RunResult, } from './types.js' const PORT = Number(process.env.PORT ?? 4000) const MAX_CODE_LENGTH = 64 * 1024 const ALLOW_LOCAL_RUN_REQUESTS = process.env.ALLOW_LOCAL_RUN_REQUESTS === 'true' const LOCAL_ADDRESSES = getLocalAddresses() const MAX_CONCURRENT_RUNS = Number(process.env.MAX_CONCURRENT_RUNS ?? 1) const executionGate = createExecutionGate(MAX_CONCURRENT_RUNS) const app = express() app.disable('x-powered-by') app.use(express.json({ limit: '128kb' })) app.get('/health', (_req: Request, res: Response) => { res.json({ status: 'ok' }) }) app.post('/run', async (req: Request, res: Response) => { if ( !ALLOW_LOCAL_RUN_REQUESTS && isLocalSourceAddress(req.socket.remoteAddress, LOCAL_ADDRESSES) ) { res.status(403).json({ error: 'Local runner calls are not allowed' }) return } const body = req.body as Partial<RunRequest> | undefined if (!body || typeof body.code !== 'string' || typeof body.language !== 'string') { res.status(400).json({ error: 'Bad request: code and language are required' }) return } if (body.code.length === 0) { res.status(400).json({ error: 'Bad request: code is empty' }) return } if (body.code.length > MAX_CODE_LENGTH) { res.status(413).json({ error: 'Payload too large: code exceeds 64KB' }) return } const language = body.language as RunLanguage if (language !== 'javascript' && language !== 'python') { res.status(400).json({ error: `Unsupported language: ${language}` }) return } const requested = typeof body.timeoutMs === 'number' ? body.timeoutMs : DEFAULT_TIMEOUT_MS const timeoutMs = Math.min(Math.max(requested, 100), MAX_TIMEOUT_MS) const releaseExecution = executionGate.tryAcquire() if (!releaseExecution) { res.status(429).json({ error: 'Runner is busy' }) return } let result: RunResult try { if (language === 'javascript') { result = await executeNode(body.code, timeoutMs) } else { result = await executePython(body.code, timeoutMs) } } catch (err) { res.status(500).json({ error: `Execution failed: ${(err as Error).message}` }) return } finally { releaseExecution() } res.json(result) }) app.listen(PORT, () => { console.log(`[runner] listening on http://0.0.0.0:${PORT}`) })