Skip to content

Commit a9c5c5b

Browse files
author
Brian Genisio
committed
Porting the server to Node.js so we can use websockets easier
1 parent 3240ed2 commit a9c5c5b

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

server.js

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
const http = require('http');
2+
const fs = require('fs');
3+
const path = require('path');
4+
5+
class RequestHandler {
6+
constructor(req, res) {
7+
this.req = req;
8+
this.res = res;
9+
}
10+
11+
sendJsonResponse(statusCode, data) {
12+
this.res.writeHead(statusCode, {
13+
'Content-Type': 'application/json',
14+
'Access-Control-Allow-Origin': '*',
15+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS'
16+
});
17+
this.res.end(JSON.stringify(data));
18+
}
19+
20+
handleGet() {
21+
// Serve static files like SimpleHTTPRequestHandler
22+
const filePath = path.join(process.cwd(), this.req.url === '/' ? 'index.html' : this.req.url);
23+
24+
fs.readFile(filePath, (err, data) => {
25+
if (err) {
26+
if (err.code === 'ENOENT') {
27+
this.sendJsonResponse(404, { error: 'Not Found' });
28+
} else {
29+
this.sendJsonResponse(500, { error: 'Internal Server Error' });
30+
}
31+
return;
32+
}
33+
34+
// Determine content type based on file extension
35+
const ext = path.extname(filePath);
36+
let contentType = 'text/html';
37+
38+
switch (ext) {
39+
case '.js':
40+
contentType = 'text/javascript';
41+
break;
42+
case '.css':
43+
contentType = 'text/css';
44+
break;
45+
case '.json':
46+
contentType = 'application/json';
47+
break;
48+
case '.png':
49+
contentType = 'image/png';
50+
break;
51+
case '.jpg':
52+
contentType = 'image/jpg';
53+
break;
54+
}
55+
56+
this.res.writeHead(200, { 'Content-Type': contentType });
57+
this.res.end(data);
58+
});
59+
}
60+
61+
handlePost() {
62+
if (this.req.url === '/answers') {
63+
let body = '';
64+
65+
this.req.on('data', (chunk) => {
66+
body += chunk.toString();
67+
});
68+
69+
this.req.on('end', () => {
70+
try {
71+
const data = JSON.parse(body);
72+
const formattedData = JSON.stringify(data, null, 2);
73+
74+
fs.writeFile('answers.json', formattedData, (err) => {
75+
if (err) {
76+
this.sendJsonResponse(500, { error: 'Failed to write file' });
77+
return;
78+
}
79+
this.sendJsonResponse(200, { status: 'success' });
80+
});
81+
} catch (e) {
82+
this.sendJsonResponse(400, { error: 'Invalid JSON' });
83+
}
84+
});
85+
} else {
86+
this.sendJsonResponse(404, { error: 'Not Found' });
87+
}
88+
}
89+
}
90+
91+
function runServer(port = 3000) {
92+
try {
93+
const server = http.createServer((req, res) => {
94+
const handler = new RequestHandler(req, res);
95+
96+
if (req.method === 'GET') {
97+
handler.handleGet();
98+
} else if (req.method === 'POST') {
99+
handler.handlePost();
100+
} else if (req.method === 'OPTIONS') {
101+
// Handle CORS preflight requests
102+
res.writeHead(204, {
103+
'Access-Control-Allow-Origin': '*',
104+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
105+
'Access-Control-Allow-Headers': 'Content-Type'
106+
});
107+
res.end();
108+
} else {
109+
handler.sendJsonResponse(405, { error: 'Method Not Allowed' });
110+
}
111+
});
112+
113+
server.listen(port, () => {
114+
console.log(`Server running on port ${port}...`);
115+
});
116+
117+
server.on('error', (e) => {
118+
console.error(`Failed to start server: ${e.message}`);
119+
process.exit(1);
120+
});
121+
} catch (e) {
122+
console.error(`Failed to start server: ${e.message}`);
123+
process.exit(1);
124+
}
125+
}
126+
127+
if (require.main === module) {
128+
runServer();
129+
}
130+
131+
module.exports = { runServer };

0 commit comments

Comments
 (0)