This is an archived copy of a previous semester's site.
Please see the current semester's site.
The Hyper-Text Transfer Protocol (HTTP) – defined in RFC 2616 and other later specifications – is the fundamental protocol for transferring data on the World Wide Web (i.e. Internet). It is an application-level protocol which through the use of its request methods, error codes and headers is widely used for various different applications.
HTTP is a Client-Server protocol, where the Client sends a request to the Server which processes the request and returns appropriate response. In this MP, you will:
curl
, and anything else that speaksHTTP).
In your CS 340 directory, merge the initial starting files with the following commands:
git fetch release
git merge release/mp4 --allow-unrelated-histories -m "Merging initial files"
Debugging the code
If you can’t run the debugger on this code, you might need to make one or both of the following changes depending on your system setup:
.vscode/launch.json
, change "run make test"
to "make test"
.vscode/launch.json
, change "[part=1]"
to "'[part=1]'"
and similarly for the other two parts.To help you organize the parts of building a web server, we’ve split up the implementation into three parts:
http.c
except httprequest_read
.httprequest_read
function).httprequest
code that can be used with Chrome or other web browsers.In your solution, you must only modify the following files. Modifications of other files may break things:
http.c
http.h
server.c
HTTP sends messages over a socket (or, for some of our tests, other file-like objects). Messages have 3 parts:
A web server (which is what you’re making in this MP) needs to receive and parse HTTP messages of the various Request types and construct and sent HTTP messages of the various Response types.
We’ve split these tasks into several functions. In order of calling, they are
Either server.c
’s main
(which is complete and needs no changes from you) or a tester file establishes a connection to a client.
Either server.c
’s client_thread
(which you’ll write in part 3) or a tester file manages that connection and calls httprequest_read
with the open connection as an argument.
http.c
’s httprequest_read
(which you’ll write in part 2) assembles an HTTP message from one or more packets, parses it, and stores it in an HTTPRequet
structure defined in http.h
by:
http.c
’s httprequest_parse_headers
to parse the start line and header lines; andThis information gets stored in the HTTPRequet
structure, which you may add to if you wish. Because you may add to it, getter functions are used to access its key details rather than using direct field access, and a destructor function is used to deallocate any resources it has used.
server.c
’s client_thread
uses the parsed request message to decide what response message to send.
The details of each of these pieces (e.g. how you know that you’ve passed the end of the headers) are defined in RFC 2616.
Implement the API provided in http.{c,h}
, excluding httprequest_read
. The main function in this part is httprequest_parse_headers
, which must populate the provided HTTPRequest *req
data structure with the contents from char *buffer
.
The other functions include:
httprequest_get_action
, to get the action verb (ex: GET
) from the HTTP request,httprequest_get_path
, to get the path (ex: /
) from the HTTP request,httprequest_get_header
, to get a value for a specific header (ex: Host
-> localhost
), andhttprequest_destroy
, to free any memory stored by an HTTPRequest
structWhile working on this part:
HTTPRequest
struct in http.h
(possibly also creating other structs in there, too).action
, path
, version
fields in HTTPRequest
while parsing the packet as part of httprequest_parse_headers
.We have provided a simple test suite to test the correctness of your parsing logic:
make test
to compile the test suite../test "[part=1]"
to run the tests that have been tagged with [part=1]
(covering this portion of the MP).Complete httprequest_read
. This function is called with a file descriptor where you must read
to read the contents of the request.
httprequest_parse_headers
to parse the headers of the request.Content-Length
header is a special HTTP header that will help you out to read the payload
of the request.To pass some of the tests you will need to use read
not recv
when reading from the socket.
We have provided a simple test suite to test the correctness of your parsing logic. The first five tests are identical to part 1, except that they’re now delivered via the sockfd
file descriptor instead of as a string. The final test tests if your code can read the payload of a requests.
make test
to compile the test suite../test "[part=2]"
to run the tests that have been tagged with [part=2]
(covering this portion of the MP).We have provided a partial threaded socket-based web server in server.c
. You need to finish implementing the client_thread
function.
Our code has a main thread in the function main
and spawns worker threads to run client_thread
. The main thread is fully complete (no edits needed) and does the following:
You will write the client_thread
function in server.c
:
fd
(use your httprequest_read
)./
, you should process that request as if the path is /index.html
.static
directory (excluding the /
), you must respond with a 404 Not Found
response.200 OK
packet and:
.png
, the Content-Type
header must be set to image/png
..html
, the Content-Type
header must be set to text/html
.close(fd)
after responding to the request. This will ensure the browser opens a new socket (and you will have a new thread) when making another request. (You can continue to re-use this same socket and keep the connection alive, but this is not required.)Web clients may send several HTTP requests over the same connection. They may also send one, wait for the reply without closing the connection, then send the next. Make sure you process each HTTP request as soon as you have the entire request, not waiting for the connection to close.
You will test Part 3 using your favorite web browser.
make
./server 34000
(or any other port number)http://sp24-cs340-###.cs.illinois.edu:34000/
if running on VM number ###
)
If you can see the pages and images, you just made your first static web server! 🎉
There are a few tests ./test "[part=3]"
to verify it works by code – but that’s not really the point of this part.
For full credit, your MP must run valgrind clean
.
valgrind ./test
.docker build -t cs340 .After the the container is built, run the container in your mp4 directory. This new container now provides you a bash prompt.
docker run -p 34000:34000 --rm -it -v "`pwd`:/mp4" cs340Once you’re into the container, you will need to
cd mp4
and then you can run the terminal commands directly! :)
cd mp4 make clean make make test ./test
Once you have locally passed all the tests, you will need to submit and grade your code. First commit using the standard git commands:
git add -A
git commit -m "MP submission"
git push
The initial grading is done via a manual GitHub Action. You MUST complete this step before the deadline to earn any points for the MP:
ActionTab
mp4 autograding
Run Workflowbutton (located on the blue bar)
Run Workflow
2/3 of points are for the autograder part of the GitHub Action
1/3 of points are for the valgrind part of the GitHub Action