Skip to content

Commit 689d819

Browse files
committed
Update README to clarify how to run unit tests for the cache exercise
1 parent 08b831d commit 689d819

File tree

1 file changed

+34
-61
lines changed

1 file changed

+34
-61
lines changed

README.md

+34-61
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ What's already there:
2525
## What is a Web Server?
2626

2727
A web server is a piece of software that accepts HTTP requests (e.g. GET
28-
requests for HTML pages), and returns responses (e.g. HTML pages). Other common
29-
uses are GET requests for getting data from RESTful API endpoints, images within
30-
web pages, and POST requests to upload data to the server (e.g. a form
31-
submission or file upload).
28+
requests for HTML pages), and returns responses (e.g. HTML pages). Other common uses are GET requests for getting data from RESTful API endpoints, images within web pages, and POST requests to upload data to the server (e.g. a form submission or file upload).
3229

3330
## Reading
3431

@@ -83,9 +80,7 @@ overall view, then come back to goal #1 and dig in._
8380

8481
1. Examine `handle_http_request()` in the file `server.c`.
8582

86-
You'll want to parse the first line of the HTTP request header to see if this
87-
is a `GET` or `POST` request, and to see what the path is. You'll use this
88-
information to decide which handler function to call.
83+
You'll want to parse the first line of the HTTP request header to see if this is a `GET` or `POST` request, and to see what the path is. You'll use this information to decide which handler function to call.
8984

9085
The variable `request` in `handle_http_request()` holds the entire HTTP
9186
request once the `recv()` call returns.
@@ -100,8 +95,7 @@ overall view, then come back to goal #1 and dig in._
10095
Hint: `strcmp()` for matching the request method and path. Another hint:
10196
`strcmp()` returns `0` if the strings are the _same_!
10297

103-
> Note: you can't `switch()` on strings in C since it will compare the string
104-
> pointer values instead of the string contents. You have to use an
98+
> Note: you can't `switch()` on strings in C since it will compare the string pointer values instead of the string contents. You have to use an
10599
> `if`-`else` block with `strcmp()` to get the job done.
106100
107101
If you can't find an appropriate handler, call `resp_404()` instead to give
@@ -115,16 +109,11 @@ overall view, then come back to goal #1 and dig in._
115109
If you need a hint as to what the `send_response()` call should look like,
116110
check out the usage of it in `resp_404()`, just above there.
117111

118-
Note that unlike the other responses that send back file contents, the `d20`
119-
endpoint will simply compute a random number and send it back. It does not
120-
read the number from a file.
112+
Note that unlike the other responses that send back file contents, the `d20` endpoint will simply compute a random number and send it back. It does not read the number from a file.
121113

122-
> The `fd` variable that is passed widely around to all the functions holds a
123-
> _file descriptor_. It's just a number use to represent an open
114+
> The `fd` variable that is passed widely around to all the functions holds a _file descriptor_. It's just a number use to represent an open
124115
> communications path. Usually they point to regular files on disk, but in
125-
> the case it points to an open _socket_ network connection. All of the code
126-
> to create and use `fd` has been written already, but we still need to pass
127-
> it around to the points it is used.
116+
> this case it points to an open _socket_ network connection. All of the code to create and use `fd` has been written already, but we still need to pass it around to the points it is used.
128117
129118
3. Implement `send_response()`.
130119

