-
Notifications
You must be signed in to change notification settings - Fork 195
Expand file tree
/
Copy pathserver.js
More file actions
78 lines (70 loc) · 2.8 KB
/
Copy pathserver.js
File metadata and controls
78 lines (70 loc) · 2.8 KB
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
70
71
72
73
74
75
76
77
78
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const path = require('path');
const http = require('http');
const app = express();
const PORT = process.env.PORT || 8080;
// Backend API URL (injected via BACKEND_URL env var at deployment time)
if (!process.env.BACKEND_URL) {
console.error('ERROR: BACKEND_URL environment variable is not set. API proxy will not work.');
}
const BACKEND_URL = process.env.BACKEND_URL;
// Create HTTP agent with extended keep-alive timeout for long-running SSE connections
const httpAgent = new http.Agent({
keepAlive: true,
keepAliveMsecs: 300000, // 5 minutes keep-alive
maxSockets: 100,
timeout: 600000 // 10 minutes socket timeout
});
// Proxy API requests to backend
if (BACKEND_URL) {
app.use('/api', createProxyMiddleware({
target: BACKEND_URL,
changeOrigin: true,
pathRewrite: {
'^/': '/api/'
},
agent: httpAgent,
// Increase timeout for long-running requests (10 minutes)
proxyTimeout: 600000,
timeout: 600000,
// Support streaming responses (SSE)
onProxyRes: (proxyRes, req, res) => {
// Disable buffering for streaming responses
if (proxyRes.headers['content-type']?.includes('text/event-stream')) {
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
res.setHeader('X-Accel-Buffering', 'no');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders();
}
// Log response for debugging
console.log(`Proxy response: ${req.method} ${req.path} -> ${proxyRes.statusCode}`);
},
onProxyReq: (proxyReq, req, res) => {
// Log request for debugging
console.log(`Proxy request: ${req.method} ${req.path}`);
},
onError: (err, req, res) => {
console.error('Proxy error:', err.message);
if (!res.headersSent) {
res.status(502).json({ error: 'Backend service unavailable', details: err.message });
}
}
}));
}
// Serve static files from the build directory
app.use(express.static(path.join(__dirname, 'static')));
// Serve index.html for all other routes (SPA support)
app.get('/{*path}', (req, res) => {
res.sendFile(path.join(__dirname, 'static', 'index.html'));
});
// Create server with extended timeouts for SSE
const server = app.listen(PORT, () => {
console.log(`Frontend server running on port ${PORT}`);
console.log(`Proxying API requests to ${BACKEND_URL}`);
});
// Extend server timeouts for long-running SSE connections
server.keepAliveTimeout = 620000; // 10 minutes + buffer
server.headersTimeout = 630000; // Slightly higher than keepAliveTimeout
server.timeout = 0; // Disable request timeout (handled by proxy)
console.log('Server timeouts configured for SSE streaming');