> For the complete documentation index, see [llms.txt](https://computer-networks-lab.gitbook.io/computer-networks-lab-manual/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://computer-networks-lab.gitbook.io/computer-networks-lab-manual/assignments/a6-http-server-500-points.md).

# HTTP Server

{% hint style="warning" %}
This assignment has automated tests! Make sure to read the [Automated Testing page](/computer-networks-lab-manual/course-information/automated-testing.md) and to download the framework [from GitHub](https://github.com/atlarge-research/cn-lab-student) before starting.
{% endhint %}

{% hint style="warning" %}
Do not use imports for this assignment.
{% endhint %}

How many websites do you visit per day? Do you need a specialized program for every one of them? Probably not. It turns out that it has not always been the same. Before the invention of HTTP protocol - the backbone of the web - by Tim Berners Lee people used different programs to access different parts of the web. What made it possible was the unification of application-layer web protocols.

However, the complexities of dealing with HTTP are usually hidden behind the abstraction of web server frameworks like Node.js, Flask, Django, and others. Not today! In this assignment, you will explore what happens behind the curtains by implementing a simplified HTTP server.

**Important**: tests will expect a server to start at address 127.0.0.1 and port 8000 (even though you can develop your server using another address and port). The address and port will be, as well, supplied via test script when starting your server script using the `--address` and `--port` . Thus tests will start your server script as `python3 server.py --address "127.0.0.1" --port 8000` .

### Assignment Description

Your job is to implement a simplified HTTP 1.1 server supporting both GET and POST methods. The website, based on HTML files and images we provide, should be loadable from your server and be visible in the Google Chrome browser. Please note, that while most modern browsers will render you an HTTP document even if was sent by a protocol other than HTTP (for example FTP), for this assignment you are required to use HTTP for **ALL** client-server communication.

With this assignment, we provide you with a template rendering which is a minimal requirement for passing an assignment (template structure is specified in the following sections). Your server **MUST** support GET requests, at least one POST endpoint, and a dynamically rendered page, your server **MUST** support different types of documents transferred namely HTML files and JPEG images, and your server **MUST** support different status codes such as 200 (successful page retrieval), 201 (successful POST request submission), 400 (validation error on POST request; for the assignment), 404 (page not found).

### Documentation

Please start by reading [RFC 2616](https://www.ietf.org/rfc/rfc2616.txt) section 1 (Introduction) to get a general overview of the HTTP 1.1 protocol and its purpose. To parse a request sent to you by a browser, you should parse the request line parsing as specified in 5.1 (Request Line), the requested resource identifier as specified in 5.2 (The Resource Identified by a Request), and the method out of which your server should support at least two: GET as specified in 9.3 (GET) and POST as specified in 9.5 (POST).

In your HTTP response, you need to include the HTTP version as specified in section 3.2 (HTTP version), the content type as specified in 7.2.1 (Type), and the content length as specified in 7.2.2 (Entity Length), and the response code. Your server should support at least fetching JPG and HTML pages, and response codes 200 as specified in 10.2.1 (OK), 404 as specified in 10.2.5 (Not Found), 201 as specified in 10.2.2 (Created), and 400 as specified in 10.4.1 (Bad Request).

One of the main HTTP 1.1 features - support for persistent connections (*question to ask yourself: why were those important to add?*). Without the persistent connections support, your browser will not likely load your HTTP 1.1 page. Implement them as specified in section 8 (Connections). You do not need to consider sections 8.2.3 (Use of the 100 (Continue) Status) and 8.2.4 (Client Behavior if Server Prematurely Closes Connection).

### Requirements

Along with your assignment, you will find a website template attached under the **data** folder. The template has the following structure:

```
data
 |---> index.html.               # the main page. to be rendered under "/" or "index.html"
                                 # path. Has a POST form for personal cat submissions
 |---> success.html              # page informing a user of successful POST form submission. 
                                 # to be rendered after form submission
 |---> personal_cats.html        # page with user-added through the form cats.
                                 # to be rendered under "/personal_cats.html"
 |---> 404.html                  # 404 Not Found page. To be rendered under any path
                                 # other than ones already specified for other pages
 |---> 400.html                  # 400 Bad Request page. To be rendered if form submitted
                                 # contains validation errors (empty field)
 |---> img
    |-------> gleb_cat.jpeg      # Picture of Gleb's cat. To be rendered 
                                 # under "/img/gleb_cat.jpeg"
    |-------> standing_cat.jpeg  # Picture of the standing cat. To be rendered under
                                 # "/img/standing_cat.jped"
```

The automated tests expect the server to support the following endpoints:

<table><thead><tr><th width="222">endpoint</th><th width="89">method</th><th>description</th></tr></thead><tbody><tr><td>/</td><td>GET</td><td>The main index.html page with the form and images</td></tr><tr><td>/index.html</td><td>GET</td><td>The main index.html page with the form and images</td></tr><tr><td>/data</td><td>POST</td><td>The form (from the main page) submission endpoint</td></tr><tr><td>/img/gleb_cat.jpeg</td><td>GET</td><td>The image of Gleb's cat on the main page</td></tr><tr><td>/img/standing_cat.jpeg</td><td>GET</td><td>The image of a standing cat</td></tr></tbody></table>

The form on the main page must use `application/x-www-form-urlencoded` encoding and have the fields:

<table><thead><tr><th width="197">Name</th><th>Description</th></tr></thead><tbody><tr><td>cat_url</td><td>A url of cat picture</td></tr><tr><td>description</td><td>Description of a cat picture</td></tr></tbody></table>

Implementation Requirements:

1. **ISR1**: Your implementation should be executable by calling `python3 server.py --address "SERVER_ADDR" --port "PORT_ADDR"`. Your assignment can use other files; however, the automated tests assume that after executing the command your server will start at `SERVER_ADDR` and `PORT_ADDR`.
2. **ISR2**: Your server.py file should be located exactly at the place it is located in the testing template. Automated tests will assume **the same** directory structure.

Server Protocol Requirements:

1. **PR1**: The server must support HTTP 1.1
2. **PR2**: The server must support the GET method.
3. **PR3**: The server must support the POST method.
4. **PR4**: The server must support HTTP 1.1 persistent connections
5. **PR5**: You must use only HTTP 1.1 for all the communication between the server and the client

Website Template Load Requirements:

1. **LR1**: The server must be able to load at least the assignment template in the Google Chrome browser
2. **LR2**: When requesting a non-existing page, the server must respond with a pre-templated 404 HTML page
3. **LR3**: When requested with “/”, the server must respond with the index.html page
4. **LR4**: The server must be able to load an arbitrary HTML file provided its file path. For example, if `SERVER_ADDRESS/index.html` was requested, your server should return `index.html`. &#x20;
5. **LR5**: The server must be able to load arbitrary JPEG pictures provided their file path. For example, if `SERVER_ADDRESS/img/cat.jpg` was requested, your server should return the contents of `/img/cat.jpg` file.&#x20;
6. **LR6:** The `personal_cats.html` page must be generated dynamically using the data from the form on the `index.html` page.
7. **LR7**: The endpoint for accepting data from the `index.html` form must be located at `SERVER_ADDRESS/data`&#x20;

Response Requirements:

1. **RR1**: The server has to support at least 200, 201, 400, and 404 status codes
2. **RR2**: The server must respond indicating an appropriate response type in a header
3. **RR3**: The server must indicate the appropriate response length in a header
4. **RR4**: The server must indicate the appropriate protocol type (HTTP 1.1) in the header
5. **RR5**: The server must use UTF-8 encoding and indicate it in every response header.
6. **RR6**: If the form was submitted successfully, the server must respond with the contents of `success.html` file and 201 status code.
7. **RR7**: The server must respond with the contents of 404.html and 404 status code if the page does not exist.
8. **RR8**: The form at `index.html` must have an empty fields server-side validation and the server must respond with the contents of 400.html and 400 status code if the form was submitted with the empty fields.

### Last Note

Did you complete the assignment? Great! On the page index.html you will see pictures of two cats. You can change those with pictures of your own cats by putting your cat picture in img folder and changing the image `src` tag. **PLEASE DO NOT DELETE OTHER JPEG FILES** as it will likely fail the tests. Submit the final version on CodeGrade (with added pictures) and hand in your assignment. In case you have completed the assignment and submitted photos we might add your cat to the next version of the HTTP assignment template.
