Bläddra i källkod

Preliminary fix for #225

lp do not work at the moment, because mg_fopen resets unused outputs
of the struct file. In this fix, the required size member is copied
from the previous call to mg_stat.

However, the real maintenance problem is, operations like mg_fopen
and mg_stat have to do exactly and exclusively what their names
suggest. They should not set different members of a common output
structure (struct file).
But this will be a more comprehensive change which needs more time.
bel2125 9 år sedan
förälder
incheckning
f16f8ebdf7
1 ändrade filer med 68 tillägg och 30 borttagningar
  1. 68 30
      src/mod_lua.inl

+ 68 - 30
src/mod_lua.inl

@@ -1398,30 +1398,54 @@ handle_lsp_request(struct mg_connection *conn,
 	void *p = NULL;
 	lua_State *L = NULL;
 	int error = 1;
+	struct file filesize = STRUCT_FILE_INITIALIZER;
 
 	/* Assume the script does not support keep_alive. The script may change this
 	 * by calling mg.keep_alive(true). */
 	conn->must_close = 1;
 
 	/* We need both mg_stat to get file size, and mg_fopen to get fd */
-	if (!mg_stat(conn, path, filep) || !mg_fopen(conn, path, "r", filep)) {
-		/* File not found or not accessible */
+	if (!mg_stat(conn, path, &filesize)) {
+
+		/* File not found */
 		if (ls == NULL) {
-			send_http_error(
-			    conn,
-			    500,
-			    "Error: Cannot open script\nFile %s can not be read",
-			    path);
+			send_http_error(conn, 500, "Error: File %s not found", path);
 		} else {
 			luaL_error(ls, "File [%s] not found", path);
 		}
-	} else if (filep->membuf == NULL
-	           && (p = mmap(NULL,
-	                        (size_t)filep->size,
-	                        PROT_READ,
-	                        MAP_PRIVATE,
-	                        fileno(filep->fp),
-	                        0)) == MAP_FAILED) {
+
+		goto cleanup_handle_lsp_request;
+	}
+
+	if (!mg_fopen(conn, path, "r", filep)) {
+
+		/* File not found or not accessible */
+		if (ls == NULL) {
+			send_http_error(conn,
+			                500,
+			                "Error: Cannot open script file %s",
+			                path);
+		} else {
+			luaL_error(ls, "Cannot  [%s] not found", path);
+		}
+
+		goto cleanup_handle_lsp_request;
+	}
+
+	/* TODO: Operations mg_fopen and mg_stat should do what their names
+	 * indicate. They should not fill in different members of the same
+	 * struct file.
+	 * See Github issue #225 */
+	filep->size = filesize.size;
+
+	if (filep->membuf == NULL
+	    && (p = mmap(NULL,
+	                 (size_t)filep->size,
+	                 PROT_READ,
+	                 MAP_PRIVATE,
+	                 fileno(filep->fp),
+	                 0)) == MAP_FAILED) {
+
 		/* mmap failed */
 		if (ls == NULL) {
 			send_http_error(
@@ -1437,31 +1461,45 @@ handle_lsp_request(struct mg_connection *conn,
 			           fileno(filep->fp),
 			           strerror(errno));
 		}
-	} else if ((L = (ls != NULL ? ls : lua_newstate(lua_allocator, NULL)))
-	           == NULL) {
-		send_http_error(conn,
-		                500,
-		                "%s",
-		                "Error: Cannot execute script\nlua_newstate failed");
+
+		goto cleanup_handle_lsp_request;
+	}
+
+	if (ls != NULL) {
+		L = ls;
 	} else {
-		/* We're not sending HTTP headers here, Lua page must do it. */
-		if (ls == NULL) {
-			prepare_lua_environment(
-			    conn->ctx, conn, NULL, L, path, LUA_ENV_TYPE_LUA_SERVER_PAGE);
+		L = lua_newstate(lua_allocator, NULL);
+		if (L == NULL) {
+			send_http_error(
+			    conn,
+			    500,
+			    "%s",
+			    "Error: Cannot execute script\nlua_newstate failed");
+
+			goto cleanup_handle_lsp_request;
 		}
-		error = lsp(conn,
-		            path,
-		            (filep->membuf == NULL) ? (const char *)p
-		                                    : (const char *)filep->membuf,
-		            filep->size,
-		            L);
+		prepare_lua_environment(
+		    conn->ctx, conn, NULL, L, path, LUA_ENV_TYPE_LUA_SERVER_PAGE);
 	}
 
+	/* Lua state is ready to use */
+	/* We're not sending HTTP headers here, Lua page must do it. */
+	error = lsp(conn,
+	            path,
+	            (filep->membuf == NULL) ? (const char *)p
+	                                    : (const char *)filep->membuf,
+	            filep->size,
+	            L);
+
+
+cleanup_handle_lsp_request:
+
 	if (L != NULL && ls == NULL)
 		lua_close(L);
 	if (p != NULL)
 		munmap(p, filep->size);
 	mg_fclose(filep);
+
 	return error;
 }