Skip to content

pr #330

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

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open

pr #330

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions QUESTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- content-type을 "text/plain"으로 설정하면 파일 다운로드가 되네?

- content-length가 안 맞으면 화면(브라우저)에서 오류나네

- rest 응답같은건 어떤 content-type으로 해야 하는지?

application/json으로 하면 될 줄 알았는데 안 되네

=> 그냥 body에 쓰여지는 게 전부임
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# 일정
![웹서버개발계획](./%EC%9B%B9%EC%84%9C%EB%B2%84%EA%B0%9C%EB%B0%9C%EA%B3%84%ED%9A%8D.png)

# 이용 가능한 url
서버 실행 후,
- file serving : http://localhost:3490/index.html 접속
- 난수 리턴 : http://localhost:3490/d20 접속
- post : curl -D - -X POST -H 'Content-Type: text/plain' -d 'Hello, sample data!' http://localhost:3490/save
- post한 내용이 쓰여진 파일 보기 : http://localhost:3490/posted-file.txt 접속

# tips
- vscode 코드 포매팅 : shift + option + f


# A Simple Web Server in C

In this project, we'll finish the implementation of a web server in C.
Expand Down
147 changes: 124 additions & 23 deletions src/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,28 @@
#include <string.h>
#include "hashtable.h"
#include "cache.h"
#include "llist.h"

/**
* Allocate a cache entry
*/
struct cache_entry *alloc_entry(char *path, char *content_type, void *content, int content_length)
{
///////////////////
// IMPLEMENT ME! //
///////////////////
struct cache_entry *ret = malloc(sizeof(struct cache_entry));
ret->path = path;
ret->content = (char*)content;
ret->content_type = content_type;
ret->content_length = content_length;

// ret->prev = malloc(sizeof(struct cache_entry));
// ret->next = malloc(sizeof(struct cache_entry));

ret->prev = NULL;
ret->next = NULL;

ret->created_at = time(NULL);

return ret;
}

