diff --git a/Makefile b/Makefile index 37552d1682f695a130ce4b36b2d3f58767cbae69..c877eb625ad7622483736f62b64e4aa6bd789542 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ server: - gcc server.c -o server -lpthread + gcc server.c -o server -lpthread -g clean: rm server diff --git a/server.c b/server.c index 4c86aa68b902e85e71c76b365d152d0ea0c34b96..a7aa67a54a3a83a342e83253386104bc0a2112b0 100644 --- a/server.c +++ b/server.c @@ -8,75 +8,27 @@ #include <pthread.h> -char *slice(char str[], int start, int finish){ - char subarray[finish - start + 1]; - int i; - for(i = start; i < finish; i ++){ - subarray[i] = str[i]; - } - return subarray; -} - -char *slice_str(const char * str, size_t start, size_t last) { - size_t j = 0; - char buffer[strlen(str)]; - for ( size_t i = start; i <= last; ++i ) { - buffer[j++] = str[i]; - } - buffer[j] = 0; - return buffer; -} - -char *get_mime(char path[]){ - int end_slice = strlen(path); - if(strcmp(slice_str(path, end_slice-strlen("js"), end_slice), "js") == 0){ - return "application/javascript"; - } - else if(strcmp(slice_str(path, end_slice-strlen("html"), end_slice), "html") == 0){ - return "text/html"; - }else - if(strcmp(slice_str(path, end_slice-strlen("css"), end_slice), "css") == 0){ - return "text/css"; - }else - if(strcmp(slice_str(path, end_slice-strlen("jpg"), end_slice), "jpg") == 0 ){ - return "image/jpeg"; - } - else{ - return "N/A"; - } -} - -// returns the address requested -char *get_path(char header[]){ - int i, start_found = 0, point_in_string = 0; - char path[strlen(header)]; - for (i = 0; i < 20; i++){ - int h = header[i]; - //find the start of the path - if(h == *"/" && start_found == 0){ - start_found = 1; - printf("%c", header[i]); - }else if(start_found && h == *" "){ - printf("\n"); - break; - }else if( start_found){ - path[point_in_string] = header[i]; - point_in_string ++; - printf("%c", header[i]); - } - } - - printf("from inside get path: %s", path); - return slice(path, 0, point_in_string); -} +//prototypes +struct Thread_args; +char *create_message(char path[], FILE* file); +char *slice(char[], int start, int finish); +char *slice_str(const char * str, size_t start, size_t last); +char *get_mime(char path[]); +char *get_path(char header[]); +void increase(char** arr, int size); +void send_msg(int sock, char msg[]); +void process_request(struct Thread_args *targs); + +struct Thread_args{ + int socket; + char *path; +}; int main(int argc, char **argv) { int sockfd, newsockfd, portno; - char buffer[256]; struct sockaddr_in serv_addr, cli_addr; socklen_t clilen; - int n; if (argc < 2) { fprintf(stderr,"ERROR, no port provided\n"); @@ -85,13 +37,11 @@ int main(int argc, char **argv) // create a TCP socket sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) { perror("ERROR opening socket"); exit(1); } - bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); @@ -113,60 +63,156 @@ int main(int argc, char **argv) clilen = sizeof(cli_addr); - // accept a connection - newsockfd = accept( sockfd, (struct sockaddr *) &cli_addr, &clilen); + pthread_t thread_id; - if (newsockfd < 0) - { - perror("ERROR on accept"); - exit(1); + while((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)) > 0){ + struct Thread_args targs; + targs.path = argv[2]; + targs.socket = newsockfd; + + if( pthread_create( &thread_id , NULL , process_request, &targs) < 0) + { + perror("could not create thread"); + return 1; + } } - bzero(buffer, 256); + if(newsockfd < 0){ + perror("accept failed"); + return 1; + } + + close(sockfd); + return 0; +} - //read what the message asks - n = read(newsockfd,buffer,255); - if (n < 0) { +void process_request(struct Thread_args *targs){ + int socket = targs->socket; + char *path = targs->path; + char buffer[256]; + bzero(buffer, 256); + + //read what the message asks + if (read(socket,buffer,255) < 0) { + printf("socket desc on read: %d\n", socket); perror("ERROR reading from socket"); exit(1); } - char found_header[] = "HTTP/1.1 200 OK"; char unfound_header[] = "HTTP/1.1 404 Not Found"; - char path[80]; - strcpy(path, argv[2]); strcat(path, get_path(buffer)); FILE *file; file = fopen(path, "r"); - char msg[1024]; - + char *msg; if(!file){ // file not found, generate a 404 message + msg = realloc(msg, sizeof(unfound_header)); strncpy(msg, unfound_header, 1024); + send_msg(socket, msg); + } else{ // file found, generate a proper header with the info - strncpy(msg, found_header, 1024); - char *mime; - mime = get_mime(path); - strcat(msg, "\nContent-Type: "); - strcat(msg, mime); - strcat(msg, "\r\r\n\n"); - char line[100]; - while(fgets(line, 1024, file)){ - strcat(msg, line); - } + char *msg = create_message(path, file); + printf("\n the message before its sent: \n%s\n\n", msg); + send_msg(socket, msg); } +} - n = write(newsockfd,msg,strlen(msg)); - if (n < 0) { +void send_msg(int sock, char msg[]){ + if (write(sock,msg,strlen(msg)) < 0) { perror("ERROR writing to socket"); exit(1); } - close(sockfd); +} + +void increase(char** data, int size) +{ + *data = realloc(*data, size); +} + +//returns the message to be sent +char *create_message(char path[], FILE *file){ + char *mime; + char *msg = malloc(1*sizeof("HTTP/1.1 200 OK\nContent-Type: \r\r\n\n") + 20); + strcat(msg, "HTTP/1.1 200 OK\nContent-Type: "); + mime = get_mime(path); + increase(&msg, (sizeof(mime) + sizeof(msg))*sizeof(char)); + strcat(msg, mime); + strcat(msg, "\r\r\n\n"); + printf("\nsize of msg: %lu, size of *msg: %lu\n", sizeof("HTTP/1.1 200 OK\nContent-Type: \r\r\n\n"),sizeof(msg)); + printf("the message so far: %s", msg); + char line[1024]; + increase(&msg, (sizeof(file) + sizeof(msg))*sizeof(char) ); + while(fgets(line, 1024, file)){ + strcat(msg, line); + } + return msg; + +} + +char *slice(char str[], int start, int finish){ + char subarray[finish - start + 1]; + int i; + for(i = start; i < finish; i ++){ + subarray[i] = str[i]; + } + return subarray; +} + +char *slice_str(const char * str, size_t start, size_t last) { + size_t j = 0; + char buffer[strlen(str)]; + for ( size_t i = start; i <= last; ++i ) { + buffer[j++] = str[i]; + } + buffer[j] = 0; + return buffer; +} + +char *get_mime(char path[]){ + int end_slice = strlen(path); + if(strcmp(slice_str(path, end_slice-strlen("js"), end_slice), "js") == 0){ + return "application/javascript"; + } + else if(strcmp(slice_str(path, end_slice-strlen("html"), end_slice), "html") == 0){ + return "text/html"; + }else + if(strcmp(slice_str(path, end_slice-strlen("css"), end_slice), "css") == 0){ + return "text/css"; + }else + if(strcmp(slice_str(path, end_slice-strlen("jpg"), end_slice), "jpg") == 0 ){ + return "image/jpeg"; + } + else{ + return "N/A"; + } +} + +// returns the address requested +char *get_path(char header[]){ + int i, start_found = 0, point_in_string = 0; + char path[strlen(header)]; + for (i = 0; i < 20; i++){ + int h = header[i]; + //find the start of the path + if(h == *"/" && start_found == 0){ + start_found = 1; + printf("%c", header[i]); + }else if(start_found && h == *" "){ + printf("\n"); + break; + }else if( start_found){ + path[point_in_string] = header[i]; + point_in_string ++; + printf("%c", header[i]); + } + } + + return slice(path, 0, point_in_string); +} + - return 0; -} \ No newline at end of file