@@ -59,10 +59,16 @@ /** Buffers **/ struct filed_fileinfo fileinfo; char tmpbuf[1010]; /** HTTP Request information **/ + /*** Type of request (HEAD or GET) ***/ + enum { + FILED_REQUEST_METHOD_GET, + FILED_REQUEST_METHOD_HEAD + } method; + /*** Path being requested ***/ char path[FILED_PATH_BUFFER_SIZE]; struct { struct { @@ -101,10 +107,11 @@ off_t req_length; off_t sent_length; off_t file_length; char ip[128]; int port; + int method; }; /* Global variables */ /** Open File cache **/ struct filed_fileinfo *filed_fileinfo_fdcache = NULL; @@ -245,10 +252,11 @@ /* Initialize logging thread */ static void *filed_logging_thread(void *arg_p) { struct filed_logging_thread_args *arg; struct filed_log_entry *curr, *prev; + const char *method; time_t now; FILE *fp; arg = arg_p; @@ -278,15 +286,28 @@ case FILED_LOG_TYPE_MESSAGE: fprintf(fp, "%s", curr->buffer); break; case FILED_LOG_TYPE_TRANSFER: + switch (curr->method) { + case FILED_REQUEST_METHOD_GET: + method="GET"; + break; + case FILED_REQUEST_METHOD_HEAD: + method="HEAD"; + break; + default: + method=""; + break; + } + if (curr->endtime == ((time_t) -1)) { curr->endtime = now; } - fprintf(fp, "TRANSFER PATH=%s SRC=%s:%i TIME.START=%llu TIME.END=%llu CODE.VALUE=%u CODE.REASON=%s REQUEST.OFFSET=%llu REQUEST.LENGTH=%llu FILE.LENGTH=%llu TRANSFER.LENGTH=%llu", + fprintf(fp, "TRANSFER METHOD=%s PATH=%s SRC=%s:%i TIME.START=%llu TIME.END=%llu CODE.VALUE=%u CODE.REASON=%s REQUEST.OFFSET=%llu REQUEST.LENGTH=%llu FILE.LENGTH=%llu TRANSFER.LENGTH=%llu", + method, curr->buffer, curr->ip, curr->port, (unsigned long long) curr->starttime, (unsigned long long) curr->endtime, curr->http_code, curr->reason, @@ -343,10 +364,11 @@ retval->req_length = 0; retval->sent_length = 0; retval->file_length = 0; retval->ip[0] = '\0'; retval->port = -1; + retval->method = -1; } return(retval); } @@ -594,13 +616,21 @@ if (buffer != NULL) { *buffer = '\0'; buffer++; } - /* We only handle the "GET" method */ - if (strcasecmp(method, "get") != 0) { - return(NULL); + /* We only handle the "GET" and "HEAD' methods */ + if (strcasecmp(method, "head") != 0) { + if (strcasecmp(method, "get") != 0) { + return(NULL); + } + + /* GET request */ + buffer_st->method = FILED_REQUEST_METHOD_GET; + } else { + /* HEAD request */ + buffer_st->method = FILED_REQUEST_METHOD_HEAD; } /* Note path */ strcpy(buffer_st->path, path); @@ -659,21 +689,27 @@ return(buffer_st); } /* Return an error page */ -static void filed_error_page(FILE *fp, const char *date_current, int error_number) { +static void filed_error_page(FILE *fp, const char *date_current, int error_number, int method) { char *error_string = "ERRORUnable to process request"; - fprintf(fp, "HTTP/1.1 %i Not OK\r\nDate: %s\r\nServer: filed\r\nLast-Modified: %s\r\nContent-Length: %llu\r\nContent-Type: %s\r\nConnection: close\r\n\r\n%s", + fprintf(fp, "HTTP/1.1 %i Not OK\r\nDate: %s\r\nServer: filed\r\nLast-Modified: %s\r\nContent-Length: %llu\r\nContent-Type: %s\r\nConnection: close\r\n\r\n", error_number, date_current, date_current, (unsigned long long) strlen(error_string), - "text/html", - error_string + "text/html" ); + + /* silence error string for HEAD requests */ + if (method != FILED_REQUEST_METHOD_HEAD) { + fprintf(fp, "%s", error_string); + } + + return; } /* Handle a single request from a client */ static void filed_handle_client(int fd, struct filed_http_request *request, struct filed_log_entry *log) { struct filed_fileinfo *fileinfo; @@ -697,11 +733,11 @@ } request = filed_get_http_request(fp, request); if (request == NULL) { - filed_error_page(fp, date_current, 500); + filed_error_page(fp, date_current, 500, FILED_REQUEST_METHOD_GET); log->buffer[0] = '\0'; log->http_code = 500; log->reason = "format"; @@ -717,20 +753,20 @@ http_code = -1; fileinfo = filed_open_file(path, &request->fileinfo); if (fileinfo == NULL) { - filed_error_page(fp, date_current, 404); + filed_error_page(fp, date_current, 404, request->method); log->http_code = 404; log->reason = "open_failed"; filed_log_entry(log); } else { if (request->headers.range.offset != 0 || request->headers.range.length >= 0) { if (request->headers.range.offset >= fileinfo->len) { - filed_error_page(fp, date_current, 416); + filed_error_page(fp, date_current, 416, request->method); log->http_code = 416; log->reason = "range_invalid"; filed_log_entry(log); @@ -783,10 +819,11 @@ log->reason = "OK"; log->starttime = time(NULL); log->req_offset = request->headers.range.offset; log->req_length = request->headers.range.length; log->file_length = fileinfo->len; + log->method = request->method; #ifdef FILED_NONBLOCK_HTTP int socket_flags; fd_set rfd, wfd; char sinkbuf[8192]; @@ -802,11 +839,11 @@ #endif sendfile_offset = request->headers.range.offset; sendfile_len = request->headers.range.length; sendfile_sent = 0; - while (1) { + while (request->method == FILED_REQUEST_METHOD_GET) { if (sendfile_len > FILED_SENDFILE_MAX) { sendfile_size = FILED_SENDFILE_MAX; } else { sendfile_size = sendfile_len; }