Browse Source

Intermediate commit for #246 (does not build)

bel 8 years ago
parent
commit
bd9eeaf6a9
5 changed files with 68 additions and 72 deletions
  1. 1 0
      VisualStudio/civetweb_lua/civetweb_lua.vcxproj
  2. 1 1
      include/civetweb.h
  3. 27 32
      src/civetweb.c
  4. 36 36
      src/handle_form.inl
  5. 3 3
      src/mod_lua.inl

+ 1 - 0
VisualStudio/civetweb_lua/civetweb_lua.vcxproj

@@ -206,6 +206,7 @@
     <None Include="..\..\src\mod_duktape.inl" />
     <None Include="..\..\src\mod_lua.inl" />
     <None Include="..\..\src\timer.inl" />
+    <None Include="..\..\src\file_ops.inl" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 1 - 1
include/civetweb.h

@@ -176,7 +176,7 @@ struct mg_callbacks {
 	   mg_set_websocket_handler instead. */
 	void (*connection_close)(const struct mg_connection *);
 
-#if 0 /* This interface is a part of the problem causing #246 and others.
+#if 0 /* This interface is a part of the problem causing #246 and others.      \
          It will be replaced. */
 
 	/* Called when civetweb tries to open a file. Used to intercept file open

+ 27 - 32
src/civetweb.c

@@ -399,15 +399,8 @@ static void path_to_unicode(const struct mg_connection *conn,
                             wchar_t *wbuf,
                             size_t wbuf_len);
 
-/* We use a special file struct to access files on disk and in
- * memory, and store all required file properties there as well. */
-struct mg_file;
-struct mg_file_stat;
-struct mg_file_access;
-
-static const char *
-mg_fgets(char *buf, size_t size, struct mg_file *fileacc, char **p);
-
+/* All file operations need to be rewritten to solve #246. */
+#include "file_ops.inl"
 
 #if defined(HAVE_STDINT)
 #include <stdint.h>
@@ -1303,12 +1296,13 @@ struct mg_file_stat {
 	int is_directory; /* Set to 1 if mg_stat is called for a directory */
 	int is_gzipped;   /* Set to 1 if the content is gzipped, in which
 	                   * case we need a "Content-Eencoding: gzip" header */
+	int location;     /* 0 = nowhere, 1 = on disk, 2 = in memory */
 };
 
 struct mg_file_access {
-	/* File properties filled by mg_fopen or open_file_in_memory: */
+	/* File properties filled by mg_fopen: */
 	FILE *fp;
-	const char *membuf; /* Non-NULL if file data is in memory */
+	const char *membuf;
 };
 
 struct mg_file {
@@ -1318,7 +1312,7 @@ struct mg_file {
 
 #define STRUCT_FILE_INITIALIZER                                                \
 	{                                                                          \
-		(uint64_t)0, (time_t)0, 0, 0, (FILE *)NULL, (const char *)NULL         \
+		(uint64_t)0, (time_t)0, 0, 0, 0, (FILE *)NULL, (const char *)NULL      \
 	}
 
 /* Describes listening socket, or socket which was accept()-ed by the master
@@ -3889,7 +3883,7 @@ spawn_process(struct mg_connection *conn,
 		if (mg_fopen(conn, cmdline, "r", &file)) {
 			p = (char *)file.access.membuf;
 			mg_fgets(buf, sizeof(buf), &file, &p);
-			mg_fclose(&file);
+			mg_fclose(&file.access);
 			buf[sizeof(buf) - 1] = '\0';
 		}
 
@@ -8600,7 +8594,7 @@ put_file(struct mg_connection *conn, const char *path)
 	          date,
 	          suggest_connection_header(conn));
 
-	mg_fclose(&file);
+	mg_fclose(&file.access);
 }
 
 
@@ -8618,7 +8612,7 @@ delete_file(struct mg_connection *conn, const char *path)
 		return;
 	}
 
-	if (de.file.membuf != NULL) {
+	if (de.access.membuf != NULL) {
 		/* the file is cached in memory */
 		send_http_error(
 		    conn,
@@ -8903,7 +8897,7 @@ handle_ssi_file_request(struct mg_connection *conn,
 	} else {
 		conn->must_close = 1;
 		gmt_time_string(date, sizeof(date), &curtime);
-		fclose_on_exec(filep.access, conn);
+		fclose_on_exec(&filep->access, conn);
 		mg_printf(conn, "HTTP/1.1 200 OK\r\n");
 		send_no_cache_header(conn);
 		mg_printf(conn,
@@ -10600,7 +10594,7 @@ handle_request(struct mg_connection *conn)
 			interpret_uri(conn,
 			              path,
 			              sizeof(path),
-			              &file,
+			              &file.stat,
 			              &is_found,
 			              &is_script_resource,
 			              &is_websocket_request,
@@ -10683,7 +10677,7 @@ handle_request(struct mg_connection *conn)
 					interpret_uri(conn,
 					              path,
 					              sizeof(path),
-					              &file,
+					              &file.stat,
 					              &is_found,
 					              &is_script_resource,
 					              &is_websocket_request,
@@ -10799,7 +10793,7 @@ handle_request(struct mg_connection *conn)
 		}
 
 		/* 12. Directory uris should end with a slash */
-		if (file.is_directory && (uri_len > 0)
+		if (file.stat.is_directory && (uri_len > 0)
 		    && (ri->local_uri[uri_len - 1] != '/')) {
 			gmt_time_string(date, sizeof(date), &curtime);
 			mg_printf(conn,
@@ -10818,7 +10812,7 @@ handle_request(struct mg_connection *conn)
 		/* 13. Handle other methods than GET/HEAD */
 		/* 13.1. Handle PROPFIND */
 		if (!strcmp(ri->request_method, "PROPFIND")) {
-			handle_propfind(conn, path, &file);
+			handle_propfind(conn, path, &file.stat);
 			return;
 		}
 		/* 13.2. Handle OPTIONS for files */
@@ -10842,7 +10836,7 @@ handle_request(struct mg_connection *conn)
 		}
 
 		/* 14. directories */
-		if (file.is_directory) {
+		if (file.stat.is_directory) {
 			if (substitute_index_file(conn, path, sizeof(path), &file)) {
 				/* 14.1. use a substitute file */
 				/* TODO (high): substitute index may be a script resource.
@@ -10923,7 +10917,8 @@ handle_file_based_request(struct mg_connection *conn,
 	                        path) > 0) {
 		handle_ssi_file_request(conn, path, file);
 #if !defined(NO_CACHING)
-	} else if ((!conn->in_error_handler) && is_not_modified(conn, file)) {
+	} else if ((!conn->in_error_handler)
+	           && is_not_modified(conn, &file->stat)) {
 		/* Send 304 "Not Modified" - this must not send any body data */
 		handle_not_modified_static_file_request(conn, file);
 #endif /* !NO_CACHING */
@@ -11321,15 +11316,15 @@ log_access(const struct mg_connection *conn)
 	if (conn->ctx->config[ACCESS_LOG_FILE] != NULL) {
 		if (mg_fopen(conn, conn->ctx->config[ACCESS_LOG_FILE], "a+", &fi)
 		    == 0) {
-			fi.fp = NULL;
+			fi.access.fp = NULL;
 		}
 	} else {
-		fi.fp = NULL;
+		fi.access.fp = NULL;
 	}
 
 	/* Log is written to a file and/or a callback. If both are not set,
 	 * executing the rest of the function is pointless. */
-	if ((fi.fp == NULL) && (conn->ctx->callbacks.log_access == NULL)) {
+	if ((fi.access.fp == NULL) && (conn->ctx->callbacks.log_access == NULL)) {
 		return;
 	}
 
@@ -11369,12 +11364,12 @@ log_access(const struct mg_connection *conn)
 		conn->ctx->callbacks.log_access(conn, buf);
 	}
 
-	if (fi.fp) {
-		flockfile(fi.fp);
-		fprintf(fi.fp, "%s\n", buf);
-		fflush(fi.fp);
-		funlockfile(fi.fp);
-		mg_fclose(&fi);
+	if (fi.access.fp) {
+		flockfile(fi.access.fp);
+		fprintf(fi.access.fp, "%s\n", buf);
+		fflush(fi.access.fp);
+		funlockfile(fi.access.fp);
+		mg_fclose(&fi.access);
 	}
 }
 
@@ -12153,7 +12148,7 @@ set_gpass_option(struct mg_context *ctx)
 	if (ctx) {
 		struct mg_file file = STRUCT_FILE_INITIALIZER;
 		const char *path = ctx->config[GLOBAL_PASSWORDS_FILE];
-		if (path != NULL && !mg_stat(fc(ctx), path, &file)) {
+		if (path != NULL && !mg_stat(fc(ctx), path, &file.stat)) {
 			mg_cry(fc(ctx), "Cannot open %s: %s", path, strerror(ERRNO));
 			return 0;
 		}

+ 36 - 36
src/handle_form.inl

@@ -270,25 +270,25 @@ mg_handle_form_request(struct mg_connection *conn,
 			if (field_storage == FORM_FIELD_STORAGE_STORE) {
 				/* Store the content to a file */
 				if (mg_fopen(conn, path, "wb", &fstore) == 0) {
-					fstore.fp = NULL;
+					fstore.access.fp = NULL;
 				}
 				file_size = 0;
-				if (fstore.fp != NULL) {
-					size_t n =
-					    (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp);
-					if ((n != (size_t)vallen) || (ferror(fstore.fp))) {
+				if (fstore.access.fp != NULL) {
+					size_t n = (size_t)
+					    fwrite(val, 1, (size_t)vallen, fstore.access.fp);
+					if ((n != (size_t)vallen) || (ferror(fstore.access.fp))) {
 						mg_cry(conn,
 						       "%s: Cannot write file %s",
 						       __func__,
 						       path);
-						fclose(fstore.fp);
-						fstore.fp = NULL;
+						fclose(fstore.access.fp);
+						fstore.access.fp = NULL;
 						remove_bad_file(conn, path);
 					}
 					file_size += (int64_t)n;
 
-					if (fstore.fp) {
-						r = fclose(fstore.fp);
+					if (fstore.access.fp) {
+						r = fclose(fstore.access.fp);
 						if (r == 0) {
 							/* stored successfully */
 							field_stored(conn, path, file_size, fdh);
@@ -299,7 +299,7 @@ mg_handle_form_request(struct mg_connection *conn,
 							       path);
 							remove_bad_file(conn, path);
 						}
-						fstore.fp = NULL;
+						fstore.access.fp = NULL;
 					}
 
 				} else {
@@ -406,10 +406,10 @@ mg_handle_form_request(struct mg_connection *conn,
 
 			if (field_storage == FORM_FIELD_STORAGE_STORE) {
 				if (mg_fopen(conn, path, "wb", &fstore) == 0) {
-					fstore.fp = NULL;
+					fstore.access.fp = NULL;
 				}
 				file_size = 0;
-				if (!fstore.fp) {
+				if (!fstore.access.fp) {
 					mg_cry(conn, "%s: Cannot create file %s", __func__, path);
 				}
 			}
@@ -446,16 +446,16 @@ mg_handle_form_request(struct mg_connection *conn,
 					                      fdh);
 					get_block++;
 				}
-				if (fstore.fp) {
-					size_t n =
-					    (size_t)fwrite(val, 1, (size_t)vallen, fstore.fp);
-					if ((n != (size_t)vallen) || (ferror(fstore.fp))) {
+				if (fstore.access.fp) {
+					size_t n = (size_t)
+					    fwrite(val, 1, (size_t)vallen, fstore.access.fp);
+					if ((n != (size_t)vallen) || (ferror(fstore.access.fp))) {
 						mg_cry(conn,
 						       "%s: Cannot write file %s",
 						       __func__,
 						       path);
-						fclose(fstore.fp);
-						fstore.fp = NULL;
+						fclose(fstore.access.fp);
+						fstore.access.fp = NULL;
 						remove_bad_file(conn, path);
 					}
 					file_size += (int64_t)n;
@@ -494,8 +494,8 @@ mg_handle_form_request(struct mg_connection *conn,
 
 			} while (!end_of_key_value_pair_found);
 
-			if (fstore.fp) {
-				r = fclose(fstore.fp);
+			if (fstore.access.fp) {
+				r = fclose(fstore.access.fp);
 				if (r == 0) {
 					/* stored successfully */
 					field_stored(conn, path, file_size, fdh);
@@ -503,7 +503,7 @@ mg_handle_form_request(struct mg_connection *conn,
 					mg_cry(conn, "%s: Error saving file %s", __func__, path);
 					remove_bad_file(conn, path);
 				}
-				fstore.fp = NULL;
+				fstore.access.fp = NULL;
 			}
 
 			/* Proceed to next entry */
@@ -673,11 +673,11 @@ mg_handle_form_request(struct mg_connection *conn,
 			if (field_storage == FORM_FIELD_STORAGE_STORE) {
 				/* Store the content to a file */
 				if (mg_fopen(conn, path, "wb", &fstore) == 0) {
-					fstore.fp = NULL;
+					fstore.access.fp = NULL;
 				}
 				file_size = 0;
 
-				if (!fstore.fp) {
+				if (!fstore.access.fp) {
 					mg_cry(conn, "%s: Cannot create file %s", __func__, path);
 				}
 			}
@@ -705,17 +705,17 @@ mg_handle_form_request(struct mg_connection *conn,
 				}
 
 				if (field_storage == FORM_FIELD_STORAGE_STORE) {
-					if (fstore.fp) {
+					if (fstore.access.fp) {
 
 						/* Store the content of the buffer. */
-						n = (size_t)fwrite(hend, 1, towrite, fstore.fp);
-						if ((n != towrite) || (ferror(fstore.fp))) {
+						n = (size_t)fwrite(hend, 1, towrite, fstore.access.fp);
+						if ((n != towrite) || (ferror(fstore.access.fp))) {
 							mg_cry(conn,
 							       "%s: Cannot write file %s",
 							       __func__,
 							       path);
-							fclose(fstore.fp);
-							fstore.fp = NULL;
+							fclose(fstore.access.fp);
+							fstore.access.fp = NULL;
 							remove_bad_file(conn, path);
 						}
 						file_size += (int64_t)n;
@@ -760,15 +760,15 @@ mg_handle_form_request(struct mg_connection *conn,
 
 			if (field_storage == FORM_FIELD_STORAGE_STORE) {
 
-				if (fstore.fp) {
-					n = (size_t)fwrite(hend, 1, towrite, fstore.fp);
-					if ((n != towrite) || (ferror(fstore.fp))) {
+				if (fstore.access.fp) {
+					n = (size_t)fwrite(hend, 1, towrite, fstore.access.fp);
+					if ((n != towrite) || (ferror(fstore.access.fp))) {
 						mg_cry(conn,
 						       "%s: Cannot write file %s",
 						       __func__,
 						       path);
-						fclose(fstore.fp);
-						fstore.fp = NULL;
+						fclose(fstore.access.fp);
+						fstore.access.fp = NULL;
 						remove_bad_file(conn, path);
 					}
 					file_size += (int64_t)n;
@@ -777,8 +777,8 @@ mg_handle_form_request(struct mg_connection *conn,
 
 			if (field_storage == FORM_FIELD_STORAGE_STORE) {
 
-				if (fstore.fp) {
-					r = fclose(fstore.fp);
+				if (fstore.access.fp) {
+					r = fclose(fstore.access.fp);
 					if (r == 0) {
 						/* stored successfully */
 						field_stored(conn, path, file_size, fdh);
@@ -789,7 +789,7 @@ mg_handle_form_request(struct mg_connection *conn,
 						       path);
 						remove_bad_file(conn, path);
 					}
-					fstore.fp = NULL;
+					fstore.access.fp = NULL;
 				}
 			}
 

+ 3 - 3
src/mod_lua.inl

@@ -1576,7 +1576,7 @@ handle_lsp_request(struct mg_connection *conn,
 	conn->must_close = 1;
 
 	/* We need both mg_stat to get file size, and mg_fopen to get fd */
-	if (!mg_stat(conn, path, &filesize)) {
+	if (!mg_stat(conn, path, &filesize.stat)) {
 
 		/* File not found */
 		if (ls == NULL) {
@@ -1607,7 +1607,7 @@ handle_lsp_request(struct mg_connection *conn,
 	 * indicate. They should not fill in different members of the same
 	 * struct mg_file.
 	 * See Github issue #225 */
-	filep->size = filesize.size;
+	filep->size = filesize.stat.size;
 
 	if (filep->access.membuf == NULL
 	    && (p = mmap(NULL,
@@ -1668,7 +1668,7 @@ cleanup_handle_lsp_request:
 	if (L != NULL && ls == NULL)
 		lua_close(L);
 	if (p != NULL)
-		munmap(p, filep->size);
+		munmap(p, filep->stat.size);
 	mg_fclose(filep);
 
 	return error;