aboutsummaryrefslogtreecommitdiff
path: root/pa2_webserver/readme.md
blob: 1c8970dfce506a642c1379ba547d5bf01f303931 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
## Web Server
### Programming Assignment 2 - HTTP Web Server

In this assignment, you will create a TCP-based web server that handles multiple
simultaneous requets from users. A web server is a program that receives requests from
a client program and then sends a result back to the client in response. The client is
usually a web browser like Safari or Firefox.

### HTTP Request
The HTTP request consists of three substrings - **request method, request URL, & request
version**. All three parts should be separated by one or more white spaces. The request
method should be capital letters like "GET", "HEAD", & "POST". The request URL is a set
of words that are case insensitive and separated by "/" and th eserver should treat the
URL as a relative path of the current document root directory. The request version
follows a rule like "HTTP/x.y" where `x` and `y` are numbers. 

If you type a url like [http://www.w3.org/Protocols/rfc1945/rfc1945](http://www.w3.org/Protocols/rfc1945/rfc1945)
in a web browser, the web browser will send an HTTP GET command to the server [http://www.w3.org](http://www.w3.org)
after establishing a TCP connection with a port 80 on the server. IN this scenario, the
format for the HTTP GET command received at the web server is as follows:
```
GET /Protocols/rfc1945/rfc1945 HTTP/1.1
```

Based on these rules, we can identify the three substrings:
```
Request Method: GET
Request URI: /rfc1945/rfc1945
Request Version: HTTP/1.1
```

### HTTP Response
All responses must include one or more response headers, starting with a status code:
**Sample Response Header**
```
HTTP/1.1 200 OK
Content-Type: <> # Tells about the type of content and the formatting of <file contents>
Content-Length: <> # Numeric value of the number of bytes of <file contents>
```
The **Status Code** indicates whether the request succeeded or failed, or whether some
other administrative issue applies (like redirection). A status code of 200 indicates
that the requested file exists and the server is going to send the requested file back
to the client. A complete list of HTTP status codes found [here](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_success).

The **Content-Type** header tells the client what format the file contents will be in
and the **Content-Length** header indicates how many bytes will be transferred for the
file. You'll also need to make sure each response header is delimited by a terminating
CRLF, sometimes written as `\r\n`. The file content should be separated by an
additional new line, meaning you need to separate the last header and your file content
by `\r\n\r\n`.

### The Web Server
The server must take one command line argument: a port number for the server to run on:
```
./server 8888 # Running on port 8888
```
Your server should run in an infinite loop once it has started. You are expected to exit
out of the server gracefully when pressing Ctrl + C.

The web server will define a **Document Root** which is the base directory where all of the various files to be served reside. When the web server receives an HTTP request from
a client for a particular file, it should open the file in relation to this document
root and then send the file back to the client with proper header information. This
document's root directory should be in the subdirectory `./www` from where your web
server program runs.

If the requested URL is a directory (ie. `GET / HTTP/1.1` or `GET /inside/ HTTP/1.1`),
the web server should attempt to find a default page named `index.html` or `index.htm`
in the requested directory.

If the client sends an HTTP/1.1 request, the server must respond with an HTTP/1.0
protocol in its reply, and similarily for the HTTP/1.1 protocol.

### Handling Multiple Connections
When a client receives a web page that contains a lot of embbeded elements, it will
repeatedly generate an HTTP GET for each element in the page. As such, the server should
be capable of serving multiple requests simultaneously. This can be done using
`select()`, `fork()`, or `pthread_create()` with the following approaches:
* A multi-threaded implementation that creates a new thread for each incoming
connection. That is, once the server accepts a connection, it will spawn a thread to
parse the request, transmit the file, etc. Alternatively, you can pre-spawn threads and
keep them in a thread pool for future use.
* A multi-process implementation that spawns a new child process to service a request.
Similar to the above, you can spawn a worker pool of active processes to hand requests
off to from the main server process.

### Error Handling
When the HTTP request results in an error then the web server should respond to the
client with the appropriate status code. Your server should support the following status
codes:
| Value                        | Description                                                   |
|------------------------------|---------------------------------------------------------------|
| 200 OK                       | The request is valid                                          |
| 400 Bad Request              | The request could not be parsed or is malformed               |
| 403 Forbidden                | The requested file cannot be accessed due to permission issue |
| 404 Not Found                | The requested file cannot be found in the document tree       |
| 405 Method Not Allowed       | A method other than GET was requested                         |
| 505 HTTP Version Not Support | An HTTP version other than 1.0 or 1.1 was requested           |

### Testing
While you can use a web browser like Firefox to visually verify your implementation
works, automated scripts will use tools like `wget`, `curl`, and `aria2c`.