diff --git a/image_tagger.c b/image_tagger.c index d099cc5b698945560620a6bdcac0e0e31e460b8f..8b6d307d6877994dc845d71ce631caa8c6fe7f94 100644 --- a/image_tagger.c +++ b/image_tagger.c @@ -3,7 +3,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> - +#include <stddef.h> #include <arpa/inet.h> #include <fcntl.h> #include <netdb.h> @@ -33,7 +33,7 @@ typedef enum UNKNOWN } METHOD; -static bool handle_http_request(int sockfd) +static bool handle_http_request(int sockfd, int player) { // try to read the request char buff[2049]; @@ -49,7 +49,7 @@ static bool handle_http_request(int sockfd) // terminate the string buff[n] = 0; - + //fwrite(buff,1,2049,stdout); char * curr = buff; // parse the method @@ -74,7 +74,106 @@ static bool handle_http_request(int sockfd) while (*curr == '.' || *curr == '/') ++curr; // assume the only valid request URI is "/" but it can be modified to accept more files - if (*curr == ' ') + + +if (strncmp(curr, "?start", 6) == 0){ + if (method == GET) + { + // get the size of the file + struct stat st; + stat("3_first_turn.html", &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("3_first_turn.html", O_RDONLY); + do + { + n = sendfile(sockfd, filefd, NULL, 2048); + } + while (n > 0); + if (n < 0) + { + perror("sendfile"); + close(filefd); + return false; + } + close(filefd); + } + else if(method == POST){ + char * quit = strstr(buff, "quit="); + char * guess = strstr(buff, "guess="); + if (quit) { + player -=1; + // get the size of the file + struct stat st; + stat("7_gameover.html", &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("7_gameover.html", O_RDONLY); + do + { + n = sendfile(sockfd, filefd, NULL, 2048); + } + while (n > 0); + if (n < 0) + { + perror("sendfile"); + close(filefd); + return false; + } + close(filefd); + } + if(guess){ + // get the size of the file + if(player < 2){ + struct stat st; + stat("5_discarded.html", &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("5_discarded.html", O_RDONLY); + do + { + n = sendfile(sockfd, filefd, NULL, 2048); + } + while (n > 0); + if (n < 0) + { + perror("sendfile"); + close(filefd); + return false; + } + close(filefd); + } + } + + } + } + + + + + + + if (*curr == ' '){ + if (method == GET) { // get the size of the file @@ -102,70 +201,107 @@ static bool handle_http_request(int sockfd) } close(filefd); } + else if (method == POST) { // 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 = strstr(buff, "user=") + 5; - int username_length = strlen(username); - // the length needs to include the "Hi, " before the username - long added_length = username_length + 4; + char * quit = strstr(buff, "quit="); + if (quit) { + player -=1; + // get the size of the file + struct stat st; + stat("7_gameover.html", &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("7_gameover.html", O_RDONLY); + do + { + n = sendfile(sockfd, filefd, NULL, 2048); + } + while (n > 0); + if (n < 0) + { + perror("sendfile"); + close(filefd); + return false; + } + close(filefd); + } + else{ + char * username = strstr(buff, "user=") + 5; + int username_length = strlen(username); + char userbuff[2049]; + strncpy(userbuff, username, username_length); + userbuff[username_length]=0; // get the size of the file - struct stat st; - stat("2_start.html", &st); - // increase file size to accommodate the username - long size = st.st_size + added_length; - 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("2_start.html", O_RDONLY); - n = read(filefd, buff, 2048); - if (n < 0) - { - perror("read"); - close(filefd); - return false; - } - close(filefd); - //move the trailing part backward - int p2; - /*for (p1 = size - 1, p2 = p1 - added_length; p1 >= size - 25; --p1, --p2) - buff[p1] = buff[p2]; - ++p2;*/ - // put the separator - buff[p2++] = 'H'; - buff[p2++] ='i'; - buff[p2++] = ','; - buff[p2++] = ' '; - // copy the username - strncpy(buff + p2, username, username_length); + struct stat st; + stat("2_start.html", &st); + // increase file size to accommodate the username + long size = st.st_size + username_length; + 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("2_start.html", O_RDONLY); + n = read(filefd, buff, 2048); + if (n < 0) + { + perror("read"); + close(filefd); + return false; + } + close(filefd); + //move the trailing part backward + int p1, p2; + for (p1 = size - 1, p2 = p1 - username_length; p1 >= size - 17; --p1, --p2) + buff[p1] = buff[p2]; + + ++p2; + + // copy the username + + for(int i=0;i<username_length;i++){ + buff[p2]=userbuff[i]; + p2++; + } + + if (write(sockfd, buff, size) < 0) { perror("write"); return false; } + } } - else - // never used, just for completeness + + 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; + // send 404 + if (write(sockfd, HTTP_404, HTTP_404_LENGTH) < 0) + { + perror("write"); + return false; + } + } } - return true; } int main(int argc, char * argv[]) { + int player = 0; if (argc < 3) { fprintf(stderr, "usage: %s ip port\n", argv[0]); @@ -222,9 +358,9 @@ int main(int argc, char * argv[]) perror("select"); exit(EXIT_FAILURE); } - + int player = 0; // loop all possible descriptor - for (int i = 0; i <= maxfd; ++i) + for (int i = 0; i <= maxfd; ++i){ // determine if the current file descriptor is active if (FD_ISSET(i, &readfds)) { @@ -252,14 +388,17 @@ int main(int argc, char * argv[]) newsockfd ); } + player += 1; } + // a request is sent from the client - else if (!handle_http_request(i)) + else if (!handle_http_request(i, player)) { close(i); FD_CLR(i, &masterfds); } - } + } + } } return 0;