Related Articles

Related Articles

Build a Simple static file web server in Node
  • Last Updated : 28 Jun, 2019

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.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // 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': 'appliaction/vnd.ms-fontobject',
        '.ttf': 'aplication/font-sfnt'
    };

    chevron_right

    
    

  • Step 2: Creating a server at the port specified (say 1800).
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // Creating a server and listening the port 1800
    http.createServer( (req, res) => {
      
    }).listen(PORT);

    chevron_right

    
    

  • 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.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // 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);
    }

    chevron_right

    
    

  • Step 4: Preprocessing the requested file pathname to avoid directory traversal (like http://localhost:1800/../fileOutofContext.txt) by replacing ‘../’ with ‘ ’.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    /* processing the requested file pathname to
    avoid directory traversal like,
    by limiting to the current directory only */
    const sanitizePath = 
    path.normalize(parsedUrl.pathname).replace(/^(\.\.[\/\\])+/, '');
      
    let pathname = path.join(__dirname, sanitizePath);

    chevron_right

    
    

  • 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.
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    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
                // extention. 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);
            }
        });
    }

    chevron_right

    
    

Complete Code:

filter_none

edit
close

play_arrow

link
brightness_4
code

/* 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': 'appliaction/vnd.ms-fontobject',
    '.ttf': 'aplication/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,
    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 extention. 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}`);

chevron_right


Output




My Personal Notes arrow_drop_up
Recommended Articles
Page :