Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sean Flannigan - C-Web-Server #301

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- https://github.com/LambdaSchool/C-Web-Server/pull/301 -->
# A Simple Web Server in C

In this project, we'll finish the implementation of a web server in C.
Expand Down
52 changes: 48 additions & 4 deletions src/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,24 @@
struct cache_entry *alloc_entry(char *path, char *content_type, void *content, int content_length)
{
///////////////////
// IMPLEMENT ME! //
struct cache_entry *ce = malloc(sizeof(struct cache_entry));

ce->path = malloc(strlen(path) + 1);
strcpy(ce->path, path);

ce->content_type = (strlen(content_type) + 1);
strcpy(ce->content_type, content_type);

ce->content_length = content_length;

ce->content = malloc(content_length);
memcpy(ce->content, content, content_length);


ce->prev = NULL;
ce->next = NULL;

return ce;
///////////////////
}

Expand All @@ -20,7 +37,10 @@ struct cache_entry *alloc_entry(char *path, char *content_type, void *content, i
void free_entry(struct cache_entry *entry)
{
///////////////////
// IMPLEMENT ME! //
free(entry->path);
free(entry->content_type);
free(entry->content);
free(entry);
///////////////////
}

Expand Down Expand Up @@ -92,7 +112,16 @@ struct cache_entry *dllist_remove_tail(struct cache *cache)
struct cache *cache_create(int max_size, int hashsize)
{
///////////////////
// IMPLEMENT ME! //
struct cache *cache = malloc(sizeof(struct cache));

cache->index = hashtable_create(hashsize, NULL);
cache->max_size = max_size;
cache->cur_size = 0;

cache->head = NULL;
cache->tail = NULL;

return cache;
///////////////////
}

Expand Down Expand Up @@ -123,7 +152,22 @@ void cache_free(struct cache *cache)
void cache_put(struct cache *cache, char *path, char *content_type, void *content, int content_length)
{
///////////////////
// IMPLEMENT ME! //
// Allocate a new cache entry with the passed parameters.
struct cache_entry *new_ce = alloc_entry(path, content_type, content, content_length);
// Insert the entry at the head of the doubly-linked list.
dllist_insert_head(cache, new_ce);
// Store the entry in the hashtable as well, indexed by the entry's `path`.

// Increment the current size of the cache.
cache->cur_size += 1;
// If the cache size is greater than the max size:
if (cache->cur_size > cache->max_size) {
// Remove the cache entry at the tail of the linked list.
// Remove that same entry from the hashtable, using the entry's `path` and the `hashtable_delete` function.
// Free the cache entry.
// Ensure the size counter for the number of entries in the cache is correct.

}
///////////////////
}

Expand Down
73 changes: 67 additions & 6 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,19 @@ int send_response(int fd, char *header, char *content_type, void *body, int cont
char response[max_response_size];

// Build HTTP response and store it in response

// change this to be the content length from return value
int response_length = snprintf(response, max_response_size, "%s\n"
"Content-Type: %s\n"
// need to add DATE to response
"Content-Length: %d\n"
"Connection: close\n"
"\n", header, content_type, content_length
);
///////////////////
// IMPLEMENT ME! //
///////////////////

memcpy(response + response_length, body, content_length);
response_length += content_length;
// Send it all!
int rv = send(fd, response, response_length, 0);

Expand All @@ -76,12 +84,26 @@ int send_response(int fd, char *header, char *content_type, void *body, int cont
void get_d20(int fd)
{
// Generate a random number between 1 and 20 inclusive
int random_value;
char body[500000];

srand(time(0));
int get_random() {
int num = (rand() % (20 - 1 + 1)) + 1;
return num;
}

random_value = get_random();

sprintf(body, "%d\n", random_value);

int content_length = strlen(body);
///////////////////
// IMPLEMENT ME! //
///////////////////

// Use send_response() to send it back as text/plain data
send_response(fd, "HTTP/1.1 200 OK", "text/plain", body, content_length);

///////////////////
// IMPLEMENT ME! //
Expand All @@ -104,7 +126,7 @@ void resp_404(int fd)
if (filedata == NULL) {
// TODO: make this non-fatal
fprintf(stderr, "cannot find system 404 file\n");
exit(3);
resp_404(fd);
}

mime_type = mime_type_get(filepath);
Expand All @@ -120,7 +142,25 @@ void resp_404(int fd)
void get_file(int fd, struct cache *cache, char *request_path)
{
///////////////////
// IMPLEMENT ME! //
char filepath[4096];
struct file_data *filedata;
char *mime_type;

// Fetch the requested file
snprintf(filepath, sizeof filepath, "%s%s", SERVER_ROOT, request_path);
filedata = file_load(filepath);

if (filedata == NULL) {
resp_404(fd);
}

mime_type = mime_type_get(filepath);

send_response(fd, "HTTP/1.1 200 OK", mime_type, filedata->data, filedata->size);

file_free(filedata);

(void) cache;
///////////////////
}

Expand All @@ -134,6 +174,8 @@ char *find_start_of_body(char *header)
{
///////////////////
// IMPLEMENT ME! // (Stretch)
(void) header;
return NULL;
///////////////////
}

Expand All @@ -144,6 +186,8 @@ void handle_http_request(int fd, struct cache *cache)
{
const int request_buffer_size = 65536; // 64K
char request[request_buffer_size];
char method[200];
char path[8192];

// Read request
int bytes_recvd = recv(fd, request, request_buffer_size - 1, 0);
Expand All @@ -159,9 +203,26 @@ void handle_http_request(int fd, struct cache *cache)
///////////////////

// Read the three components of the first request line

sscanf(request, "%s %s", method, path);
// printf("method: \"%s\"\n", method);
// printf("path: \"%s\"\n", path);
(void) cache;
// If GET, handle the get endpoints

if (strcmp(method, "GET") == 0) {
if (strcmp(path, "/d20") == 0) {
get_d20(fd);
} else if ((strcmp(path, "/index.html") == 0) || (strcmp(path, "/cat.png") == 0)) {
get_file(fd, cache, path);
} // else if (strcmp(path, "/") == 0) {
// char *home;
// home = "index.html";
// strcat(path, home);
// get_file(fd, cache, path);
//}
else {
resp_404(fd);
}
}
// Check if it's /d20 and handle that special case
// Otherwise serve the requested file by calling get_file()

Expand Down
File renamed without changes