Skip to content

Commit c7405e3

Browse files
committed
Add new node static server example
1 parent a10c5c8 commit c7405e3

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed

native-2022/main.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict';
2+
3+
const fs = require('node:fs');
4+
const http = require('node:http');
5+
const path = require('node:path');
6+
7+
const PORT = 8000;
8+
9+
const MIME_TYPES = {
10+
default: 'application/octet-stream',
11+
html: 'text/html; charset=UTF-8',
12+
js: 'application/javascript; charset=UTF-8',
13+
css: 'text/css',
14+
png: 'image/png',
15+
jpg: 'image/jpg',
16+
gif: 'image/gif',
17+
ico: 'image/x-icon',
18+
svg: 'image/svg+xml',
19+
};
20+
21+
const STATIC_PATH = path.join(process.cwd(), './static');
22+
23+
const toBool = [() => true, () => false];
24+
25+
const prepareFile = async (url) => {
26+
const paths = [STATIC_PATH, url];
27+
if (url.endsWith('/')) paths.push('index.html');
28+
const filePath = path.join(...paths);
29+
const pathTraversal = !filePath.startsWith(STATIC_PATH);
30+
const exists = await fs.promises.access(filePath).then(...toBool);
31+
const found = !pathTraversal && exists;
32+
const streamPath = found ? filePath : STATIC_PATH + '/404.html';
33+
const ext = path.extname(streamPath).substring(1).toLowerCase();
34+
const stream = fs.createReadStream(streamPath);
35+
return { found, ext, stream };
36+
};
37+
38+
http.createServer(async (req, res) => {
39+
const file = await prepareFile(req.url);
40+
const statusCode = file.found ? 200 : 404;
41+
const mimeType = MIME_TYPES[file.ext] || MIME_TYPES.default;
42+
res.writeHead(statusCode, { 'Content-Type': mimeType });
43+
file.stream.pipe(res);
44+
console.log(`${req.method} ${req.url} ${statusCode}`);
45+
}).listen(PORT);
46+
47+
console.log(`Server running at http://127.0.0.1:${PORT}/`);

native-2022/main.mjs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as fs from 'node:fs';
2+
import * as http from 'node:http';
3+
import * as path from 'node:path';
4+
5+
const PORT = 8000;
6+
7+
const MIME_TYPES = {
8+
default: 'application/octet-stream',
9+
html: 'text/html; charset=UTF-8',
10+
js: 'application/javascript; charset=UTF-8',
11+
css: 'text/css',
12+
png: 'image/png',
13+
jpg: 'image/jpg',
14+
gif: 'image/gif',
15+
ico: 'image/x-icon',
16+
svg: 'image/svg+xml',
17+
};
18+
19+
const STATIC_PATH = path.join(process.cwd(), './static');
20+
21+
const toBool = [() => true, () => false];
22+
23+
const prepareFile = async (url) => {
24+
const paths = [STATIC_PATH, url];
25+
if (url.endsWith('/')) paths.push('index.html');
26+
const filePath = path.join(...paths);
27+
const pathTraversal = !filePath.startsWith(STATIC_PATH);
28+
const exists = await fs.promises.access(filePath).then(...toBool);
29+
const found = !pathTraversal && exists;
30+
const streamPath = found ? filePath : STATIC_PATH + '/404.html';
31+
const ext = path.extname(streamPath).substring(1).toLowerCase();
32+
const stream = fs.createReadStream(streamPath);
33+
return { found, ext, stream };
34+
};
35+
36+
http.createServer(async (req, res) => {
37+
const file = await prepareFile(req.url);
38+
const statusCode = file.found ? 200 : 404;
39+
const mimeType = MIME_TYPES[file.ext] || MIME_TYPES.default;
40+
res.writeHead(statusCode, { 'Content-Type': mimeType });
41+
file.stream.pipe(res);
42+
console.log(`${req.method} ${req.url} ${statusCode}`);
43+
}).listen(PORT);
44+
45+
console.log(`Server running at http://127.0.0.1:${PORT}/`);

native-2022/static/404.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>File not found</h1>

native-2022/static/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>Hello world</h1>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy