Basic Web Server
Mon Nov 20 2023 19:34:50 GMT+0000 (Coordinated Universal Time)
Saved by @fastoch #javascript
const http = require('http');
const path = require('path');
const fs = require('fs');
const fsPromises = require('fs').promises;
const EventEmitter = require('events');
const logEvents = require('./logEvents'); // custom module
// define the web server port
const PORT = process.env.PORT || 3500;
// event emitter will listen for events and log them to corresponding files
const myEmitter = new EventEmitter();
myEmitter.on('log', (msg, fileName) => logEvents(msg, fileName));
// function that will serve the file (response)
const serveFile = async (filePath, contentType, response) => {
try {
const rawData = await fsPromises.readFile(
filePath,
!contentType.includes('image') ? 'utf8' : ''
);
const data = contentType === 'application/json'
? JSON.parse(rawData) : rawData;
response.writeHead(
filePath.includes('404.html') ? 404 : 200,
{'Content-Type': contentType}
);
response.end(
contentType === 'application/json' ? JSON.stringify(data) : data
);
} catch (err) {
console.log(err);
myEmitter.emit('log', `${err.name}: ${err.message}`, 'errLog.txt');
response.statusCode = 500; // internal server error
response.end();
}
}
// create and configure the server
const server = http.createServer((req, res) => {
console.log(req.url, req.method);
myEmitter.emit('log', `${req.url}\t${req.method}`, 'reqLog.txt');
// store file extension of the request url
const extension = path.extname(req.url);
let contentType;
// manage contentType according to file extension of the url
switch (extension) {
case '.css':
contentType = 'text/css';
break;
case '.js':
contentType = 'text/javascript';
break;
case '.json':
contentType = 'application/json';
break;
case '.jpg':
contentType = 'image/jpeg';
break;
case '.png':
contentType = 'image/png';
break;
case '.txt':
contentType = 'text/plain';
break;
default:
contentType = 'text/html';
}
let filePath =
contentType === 'text/html' && req.url === '/'
? path.join(__dirname, 'views', 'index.html')
: contentType === 'text/html' && req.url.slice(-1) === '/' // if last character in url is '/'
? path.join(__dirname, 'views', req.url, 'index.html') // req.url will specify the subdir
: contentType === 'text/html' // if req.url is not a slash and last char not a slash
? path.join(__dirname, 'views', req.url) // just look for url in the views folder
: path.join(__dirname, req.url); // if url not in views, just use req.url
// makes .html extension not required int the browser
if (!extension && req.url.slice(-1) !== '/') filePath += '.html';
// serve the file if it exists
const fileExists = fs.existsSync(filePath);
if (fileExists) {
serveFile(filePath, contentType, res);
}
// if file does not exist, response will vary
else {
switch (path.parse(filePath).base) {
case 'old-page.html':
res.writeHead(301, {'Location': 'new-page.html'}); // redirect to new page
res.end(); // end the response
break;
case 'www-page.html':
res.writeHead(301, {'Location': '/'}); // redirect to root page
res.end(); // end the response
break;
default:
// serve a 404 response
serveFile(path.join(__dirname, 'views', '404.html'), 'text/html', res);
};
// https://nodejs.org/api/path.html#pathparsepath
}
});
server.listen(PORT, () => console.log(`Server running and listening on port ${PORT}`));
Chapter 5 - Dave Gray's Node Tutorial works with logEvents.js
https://youtu.be/f2EqECiTBL8


Comments