summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjan <jan@152afb58-edef-0310-8abb-c4023f1b3aa9>2006-09-20 14:40:28 +0000
committerjan <jan@152afb58-edef-0310-8abb-c4023f1b3aa9>2006-09-20 14:40:28 +0000
commit8d1a8595072bba6b4c290f7026ba6678134e89b4 (patch)
treed441c3beb7737a595dfb1469d430a354824f1b0a
parentaa182a55106552adc768d435abecea12a63039d8 (diff)
downloadlighttpd-8d1a8595072bba6b4c290f7026ba6678134e89b4.tar.gz
reverted [1312] as it led to seg-faults
git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.11-ssl-fixes@1319 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r--src/mod_magnet.c170
1 files changed, 91 insertions, 79 deletions
diff --git a/src/mod_magnet.c b/src/mod_magnet.c
index 60cf6560..6d1bf9db 100644
--- a/src/mod_magnet.c
+++ b/src/mod_magnet.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <setjmp.h>
#include "base.h"
#include "log.h"
@@ -24,6 +25,8 @@
/* plugin config for all request/connections */
+static jmp_buf exceptionjmp;
+
typedef struct {
buffer *url_raw;
buffer *physical_path;
@@ -169,6 +172,21 @@ static int magnet_print(lua_State *L) {
return 0;
}
+static int magnet_atpanic(lua_State *L) {
+ const char *s = luaL_checkstring(L, 1);
+ server *srv;
+
+ lua_pushstring(L, "lighty.srv");
+ lua_gettable(L, LUA_REGISTRYINDEX);
+ srv = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+ "(lua-atpanic)", s);
+
+ longjmp(exceptionjmp, 1);
+}
+
static int magnet_reqhdr_get(lua_State *L) {
server *srv;
connection *con;
@@ -414,98 +432,95 @@ static int magnet_copy_response_header(server *srv, connection *con, plugin_data
*
* return 200
*/
-static int magnet_attach_content(lua_State *L) {
+static int magnet_attach_content(server *srv, connection *con, plugin_data *p, lua_State *L) {
/**
* get the environment of the function
*/
- server *srv;
- connection *con;
- int i;
-
- lua_pushstring(L, "lighty.srv");
- lua_gettable(L, LUA_REGISTRYINDEX);
- srv = lua_touserdata(L, -1);
- lua_pop(L, 1);
- lua_pushstring(L, "lighty.con");
- lua_gettable(L, LUA_REGISTRYINDEX);
- con = lua_touserdata(L, -1);
- lua_pop(L, 1);
-
- assert(lua_isfunction(L, -1)); /* this would be error in lighty */
- lua_getfenv(L, -1); /* get the script-env */
+ assert(lua_isfunction(L, -1));
+ lua_getfenv(L, -1); /* -1 is the function */
lua_getfield(L, -1, "lighty"); /* lighty.* from the env */
- if (!lua_istable(L, -1)) {
- return luaL_error(L, "lighty.* was a table and get overwritten in your script");
- }
+ assert(lua_istable(L, -1));
lua_getfield(L, -1, "content"); /* lighty.content */
- if (!lua_istable(L, -1)) {
- return luaL_error(L, "lighty.content was a table and get overwritten in your script");
- }
+ if (lua_istable(L, -1)) {
+ int i;
/* header is found, and is a table */
- for (i = 1; ; i++) {
- lua_rawgeti(L, -1, i);
+ for (i = 1; ; i++) {
+ lua_rawgeti(L, -1, i);
- /* -1 is the value and should be the value ... aka a table */
- if (lua_isstring(L, -1)) {
- size_t s_len = 0;
- const char *s = lua_tolstring(L, -1, &s_len);
+ /* -1 is the value and should be the value ... aka a table */
+ if (lua_isstring(L, -1)) {
+ size_t s_len = 0;
+ const char *s = lua_tolstring(L, -1, &s_len);
- chunkqueue_append_mem(con->write_queue, s, s_len + 1);
- } else if (lua_istable(L, -1)) {
- stat_cache_entry *sce;
- buffer *fn;
+ chunkqueue_append_mem(con->write_queue, s, s_len + 1);
+ } else if (lua_istable(L, -1)) {
+ lua_getfield(L, -1, "filename");
+ lua_getfield(L, -2, "length");
+ lua_getfield(L, -3, "offset");
- lua_getfield(L, -1, "filename");
- lua_getfield(L, -2, "length");
- lua_getfield(L, -3, "offset");
+ if (lua_isstring(L, -3)) { /* filename has to be a string */
+ buffer *fn = buffer_init();
+ stat_cache_entry *sce;
- if (!lua_isstring(L, -3)) { /* filename has to be a string */
- return luaL_error(L, "lighty.content[%d] is a table and requires the field \"filename\"", i);
- }
- fn = buffer_init();
+ buffer_copy_string(fn, lua_tostring(L, -3));
- buffer_copy_string(fn, lua_tostring(L, -3));
+ if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, fn, &sce)) {
+ off_t off = 0;
+ off_t len = 0;
- if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, fn, &sce)) {
- off_t off = 0;
- off_t len = 0;
+ if (lua_isnumber(L, -1)) {
+ off = lua_tonumber(L, -1);
+ }
- if (lua_isnumber(L, -1)) {
- off = lua_tonumber(L, -1);
- }
+ if (lua_isnumber(L, -2)) {
+ len = lua_tonumber(L, -2);
+ } else {
+ len = sce->st.st_size;
+ }
+
+ if (off < 0) {
+ return luaL_error(L, "offset for '%s' is negative", fn->ptr);
+ }
- if (lua_isnumber(L, -2)) {
- len = lua_tonumber(L, -2);
+ if (len < off) {
+ return luaL_error(L, "offset > length for '%s'", fn->ptr);
+ }
+
+ chunkqueue_append_file(con->write_queue, fn, off, len - off);
+ }
+
+ buffer_free(fn);
} else {
- len = sce->st.st_size;
- }
+ lua_pop(L, 3 + 2); /* correct the stack */
- if (off < 0) {
- /* fn leaks mem */
- return luaL_error(L, "offset for '%s' is negative", fn->ptr);
+ return luaL_error(L, "content[%d] is a table and requires the field \"filename\"", i);
}
- if (len < off) {
- /* fn leaks mem */
- return luaL_error(L, "offset > length for '%s'", fn->ptr);
- }
-
- chunkqueue_append_file(con->write_queue, fn, off, len - off);
- }
+ lua_pop(L, 3);
+ } else if (lua_isnil(L, -1)) {
+ /* oops, end of list */
- buffer_free(fn);
- } else if (lua_isnil(L, -1)) {
- /* oops, end of list */
+ lua_pop(L, 1);
- break;
- } else {
- return luaL_error(L, "lighty.content[%d] is neither a string nor a table: ", i);
+ break;
+ } else {
+ lua_pop(L, 4);
+
+ return luaL_error(L, "content[%d] is neither a string nor a table: ", i);
+ }
+
+ lua_pop(L, 1); /* pop the content[...] table */
}
+ } else {
+ return luaL_error(L, "lighty.content has to be a table");
}
+ lua_pop(L, 1); /* pop the header-table */
+ lua_pop(L, 1); /* pop the lighty-table */
+ lua_pop(L, 1); /* php the function env */
return 0;
}
@@ -543,6 +558,8 @@ static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, bu
lua_pushlightuserdata(L, con);
lua_settable(L, LUA_REGISTRYINDEX); /* registery[<id>] = con */
+ lua_atpanic(L, magnet_atpanic);
+
/**
* we want to create empty environment for our script
*
@@ -638,23 +655,18 @@ static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, bu
magnet_copy_response_header(srv, con, p, L);
- /* everything 3-digit number is a status-code */
- if (lua_return_value > 99 && lua_return_value < 1000) {
+ if (lua_return_value > 99) {
con->http_status = lua_return_value;
con->file_finished = 1;
-
- /* use the lua-system to call a lua-c-function
- * that way I can use luaL_error() without problems
- */
- if (lua_cpcall(L, magnet_attach_content, NULL)) {
- log_error_write(srv, __FILE__, __LINE__,
- "ss",
- "magnet_attach_content():",
- lua_tostring(L, -1));
-
+
+ /* try { ...*/
+ if (0 == setjmp(exceptionjmp)) {
+ magnet_attach_content(srv, con, p, L);
+ } else {
+ /* } catch () { */
con->http_status = 500;
}
-
+
assert(lua_gettop(L) == 1); /* only the function should be on the stack */
/* we are finished */