static void respond_to ( struct HTTPRequest *req, /* HTTP request */ FILE *out, /* output fd */ char *docroot /* docroot path */ ) { dbg( "req=%p, out=%p, docroot=%p\n", req, out, docroot ); if ( strcmp( req->method, "GET" ) == 0 ) { do_file_response( req, out, docroot ); } else if( strcmp( req->method, "HEAD" ) == 0 ) { do_file_response( req, out, docroot ); } else if( strcmp( req->method, "POST" ) == 0 ) { method_not_allowed( req, out ); } else { not_implemented( req, out ); } }
int handle_client_connection() { char buffer[8096]; int buffer_len; // Length of buffer char method[256]; char url[256]; char version[256]; int i = 0, // Used to iterate over the first line to get method, url, version j = 0; // Read first line buffer_len = read_line(client_sockfd, buffer, sizeof(buffer)); // Unable to read from socket, not sure what to do in this case if (buffer_len <= 0) { return -1; } fprintf(stderr, "==== Read Next Request ====\n"); // Get Method (e.g. GET, POST, etc) while ((i < (sizeof(method) - 1)) && (!isspace(buffer[i]))) { method[i] = buffer[i]; i++; } method[i] = '\0'; // fprintf(stderr, "method: %s\n", method); // Skip over spaces while (i < buffer_len && isspace(buffer[i])) { i++; } // Get URL j = 0; while (i < buffer_len && (j < (sizeof(url) - 1)) && !isspace(buffer[i])) { url[j] = buffer[i]; i++; j++; } url[j] = '\0'; // fprintf(stderr, "url: %s\n", url); // Skip over spaces while (i < buffer_len && isspace(buffer[i])) { i++; } j = 0; while (j < sizeof(version) - 1 && !isspace(buffer[i])) { version[j] = buffer[i]; i++; j++; } version[j] = '\0'; // fprintf(stderr, "version: %s\n", version); read_headers(); if (header_err_flag) { keep_alive = FALSE; bad_request(); return -1; } if (content_length > 0) { content = (char*) malloc(content_length + 1); read_socket(client_sockfd, content, content_length); } // fprintf(stderr, "Content-Length: %d\n", content_length); // fprintf(stderr, "Connection (keep_alive): %d\n", keep_alive); // fprintf(stderr, "Cookie: %d\n", cookie); // fprintf(stderr, "If-Modified-Since Valid Time: %d\n", time_is_valid); // fprintf(stderr, "If-Modified-Since Time: %p\n", if_modified_since); if (content != NULL) { // fprintf(stderr, "Content: %s\n", content); } /***********************************************************/ /* Full message has been read, respond to client */ /***********************************************************/ if (strcmp(method, "GET") != 0) { // Inform client we don't support method fprintf(stderr, "Method Not Allowed: %s\n", method); method_not_allowed(); return 0; } if (cookie) { // Inform client we don't support cookies not_implemented(); return 0; } if (not_eng) { // Inform client we only support English not_implemented(); return 0; } if (!acceptable_text) { // Inform client we only support plain text not_implemented(); return 0; } if (!acceptable_charset) { // Inform client we only support ASCII not_implemented(); return 0; } // Fix filename char file_path[512]; sprintf(file_path, "htdocs%s", url); if (file_path[strlen(file_path)-1] == '/') { file_path[strlen(file_path)-1] = '\0'; } // fprintf(stderr, "%s\n", file_path); int fname_valid = is_valid_fname(file_path); struct stat file_info; if (!fname_valid) { // invalid filename fprintf(stderr, "403 Forbidden: Invalid file name\n"); forbidden(); return 0; } if (stat(file_path, &file_info)) { fprintf(stderr, "404 Not Found: Stat failed\n"); // Stat failed not_found(); return 1; } if (!S_ISREG(file_info.st_mode)) { // Not a file forbidden(); fprintf(stderr, "403 Forbidden: Not a regular file\n"); return 0; } if (!(file_info.st_mode & S_IRUSR)) { // No read permissions forbidden(); fprintf(stderr, "403 Forbidden: No read permissions\n"); return 0; } FILE *f = fopen(file_path, "r"); if (f == NULL) { // No file not_found(); fprintf(stderr, "404 Not Found: Unable to open file\n"); return 0; } if (if_modified_since != NULL) { struct tm *last_modified = gmtime(&file_info.st_mtime); time_t last = mktime(last_modified); time_t since = mktime(if_modified_since); double diff = difftime(last, since); if (diff <= 0) { fprintf(stderr, "304 Not Modified\n"); not_modified(); return 0; } } fprintf(stderr, "All looks good, serving up content in %s\n", file_path); char *file_contents = NULL; int contents_length = 0; char line[512]; while (fgets(line, sizeof(line), f) != NULL) { if (file_contents != NULL) { char *new_contents = (char*) malloc(contents_length + strlen(line) + 1); strcpy(new_contents, file_contents); strcpy(new_contents + strlen(new_contents), line); contents_length += strlen(line); free(file_contents); file_contents = new_contents; } else { file_contents = (char*) malloc(strlen(line) + 1); strcpy(file_contents, line); contents_length += strlen(line); } } fclose(f); // fprintf(stderr, "File Contents:\n"); // fprintf(stderr, "%s\n", file_contents); ok(file_contents); return 0; }