Browse Source

Must also work for files created 1970-01-01 00:00:00 (see also #152)

bel 10 years ago
parent
commit
96568a7661
1 changed files with 34 additions and 30 deletions
  1. 34 30
      src/civetweb.c

+ 34 - 30
src/civetweb.c

@@ -841,18 +841,17 @@ struct vec {
 };
 };
 
 
 struct file {
 struct file {
-	int is_directory;
-	time_t modification_time;
 	uint64_t size;
 	uint64_t size;
+	time_t last_modified;
 	FILE *fp;
 	FILE *fp;
 	const char *membuf; /* Non-NULL if file data is in memory */
 	const char *membuf; /* Non-NULL if file data is in memory */
-	                    /* set to 1 if the content is gzipped
-	                     * in which case we need a content-encoding: gzip header */
-	int gzipped;
+	int is_directory;
+	int gzipped; /* set to 1 if the content is gzipped
+	              * in which case we need a content-encoding: gzip header */
 };
 };
 #define STRUCT_FILE_INITIALIZER                                                \
 #define STRUCT_FILE_INITIALIZER                                                \
 	{                                                                          \
 	{                                                                          \
-		0, 0, 0, NULL, NULL, 0                                                 \
+		(uint64_t)0, (time_t)0, (FILE *)NULL, (const char *)NULL, 0, 0         \
 	}
 	}
 
 
 /* Describes listening socket, or socket which was accept()-ed by the master
 /* Describes listening socket, or socket which was accept()-ed by the master
@@ -1233,7 +1232,7 @@ static int is_file_in_memory(struct mg_connection *conn,
 		return 0;
 		return 0;
 	}
 	}
 
 
-	filep->modification_time = (time_t)0;
+	filep->last_modified = (time_t)0;
 
 
 	if ((filep->membuf =
 	if ((filep->membuf =
 	         conn->ctx->callbacks.open_file == NULL
 	         conn->ctx->callbacks.open_file == NULL
@@ -2402,7 +2401,7 @@ mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
 	to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
 	to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
 	if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
 	if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
 		filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
 		filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
-		filep->modification_time =
+		filep->last_modified =
 		    SYS2UNIX_TIME(info.ftLastWriteTime.dwLowDateTime,
 		    SYS2UNIX_TIME(info.ftLastWriteTime.dwLowDateTime,
 		                  info.ftLastWriteTime.dwHighDateTime);
 		                  info.ftLastWriteTime.dwHighDateTime);
 
 
@@ -2412,8 +2411,8 @@ mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
 		 * it should be based on the most recent timestamp. */
 		 * it should be based on the most recent timestamp. */
 		creation_time = SYS2UNIX_TIME(info.ftCreationTime.dwLowDateTime,
 		creation_time = SYS2UNIX_TIME(info.ftCreationTime.dwLowDateTime,
 		                              info.ftCreationTime.dwHighDateTime);
 		                              info.ftCreationTime.dwHighDateTime);
-		if (creation_time > filep->modification_time) {
-			filep->modification_time = creation_time;
+		if (creation_time > filep->last_modified) {
+			filep->last_modified = creation_time;
 		}
 		}
 
 
 		filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
 		filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
@@ -2795,7 +2794,7 @@ mg_stat(struct mg_connection *conn, const char *path, struct file *filep)
 
 
 	if (0 == stat(path, &st)) {
 	if (0 == stat(path, &st)) {
 		filep->size = (uint64_t)(st.st_size);
 		filep->size = (uint64_t)(st.st_size);
-		filep->modification_time = st.st_mtime;
+		filep->last_modified = st.st_mtime;
 		filep->is_directory = S_ISDIR(st.st_mode);
 		filep->is_directory = S_ISDIR(st.st_mode);
 		return 1;
 		return 1;
 	}
 	}
