0

I created a BasicWebServer.js file which lives in the folder portfolio-website and this folder has the following files: index.htm, BasicWebServer.js, css/style.css.

The code I put in the BasicWebServer.js file is as following:

var http = require('http'),
    fs = require('fs'),
    path = require('path'),
    host = '127.0.0.1',
    port = '9000';

var mimes = {
    ".htm" : "text/html",
    ".css" : "text/css",
    ".js" : "text/javascript",
    ".gif" : "image/gif",
    ".jpg" : "image/jpeg",
    ".png" : "image/png"
}

var server = http.createServer(function(req, res){
    var filepath = (req.url === '/') ? ('./index.htm') : ('.' + req.url);
    var contentType = mimes[path.extname(filepath)];
    // Check to see if the file exists
    fs.exists(filepath, function(file_exists){
        if(file_exists){
            // Read and Serve
            fs.readFile(filepath, function(error, content){
                if(error){
                    res.writeHead(500);
                    res.end();
                } else{
                    res.writeHead(200, { 'Content-Type' : contentType});
                    res.end(content, 'utf-8');
                }
            })
        } else {
            res.writeHead(404);
            res.end("Sorry we could not find the file you requested!");
        }
    })
    res.writeHead(200, {'content-type' : 'text/html'});
    res.end('<h1>Hello World!</h1>');
}).listen(port, host, function(){
    console.log('Server Running on http://' + host + ':' + port);
});

UPDATE 1 Part 1)

I removed the two lines:

res.writeHead(200, {'content-type' : 'text/html'});
res.end('<h1>Hello World!</h1>');

and when I refresh the page, I get:

Sorry we could not find the file you requested!

Part 2) I have also tried piping it by doing this:

var http = require('http'),
    fs = require('fs'),
    path = require('path'),
    host = '127.0.0.1',
    port = '9000';

var mimes = {
    ".htm" : "text/html",
    ".css" : "text/css",
    ".js" : "text/javascript",
    ".gif" : "image/gif",
    ".jpg" : "image/jpeg",
    ".png" : "image/png"
}

var server = http.createServer(function (req, res) {
    var filepath = (req.url === '/') ? ('./index.htm') : ('.' + req.url);
    var contentType = mimes[path.extname(filepath)];
    // Check to see if the file exists
    fs.exists(filepath, function(file_exists){
//        if(file_exists){
//            // Read and Serve
//            fs.readFile(filepath, function(error, content){
//                if(error){
//                    res.writeHead(500);
//                    res.end();
//                } else{
//                    res.writeHead(200, { 'Content-Type' : contentType});
//                    res.end(content, 'utf-8');
//                }
//            })
            res.writeHead(200, {'Content-Type' : contentType});
            var streamFile = fs.createReadStream(filepath).pipe(res);

            streamFile.on('error', function() {
                res.writeHead(500);
                res.end();
            })
        } else {
            res.writeHead(404);
            res.end("Sorry we could not find the file you requested!");
        }
    })
}).listen(port, host, function(){
    console.log('Server Running on http://' + host + ':' + port);
});

This gives the following error:

SyntaxError: Unexpected token else
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3
roadtocode
  • 329
  • 5
  • 13
  • FWIW (among the other existing solutions) you can use [`fs.createReadStream`](https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options) and then `pipe` it. – user2864740 Sep 01 '15 at 01:33

2 Answers2

3

These two lines:

res.writeHead(200, {'content-type' : 'text/html'});
res.end('<h1>Hello World!</h1>');

Are getting executed every time and they get executed before your code has a chance to read the file. Remember, that fs.exists() and fs.readFile() are async so their response comes after the rest of your code executes.

If I remove those two lines, your code does start to work so basically you were finishing the response with those two lines before your other code had a chance to actually read the file and send it.


FYI, it is considered a bit of an anti-pattern to use fs.exists() the way you are using it. You can just use fs.readFile() and handle the error appropriately if the file is not found. Besides not having concurrency issues, this is also one less file operation.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

For sake of education, here is a working version of your example that does not use either fs.exists nor fs.readFile. Instead it uses fs.createReadStream and .pipe and .on('error'

var http = require('http'),
    fs = require('fs'),
    path = require('path'),
    host = '127.0.0.1',
    port = '9000';

var mimes = {
    ".htm": "text/html",
    ".css": "text/css",
    ".js": "text/javascript",
    ".gif": "image/gif",
    ".jpg": "image/jpeg",
    ".png": "image/png"
}

var server = http.createServer(function(req, res) {
    var filepath = (req.url === '/') ? ('./index.htm') : ('.' + req.url);
    var contentType = mimes[path.extname(filepath)];

    var file = fs.createReadStream(filepath);
    res.writeHead(200, {
        'Content-Type': contentType
    });
    file.pipe(res);
    file.on('error', function(err) {
        if (err.code === 'ENOENT') {
            res.writeHead(404);
            res.end("Sorry we could not find the file you requested!");
        } else {
            res.writeHead(500);
            res.end();
        }
    });

}).listen(port, host, function() {
    console.log('Server Running on http://' + host + ':' + port);
    console.log('Serving files from ' + process.cwd());
});
Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • Hi Dan, Thanks for your input. I tried the code but I get the following error: `Sorry we could not find the file you requested!` Is there something I'm missing in my folder? :S – roadtocode Sep 01 '15 at 02:31
  • It shows the 404 message as you requested `http://127.0.0.1:9000/` and `./index.htm` doesn't exist. Request a path that does exist. – Dan D. Sep 01 '15 at 02:35
  • [link](http://i62.tinypic.com/2jd465t.jpg) I think I'm requesting the correct path? – roadtocode Sep 01 '15 at 02:49
  • Use the new code and check that it is serving files from that directory. – Dan D. Sep 01 '15 at 02:54
  • Thanks! It's working, although I had to move my index.htm and css folder to the Desktop, since after running your code, the terminal returned: `Server Running on http://127.0.0.1:9000 Serving files from `/Users/mahtabalam/Desktop` Even though the `BasicWebServer.js` is inside `/Users/mahtabalam/Desktop/ma.com-website`, I had to transfer index.htm and css folder out of the `ma.com-website` folder and place them in Desktop. How do I make it so that index.htm is in the same location as the `BasicWebServer.js` location? Thanks again for all of your help :) – roadtocode Sep 01 '15 at 03:08
  • Add this line after `var filepath`: `filepath = path.join(__dirname, filepath);`. It makes the path names relative to the directory that contains the script rather than the current working directory. And replace `process.cwd()` with `__dirname`. – Dan D. Sep 01 '15 at 03:13