Check-in [5a054ee091]
Overview
Comment:Updated to support the HEAD HTTP method
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:5a054ee091543db480d8bdf83e8d9f9e91afa864
User & Date: rkeene on 2014-02-11 07:43:06
Original Comment: Updated to support the HEAD HTTP method5~
Other Links: manifest | tags
Context
2014-02-11
08:11
Added ETag check-in: 63a88bc1bc user: rkeene tags: trunk
07:43
Updated to support the HEAD HTTP method check-in: 5a054ee091 user: rkeene tags: trunk
05:53
Removed unneeded assignment check-in: 8cb189c633 user: rkeene tags: trunk
Changes

Modified filed.c from [8c74e1e76e] to [93c05a56c1].

    57     57   /* Request variables */
    58     58   struct filed_http_request {
    59     59   	/** Buffers **/
    60     60   	struct filed_fileinfo fileinfo;
    61     61   	char tmpbuf[1010];
    62     62   
    63     63   	/** HTTP Request information **/
           64  +	/*** Type of request (HEAD or GET) ***/
           65  +	enum {
           66  +		FILED_REQUEST_METHOD_GET,
           67  +		FILED_REQUEST_METHOD_HEAD
           68  +	} method;
           69  +
    64     70   	/*** Path being requested ***/
    65     71   	char path[FILED_PATH_BUFFER_SIZE]; 
    66     72   
    67     73   	struct {
    68     74   		struct {
    69     75   			int present;
    70     76   			off_t offset;   /*** Range start ***/
................................................................................
    99    105   	time_t endtime;
   100    106   	off_t req_offset;
   101    107   	off_t req_length;
   102    108   	off_t sent_length;
   103    109   	off_t file_length;
   104    110   	char ip[128];
   105    111   	int port;
          112  +	int method;
   106    113   };
   107    114   
   108    115   /* Global variables */
   109    116   /** Open File cache **/
   110    117   struct filed_fileinfo *filed_fileinfo_fdcache = NULL;
   111    118   unsigned int filed_fileinfo_fdcache_size = 0;
   112    119   
................................................................................
   243    250   #    define filed_log_msg_debug(x, ...) /**/
   244    251   #  endif
   245    252   
   246    253   /* Initialize logging thread */
   247    254   static void *filed_logging_thread(void *arg_p) {
   248    255   	struct filed_logging_thread_args *arg;
   249    256   	struct filed_log_entry *curr, *prev;
          257  +	const char *method;
   250    258   	time_t now;
   251    259   	FILE *fp;
   252    260   
   253    261   	arg = arg_p;
   254    262   
   255    263   	fp = arg->fp;
   256    264   
................................................................................
   276    284   		while (curr) {
   277    285   			switch (curr->type) {
   278    286   				case FILED_LOG_TYPE_MESSAGE:
   279    287   					fprintf(fp, "%s", curr->buffer);
   280    288   
   281    289   					break;
   282    290   				case FILED_LOG_TYPE_TRANSFER:
          291  +					switch (curr->method) {
          292  +						case FILED_REQUEST_METHOD_GET:
          293  +							method="GET";
          294  +							break;
          295  +						case FILED_REQUEST_METHOD_HEAD:
          296  +							method="HEAD";
          297  +							break;
          298  +						default:
          299  +							method="<unknown>";
          300  +							break;
          301  +					}
          302  +
   283    303   					if (curr->endtime == ((time_t) -1)) {
   284    304   						curr->endtime = now;
   285    305   					}
   286    306   
   287         -					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",
          307  +					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",
          308  +						method,
   288    309   						curr->buffer,
   289    310   						curr->ip, curr->port,
   290    311   						(unsigned long long) curr->starttime,
   291    312   						(unsigned long long) curr->endtime,
   292    313   						curr->http_code, curr->reason,
   293    314   						(unsigned long long) curr->req_offset,
   294    315   						(unsigned long long) curr->req_length,
................................................................................
   341    362   		retval->endtime = 0;
   342    363   		retval->req_offset = 0;
   343    364   		retval->req_length = 0;
   344    365   		retval->sent_length = 0;
   345    366   		retval->file_length = 0;
   346    367   		retval->ip[0] = '\0';
   347    368   		retval->port = -1;
          369  +		retval->method = -1;
   348    370   	}
   349    371   
   350    372   	return(retval);
   351    373   }
   352    374   
   353    375   static void filed_log_msg(const char *fmt, ...) {
   354    376   	struct filed_log_entry *entry;
................................................................................
   592    614   
   593    615   	buffer = strchr(buffer, ' ');
   594    616   	if (buffer != NULL) {
   595    617   		*buffer = '\0';
   596    618   		buffer++;
   597    619   	}
   598    620   
   599         -	/* We only handle the "GET" method */
   600         -	if (strcasecmp(method, "get") != 0) {
   601         -		return(NULL);
          621  +	/* We only handle the "GET" and "HEAD' methods */
          622  +	if (strcasecmp(method, "head") != 0) {
          623  +		if (strcasecmp(method, "get") != 0) {
          624  +			return(NULL);
          625  +		}
          626  +
          627  +		/* GET request */
          628  +		buffer_st->method = FILED_REQUEST_METHOD_GET;
          629  +	} else {
          630  +		/* HEAD request */
          631  +		buffer_st->method = FILED_REQUEST_METHOD_HEAD;
   602    632   	}
   603    633   
   604    634   	/* Note path */
   605    635   	strcpy(buffer_st->path, path);
   606    636   
   607    637   	for (i = 0; i < 100; i++) {
   608    638   		fgets_ret = fgets(buffer, buffer_len, fp);
................................................................................
   657    687   	buffer_st->headers.range.offset  = range_start;
   658    688   	buffer_st->headers.range.length  = range_length;
   659    689   
   660    690   	return(buffer_st);
   661    691   }
   662    692   
   663    693   /* Return an error page */
   664         -static void filed_error_page(FILE *fp, const char *date_current, int error_number) {
          694  +static void filed_error_page(FILE *fp, const char *date_current, int error_number, int method) {
   665    695   	char *error_string = "<html><head><title>ERROR</title></head><body>Unable to process request</body></html>";
   666    696   
   667         -	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",
          697  +	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",
   668    698   		error_number,
   669    699   		date_current,
   670    700   		date_current,
   671    701   		(unsigned long long) strlen(error_string),
   672         -		"text/html",
   673         -		error_string
          702  +		"text/html"
   674    703   	);
          704  +
          705  +	/* silence error string for HEAD requests */
          706  +	if (method != FILED_REQUEST_METHOD_HEAD) {
          707  +		fprintf(fp, "%s", error_string);
          708  +	}
          709  +
          710  +	return;
   675    711   }
   676    712   
   677    713   /* Handle a single request from a client */
   678    714   static void filed_handle_client(int fd, struct filed_http_request *request, struct filed_log_entry *log) {
   679    715   	struct filed_fileinfo *fileinfo;
   680    716   	ssize_t sendfile_ret;
   681    717   	size_t sendfile_size;
................................................................................
   695    731   
   696    732   		return;
   697    733   	}
   698    734   
   699    735   	request = filed_get_http_request(fp, request);
   700    736   
   701    737   	if (request == NULL) {
   702         -		filed_error_page(fp, date_current, 500);
          738  +		filed_error_page(fp, date_current, 500, FILED_REQUEST_METHOD_GET);
   703    739   
   704    740   		log->buffer[0] = '\0';
   705    741   		log->http_code = 500;
   706    742   		log->reason = "format";
   707    743   
   708    744   		filed_log_entry(log);
   709    745   
................................................................................
   715    751   	path = request->path;
   716    752   	strcpy(log->buffer, path);
   717    753   
   718    754   	http_code = -1;
   719    755   
   720    756   	fileinfo = filed_open_file(path, &request->fileinfo);
   721    757   	if (fileinfo == NULL) {
   722         -		filed_error_page(fp, date_current, 404);
          758  +		filed_error_page(fp, date_current, 404, request->method);
   723    759   
   724    760   		log->http_code = 404;
   725    761   		log->reason = "open_failed";
   726    762   
   727    763   		filed_log_entry(log);
   728    764   	} else {
   729    765   		if (request->headers.range.offset != 0 || request->headers.range.length >= 0) {
   730    766   			if (request->headers.range.offset >= fileinfo->len) {
   731         -				filed_error_page(fp, date_current, 416);
          767  +				filed_error_page(fp, date_current, 416, request->method);
   732    768   
   733    769   				log->http_code = 416;
   734    770   				log->reason = "range_invalid";
   735    771   
   736    772   				filed_log_entry(log);
   737    773   			} else {
   738    774   				if (request->headers.range.length == ((off_t) -1)) {
................................................................................
   781    817   
   782    818   			log->http_code = http_code;
   783    819   			log->reason = "OK";
   784    820   			log->starttime = time(NULL);
   785    821   			log->req_offset = request->headers.range.offset;
   786    822   			log->req_length = request->headers.range.length;
   787    823   			log->file_length = fileinfo->len;
          824  +			log->method = request->method;
   788    825   
   789    826   #ifdef FILED_NONBLOCK_HTTP
   790    827   			int socket_flags;
   791    828   			fd_set rfd, wfd;
   792    829   			char sinkbuf[8192];
   793    830   			ssize_t read_ret;
   794    831   
................................................................................
   800    837   			socket_flags = fcntl(fd, F_GETFL);
   801    838   			fcntl(fd, F_SETFL, socket_flags | O_NONBLOCK);
   802    839   #endif
   803    840   
   804    841   			sendfile_offset = request->headers.range.offset;
   805    842   			sendfile_len = request->headers.range.length;
   806    843   			sendfile_sent = 0;
   807         -			while (1) {
          844  +			while (request->method == FILED_REQUEST_METHOD_GET) {
   808    845   				if (sendfile_len > FILED_SENDFILE_MAX) {
   809    846   					sendfile_size = FILED_SENDFILE_MAX;
   810    847   				} else {
   811    848   					sendfile_size = sendfile_len;
   812    849   				}
   813    850   
   814    851   				sendfile_ret = sendfile(fd, fileinfo->fd, &sendfile_offset, sendfile_size);