You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+34-61
Original file line number
Diff line number
Diff line change
@@ -25,10 +25,7 @@ What's already there:
25
25
## What is a Web Server?
26
26
27
27
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).
32
29
33
30
## Reading
34
31
@@ -83,9 +80,7 @@ overall view, then come back to goal #1 and dig in._
83
80
84
81
1. Examine `handle_http_request()` in the file `server.c`.
85
82
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.
89
84
90
85
The variable `request` in `handle_http_request()` holds the entire HTTP
91
86
request once the `recv()` call returns.
@@ -100,8 +95,7 @@ overall view, then come back to goal #1 and dig in._
100
95
Hint: `strcmp()` for matching the request method and path. Another hint:
101
96
`strcmp()` returns `0` if the strings are the _same_!
102
97
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
105
99
> `if`-`else` block with `strcmp()` to get the job done.
106
100
107
101
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._
115
109
If you need a hint as to what the `send_response()` call should look like,
116
110
check out the usage of it in `resp_404()`, just above there.
117
111
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.
121
113
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
124
115
> 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.
128
117
129
118
3. Implement `send_response()`.
130
119
@@ -179,36 +168,21 @@ list](https://en.wikipedia.org/wiki/Doubly_linked_list) and a
179
168
180
169
The hashtable code is already written and can be found in `hashtable.c`.
181
170
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`.
199
172
200
173
Algorithm:
201
174
202
175
* Allocate a new cache entry with the passed parameters.
203
176
* 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.
207
181
* 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.
209
182
* Free the cache entry.
183
+
* Ensure the size counter for the number of entries in the cache is correct.
210
184
211
-
3. Implement `cache_get()` in `cache.c`.
185
+
2. Implement `cache_get()` in `cache.c`.
212
186
213
187
Algorithm:
214
188
@@ -217,10 +191,10 @@ The hashtable code is already written and can be found in `hashtable.c`.
217
191
* Move the cache entry to the head of the doubly-linked list.
218
192
* Return the cache entry pointer.
219
193
220
-
4. Add caching functionality to `server.c`.
194
+
3. Add caching functionality to `server.c`.
221
195
222
196
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).
224
198
225
199
If it's there, serve it back.
226
200
@@ -230,8 +204,24 @@ The hashtable code is already written and can be found in `hashtable.c`.
230
204
* Store it in the cache
231
205
* Serve it
232
206
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
+
233
209
### Stretch Goals
234
210
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
+
235
225
#### Automatic `index.html` serving
236
226
237
227
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?
261
251
262
252
Add a `created_at` timestamp to cache entries.
263
253
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.
274
255
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.
283
257
284
258
#### Concurrency
285
259
@@ -289,8 +263,7 @@ Research the pthreads library.
289
263
290
264
When a new connection comes in, launch a thread to handle it.
291
265
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.
294
267
295
268
Also have thread cleanup handlers to handle threads that have died.
0 commit comments