void reqs_throw_status(struct reqs_t *reqs, int status_code, char *msg) { if (status_code > 199 && status_code != 204 && status_code != 304) { int len = strlen(msg); if (!len) { msg = http_status_lines_get(status_code); len = strlen(msg); } set_http_status (reqs, status_code); set_http_header (reqs, "Content-Type", "text/html"); set_http_header_x(reqs, "Content-Length", "%d", len); send_http_header (reqs); reqs_conn_send (reqs, msg, len); } else { set_http_status (reqs, status_code); set_http_header (reqs, "Content-Type", ""); set_http_header (reqs, "Content-Length", ""); send_http_header (reqs); } }
int reqs_cont_send(struct reqs_t *reqs) { if (!reqs->rp_status_line) { set_http_status(reqs, 200); /* "200 OK" */ } if (strlen(get_http_header(reqs, "Content-Type")) == 0) { set_http_header(reqs, "Content-Type", "text/html"); } set_http_header_x(reqs, "Content-Length", "%d", bufx_get_used(reqs->contbufx)); send_http_header (reqs); bufx_get_each (reqs->contbufx, conn_send, reqs->conn); return 1; }
char* parse_HTTP_msg(char buffer[]) { char *p; char str_GET[] = "GET"; char str_HEAD[] = "HEAD"; char *path_to_file; printf("\n---------Request-------------\n%s", buffer); p = strtok(buffer, " "); //printf("Buffer after strtok: %s\n", buffer); prog_options_t *opt = &my_opt; if(strcmp(p, str_GET) == 0 || strcmp(p, str_HEAD) == 0) { p = strtok(NULL, " "); // p contains path to file /*for(int n=0; n < strlen(p); ++n) { p[n] = p[n+1]; //trim / from path }*/ //strlen von opt->root_dir int lenStr = strlen(opt->root_dir); path_to_file = malloc (lenStr + 24); //Bei + 24 tritt malloc overflow nicht mehr auf //Fehlerbehandlung von malloc falls ptr ==0 TODO //strcpy ptr, root_dir strcpy(path_to_file, opt->root_dir); strcat(path_to_file, p); return path_to_file; } else { set_http_status(HTTP_STATUS_NOT_IMPLEMENTED); } return 0; }
char* create_HTTP_response_header(const char *filename, char buffer[]) { //printf("................\n"); char* response_header = (char*) malloc(BUFFER_SIZE); int range_end; int range_start = 0; int content_length; char *ptr; char *lineRange = NULL; //char *lineModified = NULL; if(response_header == NULL) { error("Error allocating response_header"); } char status_text[100] = "HTTP/1.1 %i Partial Content\r\n"; char date_text[100] = "DATUM Funktion einbauen\r\n"; char server_text[100] = "Server: TinyWeb (Build Jun 12 2014)\r\n"; char accept_range_text[100] = "Accept-Ranges: bytes\r\n"; char last_modified_text[100] = "Last-Modified: Thu, 12 Jun 2014\r\n"; char content_type_text[100] = "Content-Type: text/html\r\n"; char content_length_text[100] = "Content-Length: 1004\r\n"; char content_range_text[100] = "Content-Range: bytes 6764-7767/7768\r\n"; char connection_text[100] = "Connection: Close\r\n\r\n"; //file length calculating struct stat buf; if(stat(filename, &buf) != 0) { printf("Error in file length calculating.\n"); } //set_http_status(HTTP_STATUS_PARTIAL_CONTENT); time_t t; struct tm *ts; t = time(NULL); ts = localtime(&t); struct stat file_Info; sprintf(status_text, "HTTP/1.1 %i %s\r\n", http_status_list[get_http_status()].code, http_status_list[get_http_status()].text ); //TODO: status dynamisch uebergeben sprintf(date_text, "Date: %s, %i %s %i %02i:%02i:%02i GMT\r\n", get_weekday(ts->tm_wday), ts->tm_mday, get_month(ts->tm_mon), ts->tm_year + 1900, ts->tm_hour, ts->tm_min, ts->tm_sec); //TODO: Reutemann fragen ob das Format so passt //sprintf(server_text, "Server: TinyWeb (Build Jun 12 2014)", ); //TODO: Buildzeit dynamisch einfuegen ptr = strtok(NULL, "\n"); while (ptr != NULL) { // extract line with the range if existing if (strncmp(ptr,"Range",5) == 0) { lineRange = ptr; } else if ((strncmp(ptr,"If-Modified-Since",strlen("If-Modified-Since"))) == 0) { //lineModified = ptr; } ptr = strtok(NULL, "\n"); } if (lineRange != NULL) { char *range = malloc(strlen(lineRange)+1); if (range == NULL) { perror("Malloc():"); } strtok(lineRange,"="); range = strtok(NULL,"="); // after "=" range_start = atoi(strtok(range,"-")); range_end = atoi(strtok(NULL,"-")); //printf("Start: %i End: %i", range_start, range_end); } int check; check = stat(filename, &file_Info); if (check < 0) { printf("NOT FOUND ACCESS CHECK "); set_http_status(HTTP_STATUS_NOT_FOUND); } // get last modified char* last_modified = malloc(32); struct tm * timeinfo; timeinfo = localtime(&file_Info.st_mtim.tv_sec); strftime (last_modified,32,"%a, %d %b %Y %H:%M:%S %Z",timeinfo); sprintf(last_modified_text, "Last-Modified: %s\n", last_modified); //TODO: Dateidatum einfuegen sprintf(content_type_text, "Content-Type: %s\r\n", get_http_content_type_str(get_http_content_type(filename))); range_end = file_Info.st_size; if(range_end < 0) { error("Error with range"); } else { content_length = range_end - range_start; } sprintf(content_length_text, "Content-Length: %i\r\n", content_length); sprintf(content_range_text, "Content-Range: bytes %i-%i/%i\n", range_start, range_end, content_length ); //TODO: Frage was das ist und wie dynamisch abgefragt wird strcat(response_header, status_text); strcat(response_header, date_text); strcat(response_header, server_text); strcat(response_header, accept_range_text); strcat(response_header, last_modified_text); strcat(response_header, content_type_text); strcat(response_header, content_length_text); strcat(response_header, content_range_text); strcat(response_header, connection_text); printf("\n------------Response-----------------\n%s------------Response-----------------\n", response_header); return response_header; }
void child_processing(int newsockfd, struct sockaddr_in cli_addr) { int read_error; int file_to_send = 0; char buffer[BUFFER_SIZE]; char *buffer_for_log; char *ptr; char *p; char *path_to_file_relativ; char *response_header; char str_GET[] = "GET"; char str_HEAD[] = "HEAD"; set_http_status(HTTP_STATUS_OK); //printf("You are in the Childprocess: %d\n", getpid()); bzero(buffer, BUFFER_SIZE); read_error = read(newsockfd, buffer, BUFFER_SIZE - 1); buffer_for_log = buffer; ptr = ""; if(read_error < 0) { error("Error reading from socket"); set_http_status(HTTP_STATUS_INTERNAL_SERVER_ERROR); } path_to_file_relativ = parse_HTTP_msg(buffer); //printf("Path to file relativ: %s\n", path_to_file_relativ); char actualpath [PATH_MAX]; p = strtok(buffer, " "); ptr = realpath(path_to_file_relativ, actualpath); printf("Realpath to File: %s\n", actualpath); printf("Ptr: %s\n", ptr); if(strcmp(p, str_GET) == 0) { if( access( actualpath, F_OK ) == -1 ) { printf("NOT FOUND ACCESS GET "); set_http_status(HTTP_STATUS_NOT_FOUND); } //printf("........test............."); if((file_to_send = open(actualpath, O_RDWR, S_IWRITE | S_IREAD)) < 0) { printf("NOT FOUND FILE TO SEND GET "); set_http_status(HTTP_STATUS_NOT_FOUND); response_header = create_HTTP_response_header(actualpath, buffer); send(newsockfd, response_header, strlen(response_header), 0); error("Error opening file"); } //printf("File to send: %i\n", file_to_send); } if(strcmp(p, str_HEAD) == 0) { struct stat buf; int check; check = stat(actualpath, &buf); if(check < 0) { printf("NOT FOUND ACCESS HEAD "); set_http_status(HTTP_STATUS_NOT_FOUND); } else{ set_http_status(HTTP_STATUS_OK); } } response_header = create_HTTP_response_header(actualpath, buffer); send(newsockfd, response_header, strlen(response_header), 0); if(strcmp(p, str_GET) == 0) { int read_count_bytes = read(file_to_send, buffer, BUFFER_SIZE); int read_count_bytes_for_log = read_count_bytes; while(read_count_bytes > 0) { if(write_to_socket(newsockfd, buffer, read_count_bytes, 1) < 0) { error("Error writing to socket"); set_http_status(HTTP_STATUS_INTERNAL_SERVER_ERROR); } read_count_bytes = read(file_to_send, buffer, BUFFER_SIZE); read_count_bytes_for_log += read_count_bytes; } if(read_count_bytes < 0) { error("Error reading from socket"); set_http_status(HTTP_STATUS_INTERNAL_SERVER_ERROR); } //printf("Here is the message: %.*s\n", read_count_bytes, buffer); if(read_error < 0) { error("Error writing to socket"); set_http_status(HTTP_STATUS_INTERNAL_SERVER_ERROR); } write_to_logfile(cli_addr, path_to_file_relativ, buffer_for_log, read_count_bytes_for_log); } close(newsockfd); }