diff --git a/hashtable.c b/hashtable.c
index a02d701a184cc1ad77aca95678480583a7b5b54a..c85a4c03f1c7b5a9de74e74d112b7701ddfedc45 100644
--- a/hashtable.c
+++ b/hashtable.c
@@ -54,6 +54,8 @@ Bucket *add_to_bucket(Bucket *bucket, char *key, char *value) {
//adds new key and avlue to end of bucket
bucket->values[bucket->n_elems-1] = value;
bucket->keys[bucket->n_elems-1] = key;
+ // printf("key is %s\n\n", bucket->keys[bucket->n_elems-1]);
+ // printf("value is %s\n\n", bucket->values[bucket->n_elems-1]);
return bucket;
}
/************************************************************************/
@@ -108,17 +110,17 @@ void hash_table_put(HashTable *table, char *key, char *value) {
int hash_value = xor_hash(key, table->size);
// look for existing key
Bucket *bucket = &table->buckets[hash_value];
+ printf("the number of elements in bucket is %d\n", bucket->n_elems);
for (int i=0; i < bucket->n_elems; i++){
if (equal(bucket->keys[i], key)){
bucket->values[i] = value;
- move_to_front(bucket, i);
return;
}
}
// adds key and value as not in hash table
bucket = add_to_bucket(bucket, key, value);
table->buckets[hash_value] = *bucket;
- move_to_front(bucket, bucket->n_elems - 1);
+ printf("the number of elements in bucket is %d\n", bucket->n_elems);
}
/************************************************************************/
void move_to_front(Bucket *bucket, int index){
@@ -176,7 +178,7 @@ bool hash_table_has(HashTable *table, char *key) {
return false;
}
char* print_hash_map(HashTable *table){
- char* headers = calloc(100,sizeof(char));
+ char* headers = calloc(800,sizeof(char));
assert(headers);
for (int i = 0; i < table->size; i++) {
if (table->buckets[i].n_elems > 0){
@@ -204,4 +206,15 @@ void free_cookie(HashTable *headers) {
free(bucket->values[i]);
}
}
-}
\ No newline at end of file
+}
+
+void free_hash_map(HashTable *table){
+ for (int i = 0; i < table->size; i++) {
+ if (table->buckets[i].n_elems > 0){
+ for (int j=0; j< table->buckets[i].n_elems; j++){
+ free(table->buckets[i].keys[j]);
+ free(table->buckets[i].values[j]);
+ }
+ }
+ }
+}
diff --git a/hashtable.h b/hashtable.h
index 4f503861db0dfb7cb9a084f685148586a1352ab5..0a266fdf7d2e6f37cb38f82f4106e4c9728b12ed 100644
--- a/hashtable.h
+++ b/hashtable.h
@@ -25,4 +25,6 @@ bool hash_table_has(HashTable *table, char *key);
char* print_hash_map(HashTable *table);
-void free_cookie(HashTable *headers);
\ No newline at end of file
+void free_cookie(HashTable *headers);
+
+void free_hash_map(HashTable *table);
\ No newline at end of file
diff --git a/http-parser.c b/http-parser.c
index a5a5a27e83f58a38fe73c91a9e568c9d37fb8416..9d2f9d2aea973005f55ca68ab06d6a1a7a4898cc 100644
--- a/http-parser.c
+++ b/http-parser.c
@@ -9,20 +9,20 @@
#include <string.h>
#include <assert.h>
#include "http-parser.h"
+#include "hashtable.h"
// user-determined constants for requests
#define MAX_URL_SIZE 60
-#define MAX_HEADER_SIZE 600
+#define MAX_HEADER_SIZE 200
#define MAX_VERSION_SIZE 10
-#define MAX_HEADERS 10
+#define MAX_HEADERS 20
Request* parse_request(char* request_message){
/**
* Reads a requests and creates a request object containing the parsed information
* */
- Request *req = calloc(1, sizeof(Request));
+ Request *req = calloc(1, sizeof *req);
assert(req);
- memset(req, 0, sizeof(Request));
// parses the method of the request
if (strncmp(request_message, "GET ", 4) == 0){
@@ -47,20 +47,24 @@ Request* parse_request(char* request_message){
//parses the headers
req->header = new_hash_table(MAX_HEADERS);
- char header_field_name[MAX_HEADER_SIZE];
- char header_value[MAX_HEADER_SIZE];
+ // char *header_field_name = calloc(MAX_HEADER_SIZE, sizeof(char));
+ // char *header_value = calloc(MAX_HEADER_SIZE, sizeof(char));
while(*request_message != '\r' && *request_message != '\n'){
+ request_message = insert_headers(request_message, req);
// printf("req message first char %d\n", *request_message);
- strcpy(header_field_name,strtok(request_message, " "));
- // printf("header field name: %s\n", header_field_name);
- request_message += strcspn(request_message, " ")+1;
- strcpy(header_value,strtok(request_message, "\r\n"));
- // printf("header value: %s\n", header_value);
- request_message += strcspn(request_message, "\r\n")+2;
- hash_table_put(req->header, header_field_name, header_value);
+ // memset(header_field_name,0,strlen(header_field_name));
+ // memset(header_value,0,strlen(header_value));
+ // size_t field_len = strcspn(request_message, " ");
+ // memcpy(header_field_name, request_message,field_len);
+ // request_message += field_len+1;
+ // size_t value_len = strcspn(request_message, "\r\n");
+ // memcpy(header_value,request_message, value_len);
+ // printf("header key: %s\n", header_field_name);
+ // request_message += value_len+2;
+ // hash_table_put(req->header, header_field_name, header_value);
}
request_message += strcspn(request_message, "\r\n")+2;
-
+ printf("request header %s\n", print_hash_map(req->header));
// parses the body
if(*request_message != '\r'||*request_message != '\n'){
req->body = request_message;
@@ -71,10 +75,27 @@ Request* parse_request(char* request_message){
return req;
}
+char* insert_headers(char* request_message, Request * req){
+ char *header_field_name = calloc(MAX_HEADER_SIZE, sizeof(char));
+ char *header_value = calloc(MAX_HEADER_SIZE, sizeof(char));
+ memset(header_field_name,0,strlen(header_field_name));
+ memset(header_value,0,strlen(header_value));
+ size_t field_len = strcspn(request_message, " ");
+ memcpy(header_field_name, request_message,field_len);
+ request_message += field_len+1;
+ size_t value_len = strcspn(request_message, "\r\n");
+ memcpy(header_value,request_message, value_len);
+ printf("header key: %s\n", header_field_name);
+ request_message += value_len+2;
+ hash_table_put(req->header, header_field_name, header_value);
+ return request_message;
+}
+
void free_request(Request* req){
/**
* Deallocates memory
* */
+ free_hash_map(req->header);
free_hash_table(req->header);
- free(req);
+ // free(req);
}
diff --git a/http-parser.h b/http-parser.h
index 203079e02a40928617fcebe05b6c2d1f8dbfadfd..03433854d3b4f6e63972565c8201da129f92b148 100644
--- a/http-parser.h
+++ b/http-parser.h
@@ -27,4 +27,6 @@ typedef struct Request {
Request* parse_request(char* request_message);
// Deallocates memory
-void free_request(Request* req);
\ No newline at end of file
+void free_request(Request* req);
+
+char* insert_headers(char* request_message, Request * req);
\ No newline at end of file
diff --git a/http-response.c b/http-response.c
index 626b5d95ee0c02f51e5055ec4daacbd8937f5868..66efeb7ae8bdf3db240c0195c4b4cc07c0598cc2 100644
--- a/http-response.c
+++ b/http-response.c
@@ -16,7 +16,7 @@
#define MAX_URL_SIZE 60
#define MAX_HEADER_SIZE 300
#define MAX_VERSION_SIZE 10
-#define MAX_N_HEADERS 2
+#define MAX_N_HEADERS 4
char* cookie_generator(){
/**
@@ -24,7 +24,7 @@ char* cookie_generator(){
* */
char* cookie_value;
cookie_value = (char*) malloc(sizeof(char)*60);
- snprintf(cookie_value, 60, "sessionToken=%d; Expires=Wed, 01 Apr 2019 10:10:10 GMT", rand());
+ snprintf(cookie_value, 60, "id=%d", rand() % (111-0+1));
return cookie_value;
}
@@ -44,7 +44,9 @@ Response* initialise_session(Request* request){
// sets the cookies
char *cookie = cookie_generator();
+ hash_table_put(resp->header, "Content-length: ", "%ld");
hash_table_put(resp->header, "Set-cookie: ", cookie);
+ hash_table_put(resp->header, "Content-type: ", "text/html");
// sends empty body
resp->body="";
@@ -69,8 +71,14 @@ char* parse_response(Response* response){
strncat(response_string, headers, strlen(headers));
strcat(response_string, "\r\n");
strcat(response_string, response->body);
- // free(headers);
- return response_string;
+ strcat(response_string, "\r\n");
+ char * new_response_string = calloc(100,sizeof(char));
+ assert(new_response_string);
+ strncpy(new_response_string, response_string, strlen(response_string));
+ free(headers);
+ free(response_string);
+ return new_response_string;
+ // return response_string;
}
diff --git a/http-server.c b/http-server.c
index 8aba4032cfae966afecc0daee55b6f166316e22e..36212c2bf8d71a9882d5c80a025164d3b593ad9e 100644
--- a/http-server.c
+++ b/http-server.c
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <unistd.h>
#include "response-formatter.h"
+#include "hashtable.h"
#include "http-parser.h"
#include "http-response.h"
#include "hashtable.h"
@@ -40,6 +41,8 @@ static int const HTTP_400_LENGTH = 47;
static char const * const HTTP_404 = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
static int const HTTP_404_LENGTH = 45;
+static Request* req;
+static User_list* user_list;
int keep_alive = 1;
@@ -49,28 +52,32 @@ bool player_session(char* buff, int sockfd, char* file_name, char* response){
* */
struct stat st;
stat(file_name, &st);
+ // printf("pre add %s\n", buff);
int n = sprintf(buff, response, st.st_size);
+ printf("post add %s\n", buff);
// send the header first
if (write(sockfd, buff, n) < 0)
{
perror("write");
return false;
}
- // send the file
+ // read the content of the HTML file
int filefd = open(file_name, O_RDONLY);
- do
- {
- n = sendfile(sockfd, filefd, NULL, 2048);
- }
- while (n > 0);
+ n = read(filefd, buff, st.st_size);
+ clean_trailing_buffer(buff);
if (n < 0)
{
- perror("sendfile");
+ perror("read");
close(filefd);
return false;
}
close(filefd);
- return true;
+ if (write(sockfd, buff, st.st_size) < 0)
+ {
+ perror("write");
+ return false;
+ }
+ return true;
}
bool text_render_response(char *buff, int sockfd, char* file_name, char* text){
/**
@@ -117,7 +124,9 @@ bool response(char *buff, int sockfd, char* file_name){
* */
struct stat st;
stat(file_name, &st);
+ printf("pre add %s\n", buff);
int n = sprintf(buff, HTTP_200_FORMAT, st.st_size);
+ printf("post add %s\n", buff);
// send the header first
if (write(sockfd, buff, n) < 0)
{
@@ -220,7 +229,7 @@ bool text_render_game_play(char *buff, int sockfd, char* file_name, char* text,
return true;
}
-static bool handle_http_request(int sockfd, User_list *users){
+static bool handle_http_request(int sockfd, User_list *user_list){
/**
* Parses the http request and sends the approapriate response
* */
@@ -241,14 +250,12 @@ static bool handle_http_request(int sockfd, User_list *users){
char * curr = buff;
// parse the method
- Request* req = parse_request(curr);
- User* user = get_current_user(users, sockfd);
- // printf("REQUEST BODY IS \n\n%s\n", req->url);
+ // printf("REQUEST IS \n\n%s\n", buff);
+ req = parse_request(curr);
// user should quit game
if(strncmp(req->body, "quit=Quit", 9) == 0){
- printf("run\n\n\n\n\\n");
- change_player_status(sockfd,users, QUIT);
+ change_player_status(sockfd,user_list, QUIT);
response(buff,sockfd, "7_gameover.html");
// free_request(req);
// return false;
@@ -256,56 +263,60 @@ static bool handle_http_request(int sockfd, User_list *users){
// user starting game
else if (strncmp(req->url, "/?start=Start", 24) == 0){
-
+ // printf("THE COOKIE IS %s\n", hash_table_get(req->header, "Cookie: "));
+ int id = atoi(hash_table_get(req->header, "Cookie:")+3);
+ User* user = get_current_user(user_list, id);
// user on first turn
- if (req->method == GET){
- change_player_status(sockfd, users, READY);
- int round = change_player_round(sockfd, users);
- game_change(buff,sockfd, "3_first_turn.html", round);
- }
- if (req->method == POST){
- if(strncmp(req->body, "keyword=", 8) == 0){
-
- // checks if other player has quit
- if(should_player_quit(users)){
- printf("is quit");
- change_player_status(sockfd,users, QUIT);
- response(buff,sockfd, "7_gameover.html");
- // free_request(req);
- // keep_alive = 0;
- // return false;
- }
-
- // checks if other player has not completed previous round
- else if (different_round_discard(sockfd,users)){
- game_change(buff,sockfd, "5_discarded.html", user->round);
- }
-
- // checks if game won
- else if(player_won(users)){
- response(buff,sockfd, "6_endgame.html");
- change_player_status(sockfd, users, WAIT);
- }
+ if (user != NULL){
+ printf("user aint null");
+ if (req->method == GET){
+ change_player_status(id, user_list, READY);
+ int round = change_player_round(id, user_list);
+ game_change(buff,sockfd, "3_first_turn.html", round);
+ }
+ if (req->method == POST){
+ if(strncmp(req->body, "keyword=", 8) == 0){
+
+ // checks if other player has quit
+ if(should_player_quit(user_list)){
+ change_player_status(id,user_list, QUIT);
+ response(buff,sockfd, "7_gameover.html");
+ // free_request(req);
+ // keep_alive = 0;
+ // return false;
+ }
- //checks if the other player is not ready and discards keyword
- else if(!players_ready(users) && user!= NULL){
- game_change(buff,sockfd, "5_discarded.html", user->round);
- //request(buff,sockfd, "5_discarded.html");
- }
- else{
- char* keyword = add_keyword(sockfd, users, req->body);
+ // checks if other player has not completed previous round
+ else if (different_round_discard(id,user_list)){
+ game_change(buff,sockfd, "5_discarded.html", user->round);
+ }
- // game ends as submitted keyword has been submitted by other player
- if(has_match_ended(users, keyword, sockfd)){
+ // checks if game won
+ else if(player_won(user_list)){
response(buff,sockfd, "6_endgame.html");
- change_all_status(users, COMPLETE);
+ change_player_status(id, user_list, WAIT);
+ }
+
+ //checks if the other player is not ready and discards keyword
+ else if(!players_ready(user_list) && user!= NULL){
+ game_change(buff,sockfd, "5_discarded.html", user->round);
+ //request(buff,sockfd, "5_discarded.html");
}
else{
- // keyword hasn't been submitted yet so is accepted and rendered on screen
- if(user!= NULL){
- char* keywords = return_all_keywords(user);
- text_render_game_play(buff,sockfd, "4_accepted.html", keywords, user->round);
- free(keywords);
+ char* keyword = add_keyword(sockfd, user_list, req->body);
+
+ // game ends as submitted keyword has been submitted by other player
+ if(has_match_ended(user_list, keyword, id)){
+ response(buff,sockfd, "6_endgame.html");
+ change_all_status(user_list, COMPLETE);
+ }
+ else{
+ // keyword hasn't been submitted yet so is accepted and rendered on screen
+ if(user!= NULL){
+ char* keywords = return_all_keywords(user);
+ text_render_game_play(buff,sockfd, "4_accepted.html", keywords, user->round);
+ free(keywords);
+ }
}
}
}
@@ -322,9 +333,9 @@ static bool handle_http_request(int sockfd, User_list *users){
char *name = strchr(req->body, '=')+1;
// printf("**%s**\n", name);
if (name != NULL){
- for (int i=0; i < users->n_users; i++){
- if(users->users[i]->id == sockfd){
- users->users[i]->name = name;
+ for (int i=0; i < user_list->n_users; i++){
+ if(user_list->users[i]->id == sockfd){
+ user_list->users[i]->name = name;
}
}
// get_request(buff,sockfd, "2_start.html");
@@ -333,30 +344,38 @@ static bool handle_http_request(int sockfd, User_list *users){
}
// user is created
- else if (req->method == GET)
+ else if (req->method == GET && !hash_table_has(req->header, "Cookie:"))
{
// printf("matches a / url but url isize is %zu\n\n", strlen(req->url));
- // Response* resp = initialise_session(req);
- // char* resp_string = parse_response(resp);
+ Response* resp = initialise_session(req);
+ char* resp_string = parse_response(resp);
// printf("COOKIE CREATING RESP %s\n", resp_string);
- // player_session(buff, sockfd, "1_welcome.html", resp_string);
- // User* new_player = new_user(sockfd);
- // add_user(new_player, users);
- // char* cookie = hash_table_get(resp->header, "Set-cookie: ")+13;
- // cookie = strtok(cookie, ";");
+ char* cookie = hash_table_get(resp->header, "Set-cookie: ")+3;
// printf("the cookie token is %s*****\n", cookie);
- // free(resp_string);
- // free_response(resp);
+ User* new_player = new_user(atoi(cookie));
+ add_user(new_player, user_list);
+ // printf("before player sesh");
+ player_session(buff, sockfd, "1_welcome.html", resp_string);
+ // free(cookie);
+ free(resp_string);
+ free_response(resp);
// ensures user is not already playing/in system
- for(int i =0; i< users->n_users; i++){
- if(sockfd == users->users[i]->id){
+ for(int i =0; i< user_list->n_users; i++){
+ if(sockfd == user_list->users[i]->id){
return false;
}
}
- User* new_player = new_user(sockfd);
- add_user(new_player, users);
- response(buff,sockfd, "1_welcome.html");
+ // User* new_player = new_user(sockfd);
+ // add_user(new_player, users);
+ // response(buff,sockfd, "1_welcome.html");
+ }
+ else if (req->method == GET){
+ int id = atoi(hash_table_get(req->header, "Cookie:")+3);
+ User* user = get_current_user(user_list, id);
+ if (user != NULL){
+ text_render_response(buff,sockfd, "2_start.html", user->name);
+ }
}
else
// unrecognised methods
@@ -369,22 +388,22 @@ static bool handle_http_request(int sockfd, User_list *users){
perror("write");
return false;
}
- printf("the numer of users is %d\n", users->n_users);
- for(int i=0; i < users->n_users; i++){
- printf("USER ID %d", users->users[i]->id);
- if(users->users[i]->status == READY){
+ printf("the numer of users is %d\n", user_list->n_users);
+ for(int i=0; i < user_list->n_users; i++){
+ printf("USER ID %d", user_list->users[i]->id);
+ if(user_list->users[i]->status == READY){
printf("is ready\n");
}
- if(users->users[i]->status == WAIT){
+ if(user_list->users[i]->status == WAIT){
printf("is wait\n");
}
- if(users->users[i]->status == QUIT){
+ if(user_list->users[i]->status == QUIT){
printf("is quit\n");
}
- if(users->users[i]->status == COMPLETE){
+ if(user_list->users[i]->status == COMPLETE){
printf("is complete\n");
}
- if(users->users[i]->status == RESTART){
+ if(user_list->users[i]->status == RESTART){
printf("is restart\n");
}
}
@@ -397,6 +416,12 @@ static void exit_handler(int sig){
* Closes TCP Connection
*/
keep_alive = 0;
+ if (req){
+ free_request(req);
+ }
+ if (user_list){
+ free_users(user_list);
+ }
printf("keep alive changed");
}
@@ -451,7 +476,7 @@ int main(int argc, char * argv[])
int maxfd = sockfd;
// game players
- User_list* users = initialise_player_list();
+ user_list = initialise_player_list();
signal(SIGINT, exit_handler);
while (keep_alive)
{
@@ -494,7 +519,7 @@ int main(int argc, char * argv[])
}
}
// a request is sent from the client
- else if (!handle_http_request(i,users))
+ else if (!handle_http_request(i,user_list))
{
close(i);
FD_CLR(i, &masterfds);
@@ -503,6 +528,6 @@ int main(int argc, char * argv[])
}
}
printf("break loop");
- free_users(users);
+ free_users(user_list);
return 0;
}
diff --git a/user.c b/user.c
index 1bf913a767920d33a34e19ba387133921d30dd2e..bc884a3c7483c4985b1e27cc9a835643bcb35178 100644
--- a/user.c
+++ b/user.c
@@ -130,9 +130,14 @@ bool players_ready(User_list* user_list){
* checks if all players are ready
* */
for(int i=0; i < user_list->n_users; i++){
+ // other player is not ready
if (user_list->users[i]->status != READY){
return false;
}
+ // only one player, need to wait
+ else if (user_list->n_users == 1){
+ return false;
+ }
}
return true;
}
@@ -265,7 +270,7 @@ char* return_all_keywords(User* user){
* */
printf("%d\n\n\n", user->n_keywords);
- int length = (user->n_keywords)*(INITIAL_KEYWORD_LENGTH+1);
+ int length = (user->n_keywords)*(INITIAL_KEYWORD_LENGTH+3);
char *keywords = calloc(length, user->n_keywords);
assert(keywords);