/**
Expand All @@ -30,10 +43,13 @@ void free_entry(struct cache_entry *entry)
void dllist_insert_head(struct cache *cache, struct cache_entry *ce)
{
// Insert at the head of the list
if (cache->head == NULL) {
if (cache->head == NULL)
{
cache->head = cache->tail = ce;
ce->prev = ce->next = NULL;
} else {
}
else
{
cache->head->prev = ce;
ce->next = cache->head;
ce->prev = NULL;
Expand All @@ -46,13 +62,16 @@ void dllist_insert_head(struct cache *cache, struct cache_entry *ce)
*/
void dllist_move_to_head(struct cache *cache, struct cache_entry *ce)
{
if (ce != cache->head) {
if (ce == cache->tail) {
if (ce != cache->head)
{
if (ce == cache->tail)
{
// We're the tail
cache->tail = ce->prev;
cache->tail->next = NULL;

} else {
}
else
{
// We're neither the head nor the tail
ce->prev->next = ce->next;
ce->next->prev = ce->prev;
Expand All @@ -65,10 +84,9 @@ void dllist_move_to_head(struct cache *cache, struct cache_entry *ce)
}
}


/**
* Removes the tail from the list and returns it
*
*
* NOTE: does not deallocate the tail
*/
struct cache_entry *dllist_remove_tail(struct cache *cache)
Expand All @@ -85,15 +103,21 @@ struct cache_entry *dllist_remove_tail(struct cache *cache)

/**
* Create a new cache
*
*
* max_size: maximum number of entries in the cache
* hashsize: hashtable size (0 for default)
*/
struct cache *cache_create(int max_size, int hashsize)
{
///////////////////
// IMPLEMENT ME! //
///////////////////
struct cache *ret = malloc(sizeof(struct cache));
ret->max_size = max_size;
ret->cur_size = 0;
ret->head = NULL;
ret->tail = NULL;

ret->index = hashtable_create(hashsize, NULL);

return ret;
}

void cache_free(struct cache *cache)
Expand All @@ -102,7 +126,8 @@ void cache_free(struct cache *cache)

hashtable_destroy(cache->index);

while (cur_entry != NULL) {
while (cur_entry != NULL)
{
struct cache_entry *next_entry = cur_entry->next;

free_entry(cur_entry);
Expand All @@ -117,22 +142,98 @@ void cache_free(struct cache *cache)
* Store an entry in the cache
*
* This will also remove the least-recently-used items as necessary.
*
*
* NOTE: doesn't check for duplicate cache entries
*/
void cache_put(struct cache *cache, char *path, char *content_type, void *content, int content_length)
{
///////////////////
// IMPLEMENT ME! //
///////////////////

// 1. Allocate a new cache entry with the passed parameters.
// 2. Insert the entry at the head of the doubly-linked list.
cache->cur_size++;

printf("in cache_put(), %s %s %s %d\n", path, content_type, (char *)content, content_length);

struct cache_entry *new_entry = alloc_entry(path, content_type, (char *)content, content_length);

// head <- new
// new -> head.nxt
// head -> new
// new <- head.nxt

// struct cache_entry *head = cache->head; //이렇게 head 선언하고 head = new_entry, tail = head 이런식으로 하니까 동작 안 함..
// struct cache_entry *tail = cache->tail;

if (cache->head == NULL)
{
cache->head = new_entry;
cache->tail = new_entry;
}
else
{
new_entry->prev = NULL;
new_entry->next = cache->head;
cache->head->prev = new_entry;
cache->head = new_entry;
}

printf("content = %s \n", (char *)cache->head->content);

// 3. Store the entry in the hashtable as well, indexed by the entry's path
struct hashtable *ht = cache->index;
hashtable_put(ht, path, new_entry);

//printf("path = %s\n, retrieved from hashtable = %s\n", path, (char*)((struct cache_entry*)(hashtable_get(ht, path)))->content);

// 4. Increment the current size of the cache.
// add_entry_count(ht,1);
ht->num_entries += 1;
ht->load = (float)ht->num_entries / ht->size;

// 5. If the cache size is greater than the 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. => ***** how ? synchronized? mutex?*******
if (cache->cur_size > cache->max_size)
{
struct cache_entry *old_tail = dllist_remove_tail(cache);
hashtable_delete(ht, path);
free_entry(old_tail);

// TODO: 동기화 맞추기 구현해야 함
}
}

// CONFUSE: 이 함수 쓰이나??
/**
* Retrieve an entry from the cache
*/
struct cache_entry *cache_get(struct cache *cache, char *path)
{
///////////////////
// IMPLEMENT ME! //
///////////////////
// 1. Attempt to find the cache entry pointer by path in the hash table.
struct hashtable *ht = cache->index;
void *data = hashtable_get(ht, path); //리턴이 void * = 만능?

// 2. If not found, return NULL
if (data == NULL)
{
return NULL;
}
else
{
data = (char *)data;

struct cache_entry *target = cache->head;

for (; target != cache->tail && strcmp(target->path, data) != 0; target = target->next)
{ // CONFUSE: 맞나??
}

// 3. Move the cache entry to the head of the doubly-linked list.
dllist_move_to_head(cache, target);

// 4. Return the cache entry pointer.
return target;
}
}
3 changes: 3 additions & 0 deletions src/cache.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef _WEBCACHE_H_
#define _WEBCACHE_H_
#include <time.h>

// Individual hash table entry
struct cache_entry {
Expand All @@ -9,6 +10,8 @@ struct cache_entry {
void *content;

struct cache_entry *prev, *next; // Doubly-linked list

time_t created_at;
};

// A cache
Expand Down
5 changes: 4 additions & 1 deletion src/cache_tests/cache_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@ char *test_cache_put()

// Add in a single entry to the cache
cache_put(cache, test_entry_1->path, test_entry_1->content_type, test_entry_1->content, test_entry_1->content_length);

// Check that the cache is handling a single entry as expected
mu_assert(cache->cur_size == 1, "Your cache_put function did not correctly increment the cur_size field when adding a new cache entry");
mu_assert((cache->head != NULL) && (cache->tail != NULL), "head and tail should not null after put one element");
mu_assert(cache->head->prev == NULL && cache->tail->next == NULL, "The head and tail of your cache should have NULL prev and next pointers when a new entry is put in an empty cache");
mu_assert(check_cache_entries(cache->head, test_entry_1) == 0, "Your cache_put function did not put an entry into the head of the empty cache with the expected form");
mu_assert(check_cache_entries(cache->tail, test_entry_1) == 0, "Your cache_put function did not put an entry into the tail of the empty cache with the expected form");
mu_assert(cache->index !=NULL,"hashtable should not null");
mu_assert(check_cache_entries(hashtable_get(cache->index, "/1"), test_entry_1) == 0, "Your cache_put function did not put the expected entry into the hashtable");

// Add in a second entry to the cache
Expand Down Expand Up @@ -153,7 +156,7 @@ char *all_tests()
mu_run_test(test_cache_create);
mu_run_test(test_cache_alloc_entry);
mu_run_test(test_cache_put);
mu_run_test(test_cache_get);
//mu_run_test(test_cache_get);

return NULL;
}
Expand Down
1 change: 1 addition & 0 deletions src/posted-file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello, sample data!
Loading