This project is STRICTLY solo. You may not collaborate with other students at all.
Setup
Register for the project using the registration tool and clone the repository as explained in the setup instructions.
You MUST work solo on this project!
You may not collaborate at all with anyone else! Please use the SSH link found on the registration page and in the email sent to you,
it should look something like git@gitlab.caltech.edu:cs3-25sp/webserver03-blank.git
.
Introduction
In the last project, you wrote code to parse requests…but then you just ignored the contents of the request and said hello! Real servers obviously don’t do that.
This project will be focused on handling the “path” part of the request which is used to specify the specific resource requested from the server. For example, on the
https://sof.tware.design/
web server (which you’ve used extensively!), there are many paths that all respond differently. For example:
- The URL https://sof.tware.design/25sp has a path of
/25sp
, and the “handler” for that path gathers and displays the homepage of this year’s CS 3 website in HTML. - The URL https://sof.tware.design/25sp/documents/debugging-guide has a path of
/25sp/documents/debugging-guide
, and the “handler” for that path gathers and returns ourC
debugging guide in HTML. - The URL https://sof.tware.design/25sp/projects/webserver/03 (the current page!) has a path of
/25sp/projects/webserver/03
, and the “handler” for that path gathers and returns the project guide for webserver03 in HTML.
The part of the server that figures out how to handle any given path is called the “router”. The router selects a “handler” (which is a function pointer) to handle the request and return an answer based on the path passed in in the request.
Routing
To implement a structure similar to the one above, we would need three “handlers”:
char *homepage_handler(request_t *request) { ... }
char *debug_guide_handler(request_t *request) { ... }
char *webserver03_handler(request_t *request) { ... }
Then, we could “install” those handlers into our router by calling the router_register
function four times:
router_register(router, "/25sp", homepage_handler);
router_register(router, "/25sp/documents/debugging-guide", debug_guide_handler);
router_register(router, "/25sp/projects/webserver/03", webserver03_handler);
Finally, the client would call router_dispatch
on each request made to the web server. router_dispatch
would then determine which of the registered routes is the one requested and call
the appropriate handler for that path!
Initialization
Task 0.
Bring over http_request.c
, http_response.c
, ll.c
, mystr.c
, and strarray.c
into the library
directory. Also copy over web_server.c
and place it in the server
directory.
You can run make task0
to run the previous projects’ tests to make sure you’ve brought everything over correctly.
Now that you have that out of the way, it’s time to get started.
Task 1.
Implement the router_init
and router_free
functions in router.c
. As usual, consult router.h
for details of their behavior.
Both of these functions require working with all the constructs we’ve learned in CS 3 so far but are otherwise simple and should be less than 10 lines each.
Run make task1
to run a basic check.
Once you’ve done that, you can get to the interesting stuff: registering and dispatching routes.
Registering routes represents telling the router that a given path should be handled by a given handler. Typically, you would register all your routes all at once when the server starts.
Dispatching routes represents analyzing a request (specifically, its path) to figure out what code should run to respond to this request. This is done each time a request comes in.
We’ll start with dispatching, since this will let us test the fallback handler behavior, though we won’t be able to fully test your dispatch until you implement registering.
Task 2a.
Implement router_dispatch
.
Now, implement registration.
Task 2b.
Implement router_register
.
Run make test
once finished to test registration and dispatching (and more fully test router_free
).
You’re all done! Next time, you will use your router in web_server.c
to register some routes that will be useful later!
Push your code to complete the project.