diff --git a/image_tagger.c b/image_tagger.c index 0c4ae13629c34fd8c294ad72361aae76e9738e69..79e4e301f14971386ccb7c187ed0f96515499657 100644 --- a/image_tagger.c +++ b/image_tagger.c @@ -25,11 +25,25 @@ static char const * const HTTP_200_FORMAT = "HTTP/1.1 200 OK\r\n\ Content-Type: text/html\r\n\ Content-Length: %ld\r\n\r\n"; +static char const * const HTTP_200_COOKIE = "HTTP/1.1 200 OK\r\n\ +Content-Type: text/html\r\n\ +Content-Length: %ld\r\n\ +Set-Cookie: player=%s\r\n\ +Set-Cookie: nameLength=%d\r\n\r\n"; static char const * const HTTP_400 = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n"; 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 char const * const SET_COOKIE = ; +static char* const PAGE_1 = "1_intro.html"; +static char* const PAGE_2 = "2_start.html"; +static char* const PAGE_3 = "3_first_turn.html"; +static char* const PAGE_4 = "4_accepted.html"; +static char* const PAGE_5 = "5_discarded.html"; +static char* const PAGE_6 = "6_endgame.html"; +static char* const PAGE_7 = "7_gameover.html"; +/* static char* P1_NAME; static char* P2_NAME; static int P1_GAME_STATE = 0; @@ -38,23 +52,38 @@ static char* KEYWORD_LIST_P1[100]; static char* KEYWORD_LIST_P2[100]; static int NUM_KEYWORD_P1 = 0; static int NUM_KEYWORD_P2 = 0; - -static char* PAGE_1 = "1_intro.html"; -static char* PAGE_2 = "2_start.html"; -static char* PAGE_3 = "3_first_turn.html"; -static char* PAGE_4 = "4_accepted.html"; -static char* PAGE_5 = "5_discarded.html"; -static char* PAGE_6 = "6_endgame.html"; -static char* PAGE_7 = "7_gameover.html"; +*/ // represents the types of method -typedef enum -{ +typedef enum { GET, POST, UNKNOWN } METHOD; +typedef enum { + WELCOME, + WAITING, + READY, + COMPLETED, + GAMEOVER +} GAMESTATE; + +struct Player { + char* name; + int nameLength; + int playerNum; + GAMESTATE gameState; + char* keywordList[100]; + int numKeywords; +}; + +static struct Player player1; +static struct Player player2; +//player1.playerNum = 1; +//player2.playerNum = 2; + + static char* getURL(char* curr) { char* url; if (strncmp(curr, "1_intro.html ", 13) == 0 || strncmp(curr, " HTTP/1.1", 9) == 0) @@ -63,7 +92,7 @@ static char* getURL(char* curr) { } else if(strncmp(curr, "2_start.html ", 13) == 0) { url = PAGE_2; - } else if(strncmp(curr, "3_first_turn.html ", 18) == 0 || strncmp(curr, "?start=Start ", 13) == 0) + } else if(strncmp(curr, "3_first_turn.html ", 18) == 0 || strstr(curr, "?start=Start ") != NULL) { url = PAGE_3; } else if(strncmp(curr, "4_accepted.html ", 16) == 0) @@ -79,7 +108,7 @@ static char* getURL(char* curr) { { url = PAGE_7; } else { - url = " "; + url = NULL; } return url; } @@ -88,32 +117,106 @@ static bool addKeyword(char * keyword, int playerNum) { int i = 0; bool match = false; if(playerNum == 1) { - while(KEYWORD_LIST_P2[i] != NULL) { - if((strcmp(KEYWORD_LIST_P2[i], keyword)) == 0) { + while(player2.keywordList[i] != NULL) { + if((strcmp(player2.keywordList[i], keyword)) == 0) { match = true; } i++; } - KEYWORD_LIST_P1[NUM_KEYWORD_P1] = keyword; - NUM_KEYWORD_P1++; + if((player1.keywordList[player1.numKeywords] = malloc(strlen(keyword)*sizeof(char))) == NULL) { + printf("malloc error"); + exit(0); + } + memcpy(player1.keywordList[player1.numKeywords],keyword,strlen(keyword)); + player1.numKeywords++; } else { - while(KEYWORD_LIST_P1[i] != NULL) { - if((strcmp(KEYWORD_LIST_P1[i], keyword)) == 0) { + while(player1.keywordList[i] != NULL) { + if((strcmp(player1.keywordList[i], keyword)) == 0) { match = true; } i++; } - KEYWORD_LIST_P2[NUM_KEYWORD_P2] = keyword; - NUM_KEYWORD_P2++; + if((player2.keywordList[player2.numKeywords] = malloc(strlen(keyword)*sizeof(char))) == NULL) { + printf("malloc error"); + exit(0); + } + memcpy(player2.keywordList[player2.numKeywords],keyword,strlen(keyword)); + player2.numKeywords++; } return match; } -static bool getRequest(int sockfd, char* buff, char* url, int n) { - // get the size of the file - struct stat st; - stat(url, &st); - n = sprintf(buff, HTTP_200_FORMAT, st.st_size); +static struct Player* checkCookie(char* buff) { + char * cookie; + if((cookie = strstr(buff,"player=")) != NULL) { + if(strncmp(cookie+7,player1.name,player1.nameLength) == 0) { + return &player1; + } else if(strncmp(cookie+7,player2.name,player2.nameLength) == 0) { + return &player2; + } else if(player1.name == NULL) { + char* length = strstr(buff,"nameLength="); + player1.nameLength = atoi(length+11); + if((player1.name = malloc(player1.nameLength*sizeof(char))) == NULL) { + printf("malloc error"); + return false; + } + memcpy(player1.name,cookie+7,player1.nameLength); + return &player1; + } else if(player2.name == NULL) { + char* length = strstr(buff,"nameLength="); + player1.nameLength = atoi(length+11); + if((player2.name = malloc(player2.nameLength*sizeof(char))) == NULL) { + printf("malloc error"); + return false; + } + memcpy(player2.name,cookie+7,player2.nameLength); + return &player2; + } + } + return NULL; +} + +static bool sendResponse(int sockfd, char* file, char* post) { + char buff[2049]; + int n; + + if(file == NULL) { + if (write(sockfd, HTTP_404, HTTP_404_LENGTH) < 0){ + perror("write"); + return false; + } + return true; + } else { + struct stat st; + stat(file, &st); + if(post != NULL && (strncmp(post,"user=",5)) == 0) { + if(player1.name == NULL) { + char* temp = post+5; + if((player1.name = malloc(strlen(temp)*sizeof(char))) == NULL) { + printf("malloc error"); + return false; + } + memcpy(player1.name,temp,strlen(temp)); + player1.nameLength = strlen(player1.name); + player1.gameState = WAITING; + n = sprintf(buff, HTTP_200_COOKIE, st.st_size, player1.name, player1.nameLength); + } else if (player2.name == NULL) { + char* temp = post+5; + if((player2.name = malloc(strlen(temp)*sizeof(char))) == NULL) { + printf("malloc error"); + return false; + } + memcpy(player2.name,temp,strlen(temp)); + player2.nameLength = strlen(player2.name); + player2.gameState = WAITING; + n = sprintf(buff, HTTP_200_COOKIE, st.st_size, player2.name, player2.nameLength); + } else { + n = sprintf(buff, HTTP_200_FORMAT, st.st_size); + } + } else { + n = sprintf(buff, HTTP_200_FORMAT, st.st_size); + } + } // send the header first if (write(sockfd, buff, n) < 0) { @@ -121,7 +224,7 @@ static bool getRequest(int sockfd, char* buff, char* url, int n) { return false; } // send the file - int filefd = open(url, O_RDONLY); + int filefd = open(file, O_RDONLY); do { n = sendfile(sockfd, filefd, NULL, 2048); @@ -137,62 +240,65 @@ static bool getRequest(int sockfd, char* buff, char* url, int n) { return true; } +static bool getRequest(int sockfd, char* buff, char* url, int n) { + + struct Player* player = checkCookie(buff); + + if(url != NULL && player != NULL) { + if (strcmp(url,PAGE_1) == 0) { + url = PAGE_2; + } + if (strcmp(url,PAGE_3) == 0 || strcmp(url,PAGE_6) == 0) { + player->gameState = READY; + } + } + + sendResponse(sockfd,url,NULL); + return true; +} + static bool postRequest(int sockfd, char* buff, char* url, int n) { char* post; char* file; if((post = strstr(buff,"user=")) != NULL) { - if(P1_GAME_STATE == 0) { - P1_NAME = post + 5; - P1_GAME_STATE++; - } else if (P2_GAME_STATE == 0) { - P2_NAME = post + 5; - P2_GAME_STATE++; - } file = PAGE_2; } else if((post = strstr(buff,"keyword=")) != NULL) { - if(P1_GAME_STATE == P2_GAME_STATE && P1_GAME_STATE == 2) { - if(addKeyword(post+8,1)) { + if(player1.gameState == player2.gameState && player1.gameState == READY) { + struct Player* player = checkCookie(buff); + if(addKeyword(post+8,player->playerNum)) { file = PAGE_6; + player1.gameState = COMPLETED; + player2.gameState = COMPLETED; } else { file = PAGE_4; } + printf("P1 keywords: \n"); + for(int i = 0; i < player1.numKeywords; i++) { + printf("%s\n",player1.keywordList[i]); + } + printf("P2 keywords: \n"); + for(int i = 0; i < player2.numKeywords; i++) { + printf("%s\n",player2.keywordList[i]); + } } else { file = PAGE_5; } - } else if((post = strstr(buff,"quit=Quit")) != NULL) { + } else if (player1.gameState == COMPLETED || player2.gameState == COMPLETED) { + file = PAGE_6; + } else if((post = strstr(buff,"quit=Quit")) != NULL || player1.gameState == GAMEOVER) { file = PAGE_7; + player1.gameState = GAMEOVER; + } else { + file = NULL; } - printf("post = %s and file = %s\n", post, file); - struct stat st; - stat(file, &st); - n = sprintf(buff, HTTP_200_FORMAT, st.st_size); - // send the header first - if (write(sockfd, buff, n) < 0) - { - perror("write"); - return false; - } - // send the file - int filefd = open(file, O_RDONLY); - do - { - n = sendfile(sockfd, filefd, NULL, 2048); - } - while (n > 0); - if (n < 0) - { - perror("sendfile"); - close(filefd); - return false; - } - close(filefd); + sendResponse(sockfd,file,post); + return true; } -static bool handle_http_request(int sockfd) -{ +static bool handle_http_request(int sockfd) { // try to read the request char buff[2049]; char * url; @@ -205,10 +311,9 @@ static bool handle_http_request(int sockfd) printf("socket %d close the connection\n", sockfd); return false; } - + printf("%s\n", buff); // terminate the string buff[n] = 0; - printf("%s\n", buff); char * curr = buff; // parse the method @@ -235,42 +340,26 @@ static bool handle_http_request(int sockfd) // assume the only valid request URI is "/" but it can be modified to accept more files } - if (*curr != '\0') - { - url = getURL(curr); - if(strcmp(url," ") == 0) { - perror("read"); + url = getURL(curr); + if (method == GET) { + if(getRequest(sockfd,buff,url,n) == false) { return false; } - if (method == GET) - { - if(getRequest(sockfd,buff,url,n) == false) { - return false; - } - } - else if (method == POST) - { - if(postRequest(sockfd,buff,url,n) == false) { - return false; - } - } - else - // never used, just for completeness - fprintf(stderr, "no other methods supported"); - // send 404 - } - else if (write(sockfd, HTTP_404, HTTP_404_LENGTH) < 0) { - perror("write"); - return false; - } - + } else if (method == POST) { + if(postRequest(sockfd,buff,url,n) == false) { + return false; + } + } else { + // never used, just for completeness + fprintf(stderr, "no other methods supported"); + } + return true; } -int main(int argc, char * argv[]) -{ +int main(int argc, char * argv[]) { if (argc < 3) { fprintf(stderr, "usage: %s ip port\n", argv[0]); @@ -320,7 +409,14 @@ int main(int argc, char * argv[]) char str[INET_ADDRSTRLEN]; printf("image_tagger server is now running at IP: %s on port %d\n", inet_ntop(AF_INET, &serv_addr.sin_addr, str, INET_ADDRSTRLEN), ntohs(serv_addr.sin_port)); - + + player1.gameState = WELCOME; + player2.gameState = WELCOME; + player1.numKeywords = 0; + player2.numKeywords = 0; + player1.playerNum = 1; + player2.playerNum = 2; + while (1) { // monitor file descriptors @@ -371,4 +467,4 @@ int main(int argc, char * argv[]) } return 0; -} +} \ No newline at end of file