DateInterval::DateInterval(const String& date_interval, bool date_string /*= false */) { if (date_string) { setDateString(date_interval); } else { setInterval(date_interval); } }
/* This is a wrapped version of the child web server thread */ static void __http_server(struct kqueue *q, struct http_connection *c, struct http_request *r) { struct stat statbuf; int j, file_fd, buflen; long i = 0, ret = 0; char *fstr; char *request_line; char *saveptr; char now[RFC1123_TIME_LEN + 1]; char mod[RFC1123_TIME_LEN + 1]; /* Try and extract a request from the connection. */ ret = extract_request(c, r); /* If there was an error, just destroy the connection, as there is * nothing more we can do with this connection anyway. */ if(ret < 0) { logger(LOG, "Connection reset by peer.", "", c->conn.id); maybe_destroy_connection(q, c); return; } /* If there was no error, but we weren't able to extract a request, finish up * if we are the last one to look at the connection. */ if(ret == 0) { maybe_destroy_connection(q, c); return; } /* Otherwise, just reenqueue the connection so another thread can grab the * next request and start processing it. */ if (!c->should_close) { if(c->burst_length) { c->burst_length--; enqueue_connection_head(q, c); } else { c->burst_length = MAX_BURST; enqueue_connection_tail(q, c); } } /* Attempt to intercept the request and do something special with it. */ struct intercept_buf ib; if (intercept_request(&ib, r)) { /* Send the necessary header info + a blank line */ logger(LOG, "INTERCEPT URL", &request_line[4], c->conn.id); setDateString(NULL, now); setDateString(NULL, mod); sprintf(r->buf, page_data[OK_HEADER], VERSION, now, ib.mime_type, ib.size, mod); serialized_write(c, r->buf, strlen(r->buf)); serialized_write(c, ib.buf, ib.size); free(ib.buf); maybe_destroy_connection(q, c); return; } /* If not intercepted, parse through the extracted request, grabbing only the * first line. */ request_line = strtok_r(r->buf, "\r\n", &saveptr); if (!request_line) { logger(LOG, "Unterminated request buffer.", "", c->conn.id); maybe_destroy_connection(q, c); return; } /* Make sure it's a GET operation */ if(strncmp(request_line, "GET ", 4) && strncmp(request_line, "get ", 4)) { logger(FORBIDDEN, "Only simple GET operation supported", request_line, c->socketfd); serialized_write(c, page_data[FORBIDDEN_PAGE], strlen(page_data[FORBIDDEN_PAGE])); maybe_destroy_connection(q, c); return; } logger(LOG, "Request", request_line, c->conn.id); /* Strip the version info from the request_line */ for(i=4; i<strlen(request_line); i++) { /* String is "GET URL?<query_data> HTTP_VERSION" */ if(request_line[i] == ' ') { request_line[i] = '\0'; break; } } /* Strip all query data from the request_line */ for(i=4; i<strlen(request_line); i++) { /* String is "GET URL?<query_data>" */ if(request_line[i] == '?') { request_line[i] = '\0'; break; } } /* Otherwise, check for illegal parent directory use .. */ for(j=4; j<i-1; j++) { if(request_line[j] == '.' && request_line[j+1] == '.') { logger(FORBIDDEN, "Parent directory (..) path names not supported", request_line, c->socketfd); serialized_write(c, page_data[FORBIDDEN_PAGE], strlen(page_data[FORBIDDEN_PAGE])); maybe_destroy_connection(q, c); return; } } /* Convert no filename to index file */ if(!strncmp(request_line, "GET /\0", 6) || !strncmp(request_line, "get /\0", 6)) strcpy(request_line, "GET /index.html"); /* Work out the file type and check we support it */ buflen=strlen(request_line); fstr = 0; for(i=0; extensions[i].ext != 0; i++) { int len = strlen(extensions[i].ext); if(!strncmp(&request_line[buflen-len], extensions[i].ext, len)) { fstr =extensions[i].filetype; break; } } if(fstr == 0) { logger(FORBIDDEN, "File extension type not supported", request_line, c->socketfd); serialized_write(c, page_data[FORBIDDEN_PAGE], strlen(page_data[FORBIDDEN_PAGE])); maybe_destroy_connection(q, c); return; } /* Open the file for reading */ if((file_fd = open(&request_line[5], O_RDONLY)) == -1) { logger(NOTFOUND, "Failed to open file", &request_line[5], c->socketfd); serialized_write(c, page_data[NOTFOUND_PAGE], strlen(page_data[NOTFOUND_PAGE])); maybe_destroy_connection(q, c); return; } /* Get the File Stats */ fstat(file_fd, &statbuf); /* Prepopulate the request buf with the beginning of the requested file */ ret = read(file_fd, r->buf, sizeof(r->buf)); if (ret < 0) { logger(ERROR, "Failed to read file", "...", 0); close(file_fd); maybe_destroy_connection(q, c); return; } /* Prepare the header info + a blank line */ setDateString(NULL, now); setDateString(&statbuf.st_mtime, mod); sprintf(r->rsp_header, page_data[OK_HEADER], VERSION, now, fstr, statbuf.st_size, mod); logger(LOG, "Header", r->rsp_header, c->conn.id); /* Start sending a response */ logger(LOG, "SEND", &request_line[5], c->conn.id); tpool_inform_blocking(&tpool); mutex_lock(&c->writelock); tpool_inform_unblocked(&tpool); timed_write(c, r->rsp_header, strlen(r->rsp_header)); /* Send the file itself in 8KB chunks - last block may be smaller */ do { if(timed_write(c, r->buf, ret) < 0) logger(LOG, "Write error on socket.", "", c->socketfd); } while((ret = read(file_fd, r->buf, sizeof(r->buf))) > 0); mutex_unlock(&c->writelock); close(file_fd); maybe_destroy_connection(q, c); }