|
@@ -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;
|
|
|
}
|
|
|
|