WebFund 2015W Lecture 7

From Soma-notes

Resources

Video

The video from the lecture given on January 26, 2015 is available now as an MP4.

Notes

Tutorial 3 / Assignment 3

  • Assignment 3 is about tinywebserver.js
  • 170 lines of code (40 lines are comments)
  • tinywebserver.js is a static web server in Node
  • The understanding of this code leads to a better understanding of:
    • JavaScript
    • Callbacks
    • What is a web server?
  • The tutorial consists of exercises involving changing things around in the code
  • The assignment consists of more in-depth questions such as:
    • Breaking lines of code and see what happens
    • Explaining what various functions do
  • Download some web sites and try to serve them from tinywebserver.js

Tinywebserver

  • Running tinywebserver.js for the first time and immediately trying to access a web page yields a 404 error because there is no index.html file in the directory of tinywebserver.js
  • tinywebserver.js serves the files that are in the directory when the server is executed
  • You can put content onto the web server by putting files in its directory
  • Any page that you add to the web server in this way is a static resource
  • If you download a web page and try to add it to your server, you should expect it to break
  • This can happen when downloading modern web pages because the web browser cannot get the entire web page (it gets the html document and any other files that are associated with it but may miss some resources)
  • You can go through the lines of code that break by seeing what requests have been successful and what requests have received 404 errors
  • tinywebserver.js depends on the Node modules path, http, and fs
    • path is used to parse request and resource paths
    • fs is for basic file system operations
    • http gives you the barest bones of a web

var server = http.createServer(request_handler)

  • Creates a web server
  • Given a function called request_handler
  • request_handler handles every incoming HTTP request
  • server.listen() tells the server to begin listening for incoming requests for a the supplied port and host
  • server.listen() is also given a callback function which prints the host and port that the server is listening at

var request_handler = function(request, response)

  • This function is used to deal with all incoming requests
  • It takes a request and a response object as parameters
  • We can find out what the request and response objects are through the debugger
  • We can access specific fields of the request object
  • If you want to find out what a specific line does; type it in when you run node in the terminal
  • requestpath is the incoming url concatenated with the docroot after it has been cleaned up
  • We can see that there are two more functions defined within this function
  • These additional functions are callback functions which are supplied to other function calls
  • fs.exists() is a method which checks if the file specified in the first parameter exists and then calls the function in its second parameter
  • This second parameter is a callback function with a parameter file_exists
  • A callback function is used because we don’t how long it will take for fs.exists() to run and we don't want to wait for it so we let it work asynchronously and then call the callback function when it is done
  • If the requested path is found and it is a directory then return_index() is called
  • If the requested path is found and it is a file then serve_file() is called

var return_index = function(request, response, requestpath)

  • return_index() sends a response with an index page
  • If neccessary, it adds a ‘/’ to the requestpath and then adds the options.index value, which in this case is index.html
  • Using fs, it checks to see if the requestpath exists
  • Once again, a callback function is seen in the call to fs.exists()
  • Inside the callback function, if the file was found to exist, then serve_file() is called
  • If the file does not exist then respond() is called to provide a response with an error

var serve_file = function(request, response, requestpath)

  • serve_file() sends a response with the specified file
  • It reads the file using fs.readFile and then serves the response inside the callback function which is called after reading the file
  • If there is an error, it sends a response with a 500 error
  • If there is no error, it send a response with the contents of the file and a 200 HTTP code in the header
  • In either case, the response is sent using the respond() function

var respond = function(request, response, status, content, content_type)

  • This function is responsible for sending a response to the client
  • The response may simply be a page with an error in the response headers or it may be an actual file depending on what happened in the functions leading up to the call to respond()
  • response.writeHead() writes headers in the response including one which indicates the type of content that is being served
  • response.write() writes content to the body of the response
  • response.end() sends the response to the client

Flow of control

  • All functions are defined in sequential order
  • The web server is created
  • The web server begins listening for incoming requests and the callback function of the listen() function runs
  • When the server receives a request, request_handler() runs
  • Subsequent function calls occur with each incoming request based on the nature of the request

Callbacks / asynchronous function calls

  • Asynchronous means non-blocking
  • We use an asynchronous function call because we don’t want to block and wait a long time for something to finish while other work can still be done
  • The functions defined in request_handler() are callback functions used for fs.exists() and fs.stat() since file system operations are slow
  • To better understand the flow of the code try to rewrite it synchronously (without the use of callback functions)