@@ -179,36 +168,21 @@ list](https://en.wikipedia.org/wiki/Doubly_linked_list) and a
179168

180169
The hashtable code is already written and can be found in `hashtable.c`.
181170

182-
1. Add cache entries to `cache.h`.
183-
184-
A cache entry should contain everything needed to serve the file:
185-
186-
* Endpoint path (e.g. `"/foo/bar.html"`)
187-
* Content length (e.g. `2123`)
188-
* Content type (e.g. `"text/html"`)
189-
* Content itself (e.g. `"<html><head>...etc."`)
190-
191-
The strings should be of type `char *` (as opposed to arrays). We'll allocate
192-
the space for them later.
193-
194-
In addition, since it's a doubly-linked list, the cache entry should have:
195-
196-
* Prev and next pointers to cache entries.
197-
198-
2. Implement `cache_put()` in `cache.c`.
171+
1. Implement `cache_put()` in `cache.c`.
199172

200173
Algorithm:
201174

202175
* Allocate a new cache entry with the passed parameters.
203176
* Insert the entry at the head of the doubly-linked list.
204-
* Store it in the hash table keyed by `path`.
205-
* Increment the current cache size.
206-
* If the cache size is greater than max size:
177+
* Store the entry in the hashtable as well, indexed by the entry's `path`.
178+
* Increment the current size of the cache.
179+
* If the cache size is greater than the max size:
180+
* Remove the entry from the hashtable, using the entry's `path` and the `hashtable_delete` function.
207181
* Remove the cache entry at the tail of the linked list.
208-
* For the path in that cache entry, delete the item from the hash table.
209182
* Free the cache entry.
183+
* Ensure the size counter for the number of entries in the cache is correct.
210184

211-
3. Implement `cache_get()` in `cache.c`.
185+
2. Implement `cache_get()` in `cache.c`.
212186

213187
Algorithm:
214188

@@ -217,10 +191,10 @@ The hashtable code is already written and can be found in `hashtable.c`.
217191
* Move the cache entry to the head of the doubly-linked list.
218192
* Return the cache entry pointer.
219193

220-
4. Add caching functionality to `server.c`.
194+
3. Add caching functionality to `server.c`.
221195

222196
When a file is requested, first check to see if the path to the file is in
223-
the cache. (Use the file path as the key.)
197+
the cache (use the file path as the key).
224198

225199
If it's there, serve it back.
226200

@@ -230,8 +204,24 @@ The hashtable code is already written and can be found in `hashtable.c`.
230204
* Store it in the cache
231205
* Serve it
232206

207+
There's a set of unit tests included to ensure that your cache implementation is functioning correctly. From the `src` directory, run `make tests` in order to run the unit tests against your implementation.
208+
233209
### Stretch Goals
234210

211+
#### Post a file:
212+
213+
1. Implement `find_start_of_body()` to locate the start of the HTTP request body
214+
(just after the header).
215+
216+
2. Implement the `post_save()` handler. Modify the main loop to pass the body
217+
into it. Have this handler write the file to disk. Hint: `open()`, `write()`,
218+
`close()`. `fopen()`, `fwrite()`, and `fclose()` variants can also be used,
219+
but the former three functions will be slightly more straightforward to use
220+
in this case.
221+
222+
The response from `post_save()` should be of type `application/json` and
223+
should be `{"status":"ok"}`.
224+
235225
#### Automatic `index.html` serving
236226

237227
We know that if the user hits `http://localhost:3490/index.html` it should
@@ -261,25 +251,9 @@ It doesn't make sense to cache things forever--what if the file changes on disk?
261251

262252
Add a `created_at` timestamp to cache entries.
263253

264-
If an item is found in the cache, check to see if it is more than 1 minute old.
265-
If it is, delete it from the cache, then load the new one from disk as if it
266-
weren't found.
267-
268-
You'll have to add `cache_delete` functionality to your cache code.
269-
270-
#### Post a file:
271-
272-
1. Implement `find_start_of_body()` to locate the start of the HTTP request body
273-
(just after the header).
254+
If an item is found in the cache, check to see if it is more than 1 minute old. If it is, delete it from the cache, then load the new one from disk as if it weren't found.
274255

275-
2. Implement the `post_save()` handler. Modify the main loop to pass the body
276-
into it. Have this handler write the file to disk. Hint: `open()`, `write()`,
277-
`close()`. `fopen()`, `fwrite()`, and `fclose()` variants can also be used,
278-
but the former three functions will be slightly more straightforward to use
279-
in this case.
280-
281-
The response from `post_save()` should be of type `application/json` and
282-
should be `{"status":"ok"}`.
256+
You'll have to add a `cache_delete` function to your cache code that does the work of actually removing entries that are too old from the cache.
283257

284258
#### Concurrency
285259

@@ -289,8 +263,7 @@ Research the pthreads library.
289263

290264
When a new connection comes in, launch a thread to handle it.
291265

292-
Be sure to lock the cache when a thread accesses it so the threads don't step on
293-
each other's toes and corrupt the cache.
266+
Be sure to lock the cache when a thread accesses it so the threads don't step on each other's toes and corrupt the cache.
294267

295268
Also have thread cleanup handlers to handle threads that have died.
296269

0 commit comments

Comments
 (0)