-
Notifications
You must be signed in to change notification settings - Fork 13
/
server.js
102 lines (89 loc) · 3.15 KB
/
server.js
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import http from 'http';
import fs from 'fs';
import path from 'path';
const root = process.env.ROOT || '.';
const userHeaders = JSON.parse(process.env.HEAD || null);
const mimeLookup = new Map([
['.css', 'text/css'],
['.html', 'text/html'],
['.ico', 'image/x-icon'],
['.js', 'application/javascript'],
['.json', 'application/json'],
['.md', 'text/markdown'],
['.png', 'image/png'],
['.txt', 'text/plain'],
]);
class Server {
static origin;
static requestListener(request, response) {
if (request.method === 'GET') {
const url = new URL(request.url, Server.origin);
const filePath = path.resolve(`${root}/${url.pathname}`);
const fileExt = path.extname(filePath);
const mimeType = mimeLookup.get(fileExt);
if (fileExt) {
if (mimeType) {
fs.stat(filePath, (error, stats) => {
if (stats) {
Server.sendFile(response, filePath, mimeType, stats.size);
} else {
Server.sendFileNotFound(response);
}
});
} else {
Server.sendUnknownMimeType(response, fileExt);
}
} else {
if (url.pathname.endsWith('/')) {
const directoryIndex = `${filePath}/index.html`;
fs.stat(directoryIndex, (error, stats) => {
if (stats) {
Server.sendFile(response, directoryIndex, 'text/html', stats.size);
} else {
// @TODO pushState optional
Server.sendRootIndex(response);
}
});
} else {
Server.sendRedirect(response, `${url.pathname}/`);
}
}
}
}
static sendUnknownMimeType(response, fileExt) {
const message = `Error 500: Unknown MIME type for file extension: ${fileExt}`;
response.writeHead(500, { 'Content-Type': 'text/plain', 'Content-Length': message.length, ...userHeaders });
response.write(message);
response.end();
}
static sendFileNotFound(response) {
const message = 'Error 404: Resource not found.';
response.writeHead(404, { 'Content-Type': 'text/plain', 'Content-Length': message.length, ...userHeaders });
response.write(message);
response.end();
}
static sendRedirect(response, location) {
response.writeHead(301, { 'Content-Type': 'text/plain', 'Content-Length': 0, location, ...userHeaders });
response.end();
}
static sendFile(response, filePath, mimeType, contentLength) {
response.writeHead(200, { 'Content-Type': mimeType, 'Content-Length': contentLength, ...userHeaders });
fs.createReadStream(filePath).pipe(response);
}
static sendRootIndex(response) {
const rootIndex = `${root}/index.html`;
fs.stat(rootIndex, (error, stats) => {
if (stats) {
Server.sendFile(response, rootIndex, 'text/html', stats.size);
} else {
Server.sendFileNotFound(response);
}
});
}
}
const server = http.createServer(Server.requestListener);
server.listen(process.env.PORT || 8080, () => {
const { address, port } = server.address();
Server.origin = `http://[${address}]:${port}`;
console.log(`Development server running: ${Server.origin}`); // eslint-disable-line no-console
});