Close Menu
Soshace Digital Blog

    Subscribe to Updates

    Get The Latest News, Updates, And Amazing Offers

    What's Hot
    Interview

    Strategies for Effectively Discussing Weaknesses in Interviews

    Trends

    Diam Maecenas Ultricies Mieget Wauris Bibendum Neque

    Soshace

    Happy New 2020 Year!

    Important Pages:
    • Home
    • About
    • Services
    • Contact Us
    • Privacy Policy
    • Terms & Conditions
    Facebook X (Twitter) Instagram LinkedIn YouTube
    Today's Picks:
    • Scaling Success: Monitoring Indexation of Programmatic SEO Content
    • Leveraging Influencers: Key Drivers in New Product Launches
    • How Privacy-First Marketing Will Transform the Industry Landscape
    • The Impact of Social Proof on Thought Leadership Marketing
    • Balancing Value-Driven Content and Promotional Messaging Strategies
    • Top Influencer Marketing Platforms to Explore in 2025
    • Emerging Trends in Marketing Automation and AI Tools for 2023
    • Strategies to Mitigate Duplicate Content in Programmatic SEO
    Thursday, September 11
    Facebook X (Twitter) Instagram LinkedIn YouTube
    Soshace Digital Blog
    • Home
    • About
    • Services
    • Contact Us
    • Privacy Policy
    • Terms & Conditions
    Services
    • SaaS & Tech

      Maximizing Efficiency: How SaaS Lowers IT Infrastructure Costs

      August 27, 2025

      Navigating Tomorrow: Innovations Shaping the Future of SaaS

      August 27, 2025

      Maximizing Impact: Strategies for SaaS & Technology Marketing

      August 27, 2025
    • AI & Automation

      Enhancing Customer Feedback Analysis Through AI Innovations

      August 27, 2025

      Navigating the Impact of AI on SEO and Search Rankings

      August 27, 2025

      5 Automation Hacks Every Home Service Business Needs to Know

      May 3, 2025
    • Finance & Fintech

      Critical Missteps in Finance Marketing: What to Avoid

      August 27, 2025

      Analyzing Future Fintech Marketing Trends: Insights Ahead

      August 27, 2025

      Navigating the Complex Landscape of Finance and Fintech Marketing

      August 27, 2025
    • Legal & Compliance

      Exploring Thought Leadership’s Impact on Legal Marketing

      August 27, 2025

      Maximizing LinkedIn: Strategies for Legal and Compliance Marketing

      August 27, 2025

      Why Transparency Matters in Legal Advertising Practices

      August 27, 2025
    • Medical Marketing

      Enhancing Online Reputation Management in Hospitals: A Guide

      August 27, 2025

      Analyzing Emerging Trends in Health and Medical Marketing

      August 27, 2025

      Exploring Innovative Content Ideas for Wellness Blogs and Clinics

      August 27, 2025
    • E-commerce & Retail

      Strategic Seasonal Campaign Concepts for Online and Retail Markets

      August 27, 2025

      Emerging Trends in E-commerce and Retail Marketing Strategies

      August 27, 2025

      Maximizing Revenue: The Advantages of Affiliate Marketing for E-Commerce

      August 27, 2025
    • Influencer & Community

      Leveraging Influencers: Key Drivers in New Product Launches

      August 27, 2025

      Top Influencer Marketing Platforms to Explore in 2025

      August 27, 2025

      Key Strategies for Successful Influencer Partnership Negotiations

      August 27, 2025
    • Content & Leadership

      The Impact of Social Proof on Thought Leadership Marketing

      August 27, 2025

      Balancing Value-Driven Content and Promotional Messaging Strategies

      August 27, 2025

      Analyzing Storytelling’s Impact on Content Marketing Effectiveness

      August 27, 2025
    • SEO & Analytics

      Scaling Success: Monitoring Indexation of Programmatic SEO Content

      August 27, 2025

      Strategies to Mitigate Duplicate Content in Programmatic SEO

      August 27, 2025

      Effective Data Visualization Techniques for SEO Reporting

      August 27, 2025
    • Marketing Trends

      How Privacy-First Marketing Will Transform the Industry Landscape

      August 27, 2025

      Emerging Trends in Marketing Automation and AI Tools for 2023

      August 27, 2025

      Maximizing ROI: Key Trends in Paid Social Advertising

      August 27, 2025
    Soshace Digital Blog
    Blog / Programming / 19. Node.js Lessons. Safe Way to a FS File and Path
    Programming

    19. Node.js Lessons. Safe Way to a FS File and Path

    Ivan RastvorovBy Ivan RastvorovOctober 21, 2016Updated:December 6, 2024No Comments7 Mins Read
    Facebook Twitter Pinterest Telegram LinkedIn Tumblr Email Reddit
    19. Node.js Lessons. Safe Way to a FS File and Path
    Share
    Facebook Twitter LinkedIn Pinterest Email Copy Link

    fantastic-wooden-pier-frisco-night

    This article will deal with how to create a web server in Node.js, which will return a file to a user from a public directory. You may wonder: why do we need Node.js here? Why can’t we use another server? You question surely does make sense. Yes, for returning files other servers are generally more effective. From the other side, Node.js works pretty well, too. Second, before returning a file it can also perform some intellectual activities: for example, refer to a database, check out whether a user is permitted to access the file and give the file to him, if it’s permitted.

    Please, submit coding from our repository, we won’t write anything today. But before you start, you will need to install the mime module:

    npm install mime

    That’s how our server.js looks like:

    var http = require('http');
    var fs = require('fs');
    var url = require('url');
    var path = require('path');
    
    var ROOT = __dirname + "/public";
    
    http.createServer(function(req, res) {
    
        if (!checkAccess(req)) {
            res.statusCode = 403;
            res.end("Tell me the secret to access!");
            return;
        }
    
        sendFileSafe(url.parse(req.url).pathname, res);
    
    }).listen(3000);
    
    function checkAccess(req) {
        return url.parse(req.url, true).query.secret == 'o_O';
    }
    
    function sendFileSafe(filePath, res) {
    
        try {
            filePath = decodeURIComponent(filePath);
        } catch(e) {
            res.statusCode = 400;
            res.end("Bad Request");
            return;
        }
    
        if (~filePath.indexOf('')) {
            res.statusCode = 400;
            res.end("Bad Request");
            return;
        }
        
        filePath = path.normalize(path.join(ROOT, filePath));
    
        if (filePath.indexOf(path.normalize(ROOT)) != 0) {
            res.statusCode = 404;
            res.end("File not found");
            return;
        }
    
        fs.stat(filePath, function(err, stats) {
            if (err || !stats.isFile()) {
                res.statusCode = 404;
                res.end("File not found");
                return;
            }
    
            sendFile(filePath, res);
        });
    }
    
    function sendFile(filePath, res) {
    
        fs.readFile(filePath, function(err, content) {
            if (err) throw err;
    
            var mime = require('mime').lookup(filePath); // npm install mime
            res.setHeader('Content-Type', mime + "; charset=utf-8");
            res.end(content);
        });
    
    }

    http.create is very simple here.

    http.createServer(function(req, res) {
    
        if (!checkAccess(req)) {
            res.statusCode = 403;
            res.end("Tell me the secret to access!");
            return;
        }
    
        sendFileSafe(url.parse(req.url).pathname, res);
    
    }).listen(3000);

    It will check whether you are permitted to access the file and give it to you, if the answer is positive. To check the access right, we will use the following function (which is Fake function as it is). This function will perform url parse and if there is a parameter named secret equal to ‘o_O’, it means you’ve got an access:

    function checkAccess(req) {  
      return url.parse(req.url, true).query.secret == 'o_O';  
    } 
    

    In practice, a check of this kind will be done using cookies, databases, etc.
    The key function we are interested in is sendFileSafe:

    sendFileSafe(url.parse(req.url).pathname, res);
    

    This is the very function that upon receiving the path from a user has to send a respective file from the public directory considering the directory path. The key aspect that should be contained here is safety. Whatever path is delivered by a user, he has to receive a file within the public directory. For example, this request:

    http://localhost:3000/index.html?secret=o_O

    should return an index.html file. The picture is taken here from a directory

    <img src ="deep/nodejs.jpg?secret=o_O">

    And if we hadn’t indicated secret:

    http://localhost:3000/index.html

    it will have shown an error with the code 403.

    And if I had indicated it the following way:

    Read More:  Monthly Digest of the Most Popular JS Github Repositories

    http://localhost:3000/server.js

    it will have shown an error, too. The principle is the same for any attempt to get away from this directory.

    So, we look for the function sendFileSafe, in order to get an example of a safe work with the path from a visitor. This function contains a number of steps.

    function sendFileSafe(filePath, res) {
    
        try {
            filePath = decodeURIComponent(filePath);
        } catch(e) {
            res.statusCode = 400;
            res.end("Bad Request");
            return;
        }

    The first step is when we handle the path with decodeURIComponent, since the “HTTP” standard means coding of many symbols. Once this kind of url is received, we have to decode it in return using this call:

    decodeURIComponent

    Thus, if url has been coded incorrectly, an error will occur, and we will need to catch and handle it. Code 400 means that your url is incorrect and the request is invalid. Well, you can get back the code 404, too.
    Once the request is decoded, it is high time to check it. There is a specialized ‘zero byte’ that must not be contained in the url string:

    if (~filePath.indexOf('')) {  
      res.statusCode = 400;  
      res.end("Bad Request");  
      return;  
    }  
    

    If it is there, it means someone has maliciously brought it here because some built-in Node.js functions will work incorrectly with this byte. Respectively, if you’ve got it, you need to get back Bad Request, and your request is incorrect.

    Now it’s time to get a full path to the file on a disk. To do so, we will use our path module.

    filePath = path.normalize(path.join(ROOT, filePath));
    

    This built-in module contains a set of various functions to work with paths. For example join unites paths, normalize eliminates different strange things from a path: such as “.”, “:”, “//”, etc., which means it gives a path a correct form. If an url delivered by a user looked like this:

    //  /deep/nodejs.jpg

    after join with ROOT that represents this directory:

    var ROOT = __dirname + "/public";

    it would look differently, for example:

    //  /deep/nodejs.jpg ->  /Users/learn/node/path/public/deep/nodejs.jpg  
    

    Our next task is to make sure this path is within the public directory. Right now, when we already have a correct and precise path, it is quite simple. You only need to make sure this prefix is contained in the beginning:

    Users/learn/node/path/public
    

    Which means the path starts with ROOT. Let’s check it out. If it’s not, you will see File not Found:

    filePath = path.normalize(path.join(ROOT, filePath));
    
        if (filePath.indexOf(path.normalize(ROOT)) != 0) {
            res.statusCode = 404;
            res.end("File not found");
            return;
        }

    If your access is permitted, let us check what the path includes. If there is nothing, fs.stat will bring back err:

    fs.stat(filePath, function(err, stats) {  
      if (err || !stats.isFile()) {  
        res.statusCode = 404;  
        res.end("File not found");  
        return;  
      }  
    

    Even if there is no error, you still need to make sure whether it is a file. If it isn’t a file, it is an error. If it is a file, it means everything is checked and you need to send the file. This can be done using the built-in call sendFile:

    sendFile(filePath, res);  
      });  
    }  
    

    sendFile is a function contained in the file, but a little bit below:

    function sendFile(filePath, res) {
    
        fs.readFile(filePath, function(err, content) {
            if (err) throw err;
    
            var mime = require('mime').lookup(filePath); // npm install mime
            res.setHeader('Content-Type', mime + "; charset=utf-8");
            res.end(content);
        });
    
    }

    For reading a file it uses the call fs.readFile, and upon being read it will be outputted through res.end:

    res.end(content);

    Pay your attention to the following: any mistake in this callback is barely possible

    if (err) throw err;

    at least because we’ve already checked the file does exist, it is a file and it can be delivered. But you never know what may happen. For example, an error can occur while the file is being read on a disk. Anyway, we have to handle this possible error. Just to read the file and send it won’t be enough, since various files should contain various Content-Type titles.

    Read More:  Programming Patterns. Strategy, Observer, Iterator

    For example, an HTML file needs to be of a text/html type, a file with a JPEG picture – of a image/jpeg type, etc. The needed file type gets defined according to its extension using the mime module.

     var mime = require('mime').lookup(filePath); // npm install

    In order to make it work, do not forget to install it. And, eventually, this article deals on how to work with a path from a visitor correctly, in order to do all needed checks, decoding, etc. All these things are extremely important, but if it comes to the file return, this code is incorrect:

    function sendFile(filePath, res) {
    
        fs.readFile(filePath, function(err, content) {
            if (err) throw err;
    
            var mime = require('mime').lookup(filePath); // npm install mime
            res.setHeader('Content-Type', mime + "; charset=utf-8");
            res.end(content);
        });
    
    }

    because readFile computes the whole file and then sends it to content. Just imagine what will happen, if a file is very big. And what if it’s even bigger than the memory left? It will crash! So, in order to send a file you need to give a command to a specialized server or use the streams that we will talk about in our next article.

    tumblr_nvdx0jpq7F1rf2fjgo1_1280
    The article materials were borrowed from the following screencast.

    We are looking forward to meeting you on our website blog.soshace.com

    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Ivan Rastvorov
    • Website

    Related Posts

    Mastering REST APIs: Essential Techniques for Programmers

    December 18, 2024

    Crafting Interactive User Interfaces Using JavaScript Techniques

    December 17, 2024

    Effective Strategies for Utilizing Frameworks in Web Development

    December 16, 2024
    Leave A Reply Cancel Reply

    You must be logged in to post a comment.

    Stay In Touch
    • Facebook
    • Twitter
    • Pinterest
    • Instagram
    • YouTube
    • Vimeo
    Don't Miss
    LinkedIn November 29, 2024

    Strategic Approaches to Engaging Cold Prospects on LinkedIn

    Engaging cold prospects on LinkedIn requires a strategic approach that combines targeted messaging and personalized content. Research emphasizes the importance of establishing common ground through mutual connections and tailored value propositions to enhance response rates.

    Agile Software Development, Scrum part 3

    August 12, 2016

    SMART Financial Goals for Remote Workers

    January 28, 2019

    Developer Guide to GDPR

    August 29, 2019

    Categories

    • AI & Automation
    • Angular
    • ASP.NET
    • AWS
    • B2B Leads
    • Beginners
    • Blogs
    • Business Growth
    • Case Studies
    • Comics
    • Consultation
    • Content & Leadership
    • CSS
    • Development
    • Django
    • E-commerce & Retail
    • Entrepreneurs
    • Entrepreneurship
    • Events
    • Express.js
    • Facebook Ads
    • Finance & Fintech
    • Flask
    • Flutter
    • Franchising
    • Funnel Strategy
    • Git
    • GraphQL
    • Home Services Marketing
    • Influencer & Community
    • Interview
    • Java
    • Java Spring
    • JavaScript
    • Job
    • Laravel
    • Lead Generation
    • Legal & Compliance
    • LinkedIn
    • Machine Learning
    • Marketing Trends
    • Medical Marketing
    • MSP Lead Generation
    • MSP Marketing
    • NestJS
    • Next.js
    • Node.js
    • Node.js Lessons
    • Paid Advertising
    • PHP
    • Podcasts
    • POS Tutorial
    • Programming
    • Programming
    • Python
    • React
    • React Lessons
    • React Native
    • React Native Lessons
    • Recruitment
    • Remote Job
    • SaaS & Tech
    • SEO & Analytics
    • Soshace
    • Startups
    • Swarm Intelligence
    • Tips
    • Trends
    • Vue
    • Wiki
    • WordPress
    Top Posts

    Уроки Express.js . Логгер, Конфигурация, Шаблонизация с EJS. Часть 2.

    Programming December 2, 2016

    Interview with Sergey

    Interview October 21, 2018

    Two 2017 Collaboration Software Awards Now Belong To Soshace

    Events December 8, 2017

    Effective Strategies for Managing Scope Creep in Projects

    JavaScript November 26, 2024

    Subscribe to Updates

    Get The Latest News, Updates, And Amazing Offers

    About Us
    About Us

    Soshace Digital delivers comprehensive web design and development solutions tailored to your business objectives. Your website will be meticulously designed and developed by our team of seasoned professionals, who combine creative expertise with technical excellence to transform your vision into a high-impact, user-centric digital experience that elevates your brand and drives measurable results.

    7901 4th St N, Suite 28690
    Saint Petersburg, FL 33702-4305
    Phone: 1(877)SOSHACE

    Facebook X (Twitter) Instagram Pinterest YouTube LinkedIn
    Our Picks
    JavaScript

    Building React Components Using Children Props and Context API

    JavaScript

    Advanced Mapmaking: Using d3, d3-scale and d3-zoom With Changing Data to Create Sophisticated Maps

    Interview

    Interview with Stepan

    Most Popular

    7 Concepts: Why Your SVG Is the Way It Is

    Beginners

    24. Node.js Lessons.Reading Parameters From the Command Line and Environment.

    Programming

    Инструменты JavaScript / Node.js разработчика

    Programming
    © 2025 Soshace Digital.
    • Home
    • About
    • Services
    • Contact Us
    • Privacy Policy
    • Terms & Conditions

    Type above and press Enter to search. Press Esc to cancel.