--- templateEngineOverride: false --- DOCTYPE html> CS 351 Spring 2020 Homework 8

CS 351 Spring 2020 Homework 8

Promises, requests, and WebServers

Dr. Greg M. Bernstein

Due Monday, April 5th (recommended March 29nd), 2021 by 11:59PM, 50 points.

General Instructions

In this homework: We will get hands on with JavaScript Promises, HTTP requests the node-fetch library, and the Express web server framework. Put any code you write for this homework into a high level directory with the name practice. Clear out any old files that you may have in this directory.

Create and Use a new Branch hw8

We will create a new git branch called hw8 (starting from your ‘hw7’ branch) for use in this assignment. The branch you create must exactly match the one I’ve given you for you to receive any credit for this homework.

Prior to creating this new branch make sure your working directory is “clean”, i.e., consistent with the last commit you did when you turned in homework 7. Follow the procedures in GitHub for Classroom Use to create the new branch, i.e., git checkout -b hw8. Review the section on submission for using push with a new branch.

Use README.md for Answers

You will modify the README.md file to contain the answers to this homework.

# Homework #8 Solution

**Your name**
**NetID: yourNetID**

Questions

Question 1. (10 pts) HTTP

Visit your Blackboard login page and use the developer tools network panel to answer the following questions about the HTTP request and response messages sent between your browser and the Blackboard server.

(a)

What HTTP Method is used in the request?

What is the response code and what does it mean?

What version of HTTP is being used?

(b)

List the request headers and their values here (copy and paste, don’t write these out by hand!)

(c)

List the response headers and their values here (copy and paste)

(d)

What server is BlackBoard based on?

Are any cookies set? If so what are they.

(e) Object/String Chaining

The following code when run in the JavaScript console produces a string with the current time (based on UTC). Describe how the second line of code works from a programming perspective.

var myDate = new Date()
myDate.toISOString().toLowerCase().split("t")[1]

(f) URLs

For the following URLs identify the protocol, domain, port, path, query and fragment portions (if any):

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_Types#Comments

https://www.google.com/search?q=gaia+mission&rlz=1CYPO_enUS751

http://127.0.0.2:8282/static/index.html

Question 2. (10 pts) Requests and Promises

Put any code you write for this question in the practice directory of your repo. Note you make need to install some NPM packages for this problem.

(a) SetTimeout and The Event Queue

Show what this code will print out and more importantly explain why?.

function cs351() {
  console.log('This is a msg from CS351');
}
function cs651() {
  console.log('this is a msg from CS651');
}

console.log('Is this the start?');
setTimeout(cs651); // What does this do
console.log('When does this print?');
setTimeout(cs351, 0); // Is this different
console.log('Is this the end?');

(b) Promises

What does the following code do? And how can you find out the winner of the “promise race”?

function winner(name) {
  console.log(`The winner is ${name}`);
}
myP1 = new Promise(function(resolve, reject){
    setTimeout(()=>resolve("P1"), 1000*Math.random());
});
myP2 = new Promise(function(resolve, reject){
    setTimeout(()=>resolve("P2"), 1000*Math.random());
});
myP3 = new Promise(function(resolve, reject){
    setTimeout(()=>resolve("P3"), 1000*Math.random());
});
myPs = [myP1, myP2, myP3];
racingPs = Promise.race(myPs);

(c) Three HTTP Requests “in order”

Choose three different websites in order to practice making HTTP requests in code via the node-fetch library. Preferably at least one of your sites should be on a different continent. Visit each site one at a time in an order of your choosing and have your program print the time taken to receive from each site (Hint: modify the code in the Node Requests course slides or the example files. You cannot use the same sites as me). Take a screen shot. I get something like:

Serial

(d) Three HTTP Requests “in parallel”

Using the same three websites as above, run the three HTTP requests in parallel and output the time it takes. (Hint: modify the code in the Request course slides or the example files. You cannot use the same sites as me). Take a screen shot. I get something like:

Parallel

Put all the server code your write here in the practice directory of your repo. The purpose of this question is to get you practice setting up and running a bunch of simple web server applications on different addresses and/or ports. Note that you may need to install some NPM packages for this problem.

Some operating systems may not permit using different loopback addresses without additional configuration. If that is the case describe your system and take a screen shot of the error message you get and proceed with using localhost with different ports.

(a) Simple Date Server

Write a simple server based on Express to return your name and the current date and time when a GET request is made to the path /date. Use the built in JavaScript Date class. Run the server on a loopback address different from localhost (127.0.0.1), if possible, and a TCP port different from 80. No HTML generation is required. Use your browser to test and demonstrate the server is working. Take a screen shot showing both browser window and command line running the server. I get something like:

Screenshot

(b) Simple Name/NetID Server

Write a simple server based on Express to return your name, netID and number of visits when a GET request is made to the path /netID. Run the server on a loopback address different from localhost (127.0.0.1), if possible, and a TCP port different from 80, and from that used in part a. No HTML generation is required. Use your browser to test and demonstrate the server is working.

Note: Besides the use of the Express server methods you can use any JavaScript you like (variables, functions, etc.) in the file. Hence you can just define and update a variable to keep track of the number of visits to the “page”

Take a screen shot. I get something like:

Screen shot with two servers

(c) Combine services

Combine both services from above into a single server. Run the server on yet another loopback address and port. Take a screen shot of one request and show your server code here.

Three servers

Question 4. (20 pts) Server Side Rendering

(a) Set up directories

Within your repo create a new top level directory called clubServer. Within this directory create a public directory and a templates directory.

(b) Deployment Test Server

The deployTest.js server shown below isn’t returning valid HTML. Let’s fix that by using some templates, but first make your own copy and put it in your clubServer directory. Add the code necessary to this file to use nunjucks templates.

// deployTest.js
const express = require('express');
const app = express();
const port = 3001; // !!! WARNING YOU MUST CONFIGURE THIS CORRECTLY WHEN WE DEPLOY !!!

let count = 0; // Visit count
let startDate = new Date(); // Server start Date time
let yourName = "Your Name Here";
let netId = "Your Net Id";

app.get('/', function (req, res) {
    count++;
    res.send(`Hi from ${yourName}, NetId: ${netId}, Visited: ${count} times.`);
});

app.get('/uptime', function(req, res){
    let curDate = new Date();
    res.send(`Current Date/Time: ${curDate.toLocaleString()}, Server Up Since: ${startDate.toLocaleString()}`);
})

host = 'localhost';

app.listen(port, host, function () {
console.log(`deployTest.js app listening on IPv4: ${host}:${port}`);
});

(c) Create “base.njk” template

We will be using “template inheritance” to reduce redundancy in our templates. First we will create a base template called base.njk. Make Nunjucks blocks for holding metadata and the main content.

Show your base.njk code here. I wrote something like:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        {% block metaStuff %}
        <title>Bay Area Windsurf Foil Club</title>
        {% endblock %}
        <link href="css/club.css" rel="stylesheet">
    </head>
    <body>
    <main>
        {% block main %}{% endblock %}
    </main>
    <footer>
        <p>🐳 &copy; 2020 Grotto Networking! 🐬</p>
    </footer>
    </body>
</html>

(d) Create Templates based on base.njk

The deployTest.js server has two paths / and /uptime. Create “derived” templates for each of these paths to properly display their information.

For example here is most of my template for showing the “up time” for the server.

{% extends "base.njk" %}

{% block metaStuff %}
        <title>Server Uptime</title>
{% endblock %}
    
{% block main %}
    <h1>Server Uptime</h1>
    <h2>Server Started: {{startDate}}</h2>
    <!-- more stuff -->

{% endblock %}

(e) Use Nunjucks in deployTest.js

Now use nunjucks to render the pages. Note: CSS is not being included yet. Show the code you used to do this in deployTest (just the relevant functions not the entire file).

One of my screens looks like:

Screenshot

(f) Static Files and CSS

Now we’d like to serve up static resources such as CSS files, logos, icons, etc. We will put these in the public subdirectory. Configure the express.static middleware. Update your base.njk template to link to your stylesheet. Get everything working and take a screenshot of one of the two pages.

Styling with static CSS file
>