Commit eb2b9acc authored by Nathan Bean's avatar Nathan Bean
Browse files

Revising chapter 6

parent 038c3406
......@@ -5,7 +5,7 @@ weight: 70
date: 2018-08-24T10:53:26-05:00
---
While we normally think of downloading an entire file from the web, there are some situations where it makes sense to download only _part_ of a file. One case is with a large file download that gets interrupted - it makes a lot of sense to start downloading the remaining bytes from where you left off, rather han starting over again. A second case is when you are streaming media; often the user may not watch or listen to the entire media file, so why download the bytes they don't need? Or if it is a live stream, we explicitly _can't_ download the entire thing, becuase later parts do not yet exist!
While we normally think of downloading an entire file from the web, there are some situations where it makes sense to download only _part_ of a file. One case is with a large file download that gets interrupted - it makes a lot of sense to start downloading the remaining bytes from where you left off, rather han starting over again. A second case is when you are streaming media; often the user may not watch or listen to the entire media file, so why download the bytes they don't need? Or if it is a live stream, we explicitly _can't_ download the entire thing, because later parts do not yet exist!
## Range Headers
......
---
title: "Custom Servers"
pre: "4. "
weight: 40
date: 2018-08-24T10:53:26-05:00
---
While CGI Scripts and Server Pages offered ways to build dynamic websites using off-the shelf web server technologies (Apache, IIS), many programmers found these approaches limiting. Instead, they sought to build the entire web server as a custom program.
Node was actually developed for exactly this approach - it provides abstractions around the fundamental aspects of HTTP in its [http](https://nodejs.org/api/http.html) library. This library handles the listening for HTTP requests, and parses the request and uses it to populate a [http.ClientRequest object](https://nodejs.org/api/http.html#http_class_http_clientrequest) and provides a [http.ServerResponse object](https://nodejs.org/api/http.html#http_class_http_serverresponse) to prepare and send the response. These are abstractions around the HTTP Request and Response we discussed in chapter 2.
The authors of Node took advantage of the functional nature of JavaScript to make writing servers easy - we just need to provide a function to the server that takes a request/response pair. This has been our `handleRequest()` method, and we can pack it with custom logic to determine the correct _response_ for the incoming _request_.
We've already written a number of functions that take in a request and response object, and determine the correct response to send. This includes our `serveFile()`, and our `listDirectory()`. We can create dynamic pages in much the same way - by writing a custom function to serve the dynamic page.
For example, a very simple dynamic page could be created with this function:
```js
function serveTime(req, res) {
var html = `
<!doctype html>
<html>
<head>
<title>Server Time</title>
</head>
<body>
<h1>Time on the server is ${new Date()}</h1>
</body>
</html>
`;
req.writeHead(200, {
"Content-Type": "text/html",
"Content-Length": html.length
}).end(html);
}
```
But for a server to be _dynamic_, we typically want more than just the ability to render a page from code. We _also_ want to interact with the user in some meaningful way - and that means receiving data _from_ them. In the HTTP protocol there are several ways for the user to send data:
1. By the path of the request, i.e. when we request `https://support.cs.ksu.edu/CISDocs/wiki/Main_Page` the path `CISDocs/wiki/Main_Page` indicates the page we are requesting
2. By additional information contained in the URL, specifically the _query string_ (the part of the URL that follows the `?`) and the _hash string_ (the part of hte URL that follows the `#`)
3. By information contained in the _body_ of the request
We've already looked at the path portion of the URL in describing how we can implement a file server to serve files and directories. But what about the query string and body of the request? Let's look at how those are handled in Node next.
---
title: "Query and Hash Strings"
pre: "6. "
weight: 60
pre: "5. "
weight: 50
date: 2018-08-24T10:53:26-05:00
---
Query strings (aka search strings) are the part of the URL that appear after the `?` and before the optional `#`. The hash string is the portion of the url after the `#`. We've mentioned them a bit before, but as we dig into dynamic web servers it makes sense to do a deeper dive, as this is where they really come into play.
## The Hash String
......@@ -12,7 +13,7 @@ First, let's briefly visit the hash string. It's traditional use is to indicate
With the advent of single-page apps, it has come to serve additional purposes; but we'll talk about those when we visit that topic in a future chapter.
## The Query/Search String
Now, the Query string is a vital tool for dynamic web pages, as it conveys information _beyond_ the specific resource being asked for to the server. Consider what a dynamic webserver does - it takes an incoming request, and sends a response. In many ways, this is similar to a function call - you invoke a function, and it returns a value. With this in mind, the path of the URL is like the function name, and the query string becomes its _parameters_.
Now, the query string is a vital tool for dynamic web pages, as it conveys information _beyond_ the specific resource being asked for to the server. Consider what a dynamic webserver does - it takes an incoming request, and sends a response. In many ways, this is similar to a function call - you invoke a function, and it returns a value. With this in mind, the path of the URL is like the function name, and the query string becomes its _parameters_.
Much like parameters have a name and a value, the query string is composed of key/value pairs. Between the key and value of each pair is a `=`, and between the pairs is a `&`. Because the `=` and `&` character now have a special meaning, any that appear in the key or value are swapped with a special percent value, i.e. `&` becomes `%26` and `=` becomes `%3D`. Similarly, other characters that have special meanings in URLs are likewise swapped. This is known as URL or percent encoding, and you can see the swapped values in the table below:
......
---
title: "Form Encoding"
pre: "7. "
weight: 70
pre: "6. "
weight: 60
date: 2018-08-24T10:53:26-05:00
---
......
---
title: "Request Body"
pre: "8. "
weight: 80
pre: "7. "
weight: 70
date: 2018-08-24T10:53:26-05:00
---
......@@ -11,7 +11,7 @@ This is fine for GET requests, as they don't have a body. But for requests that
To do so, there are three events made available in the [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) object: `data`, `end`, and `error`.
The `data` event occurs whenever a new chunk of the body is available, and that chunk is passed to the event listener. The `end` event occurs once all the chunks have been recieved. And the `error` event occurs when something goes wrong. The chunks are [Buffer](https://nodejs.org/api/buffer.html) objects, and are always received in order.
The `data` event occurs whenever a new chunk of the body is available, and that chunk is passed to the event listener. The `end` event occurs once all the chunks have been received. And the `error` event occurs when something goes wrong. The chunks are [Buffer](https://nodejs.org/api/buffer.html) objects, and are always received in order.
Thus, we need to collect each chunk from each `data` event, and join them together into a single buffer at the `end` event. Thus, the basic scaffold for doing so is:
......
......@@ -3,6 +3,7 @@ title: "Cookies"
pre: "9. "
weight: 90
date: 2018-08-24T10:53:26-05:00
draft: true
---
HTML was designed as a _stateless_ protocol. This means that there is no expectation for the server to keep track of prior requests made to it. Each incoming HTTP request is effectively treated as if it is the _first_ request ever made to the server.
......
......@@ -3,6 +3,7 @@ title: "Sessions"
pre: "10. "
weight: 100
date: 2018-08-24T10:53:26-05:00
draft: true
---
If HTTP is stateless, how do e-commerce websites manage to keep track of the contents of your shopping cart as you navigate from page to page? The answer is the use of a _session_ - a technique by which state is added to a web application.
......
......@@ -3,6 +3,7 @@ title: "Full Stack Development"
pre: "4. "
weight: 40
date: 2018-08-24T10:53:26-05:00
draft: true
---
Server pages represented one approach to tackling the dynamic web server challenge, and one that was especially suitable for those web developers who primarily worked with static HTML, CSS, and JavaScript backgrounds. But for those that were already programmers, the server page approach could feel confining. Instead, these programmers wanted more control over the web server and its working parts.
......@@ -16,7 +17,7 @@ For a dynamic web server, we can separate the needed functionality into three pr
3. Providing persistent data storage
## Serving Static Content
We've already discussed file servers extensively, and even discussed some options for optimizing thier performance - like caching the most frequently requested files. There are a number of software packages that have been developed and optimized for this task. Some of the best known are:
We've already discussed file servers extensively, and even discussed some options for optimizing their performance - like caching the most frequently requested files. There are a number of software packages that have been developed and optimized for this task. Some of the best known are:
* [The Apache HTTP Server Project](https://httpd.apache.org/), an open-source server project originally launched in 1995, and consistently the most popular server software on the Internet. The CS department website is hosted on an Apache server, as is your personal web site on the departmental server.
* [Internet Information Services (IIS)](https://www.iis.net/), Microsoft's flagship web server bundled with the Windows Server operating system.
......
......@@ -3,6 +3,7 @@ title: "HTML Templates"
pre: "5. "
weight: 50
date: 2018-08-24T10:53:26-05:00
draft: true
---
While full-stack developers may have chafed at the restrictions imposed by server pages, there was one aspect that came to be greatly valued - the ability to embed script directly in HTML, and have it evaluated and concatenated into the HTML text.
......@@ -10,11 +11,11 @@ While full-stack developers may have chafed at the restrictions imposed by serve
## Template Libraries
This is where template libraries come in. A template library allows you to write your HTML content _as HTML in a separate file_ with a special syntax to inject dynamic programming script. This is often some variation of `<>` or `{}`. This approach allows you to validate the HTML, as the script portions are ignored as unknown tags (when using `<>`) or as static text.
When the server is running, these templates are rendered, evaluating any code and suppling the applicable variables. This process generates the HTML snippet.
When the server is running, these templates are rendered, evaluating any code and supplying the applicable variables. This process generates the HTML snippet.
This is similar to what server pages do. However, server pages represent an _integrated_ approach - the server page framework defined all aspects of how you could interact with the OS, the web server, and other programs. In contrast, a template library provides the option of using templates within any project - obviously for generating HTML as part of a dynamic website, but potentially for other kinds of applications as well.
Thus, a template rendering library gives us a lot of flexibilty in how and when we use it. For example, in using the [Embedded JavaScript](https://ejs.co/) template library, we could rewrite our directory listing as:
Thus, a template rendering library gives us a lot of flexibility in how and when we use it. For example, in using the [Embedded JavaScript](https://ejs.co/) template library, we could rewrite our directory listing as:
```html
<!doctype html>
......@@ -59,7 +60,7 @@ ejs.renderFile("templates/directory-listing.ejs", data, function(err, html){
While this may _seem_ like just as much work as the concatenation approach, where it really shines is the ability to combine multiple templates, separating parts of the pages out into different, reusable template files. These are typically separated into two categories based on how they are used, _partials_ and _layouts_.
### Partials
A partial is simply a _part_ of a larger page. For example, the entries we are rendering in the listing could be defined in thier own template file, _directory-listing-entry.ejs_:
A partial is simply a _part_ of a larger page. For example, the entries we are rendering in the listing could be defined in their own template file, _directory-listing-entry.ejs_:
```html
<a href="<%= path %">
......
......@@ -3,6 +3,7 @@ title: "Dynamic Pages"
pre: "6. "
weight: 60
date: 2018-08-24T10:53:26-05:00
draft: true
---
We've already written a number of functions that take in a request and response object, and determine the correct response to send. This includes our `serveFile()`, and our `listDirectory()`. We can create dynamic pages in much the same way - by writing a custom function to serve the dynamic page.
......@@ -31,5 +32,4 @@ function serveTime(req, res) {
But let's expand our thinking to tackle a more involved website
With a template library, we can start thinking about how to better structure our software to produce the web pages that our dynamic web application consists of. The template library can be used to produce the HTML we need to serve, now we need to consider exactly which templates to use, in what combination, and what data needs to be provided to them.
\ No newline at end of file
......@@ -3,6 +3,7 @@ title: "Routing"
pre: "4. "
weight: 40
date: 2018-08-24T10:53:26-05:00
draft: true
---
A second major item to consider with dynamic web servers is how to respond to incoming requests. With static web servers, it is pretty simple - we map the virtual path supplied by the URL to a file path on the file server. But the URL supplied in a request _doesn't_ have to correspond to any real object on the server - we can create any object we want, and send it back.
......
......@@ -36,5 +36,5 @@ The downside is that it takes longer to log a user in using this strategy, but i
This brings us to the second half of the username/password approach - we have to implement some form of user session. To do user sessions, we must also employ cookies. By their nature, cookies are not as secure as we might like, but there are some strategies we can use to make them more secure. First, we should specify the cookies using the `Secure` and `HttpOnly` attributes, and the `SameSite` attribute set to `Strict`. Moreover, the values set in the cookie should also be encrypted before being set (in this case, with a two-way encryption). Commonly, only the session id or user id will be included in the cookie, while the actual session data will be stored server-side in memory or in a sessions table.
{{% notice warning %}}
As with HTTP Authentication (and indeed, all authentication approaches) password-based authentcation should only be used with HTTPS connections.
As with HTTP Authentication (and indeed, all authentication approaches) password-based authentication should only be used with HTTPS connections.
{{% /notice %}}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment