diff --git a/http-parser.c b/http-parser.c
index b55de391f0e245cba0a23660eff0454ee58c975d..68c8931e4830956e7baa16ddf3873ffe8b0efa7e 100644
--- a/http-parser.c
+++ b/http-parser.c
@@ -11,8 +11,9 @@
 #define MAX_VERSION_SIZE 10
 
 Request* parse_request(char* request_message){
-    Request *req = malloc(sizeof *req);
+    Request *req = calloc(1, sizeof(Request));
 	assert(req);
+    memset(req, 0, sizeof(Request));
     int n_headers = 10;
     if (strncmp(request_message, "GET ", 4) == 0){
         req->method = GET;
@@ -33,12 +34,12 @@ Request* parse_request(char* request_message){
     char header_field_name[MAX_HEADER_SIZE];
     char header_value[MAX_HEADER_SIZE];
     while(*request_message != '\r' && *request_message != '\n'){
-       printf("req message first char %d\n", *request_message);
+    //    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);
+    //    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);
+    //    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);
     }
@@ -53,6 +54,6 @@ Request* parse_request(char* request_message){
 }
 
 void free_request(Request* req){
-    free_hash_table(req->header);
+   free_hash_table(req->header);
     free(req);
-}
\ No newline at end of file
+}
diff --git a/http-parser.o b/http-parser.o
index 66aae21511f7e3a278dab384323187d943ac15ab..2b8275ce460326732ac11963bb8fce87c42ee2ee 100644
Binary files a/http-parser.o and b/http-parser.o differ
diff --git a/http-server.c b/http-server.c
index 83b7af0943de34f80e804628cce1d7f79d3719c4..c5e1d8ae368349bc22e4f57df31989cacb6cf3cf 100644
--- a/http-server.c
+++ b/http-server.c
@@ -33,6 +33,37 @@ 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;
 
+char *substring(char *string, int position, int length)
+{
+   char *p;
+   int c;
+ 
+   p = malloc(length+1);
+   
+   if( p == NULL )
+       exit(EXIT_FAILURE);
+ 
+   for( c = 0 ; c < length ; c++ )
+      *(p+c) = *((string+position-1)+c);      
+       
+   *(p+c) = '\0';
+ 
+   return p;
+}
+void insert_substring(char *a, char *b, int position)
+{
+   char *start, *end;
+   int length;
+   
+   length = strlen(a);
+   
+   start = substring(a, 1, position);      
+   end = substring(a, position+1, length-position);
+   sprintf(a, "%s%s%s", start, b, end);
+   free(start);
+   free(end);
+}
+
 
 bool player_session(char* buff, int sockfd, char* file_name, char* response){
     // get the size of the file
@@ -96,11 +127,12 @@ bool get_request(char* buff, int sockfd, char* file_name){
 bool post_request(char *buff, int sockfd, char* file_name){
 	// locate the username, it is safe to do so in this sample code, but usually the result is expected to be
     // copied to another buffer using strcpy or strncpy to ensure that it will not be overwritten.
+    printf("\n\n1. the bufferis: %s\n\n", buff);
     char * username = strcpy(buff, "user=") + 5;
     int username_length = strlen(username);
     // the length needs to include the ", " before the username
     long added_length = username_length + 2;
-
+    printf("\n\n2. the bufferis: %s\n\n", buff);
     // get the size of the file
     struct stat st;
     stat(file_name, &st);
@@ -108,6 +140,7 @@ bool post_request(char *buff, int sockfd, char* file_name){
     long size = st.st_size + added_length;
     int n = sprintf(buff, HTTP_200_FORMAT, size);
     // send the header first
+    printf("\n\n3. the bufferis: %s\n\n", buff);
     if (write(sockfd, buff, n) < 0)
     {
         perror("write");
@@ -115,7 +148,10 @@ bool post_request(char *buff, int sockfd, char* file_name){
     }
     // read the content of the HTML file
     int filefd = open(file_name, O_RDONLY);
-    n = read(filefd, buff, 2048);
+    n = read(filefd, buff, size);
+    // const char needle[10] = "</html>";
+    // buff = strstr(buff, needle)+strlen(needle);
+    printf("\n\n4. the bufferis: %s\n\n", buff);
     if (n < 0)
     {
         perror("read");
@@ -128,11 +164,6 @@ bool post_request(char *buff, int sockfd, char* file_name){
     for (p1 = size - 1, p2 = p1 - added_length; p1 >= size - 25; --p1, --p2)
         buff[p1] = buff[p2];
     ++p2;
-    // put the separator
-    buff[p2++] = ',';
-    buff[p2++] = ' ';
-    // copy the username
-    strncpy(buff + p2, username, username_length);
     if (write(sockfd, buff, size) < 0)
     {
         perror("write");
@@ -141,19 +172,84 @@ bool post_request(char *buff, int sockfd, char* file_name){
 	return true;
 }
 
+bool dynamic_post_request(char *buff, int sockfd, char* file_name, User *user){
+	// locate the username, it is safe to do so in this sample code, but usually the result is expected to be
+    // copied to another buffer using strcpy or strncpy to ensure that it will not be overwritten.
+    char * username = strcpy(buff, "user=") + 5;
+    int username_length = strlen(username);
+    // the length needs to include the ", " before the username
+    long added_length = username_length + 2;
 
-static bool handle_http_request(int sockfd, User_list* users)
+    // get the size of the file
+    struct stat st;
+    stat(file_name, &st);
+    // increase file size to accommodate the username
+    long size = st.st_size + added_length;
+    int n = sprintf(buff, HTTP_200_FORMAT, size);
+    // send the header first
+    if (write(sockfd, buff, n) < 0)
+    {
+        perror("write");
+        return false;
+    }
+    // read the content of the HTML file
+    int filefd = open(file_name, O_RDONLY);
+    n = read(filefd, buff, 2048);
+   // printf("%s\n", buff);
+    char insert[60];
+    strcpy(insert, "");
+    for(int i=0; i< user->n_keywords; i++){
+        strcat(insert, user->keywords[i]);
+        strcat(insert,",");
+    }
+    insert[strlen(insert)-1] = '\0';
+    // printf("the html to be inserted is %s\n", insert);
+    const char needle[10] = "</form>";
+    char *ret;
+
+    ret = strstr(buff, needle)+strlen(needle);
+    int position = ret - buff;
+    // printf("The substring is: %s\n", ret);
+    insert_substring(buff, insert, position);
+    if (n < 0)
+    {
+        perror("read");
+        close(filefd);
+        return false;
+    }
+    printf("dynamic %s\n", buff);
+    close(filefd);
+    // move the trailing part backward
+    // int p1, p2;
+    // for (p1 = size - 1, p2 = p1 - added_length; p1 >= size - 25; --p1, --p2)
+    //     buff[p1] = buff[p2];
+    // ++p2;
+    // // put the separator
+    // buff[p2++] = ',';
+    // buff[p2++] = ' ';
+    // // copy the username
+    strncpy(buff, username, username_length);
+    if (write(sockfd, buff, size) < 0)
+    {
+        perror("write");
+        return false;
+    }
+	return true;
+}
+
+static bool handle_http_request(int sockfd, User_list *users)
 {
     // try to read the request
-    printf("THE NUMBER OF USERS IS (in http req) %d\n", users->n_users);
+    // printf("THE NUMBER OF USERS IS (in http req) %d\n", users->n_users);
     char buff[2049];
+    memset(buff, '\0', 2049);
     int n = read(sockfd, buff, 2049);
     if (n <= 0)
     {
         if (n < 0)
             perror("read");
         else
-            printf("socket %d close the connection\n", sockfd);
+            // printf("socket %d close the connection\n", sockfd);
         return false;
     }
 
@@ -161,37 +257,36 @@ static bool handle_http_request(int sockfd, User_list* users)
     buff[n] = 0;
 
     char * curr = buff;
-
     // parse the method
     Request* req = parse_request(curr);
-    printf("REQUEST BODY IS \n\n%s\n", req->body);
+    // printf("REQUEST BODY IS \n\n%s\n", req->body);
     if(strncmp(req->body, "quit=Quit", 9)  == 0){
         change_player_status(sockfd,users, QUIT);
         post_request(buff,sockfd, "7_gameover.html");
     }
-    if (strncmp(req->url, "/?start=Start", 24)  == 0){
-        printf("matches start");
+    else if (strncmp(req->url, "/?start=Start", 24)  == 0){
+        // printf("matches start");
         if (req->method == GET){
             change_player_status(sockfd, users, READY);
             get_request(buff,sockfd, "3_first_turn.html");
         }
         if (req->method == POST){
             if(strncmp(req->body, "keyword=", 8)  == 0){
-                printf("strncmp with keywoprds is successful");
-                printf("the numer of users is %d\n", users->n_users);
+                // printf("strncmp with keywoprds is successful");
+                // 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);
+                    // printf("USER ID %d", users->users[i]->id);
                     if(users->users[i]->status == READY){
-                        printf("is ready\n");
+                        // printf("is ready\n");
                     }
                     if(users->users[i]->status == WAIT){
-                        printf("is wait\n");
+                        // printf("is wait\n");
                     }
                     if(users->users[i]->status == QUIT){
-                        printf("is quit\n");
+                        // printf("is quit\n");
                     }
                     if(users->users[i]->status == COMPLETE){
-                        printf("is complete\n");
+                        // printf("is complete\n");
                     }
                 }
                 if(player_won(users)){
@@ -211,21 +306,18 @@ static bool handle_http_request(int sockfd, User_list* users)
                         change_player_status(sockfd, users, COMPLETE);
                     }
                     else{
-                        post_request(buff,sockfd, "4_accepted.html");
+                        User* user = get_current_user(users, keyword, sockfd);
+                        post_request(buff, sockfd, "4_accepted.html");
+                       // dynamic_post_request(buff,sockfd, "4_accepted.html", user);
                     }
                 }
             }
         }
     }
-    else if (strncmp(req->url, "/welcome_page", 13) == 0){
-        if(req->method == GET){
-            get_request(buff,sockfd, "2_start.html");
-        }
-    }
     else if (*req->url == '/' && (strlen(req->url) == 1)){
         if (req->method == POST)
         {
-            char *name = strchr(req->body, '=')+1;
+           char *name = strchr(req->body, '=')+1;
             printf("**%s**\n", name);
             if (name != NULL){
                  for (int i=0; i < users->n_users; i++){
@@ -344,10 +436,6 @@ int main(int argc, char * argv[])
                         
                         // print out the IP and the socket number
                         char ip[INET_ADDRSTRLEN];
-                        // User* new_player = new_user(sockfd);
-                        // add_user(new_player, users);
-                        //printf(" %d \n", users->n_users);
-                        // printf("THE NUMBER OF USERS IS %d\n", users->n_users);
                         printf(
                             "new connection from %s on socket %d\n",
                             // convert to human readable string
@@ -357,7 +445,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,users))
                 {
                     close(i);
                     FD_CLR(i, &masterfds);
@@ -365,6 +453,6 @@ int main(int argc, char * argv[])
             }
         }
     }
-    free(users);
+   free(users);
     return 0;
 }
diff --git a/http-server.o b/http-server.o
index ef236fb0772a097b1e53a03c54f0c3089a37957f..01d0e66c9ce7ebac5f8c6b9f431adc36eed0f4b9 100644
Binary files a/http-server.o and b/http-server.o differ
diff --git a/image_tagger b/image_tagger
index 73b51c68ecf5c959730949fe23155609e416819a..500d4670814ad0bae7fccbda331e51c3d06b059f 100644
Binary files a/image_tagger and b/image_tagger differ
diff --git a/user.c b/user.c
index 2555d0a0e1938822ee56a42d0e868b312cf1b284..9f1b735b788f4c3eba40a3fbd4f562dbdb298bc3 100644
--- a/user.c
+++ b/user.c
@@ -6,24 +6,27 @@
 
 #include "user.h"
 
+#define INITIAL_KEYWORDS 5
+#define INITAL_N_USERS 5
+#define INITIAL_KEYWORD_LENGTH 30
 
 User* new_user(int id){
-    User *user = malloc(sizeof *user);
+    User *user = calloc(1, sizeof *user);
     assert(user);
     user->id = id;
-    user->n_capacity = 5;
+    user->n_capacity = INITIAL_KEYWORDS;
     user->n_keywords = 0;
     user->status = WAIT;
-    user->keywords = malloc(sizeof(char*)*user->n_capacity);
+    user->keywords = calloc(user->n_capacity,sizeof(char*));
     assert(user->keywords);
     return user;
 }
 
 User_list* initialise_player_list(){
-    User_list *users = malloc(sizeof(User_list));
+    User_list *users = calloc(1, sizeof(User_list));
     assert(users);
     users->n_users = 0;
-    users->users = malloc(sizeof(User*)*5);
+    users->users = calloc(INITAL_N_USERS, sizeof(User*));
     assert(users->users);
     return users;
 }
@@ -44,10 +47,11 @@ void resize_keywords(User* user, char* keyword){
 char* add_keyword(int id, User_list* users, char* query){
     const char s[2] = "&";
     char * curr = query;
-    char * token = malloc(sizeof(char)*20);
+    char * token = calloc(INITIAL_KEYWORD_LENGTH, sizeof(char));
+    token[0] = '\0';
     assert(token);
     curr += 8;
-    memcpy(token, strtok(curr, s), strlen(strtok(curr, s)));
+    strcat(token, strtok(curr, s));
     printf("the keywod is %s\n", token);
     for(int i=0; i < users->n_users; i++){
         if(users->users[i]->id == id){
@@ -117,9 +121,6 @@ bool keyword_match(User* user, char* keyword){
 
 void reset_players(User_list *users){
     for(int i=0; i< users->n_users;i++){
-        for(int j=0; j< users->users[i]->n_keywords; j++){
-            free(users->users[i]->keywords[j]);
-        }
         users->users[i]->n_keywords = 0;
     }
 }
@@ -143,4 +144,14 @@ bool player_won(User_list *users){
         }
     }
     return false;
+}
+
+User* get_current_user(User_list* users, char* keyword, int id){
+    User *user = NULL;
+    for(int i=0; i < users->n_users; i++){
+        if (users->users[i]->id == id){
+            user = users->users[i];
+        }
+    }
+    return user;
 }
\ No newline at end of file
diff --git a/user.h b/user.h
index 969c17896d17ed7a441e4bdba7753fe4f04a83ca..6ca8b169f6431f9a176380788be53adeb983ae54 100644
--- a/user.h
+++ b/user.h
@@ -48,4 +48,6 @@ void reset_players(User_list *users);
 
 bool has_match_ended(User_list* users, char* keyword, int id);
 
-bool player_won(User_list *users);
\ No newline at end of file
+bool player_won(User_list *users);
+
+User* get_current_user(User_list* users, char* keyword, int id);
\ No newline at end of file
diff --git a/user.o b/user.o
index 7c8a2d69f9601114696a54bfdb31181e3d0f2ad1..016374a793e8702125fd09ac11093888a1cf1835 100644
Binary files a/user.o and b/user.o differ