Page requests to the metal - frontend
This post is part of the page requests to the metal series where we cover all the steps from a web request down to the electrons that move in the CPU, see the intro/overview page to see where this fits in.
At this stage we are dealing with the processing of the information on the users machine. When we talk about frontend we are referring to the category of things that occurs on the users machine. Generally speaking this is just the things that occur within the users web browser.
Prelude - GET request
Before anything else we have to actually retrieve the page we want to view in our web browser. We navigate to the URL we want and then we submit a GET request to send to the server requesting the page that is at that URL.
Because we are being good with our web standards the GET request only starts the process of retrieving the data in the page, nothing that changes the state is carried out at this point.
We send out a request such as this:
Host: 127.0.0.1:8000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Cookie: csrftoken=RAV15luEfhxVAqHRjT1FAUtKzPEizBjOTuPElo3T76fnx1v5tLOWL4sy8J1RTKOj Connection: keep-alive Upgrade-Insecure-Requests: 1
To which we get back a response with status code 200 (indicating everything is OK) with the following header:
Date: Mon, 11 Sep 2017 04:21:03 GMT Server: WSGIServer/0.2 CPython/3.5.2 Vary: Cookie Content-Type: text/html; charset=utf-8 X-Frame-Options: SAMEORIGIN Content-Length: 349 Set-Cookie: csrftoken=RAV15luEfhxVAqHRjT1FAUtKzPEizBjOTuPElo3T76fnx1v5tLOWL4sy8J1RTKOj; expires=Mon, 10-Sep-2018 04:21:03 GMT; Max-Age=31449600; Path=/
This response has the payload of the HTML that gets rendered in the browser.
Both these raw headers can be found via the browsers web-developer tools. The payload can be found in the usual show-source command:
<html> <body> <h1> Add 2 numbers! </h1> <form method="post"> <input type='hidden' name='csrfmiddlewaretoken' value='8EFi3KDGaWVcLAxwcFTQTZ3LSuTXI3HVayzVjNcV2LDEIblKmxG7492zrogw2ccq' /> <tr><th><label for="id_number1">number1:</label></th><td><input type="number" name="number1" required id="id_number1" /></td></tr> <tr><th><label for="id_number2">number2:</label></th><td><input type="number" name="number2" required id="id_number2" /></td></tr> <input type="submit" value="Submit" /> </form> </body> </html>
We won't travel through all the layers on this first web request since we could have loaded this page just from disk and it keeps it simpler to wait until the POST request to travel down the layers. There's already a few hints at the things to come, such as the form we see on the page and the mention of WSGI and CPython in the headers.
So now that the HTML source of the page is actually loaded it has to get rendered from markup to a visual representation on our screen where we can enter in some inputs.
Unfortunately I'm not familiar with the internals of these, contributions to this article at this step are greatly appreciated!
Once the button to submit the form is clicked an event will fire that will eventually lead to a POST request being sent to the URL specified in the action.
The data in the form gets placed into a POST containing the relevant data to send to the server.
This now looks something like:
The web browser then hands this off to the network to be sent to the domain name. At this point we are now entering into the network stack.
Sidenote: What is the CSRF token?
You may have noticed that in this form there's a CSRF token that is included with the Django form. This is to prevent a type of security vulnerability called Cross-site request forgery (CSRF) that exploits the trust that a site has in a user's browser.
We know that a web form has to send something over the server to process it, see the next article in the series to get an overview of how that works.
This post is part 2 of the "PageRequestsToTheMetal" series:
- Page requests to the metal - introduction
- Page requests to the metal - frontend *
- Page requests to the metal - Network stack - From frontend to backend
- Page requests to the metal - Backend - What happens on the server
- Page requests to the metal - Backend web framework
- Page requests to the metal - Backend implementation
- Page requests to the metal - hardware level