(solution) This is the following code of the assignment: // tinywebserver.js

(solution) This is the following code of the assignment: // tinywebserver.js

This is the following code of the assignment:

// tinywebserver.js // // A modification of Rod Waldhoff's tiny node.js webserver // original written in coffeescript // simplified and made more native-ish by Anil Somayaji // March 19, 2014 // // original headers of coffeescript version: // // A simple static-file web server implemented as a stand-alone // Node.js/CoffeeScript app. //--------------------------------------------------------------------- // For more information, see: // <https://github.com/rodw/tiny-node.js-webserver> //--------------------------------------------------------------------- // This program is distributed under the "MIT License". // (See <http://www.opensource.org/licenses/mit-license.php>.) //--------------------------------------------------------------------- // Copyright (c) 2012 Rodney Waldhoff // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. //--------------------------------------------------------------------- var path = require('path'); var http = require('http'); var fs = require('fs'); var MIME_TYPES = { 'css': 'text/css', 'gif': 'image/gif', 'htm': 'text/html', 'html': 'text/html', 'ico': 'image/x-icon', 'jpeg': 'image/jpeg', 'jpg': 'image/jpeg', 'js': 'text/javascript', 'json': 'application/json', 'png': 'image/png', 'txt': 'text/text' }; var options = { host: 'localhost', port: 8080, index: 'index.html', docroot: '.' }; var get_mime = function(filename) { var ext, type; for (ext in MIME_TYPES) { type = MIME_TYPES[ext]; if (filename.indexOf(ext, filename.length - ext.length) !== -1) { return type; } } return null; }; var respond = function(request, response, status, content, content_type) { if (!status) { status = 200; } if (!content_type) { content_type = 'text/plain'; } console.log("" + status + "t" + request.method + "t" + request.url); response.writeHead(status, { "Content-Type": content_type }); if (content) { response.write(content); } return response.end(); }; var serve_file = function(request, response, requestpath) { return fs.readFile(requestpath, function(error, content) { if (error != null) { console.error("ERROR: Encountered error while processing " + request.method + " of "" + request.url + "".", error); return respond(request, response, 500); } else { return respond(request, response, 200, content, get_mime(requestpath)); } }); }; var return_index = function(request, response, requestpath) { var exists_callback = function(file_exists) { if (file_exists) { return serve_file(request, response, requestpath); } else { return respond(request, response, 404); } } if (requestpath.substr(-1) !== '/') { requestpath += "/"; } requestpath += options.index; return fs.exists(requestpath, exists_callback); } var request_handler = function(request, response) { var requestpath; if (request.url.match(/((.|%2E|%2e)(.|%2E|%2e))|(~|%7E|%7e)/) != null) { console.warn("WARNING: " + request.method + " of "" + request.url + "" rejected as insecure."); return respond(request, response, 403); } else { requestpath = path.normalize(path.join(options.docroot, request.url)); return fs.exists(requestpath, function(file_exists) { if (file_exists) { return fs.stat(requestpath, function(err, stat) { if (err != null) { console.error("ERROR: Encountered error calling" + "fs.stat on "" + requestpath + "" while processing " + request.method + " of "" + request.url + "".", err); return respond(request, response, 500); } else { if ((stat != null) && stat.isDirectory()) { return return_index(request, response, requestpath); } else { return serve_file(request, response, requestpath); } } }); } else { return respond(request, response, 404); } }); } }; var server = http.createServer(request_handler); server.listen(options.port, options.host, function() { return console.log("Server listening at http://" + options.host + ":" + options.port + "/"); });

This is the following question in the assignment:

Tasks

  1. 1.Change the port the server listens on to be 3000.
  2. 2.Change the server to serve files from /home/student/public_html rather than the current directory. Be sure to put some files in it! (Hint: you can grab HTML files    
  3.     from any webserver using wget or curl.)
  4. 3. Change tinywebserver.js so it returns a simple HTML error page in response to 404 errors (page not found). (Hint: Make sure you keep all your JavaScript and 
  5.     HTML files in the same folder!)
  6. 4. Make the options object be stored in a file options.json and read on server startup. This load may be synchronous! Use JSON.parse() to convert the file data into an object.

5. [1] Add a new 777 status code if there is a request for any document with the word “lucky” in its URL (path or document name).

  1. 6. [1] Add a command line argument which is the name of a configuration file. This file should contain the contents of the options object. Note that tinyweb.js should start up correctly without this option file being specified; in this case it should behave as tinywebserver.js does (with respect to the options, not the lucky return code).
  2. 7. In the configuration file add the following properties to the option object that change the behavior of the app as follows (note it should also contain all the   
  3.     options that were already part of the options object):         
    • [2] logged-headers: an array of headers (as strings) that should be logged for each incoming request. If no logged headers are specified, no headers should be logged. Header names should be in all lowercase with words separated by dashes. Thus “UserAgent” becomes “user-agent”. (This change is because this is the format of header names in request.headers.) The format should be three spaces, the header name, a colon, a space, then the contents of the header.      
    • [2] logfile: the filename where to write log messages. They should be written to standard out (as console.log does) if no logfile is specified.      
    • [2] errorpage: html file to be returned when an error page is returned (not 200). The 777 status code should NOT return an error page, it should return the regular document (777 is an alias for 200).      
    • [2] aliases: object where the key is the alias and the value is what should be substituted. The alias should be for the entire doc path (the URL without the hostname). Aliases should be handled before lucky URL processing (and really, just about everything else).