Open In App

Build a Simple static file web server in Node.js

Last Updated : 14 Oct, 2021
Comments
Improve
Suggest changes
Like Article
Like
Report

In this article, we will build a static file web server which will list out all the files in the directory and on clicking the file name it displays the file content. Steps for creating a static file server is as follows:

  • Step 1: Importing necessary modules, and defining MIME types which helps browser to understand the type of file that is being sent.
JavaScript
// Importing necessary modules
const http = require('http');
const url = require('url');
const fs = require('fs');
const path = require('path');
 
// Port on which the server will create
const PORT = 1800;
 
// Maps file extension to MIME types which
// helps the browser to understand what to
// do with the file
const mimeType = {
    '.ico': 'image/x-icon',
    '.html': 'text/html',
    '.js': 'text/javascript',
    '.json': 'application/json',
    '.css': 'text/css',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
    '.wav': 'audio/wav',
    '.mp3': 'audio/mpeg',
    '.svg': 'image/svg+xml',
    '.pdf': 'application/pdf',
    '.doc': 'application/msword',
    '.eot': 'application/vnd.ms-fontobject',
    '.ttf': 'application/font-sfnt'
};
  • Step 2: Creating a server at the port specified (say 1800).
JavaScript
// Creating a server and listening the port 1800
http.createServer( (req, res) => {

}).listen(PORT);
  • Step 3: We will respond the URL “/” to list all the files in the directory. We will limit this article to the current working directory only. Add the below code to the server's function call.
JavaScript
// Parsing the requested URL
const parsedUrl = url.parse(req.url);
 
// If requested url is "/" like "http://localhost:8100/"
if(parsedUrl.pathname==="/") {
    var filesLink="<ul>";
    res.setHeader('Content-type', 'text/html');
    var filesList=fs.readdirSync("./");
    
    filesList.forEach(element => {
        if(fs.statSync("./"+element).isFile()) {
            filesLink +=`<br/><li><a href='./${element}'>
                ${element}
            </a></li>` ;        
        }
    });
    filesLink+="</ul>";
   
    res.end("<h1>List of files:</h1> " + filesLink);
}
  • Step 4: Preprocessing the requested file pathname to avoid directory traversal (like http://localhost:1800/../fileOutofContext.txt) by replacing ‘../’ with ‘ ’.
JavaScript
/* processing the requested file pathname to
avoid directory traversal like,
http://localhost:1800/../fileOutofContext.txt
by limiting to the current directory only */
const sanitizePath = 
path.normalize(parsedUrl.pathname).replace(/^(\.\.[\/\\])+/, '');

let pathname = path.join(__dirname, sanitizePath);
  • Step 5: Finally, check whether the file exists. If exists then send the file with the proper header 'Content-type' having value as per the file extension mapped with the MIME type above. Else if not exist then send File not found! with 404 status code.
JavaScript
if(!fs.existsSync(pathname)) {
    
    // If the file is not found, return 404
    res.statusCode = 404;
    res.end(`File ${pathname} not found!`);
}
else {
      
    // Read file from file system limit to the
    // current directory only.
    fs.readFile(pathname, function(err, data) {
        if(err) {
            res.statusCode = 500;
            res.end(`Error in getting the file.`);
        } 
        else {
            
            // Based on the URL path, extract the file
            // extension. Ex .js, .doc, ...
            const ext = path.parse(pathname).ext;
            
            // If the file is found, set Content-type
            // and send data
            res.setHeader('Content-type',
                    mimeType[ext] || 'text/plain' );
            res.end(data);
        }
    });
}


Complete Code: 

JavaScript
/* Node.js static file web server */
 
// Importing necessary modules
const http = require('http');
const url = require('url');
const fs = require('fs');
const path = require('path');
 
// Port on which the server will create
const PORT = 1800;
 
// Maps file extension to MIME types which
// helps browser to understand what to do
// with the file
const mimeType = {
    '.ico': 'image/x-icon',
    '.html': 'text/html',
    '.js': 'text/javascript',
    '.json': 'application/json',
    '.css': 'text/css',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
    '.wav': 'audio/wav',
    '.mp3': 'audio/mpeg',
    '.svg': 'image/svg+xml',
    '.pdf': 'application/pdf',
    '.doc': 'application/msword',
    '.eot': 'application/vnd.ms-fontobject',
    '.ttf': 'application/font-sfnt'
};
 
// Creating a server and listening at port 1800
http.createServer( (req, res) => {
   
 
    // Parsing the requested URL
    const parsedUrl = url.parse(req.url);
 
    // If requested url is "/" like "http://localhost:1800/"
    if(parsedUrl.pathname==="/"){
        var filesLink="<ul>";
        res.setHeader('Content-type', 'text/html');
        var filesList=fs.readdirSync("./");
        filesList.forEach(element => {
            if(fs.statSync("./"+element).isFile()){
                filesLink+=`<br/><li><a href='./${element}'>
                    ${element}
                </a></li>` ;        
            }
        });
        
        filesLink+="</ul>";
     
        res.end("<h1>List of files:</h1> " + filesLink);
    }
 
    /* Processing the requested file pathname to
    avoid directory traversal like,
    http://localhost:1800/../fileOutofContext.txt
    by limiting to the current directory only. */
    const sanitizePath = 
    path.normalize(parsedUrl.pathname).replace(/^(\.\.[\/\\])+/, '');
    
    let pathname = path.join(__dirname, sanitizePath);
    
    if(!fs.existsSync(pathname)) {
        
        // If the file is not found, return 404
        res.statusCode = 404;
        res.end(`File ${pathname} not found!`);
    }
    else {
        
        // Read file from file system limit to 
        // the current directory only.
        fs.readFile(pathname, function(err, data) {
            if(err){
                res.statusCode = 500;
                res.end(`Error in getting the file.`);
            } 
            else {
                
                // Based on the URL path, extract the
                // file extension. Ex .js, .doc, ...
                const ext = path.parse(pathname).ext;
                
                // If the file is found, set Content-type
                // and send data
                res.setHeader('Content-type',
                        mimeType[ext] || 'text/plain' );
                
                res.end(data);
            }
        });
    }
}).listen(PORT);
 
console.log(`Server listening on port ${PORT}`);

Output 


 


 


Next Article
Article Tags :

Similar Reads