/** * HTTP Middleware for Worker Service * * Extracted from WorkerService.ts for better organization. * Handles request/response logging, CORS, JSON parsing, and static file serving. */ import express, { Request, Response, NextFunction, RequestHandler } from 'express'; import cors from 'cors'; import path from 'path'; import { getPackageRoot } from '../../../shared/paths.js'; import { logger } from '../../../utils/logger.js'; /** * Create all middleware for the worker service * @param summarizeRequestBody - Function to summarize request bodies for logging * @returns Array of middleware functions */ export function createMiddleware( summarizeRequestBody: (method: string, path: string, body: any) => string ): RequestHandler[] { const middlewares: RequestHandler[] = []; // JSON parsing with 50mb limit middlewares.push(express.json({ limit: '50mb' })); // CORS middlewares.push(cors()); // HTTP request/response logging middlewares.push((req: Request, res: Response, next: NextFunction) => { // Skip logging for static assets and health checks if (req.path.startsWith('/health') || req.path === '/' || req.path.includes('.')) { return next(); } const start = Date.now(); const requestId = `${req.method}-${Date.now()}`; // Log incoming request with body summary const bodySummary = summarizeRequestBody(req.method, req.path, req.body); logger.info('HTTP', `→ ${req.method} ${req.path}`, { requestId }, bodySummary); // Capture response const originalSend = res.send.bind(res); res.send = function(body: any) { const duration = Date.now() - start; logger.info('HTTP', `← ${res.statusCode} ${req.path}`, { requestId, duration: `${duration}ms` }); return originalSend(body); }; next(); }); // Serve static files for web UI (viewer-bundle.js, logos, fonts, etc.) const packageRoot = getPackageRoot(); const uiDir = path.join(packageRoot, 'plugin', 'ui'); middlewares.push(express.static(uiDir)); return middlewares; } /** * Summarize request body for logging * Used to avoid logging sensitive data or large payloads */ export function summarizeRequestBody(method: string, path: string, body: any): string { if (!body || Object.keys(body).length === 0) return ''; // Session init if (path.includes('/init')) { return ''; } // Observations if (path.includes('/observations')) { const toolName = body.tool_name || '?'; const toolInput = body.tool_input; const toolSummary = logger.formatTool(toolName, toolInput); return `tool=${toolSummary}`; } // Summarize request if (path.includes('/summarize')) { return 'requesting summary'; } return ''; }