@@ -3752,6 +3751,7 @@ interpret_uri(struct mg_connection *conn,   /* in: request */
               char *filename,               /* out: filename */
               char *filename,               /* out: filename */
               size_t filename_buf_len,      /* in: size of filename buffer */
               size_t filename_buf_len,      /* in: size of filename buffer */
               struct file *filep,           /* out: file structure */
               struct file *filep,           /* out: file structure */
+              int *is_found,                /* out: file is found (directly) */
               int *is_script_ressource,     /* out: handled by a script? */
               int *is_script_ressource,     /* out: handled by a script? */
               int *is_websocket_request,    /* out: websocket connetion? */
               int *is_websocket_request,    /* out: websocket connetion? */
               int *is_put_or_delete_request /* out: put/delete a file? */
               int *is_put_or_delete_request /* out: put/delete a file? */
@@ -3772,6 +3772,7 @@ interpret_uri(struct mg_connection *conn,   /* in: request */
 
 
 		memset(filep, 0, sizeof(*filep));
 		memset(filep, 0, sizeof(*filep));
 		*filename = 0;
 		*filename = 0;
+		*is_found = 0;
 		*is_script_ressource = 0;
 		*is_script_ressource = 0;
 		*is_put_or_delete_request = is_put_or_delete_method(conn);
 		*is_put_or_delete_request = is_put_or_delete_method(conn);
 
 
@@ -3843,6 +3844,7 @@ interpret_uri(struct mg_connection *conn,   /* in: request */
 				 * generated response. */
 				 * generated response. */
 				*is_script_ressource = !*is_put_or_delete_request;
 				*is_script_ressource = !*is_put_or_delete_request;
 			}
 			}
+			*is_found = 1;
 			return;
 			return;
 		}
 		}
 
 
@@ -4917,7 +4919,7 @@ static void print_dir_entry(struct de *de)
 			            (double)de->file.size / 1073741824);
 			            (double)de->file.size / 1073741824);
 		}
 		}
 	}
 	}
-	tm = localtime(&de->file.modification_time);
+	tm = localtime(&de->file.last_modified);
 	if (tm != NULL) {
 	if (tm != NULL) {
 		strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", tm);
 		strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", tm);
 	} else {
 	} else {
@@ -4965,11 +4967,10 @@ static int WINCDECL compare_dir_entries(const void *p1, const void *p2)
 			                 : a->file.size > b->file.size ? 1 : -1;
 			                 : a->file.size > b->file.size ? 1 : -1;
 		} else if (*query_string == 'd') {
 		} else if (*query_string == 'd') {
 			cmp_result =
 			cmp_result =
-			    a->file.modification_time == b->file.modification_time
+			    (a->file.last_modified == b->file.last_modified)
 			        ? 0
 			        ? 0
-			        : a->file.modification_time > b->file.modification_time
-			              ? 1
-			              : -1;
+			        : ((a->file.last_modified > b->file.last_modified) ? 1
+			                                                           : -1);
 		}
 		}
 
 
 		return query_string[1] == 'd' ? -cmp_result : cmp_result;
 		return query_string[1] == 'd' ? -cmp_result : cmp_result;
@@ -5071,7 +5072,8 @@ static int remove_directory(struct mg_connection *conn, const char *dir)
 				       path,
 				       path,
 				       strerror(ERRNO));
 				       strerror(ERRNO));
 			}
 			}
-			if (de.file.modification_time) {
+			if (de.file.membuf == NULL) {
+				/* file is not in memory */
 				if (de.file.is_directory) {
 				if (de.file.is_directory) {
 					remove_directory(conn, path);
 					remove_directory(conn, path);
 				} else {
 				} else {
@@ -5267,7 +5269,7 @@ static void construct_etag(char *buf, size_t buf_len, const struct file *filep)
 		snprintf(buf,
 		snprintf(buf,
 		         buf_len,
 		         buf_len,
 		         "\"%lx.%" INT64_FMT "\"",
 		         "\"%lx.%" INT64_FMT "\"",
-		         (unsigned long)filep->modification_time,
+		         (unsigned long)filep->last_modified,
 		         filep->size);
 		         filep->size);
 	}
 	}
 }
 }
@@ -5382,7 +5384,7 @@ static void handle_static_file_request(struct mg_connection *conn,
 	/* Prepare Etag, Date, Last-Modified headers. Must be in UTC, according to
 	/* Prepare Etag, Date, Last-Modified headers. Must be in UTC, according to
 	 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3 */
 	 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3 */
 	gmt_time_string(date, sizeof(date), &curtime);
 	gmt_time_string(date, sizeof(date), &curtime);
-	gmt_time_string(lm, sizeof(lm), &filep->modification_time);
+	gmt_time_string(lm, sizeof(lm), &filep->last_modified);
 	construct_etag(etag, sizeof(etag), filep);
 	construct_etag(etag, sizeof(etag), filep);
 
 
 	(void)mg_printf(conn,
 	(void)mg_printf(conn,
@@ -5630,7 +5632,7 @@ static int is_not_modified(const struct mg_connection *conn,
 		return 0;
 		return 0;
 	}
 	}
 	return (inm != NULL && !mg_strcasecmp(etag, inm)) ||
 	return (inm != NULL && !mg_strcasecmp(etag, inm)) ||
-	       (ims != NULL && filep->modification_time <= parse_date_string(ims));
+	       (ims != NULL && (filep->last_modified <= parse_date_string(ims)));
 }
 }
 
 
 static int
 static int
