## 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`.