@@ -6188,7 +6190,8 @@ static void mkcol(struct mg_connection *conn, const char *path)
 		       strerror(ERRNO));
 		       strerror(ERRNO));
 	}
 	}
 
 
-	if (de.file.modification_time) {
+	if (de.file.last_modified) {
+		/* TODO (high): This check does not seem to make any sense ! */
 		send_http_error(
 		send_http_error(
 		    conn, 405, "Error: mkcol(%s): %s", path, strerror(ERRNO));
 		    conn, 405, "Error: mkcol(%s): %s", path, strerror(ERRNO));
 		return;
 		return;
@@ -6254,7 +6257,7 @@ static void put_file(struct mg_connection *conn, const char *path)
 			/* File exists and is not a directory. */
 			/* File exists and is not a directory. */
 			/* Can it be replaced? */
 			/* Can it be replaced? */
 
 
-			if (file.modification_time == 0) {
+			if (file.membuf != NULL) {
 				/* This is an "in-memory" file, that can not be replaced */
 				/* This is an "in-memory" file, that can not be replaced */
 				send_http_error(
 				send_http_error(
 				    conn,
 				    conn,
@@ -6373,9 +6376,8 @@ static void delete_file(struct mg_connection *conn, const char *path)
 		return;
 		return;
 	}
 	}
 
 
-	if (de.file.modification_time == 0) {
-		/* mg_stat returns != 0 and modification_time == 0
-		 * if the file is cached in memory */
+	if (de.file.membuf != NULL) {
+		/* the file is cached in memory */
 		send_http_error(
 		send_http_error(
 		    conn,
 		    conn,
 		    405,
 		    405,
@@ -6678,7 +6680,7 @@ print_props(struct mg_connection *conn, const char *uri, struct file *filep)
 		return;
 		return;
 	}
 	}
 
 
-	gmt_time_string(mtime, sizeof(mtime), &filep->modification_time);
+	gmt_time_string(mtime, sizeof(mtime), &filep->last_modified);
 	conn->num_bytes_sent +=
 	conn->num_bytes_sent +=
 	    mg_printf(conn,
 	    mg_printf(conn,
 	              "<d:response>"
 	              "<d:response>"
@@ -7936,8 +7938,9 @@ static void handle_request(struct mg_connection *conn)
 	if (conn) {
 	if (conn) {
 		struct mg_request_info *ri = &conn->request_info;
 		struct mg_request_info *ri = &conn->request_info;
 		char path[PATH_MAX];
 		char path[PATH_MAX];
-		int uri_len, ssl_index, is_script_resource, is_websocket_request,
-		    is_put_or_delete_request, is_callback_resource;
+		int uri_len, ssl_index, is_found, is_script_resource,
+		    is_websocket_request, is_put_or_delete_request,
+		    is_callback_resource;
 		int i;
 		int i;
 		struct file file = STRUCT_FILE_INITIALIZER;
 		struct file file = STRUCT_FILE_INITIALIZER;
 		time_t curtime = time(NULL);
 		time_t curtime = time(NULL);
@@ -8049,6 +8052,7 @@ static void handle_request(struct mg_connection *conn)
 			              path,
 			              path,
 			              sizeof(path),
 			              sizeof(path),
 			              &file,
 			              &file,
+			              &is_found,
 			              &is_script_resource,
 			              &is_script_resource,
 			              &is_websocket_request,
 			              &is_websocket_request,
 			              &is_put_or_delete_request);
 			              &is_put_or_delete_request);
@@ -8108,6 +8112,7 @@ static void handle_request(struct mg_connection *conn)
 					              path,
 					              path,
 					              sizeof(path),
 					              sizeof(path),
 					              &file,
 					              &file,
+					              &is_found,
 					              &is_script_resource,
 					              &is_script_resource,
 					              &is_websocket_request,
 					              &is_websocket_request,
 					              &is_put_or_delete_request);
 					              &is_put_or_delete_request);
@@ -8197,8 +8202,7 @@ static void handle_request(struct mg_connection *conn)
 
 
 		/* 11. File does not exist, or it was configured that it should be
 		/* 11. File does not exist, or it was configured that it should be
 		 * hidden */
 		 * hidden */
-		if (((file.membuf == NULL) && (file.modification_time == (time_t)0)) ||
-		    (must_hide_file(conn, path))) {
+		if (!is_found || (must_hide_file(conn, path))) {
 			send_http_error(conn, 404, "%s", "Not found");
 			send_http_error(conn, 404, "%s", "Not found");
 			return;
 			return;
 		}
 		}