Diff for /embedaddon/lighttpd/src/mod_magnet.c between versions 1.1 and 1.1.1.3

version 1.1, 2013/10/14 10:32:48 version 1.1.1.3, 2016/11/02 10:35:00
Line 1 Line 1
   #include "first.h"
   
 #include "base.h"  #include "base.h"
 #include "log.h"  #include "log.h"
 #include "buffer.h"  #include "buffer.h"
   #include "http_chunk.h"
   
 #include "plugin.h"  #include "plugin.h"
   
Line 20 Line 23
 #include <lua.h>  #include <lua.h>
 #include <lauxlib.h>  #include <lauxlib.h>
   
   #define LUA_RIDX_LIGHTTPD_SERVER     "lighty.srv"
   #define LUA_RIDX_LIGHTTPD_CONNECTION "lighty.con"
   
 #define MAGNET_CONFIG_RAW_URL       "magnet.attract-raw-url-to"  #define MAGNET_CONFIG_RAW_URL       "magnet.attract-raw-url-to"
 #define MAGNET_CONFIG_PHYSICAL_PATH "magnet.attract-physical-path-to"  #define MAGNET_CONFIG_PHYSICAL_PATH "magnet.attract-physical-path-to"
 #define MAGNET_RESTART_REQUEST      99  #define MAGNET_RESTART_REQUEST      99
Line 71  FREE_FUNC(mod_magnet_free) { Line 77  FREE_FUNC(mod_magnet_free) {
                 for (i = 0; i < srv->config_context->used; i++) {                  for (i = 0; i < srv->config_context->used; i++) {
                         plugin_config *s = p->config_storage[i];                          plugin_config *s = p->config_storage[i];
   
                        if (!s) continue;                        if (NULL == s) continue;
   
                         array_free(s->url_raw);                          array_free(s->url_raw);
                         array_free(s->physical_path);                          array_free(s->physical_path);
Line 103  SETDEFAULTS_FUNC(mod_magnet_set_defaults) { Line 109  SETDEFAULTS_FUNC(mod_magnet_set_defaults) {
   
         if (!p) return HANDLER_ERROR;          if (!p) return HANDLER_ERROR;
   
        p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));        p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *));
   
         for (i = 0; i < srv->config_context->used; i++) {          for (i = 0; i < srv->config_context->used; i++) {
                   data_config const* config = (data_config const*)srv->config_context->data[i];
                 plugin_config *s;                  plugin_config *s;
   
                 s = calloc(1, sizeof(plugin_config));                  s = calloc(1, sizeof(plugin_config));
Line 117  SETDEFAULTS_FUNC(mod_magnet_set_defaults) { Line 124  SETDEFAULTS_FUNC(mod_magnet_set_defaults) {
   
                 p->config_storage[i] = s;                  p->config_storage[i] = s;
   
                if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {                if (0 != config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) {
                         return HANDLER_ERROR;                          return HANDLER_ERROR;
                 }                  }
         }          }
Line 158  static int mod_magnet_patch_connection(server *srv, co Line 165  static int mod_magnet_patch_connection(server *srv, co
 }  }
 #undef PATCH  #undef PATCH
   
/* See http://lua-users.org/wiki/GeneralizedPairsAndIpairs for implementation details. */#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
 /* lua5.1 backward compat definition */
 static void lua_pushglobaltable(lua_State *L) { /* (-0, +1, -) */
         lua_pushvalue(L, LUA_GLOBALSINDEX);
 }
 #endif
   
/* Override the default pairs() function to allow us to use a __pairs metakey */static void magnet_setfenv_mainfn(lua_State *L, int funcIndex) { /* (-1, 0, -) */
 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
         /* set "_ENV" upvalue, which should be the first upvalue of a "main" lua
          * function if it uses any global names
          */
 
         const char* first_upvalue_name = lua_getupvalue(L, funcIndex, 1);
         if (NULL == first_upvalue_name) return; /* doesn't have any upvalues */
         lua_pop(L, 1); /* only need the name of the upvalue, not the value */
 
         if (0 != strcmp(first_upvalue_name, "_ENV")) return;
 
         if (NULL == lua_setupvalue(L, funcIndex, 1)) {
                 /* pop value if lua_setupvalue didn't set the (not existing) upvalue */
                 lua_pop(L, 1);
         }
 #else
         lua_setfenv(L, funcIndex);
 #endif
 }
 
 #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
 /* lua 5.2 already supports __pairs */
 
 /* See http://lua-users.org/wiki/GeneralizedPairsAndIpairs for implementation details.
  * Override the default pairs() function to allow us to use a __pairs metakey
  */
 static int magnet_pairs(lua_State *L) {  static int magnet_pairs(lua_State *L) {
        luaL_checkany(L, 1);        luaL_checkany(L, 1); /* "self" */
   
         if (luaL_getmetafield(L, 1, "__pairs")) {          if (luaL_getmetafield(L, 1, "__pairs")) {
                lua_insert(L, 1);                /* call __pairs(self) */
                lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);                lua_pushvalue(L, 1);
                return lua_gettop(L);                lua_call(L, 1, 3);
         } else {          } else {
                   /* call <original-pairs-method>(self) */
                 lua_pushvalue(L, lua_upvalueindex(1));                  lua_pushvalue(L, lua_upvalueindex(1));
                lua_insert(L, 1);                lua_pushvalue(L, 1);
                lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);                lua_call(L, 1, 3);
                return lua_gettop(L); 
         }          }
           return 3;
 }  }
   #endif
   
 /* Define a function that will iterate over an array* (in upval 1) using current position (upval 2) */  /* Define a function that will iterate over an array* (in upval 1) using current position (upval 2) */
 static int magnet_array_next(lua_State *L) {  static int magnet_array_next(lua_State *L) {
Line 189  static int magnet_array_next(lua_State *L) { Line 229  static int magnet_array_next(lua_State *L) {
   
         if (pos >= a->used) return 0;          if (pos >= a->used) return 0;
         if (NULL != (du = a->data[pos])) {          if (NULL != (du = a->data[pos])) {
                if (du->key->used) {                lua_pushlstring(L, CONST_BUF_LEN(du->key));
                        lua_pushlstring(L, du->key->ptr, du->key->used - 1); 
                } 
                else { 
                        lua_pushlstring(L, "", 0); 
                } 
                 switch (du->type) {                  switch (du->type) {
                         case TYPE_STRING:                          case TYPE_STRING:
                                 ds = (data_string *)du;                                  ds = (data_string *)du;
                                if (ds->value && ds->value->used) {                                if (!buffer_is_empty(ds->value)) {
                                        lua_pushlstring(L, ds->value->ptr, ds->value->used - 1);                                        lua_pushlstring(L, CONST_BUF_LEN(ds->value));
                                 } else {                                  } else {
                                         lua_pushnil(L);                                          lua_pushnil(L);
                                 }                                  }
Line 233  static int magnet_array_pairs(lua_State *L, array *a)  Line 268  static int magnet_array_pairs(lua_State *L, array *a) 
         return 1;          return 1;
 }  }
   
static int magnet_print(lua_State *L) {static server* magnet_get_server(lua_State *L) {
        const char *s = luaL_checkstring(L, 1); 
         server *srv;          server *srv;
   
        lua_pushstring(L, "lighty.srv");        lua_getfield(L, LUA_REGISTRYINDEX, LUA_RIDX_LIGHTTPD_SERVER);
        lua_gettable(L, LUA_REGISTRYINDEX); 
         srv = lua_touserdata(L, -1);          srv = lua_touserdata(L, -1);
         lua_pop(L, 1);          lua_pop(L, 1);
   
        log_error_write(srv, __FILE__, __LINE__, "ss",        return srv;
                        "(lua-print)", s);}
   
   static connection* magnet_get_connection(lua_State *L) {
           connection *con;
   
           lua_getfield(L, LUA_REGISTRYINDEX, LUA_RIDX_LIGHTTPD_CONNECTION);
           con = lua_touserdata(L, -1);
           lua_pop(L, 1);
   
           return con;
   }
   
   typedef struct {
           const char *ptr;
           size_t len;
   } const_buffer;
   
   static const_buffer magnet_checkconstbuffer(lua_State *L, int index) {
           const_buffer cb;
           cb.ptr = luaL_checklstring(L, index, &cb.len);
           return cb;
   }
   
   static buffer* magnet_checkbuffer(lua_State *L, int index) {
           const_buffer cb = magnet_checkconstbuffer(L, index);
           buffer *b = buffer_init();
           buffer_copy_string_len(b, cb.ptr, cb.len);
           return b;
   }
   
   static int magnet_print(lua_State *L) {
           buffer *b = magnet_checkbuffer(L, 1);
   
           log_error_write(magnet_get_server(L), __FILE__, __LINE__, "sB",
                   "(lua-print)",
                   b);
   
           buffer_free(b);
   
         return 0;          return 0;
 }  }
   
 static int magnet_stat(lua_State *L) {  static int magnet_stat(lua_State *L) {
        const char *s = luaL_checkstring(L, 1);        buffer *sb = magnet_checkbuffer(L, 1);
        server *srv;        server *srv = magnet_get_server(L);
        connection *con;        connection *con = magnet_get_connection(L);
        buffer sb; 
         stat_cache_entry *sce = NULL;          stat_cache_entry *sce = NULL;
           handler_t res;
   
        lua_pushstring(L, "lighty.srv");        res = stat_cache_get_entry(srv, con, sb, &sce);
        lua_gettable(L, LUA_REGISTRYINDEX);        buffer_free(sb);
        srv = lua_touserdata(L, -1); 
        lua_pop(L, 1); 
   
        lua_pushstring(L, "lighty.con");        if (HANDLER_GO_ON != res) {
        lua_gettable(L, LUA_REGISTRYINDEX); 
        con = lua_touserdata(L, -1); 
        lua_pop(L, 1); 
 
        sb.ptr = (char *)s; 
        sb.used = sb.size = strlen(s) + 1; 
         
        if (HANDLER_GO_ON != stat_cache_get_entry(srv, con, &sb, &sce)) { 
                 lua_pushnil(L);                  lua_pushnil(L);
   
                 return 1;                  return 1;
         }          }
   
        lua_newtable(L);        lua_newtable(L); // return value
   
         lua_pushboolean(L, S_ISREG(sce->st.st_mode));          lua_pushboolean(L, S_ISREG(sce->st.st_mode));
         lua_setfield(L, -2, "is_file");          lua_setfield(L, -2, "is_file");
        
         lua_pushboolean(L, S_ISDIR(sce->st.st_mode));          lua_pushboolean(L, S_ISDIR(sce->st.st_mode));
         lua_setfield(L, -2, "is_dir");          lua_setfield(L, -2, "is_dir");
   
Line 318  static int magnet_stat(lua_State *L) { Line 377  static int magnet_stat(lua_State *L) {
         lua_pushinteger(L, sce->st.st_ino);          lua_pushinteger(L, sce->st.st_ino);
         lua_setfield(L, -2, "st_ino");          lua_setfield(L, -2, "st_ino");
   
        if (!buffer_string_is_empty(sce->etag)) {
        if (!buffer_is_empty(sce->etag)) { 
                 /* we have to mutate the etag */                  /* we have to mutate the etag */
                 buffer *b = buffer_init();                  buffer *b = buffer_init();
                 etag_mutate(b, sce->etag);                  etag_mutate(b, sce->etag);
   
                lua_pushlstring(L, b->ptr, b->used - 1);                lua_pushlstring(L, CONST_BUF_LEN(b));
                 buffer_free(b);                  buffer_free(b);
         } else {          } else {
                 lua_pushnil(L);                  lua_pushnil(L);
         }          }
         lua_setfield(L, -2, "etag");          lua_setfield(L, -2, "etag");
   
        if (!buffer_is_empty(sce->content_type)) {        if (!buffer_string_is_empty(sce->content_type)) {
                lua_pushlstring(L, sce->content_type->ptr, sce->content_type->used - 1);                lua_pushlstring(L, CONST_BUF_LEN(sce->content_type));
         } else {          } else {
                 lua_pushnil(L);                  lua_pushnil(L);
         }          }
Line 343  static int magnet_stat(lua_State *L) { Line 401  static int magnet_stat(lua_State *L) {
   
   
 static int magnet_atpanic(lua_State *L) {  static int magnet_atpanic(lua_State *L) {
        const char *s = luaL_checkstring(L, 1);        buffer *b = magnet_checkbuffer(L, 1);
        server *srv; 
   
        lua_pushstring(L, "lighty.srv");        log_error_write(magnet_get_server(L), __FILE__, __LINE__, "sB",
        lua_gettable(L, LUA_REGISTRYINDEX);                "(lua-atpanic)",
        srv = lua_touserdata(L, -1);                b);
        lua_pop(L, 1); 
   
        log_error_write(srv, __FILE__, __LINE__, "ss",        buffer_free(b);
                        "(lua-atpanic)", s); 
   
         longjmp(exceptionjmp, 1);          longjmp(exceptionjmp, 1);
 }  }
   
 static int magnet_reqhdr_get(lua_State *L) {  static int magnet_reqhdr_get(lua_State *L) {
        connection *con;        connection *con = magnet_get_connection(L);
         data_string *ds;          data_string *ds;
   
           /* __index: param 1 is the (empty) table the value was not found in */
         const char *key = luaL_checkstring(L, 2);          const char *key = luaL_checkstring(L, 2);
   
         lua_pushstring(L, "lighty.con");  
         lua_gettable(L, LUA_REGISTRYINDEX);  
         con = lua_touserdata(L, -1);  
         lua_pop(L, 1);  
   
         if (NULL != (ds = (data_string *)array_get_element(con->request.headers, key))) {          if (NULL != (ds = (data_string *)array_get_element(con->request.headers, key))) {
                if (ds->value->used) {                if (!buffer_is_empty(ds->value)) {
                        lua_pushlstring(L, ds->value->ptr, ds->value->used - 1);                        lua_pushlstring(L, CONST_BUF_LEN(ds->value));
                 } else {                  } else {
                         lua_pushnil(L);                          lua_pushnil(L);
                 }                  }
Line 381  static int magnet_reqhdr_get(lua_State *L) { Line 432  static int magnet_reqhdr_get(lua_State *L) {
 }  }
   
 static int magnet_reqhdr_pairs(lua_State *L) {  static int magnet_reqhdr_pairs(lua_State *L) {
        connection *con;        connection *con = magnet_get_connection(L);
   
         lua_pushstring(L, "lighty.con");  
         lua_gettable(L, LUA_REGISTRYINDEX);  
         con = lua_touserdata(L, -1);  
         lua_pop(L, 1);  
   
         return magnet_array_pairs(L, con->request.headers);          return magnet_array_pairs(L, con->request.headers);
 }  }
   
 static int magnet_status_get(lua_State *L) {  static int magnet_status_get(lua_State *L) {
         data_integer *di;          data_integer *di;
        server *srv;        server *srv = magnet_get_server(L);
        size_t key_len = 0; 
   
        const char *key = luaL_checklstring(L, 2, &key_len);        /* __index: param 1 is the (empty) table the value was not found in */
         const_buffer key = magnet_checkconstbuffer(L, 2);
   
        lua_pushstring(L, "lighty.srv");        di = status_counter_get_counter(srv, key.ptr, key.len);
        lua_gettable(L, LUA_REGISTRYINDEX); 
        srv = lua_touserdata(L, -1); 
        lua_pop(L, 1); 
   
        di = status_counter_get_counter(srv, key, key_len);        lua_pushinteger(L, (lua_Integer)di->value);
   
         lua_pushnumber(L, (double)di->value);  
   
         return 1;          return 1;
 }  }
   
 static int magnet_status_set(lua_State *L) {  static int magnet_status_set(lua_State *L) {
        size_t key_len = 0;        server *srv = magnet_get_server(L);
        server *srv; 
   
        const char *key = luaL_checklstring(L, 2, &key_len);        /* __newindex: param 1 is the (empty) table the value is supposed to be set in */
        int counter = luaL_checkint(L, 3);        const_buffer key = magnet_checkconstbuffer(L, 2);
         int counter = (int) luaL_checkinteger(L, 3);
   
        lua_pushstring(L, "lighty.srv");        status_counter_set(srv, key.ptr, key.len, counter);
        lua_gettable(L, LUA_REGISTRYINDEX); 
        srv = lua_touserdata(L, -1); 
        lua_pop(L, 1); 
   
         status_counter_set(srv, key, key_len, counter);  
   
         return 0;          return 0;
 }  }
   
 static int magnet_status_pairs(lua_State *L) {  static int magnet_status_pairs(lua_State *L) {
        server *srv;        server *srv = magnet_get_server(L);
   
         lua_pushstring(L, "lighty.srv");  
         lua_gettable(L, LUA_REGISTRYINDEX);  
         srv = lua_touserdata(L, -1);  
         lua_pop(L, 1);  
   
         return magnet_array_pairs(L, srv->status);          return magnet_array_pairs(L, srv->status);
 }  }
   
Line 446  typedef struct { Line 477  typedef struct {
                 MAGNET_ENV_PHYICAL_PATH,                  MAGNET_ENV_PHYICAL_PATH,
                 MAGNET_ENV_PHYICAL_REL_PATH,                  MAGNET_ENV_PHYICAL_REL_PATH,
                 MAGNET_ENV_PHYICAL_DOC_ROOT,                  MAGNET_ENV_PHYICAL_DOC_ROOT,
                   MAGNET_ENV_PHYICAL_BASEDIR,
   
                 MAGNET_ENV_URI_PATH,                  MAGNET_ENV_URI_PATH,
                 MAGNET_ENV_URI_PATH_RAW,                  MAGNET_ENV_URI_PATH_RAW,
Line 466  static const magnet_env_t magnet_env[] = { Line 498  static const magnet_env_t magnet_env[] = {
         { "physical.path", MAGNET_ENV_PHYICAL_PATH },          { "physical.path", MAGNET_ENV_PHYICAL_PATH },
         { "physical.rel-path", MAGNET_ENV_PHYICAL_REL_PATH },          { "physical.rel-path", MAGNET_ENV_PHYICAL_REL_PATH },
         { "physical.doc-root", MAGNET_ENV_PHYICAL_DOC_ROOT },          { "physical.doc-root", MAGNET_ENV_PHYICAL_DOC_ROOT },
           { "physical.basedir", MAGNET_ENV_PHYICAL_BASEDIR },
   
         { "uri.path", MAGNET_ENV_URI_PATH },          { "uri.path", MAGNET_ENV_URI_PATH },
         { "uri.path-raw", MAGNET_ENV_URI_PATH_RAW },          { "uri.path-raw", MAGNET_ENV_URI_PATH_RAW },
Line 497  static buffer *magnet_env_get_buffer_by_id(server *srv Line 530  static buffer *magnet_env_get_buffer_by_id(server *srv
         case MAGNET_ENV_PHYICAL_PATH: dest = con->physical.path; break;          case MAGNET_ENV_PHYICAL_PATH: dest = con->physical.path; break;
         case MAGNET_ENV_PHYICAL_REL_PATH: dest = con->physical.rel_path; break;          case MAGNET_ENV_PHYICAL_REL_PATH: dest = con->physical.rel_path; break;
         case MAGNET_ENV_PHYICAL_DOC_ROOT: dest = con->physical.doc_root; break;          case MAGNET_ENV_PHYICAL_DOC_ROOT: dest = con->physical.doc_root; break;
           case MAGNET_ENV_PHYICAL_BASEDIR: dest = con->physical.basedir; break;
   
         case MAGNET_ENV_URI_PATH: dest = con->uri.path; break;          case MAGNET_ENV_URI_PATH: dest = con->uri.path; break;
         case MAGNET_ENV_URI_PATH_RAW: dest = con->uri.path_raw; break;          case MAGNET_ENV_URI_PATH_RAW: dest = con->uri.path_raw; break;
Line 534  static buffer *magnet_env_get_buffer(server *srv, conn Line 568  static buffer *magnet_env_get_buffer(server *srv, conn
 }  }
   
 static int magnet_env_get(lua_State *L) {  static int magnet_env_get(lua_State *L) {
        server *srv;        server *srv = magnet_get_server(L);
        connection *con;        connection *con = magnet_get_connection(L);
   
           /* __index: param 1 is the (empty) table the value was not found in */
         const char *key = luaL_checkstring(L, 2);          const char *key = luaL_checkstring(L, 2);
         buffer *dest = NULL;          buffer *dest = NULL;
   
         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);  
   
         dest = magnet_env_get_buffer(srv, con, key);          dest = magnet_env_get_buffer(srv, con, key);
   
        if (dest && dest->used) {        if (!buffer_is_empty(dest)) {
                lua_pushlstring(L, dest->ptr, dest->used - 1);                lua_pushlstring(L, CONST_BUF_LEN(dest));
         } else {          } else {
                 lua_pushnil(L);                  lua_pushnil(L);
         }          }
Line 562  static int magnet_env_get(lua_State *L) { Line 587  static int magnet_env_get(lua_State *L) {
 }  }
   
 static int magnet_env_set(lua_State *L) {  static int magnet_env_set(lua_State *L) {
        server *srv;        server *srv = magnet_get_server(L);
        connection *con;        connection *con = magnet_get_connection(L);
   
           /* __newindex: param 1 is the (empty) table the value is supposed to be set in */
         const char *key = luaL_checkstring(L, 2);          const char *key = luaL_checkstring(L, 2);
         const char *val = luaL_checkstring(L, 3);  
         buffer *dest = NULL;          buffer *dest = NULL;
   
        lua_pushstring(L, "lighty.srv");        luaL_checkany(L, 3); /* nil or a string */
        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);  
   
         if (NULL != (dest = magnet_env_get_buffer(srv, con, key))) {          if (NULL != (dest = magnet_env_get_buffer(srv, con, key))) {
                buffer_copy_string(dest, val);                if (lua_isnil(L, 3)) {
                         buffer_reset(dest);
                 } else {
                         const_buffer val = magnet_checkconstbuffer(L, 3);
                         buffer_copy_string_len(dest, val.ptr, val.len);
                 }
         } else {          } else {
                 /* couldn't save */                  /* couldn't save */
   
Line 591  static int magnet_env_set(lua_State *L) { Line 613  static int magnet_env_set(lua_State *L) {
 }  }
   
 static int magnet_env_next(lua_State *L) {  static int magnet_env_next(lua_State *L) {
        server *srv;        server *srv = magnet_get_server(L);
        connection *con;        connection *con = magnet_get_connection(L);
        int pos = lua_tointeger(L, lua_upvalueindex(1));        const int pos = lua_tointeger(L, lua_upvalueindex(1));
   
         buffer *dest;          buffer *dest;
   
        lua_pushstring(L, "lighty.srv");        /* ignore previous key: use upvalue for current pos */
        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); 
 
         lua_settop(L, 0);          lua_settop(L, 0);
   
         if (NULL == magnet_env[pos].name) return 0; /* end of list */          if (NULL == magnet_env[pos].name) return 0; /* end of list */
           /* Update our positional upval to reflect our new current position */
           lua_pushinteger(L, pos + 1);
           lua_replace(L, lua_upvalueindex(1));
   
           /* key to return */
         lua_pushstring(L, magnet_env[pos].name);          lua_pushstring(L, magnet_env[pos].name);
   
           /* get value */
         dest = magnet_env_get_buffer_by_id(srv, con, magnet_env[pos].type);          dest = magnet_env_get_buffer_by_id(srv, con, magnet_env[pos].type);
        if (dest && dest->used) {        if (!buffer_is_empty(dest)) {
                lua_pushlstring(L, dest->ptr, dest->used - 1);                lua_pushlstring(L, CONST_BUF_LEN(dest));
         } else {          } else {
                 lua_pushnil(L);                  lua_pushnil(L);
         }          }
   
        /* Update our positional upval to reflect our new current position */        /* return 2 items on the stack (key, value) */
        pos++; 
        lua_pushinteger(L, pos); 
        lua_replace(L, lua_upvalueindex(1)); 
 
        /* Returning 2 items on the stack (key, value) */ 
         return 2;          return 2;
 }  }
   
Line 636  static int magnet_env_pairs(lua_State *L) { Line 649  static int magnet_env_pairs(lua_State *L) {
 }  }
   
 static int magnet_cgi_get(lua_State *L) {  static int magnet_cgi_get(lua_State *L) {
        connection *con;        connection *con = magnet_get_connection(L);
         data_string *ds;          data_string *ds;
   
           /* __index: param 1 is the (empty) table the value was not found in */
         const char *key = luaL_checkstring(L, 2);          const char *key = luaL_checkstring(L, 2);
   
        lua_pushstring(L, "lighty.con");        ds = (data_string *)array_get_element(con->environment, key);
        lua_gettable(L, LUA_REGISTRYINDEX);        if (NULL != ds && !buffer_is_empty(ds->value))
        con = lua_touserdata(L, -1); 
        lua_pop(L, 1); 
 
        if (NULL != (ds = (data_string *)array_get_element(con->environment, key)) && ds->value->used) 
                 lua_pushlstring(L, CONST_BUF_LEN(ds->value));                  lua_pushlstring(L, CONST_BUF_LEN(ds->value));
         else          else
                 lua_pushnil(L);                  lua_pushnil(L);
Line 655  static int magnet_cgi_get(lua_State *L) { Line 665  static int magnet_cgi_get(lua_State *L) {
 }  }
   
 static int magnet_cgi_set(lua_State *L) {  static int magnet_cgi_set(lua_State *L) {
        connection *con;        connection *con = magnet_get_connection(L);
   
        const char *key = luaL_checkstring(L, 2);        /* __newindex: param 1 is the (empty) table the value is supposed to be set in */
        const char *val = luaL_checkstring(L, 3);        const_buffer key = magnet_checkconstbuffer(L, 2);
         const_buffer val = magnet_checkconstbuffer(L, 2);
   
        lua_pushstring(L, "lighty.con");        array_set_key_value(con->environment, key.ptr, key.len, val.ptr, val.len);
        lua_gettable(L, LUA_REGISTRYINDEX); 
        con = lua_touserdata(L, -1); 
        lua_pop(L, 1); 
   
         array_set_key_value(con->environment, key, strlen(key), val, strlen(val));  
   
         return 0;          return 0;
 }  }
   
 static int magnet_cgi_pairs(lua_State *L) {  static int magnet_cgi_pairs(lua_State *L) {
        connection *con;        connection *con = magnet_get_connection(L);
   
         lua_pushstring(L, "lighty.con");  
         lua_gettable(L, LUA_REGISTRYINDEX);  
         con = lua_touserdata(L, -1);  
         lua_pop(L, 1);  
   
         return magnet_array_pairs(L, con->environment);          return magnet_array_pairs(L, con->environment);
 }  }
   
   
static int magnet_copy_response_header(server *srv, connection *con, plugin_data *p, lua_State *L) {static int magnet_copy_response_header(server *srv, connection *con, lua_State *L, int lighty_table_ndx) {
        UNUSED(p);        force_assert(lua_istable(L, lighty_table_ndx));
        /** 
         * get the environment of the function 
         */ 
   
        lua_getfenv(L, -1); /* -1 is the function */        lua_getfield(L, lighty_table_ndx, "header"); /* lighty.header */
 
        /* lighty.header */ 
 
        lua_getfield(L, -1, "lighty"); /* lighty.* from the env  */ 
        assert(lua_istable(L, -1)); 
 
        lua_getfield(L, -1, "header"); /* lighty.header */ 
         if (lua_istable(L, -1)) {          if (lua_istable(L, -1)) {
                 /* header is found, and is a table */                  /* header is found, and is a table */
   
                 lua_pushnil(L);                  lua_pushnil(L);
                 while (lua_next(L, -2) != 0) {                  while (lua_next(L, -2) != 0) {
                         if (lua_isstring(L, -1) && lua_isstring(L, -2)) {                          if (lua_isstring(L, -1) && lua_isstring(L, -2)) {
                                const char *key, *val;                                const_buffer key = magnet_checkconstbuffer(L, -2);
                                size_t key_len, val_len;                                const_buffer val = magnet_checkconstbuffer(L, -1);
   
                                key = lua_tolstring(L, -2, &key_len);                                response_header_overwrite(srv, con, key.ptr, key.len, val.ptr, val.len);
                                val = lua_tolstring(L, -1, &val_len); 
 
                                response_header_overwrite(srv, con, key, key_len, val, val_len); 
                         }                          }
   
                         lua_pop(L, 1);                          lua_pop(L, 1);
                 }                  }
         }          }
           lua_pop(L, 1); /* pop lighty.header */
   
         lua_pop(L, 1); /* pop the header-table */  
         lua_pop(L, 1); /* pop the lighty-env */  
         lua_pop(L, 1); /* pop the function env */  
   
         return 0;          return 0;
 }  }
   
Line 731  static int magnet_copy_response_header(server *srv, co Line 716  static int magnet_copy_response_header(server *srv, co
  *   *
  * return 200   * return 200
  */   */
static int magnet_attach_content(server *srv, connection *con, plugin_data *p, lua_State *L) {static int magnet_attach_content(server *srv, connection *con, lua_State *L, int lighty_table_ndx) {
        UNUSED(p);        force_assert(lua_istable(L, lighty_table_ndx));
        /** 
         * get the environment of the function 
         */ 
   
        assert(lua_isfunction(L, -1));        lua_getfield(L, lighty_table_ndx, "content"); /* lighty.content */
        lua_getfenv(L, -1); /* -1 is the function */ 
 
        lua_getfield(L, -1, "lighty"); /* lighty.* from the env  */ 
        assert(lua_istable(L, -1)); 
 
        lua_getfield(L, -1, "content"); /* lighty.content */ 
         if (lua_istable(L, -1)) {          if (lua_istable(L, -1)) {
                 int i;                  int i;
                /* header is found, and is a table */                /* content is found, and is a table */
   
                 for (i = 1; ; i++) {                  for (i = 1; ; i++) {
                         lua_rawgeti(L, -1, i);                          lua_rawgeti(L, -1, i);
   
                         /* -1 is the value and should be the value ... aka a table */                          /* -1 is the value and should be the value ... aka a table */
                         if (lua_isstring(L, -1)) {                          if (lua_isstring(L, -1)) {
                                size_t s_len = 0;                                const_buffer data = magnet_checkconstbuffer(L, -1);
                                const char *s = lua_tolstring(L, -1, &s_len); 
   
                                chunkqueue_append_mem(con->write_queue, s, s_len + 1);                                chunkqueue_append_mem(con->write_queue, data.ptr, data.len);
                         } else if (lua_istable(L, -1)) {                          } else if (lua_istable(L, -1)) {
                                 lua_getfield(L, -1, "filename");                                  lua_getfield(L, -1, "filename");
                                lua_getfield(L, -2, "length");                                lua_getfield(L, -2, "length"); /* (0-based) end of range (not actually "length") */
                                lua_getfield(L, -3, "offset");                                lua_getfield(L, -3, "offset"); /* (0-based) start of range */
   
                                 if (lua_isstring(L, -3)) { /* filename has to be a string */                                  if (lua_isstring(L, -3)) { /* filename has to be a string */
                                        buffer *fn = buffer_init();                                        buffer *fn = magnet_checkbuffer(L, -3);
                                        stat_cache_entry *sce;                                        off_t off = (off_t) luaL_optinteger(L, -1, 0);
                                         off_t len = (off_t) luaL_optinteger(L, -2, -1); /*(-1 to http_chunk_append_file_range() uses file size minus offset)*/
                                         if (off < 0) {
                                                 buffer_free(fn);
                                                 return luaL_error(L, "offset for '%s' is negative", lua_tostring(L, -3));
                                         }
   
                                        buffer_copy_string(fn, lua_tostring(L, -3));                                        if (len >= off) {
                                                 len -= off;
                                         } else if (-1 != len) {
                                                 buffer_free(fn);
                                                 return luaL_error(L, "offset > length for '%s'", lua_tostring(L, -3));
                                         }
   
                                        if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, fn, &sce)) {                                        if (0 != len && 0 != http_chunk_append_file_range(srv, con, fn, off, len)) {
                                                off_t off = 0;                                                buffer_free(fn);
                                                off_t len = 0;                                                return luaL_error(L, "error opening file content '%s' at offset %lld", lua_tostring(L, -3), (long long)off);
 
                                                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 (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);                                          buffer_free(fn);
                                 } else {                                  } else {
                                         lua_pop(L, 3 + 2); /* correct the stack */  
   
                                         return luaL_error(L, "content[%d] is a table and requires the field \"filename\"", i);                                          return luaL_error(L, "content[%d] is a table and requires the field \"filename\"", i);
                                 }                                  }
   
                                 lua_pop(L, 3);                                  lua_pop(L, 3);
                         } else if (lua_isnil(L, -1)) {                          } else if (lua_isnil(L, -1)) {
                                /* oops, end of list */                                /* end of list */
   
                                 lua_pop(L, 1);                                  lua_pop(L, 1);
   
                                 break;                                  break;
                         } else {                          } else {
                                 lua_pop(L, 4);  
   
                                 return luaL_error(L, "content[%d] is neither a string nor a table: ", i);                                  return luaL_error(L, "content[%d] is neither a string nor a table: ", i);
                         }                          }
   
                        lua_pop(L, 1); /* pop the content[...] table */                        lua_pop(L, 1); /* pop the content[...] entry value */
                 }                  }
         } else {          } else {
                 return luaL_error(L, "lighty.content has to be a table");                  return luaL_error(L, "lighty.content has to be a table");
         }          }
        lua_pop(L, 1); /* pop the header-table */        lua_pop(L, 1); /* pop lighty.content */
        lua_pop(L, 1); /* pop the lighty-table */ 
        lua_pop(L, 1); /* php the function env */ 
   
         return 0;          return 0;
 }  }
   
static int traceback (lua_State *L) {static int traceback(lua_State *L) {
         if (!lua_isstring(L, 1))  /* 'message' not a string? */          if (!lua_isstring(L, 1))  /* 'message' not a string? */
                 return 1;  /* keep it intact */                  return 1;  /* keep it intact */
        lua_getfield(L, LUA_GLOBALSINDEX, "debug");        lua_getglobal(L, "debug");
         if (!lua_istable(L, -1)) {          if (!lua_istable(L, -1)) {
                 lua_pop(L, 1);                  lua_pop(L, 1);
                 return 1;                  return 1;
Line 844  static int traceback (lua_State *L) { Line 803  static int traceback (lua_State *L) {
         return 1;          return 1;
 }  }
   
   /* push traceback function before calling lua_pcall after narg arguments
    * have been pushed (inserts it before the arguments). returns index for
    * traceback function ("msgh" in lua_pcall)
    */
 static int push_traceback(lua_State *L, int narg) {  static int push_traceback(lua_State *L, int narg) {
         int base = lua_gettop(L) - narg;  /* function index */          int base = lua_gettop(L) - narg;  /* function index */
         lua_pushcfunction(L, traceback);          lua_pushcfunction(L, traceback);
Line 853  static int push_traceback(lua_State *L, int narg) { Line 816  static int push_traceback(lua_State *L, int narg) {
   
 static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, buffer *name) {  static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, buffer *name) {
         lua_State *L;          lua_State *L;
        int lua_return_value = -1;        int lua_return_value;
        int errfunc;        const int func_ndx = 1;
        /* get the script-context */        const int lighty_table_ndx = 2;
   
        /* get the script-context */
         L = script_cache_get_script(srv, con, p->cache, name);          L = script_cache_get_script(srv, con, p->cache, name);
   
         if (lua_isstring(L, -1)) {          if (lua_isstring(L, -1)) {
Line 870  static handler_t magnet_attract(server *srv, connectio Line 833  static handler_t magnet_attract(server *srv, connectio
   
                 lua_pop(L, 1);                  lua_pop(L, 1);
   
                assert(lua_gettop(L) == 0); /* only the function should be on the stack */                force_assert(lua_gettop(L) == 0); /* only the error should have been on the stack */
   
                 con->http_status = 500;                  con->http_status = 500;
                 con->mode = DIRECT;                  con->mode = DIRECT;
Line 878  static handler_t magnet_attract(server *srv, connectio Line 841  static handler_t magnet_attract(server *srv, connectio
                 return HANDLER_FINISHED;                  return HANDLER_FINISHED;
         }          }
   
        lua_pushstring(L, "lighty.srv");        force_assert(lua_gettop(L) == 1);
         force_assert(lua_isfunction(L, func_ndx));
 
         lua_pushlightuserdata(L, srv);          lua_pushlightuserdata(L, srv);
        lua_settable(L, LUA_REGISTRYINDEX); /* registery[<id>] = srv */        lua_setfield(L, LUA_REGISTRYINDEX, LUA_RIDX_LIGHTTPD_SERVER);
   
         lua_pushstring(L, "lighty.con");  
         lua_pushlightuserdata(L, con);          lua_pushlightuserdata(L, con);
        lua_settable(L, LUA_REGISTRYINDEX); /* registery[<id>] = con */        lua_setfield(L, LUA_REGISTRYINDEX, LUA_RIDX_LIGHTTPD_CONNECTION);
   
         lua_atpanic(L, magnet_atpanic);          lua_atpanic(L, magnet_atpanic);
   
Line 893  static handler_t magnet_attract(server *srv, connectio Line 857  static handler_t magnet_attract(server *srv, connectio
          *           *
          * setmetatable({}, {__index = _G})           * setmetatable({}, {__index = _G})
          *           *
         * if a function, symbol is not defined in our env, __index will lookup         * if a function symbol is not defined in our env, __index will lookup
          * in the global env.           * in the global env.
          *           *
          * all variables created in the script-env will be thrown           * all variables created in the script-env will be thrown
Line 906  static handler_t magnet_attract(server *srv, connectio Line 870  static handler_t magnet_attract(server *srv, connectio
         lua_setfield(L, -2, "print"); /* -1 is the env we want to set(sp -= 1) */          lua_setfield(L, -2, "print"); /* -1 is the env we want to set(sp -= 1) */
   
         /**          /**
         * lighty.request[] has the HTTP-request headers         * lighty.request[] (ro) has the HTTP-request headers
         * lighty.content[] is a table of string/file         * lighty.env[] (rw) has various url/physical file paths and
         * lighty.header[] is a array to set response headers         *                   request meta data; might contain nil values
          * lighty.req_env[] (ro) has the cgi environment
          * lighty.status[] (ro) has the status counters
          * lighty.content[] (rw) is a table of string/file
          * lighty.header[] (rw) is a array to set response headers
          */           */
   
         lua_newtable(L); /* lighty.*                                 (sp += 1) */          lua_newtable(L); /* lighty.*                                 (sp += 1) */
Line 923  static handler_t magnet_attract(server *srv, connectio Line 891  static handler_t magnet_attract(server *srv, connectio
         lua_setfield(L, -2, "request"); /* content = {}              (sp -= 1) */          lua_setfield(L, -2, "request"); /* content = {}              (sp -= 1) */
   
         lua_newtable(L); /*  {}                                      (sp += 1) */          lua_newtable(L); /*  {}                                      (sp += 1) */
        lua_newtable(L); /* the meta-table for the request-table     (sp += 1) */        lua_newtable(L); /* the meta-table for the env-table         (sp += 1) */
         lua_pushcfunction(L, magnet_env_get);                     /* (sp += 1) */          lua_pushcfunction(L, magnet_env_get);                     /* (sp += 1) */
         lua_setfield(L, -2, "__index");                           /* (sp -= 1) */          lua_setfield(L, -2, "__index");                           /* (sp -= 1) */
         lua_pushcfunction(L, magnet_env_set);                     /* (sp += 1) */          lua_pushcfunction(L, magnet_env_set);                     /* (sp += 1) */
         lua_setfield(L, -2, "__newindex");                        /* (sp -= 1) */          lua_setfield(L, -2, "__newindex");                        /* (sp -= 1) */
         lua_pushcfunction(L, magnet_env_pairs);                   /* (sp += 1) */          lua_pushcfunction(L, magnet_env_pairs);                   /* (sp += 1) */
         lua_setfield(L, -2, "__pairs");                           /* (sp -= 1) */          lua_setfield(L, -2, "__pairs");                           /* (sp -= 1) */
        lua_setmetatable(L, -2); /* tie the metatable to request     (sp -= 1) */        lua_setmetatable(L, -2); /* tie the metatable to env         (sp -= 1) */
         lua_setfield(L, -2, "env"); /* content = {}                  (sp -= 1) */          lua_setfield(L, -2, "env"); /* content = {}                  (sp -= 1) */
   
         lua_newtable(L); /*  {}                                      (sp += 1) */          lua_newtable(L); /*  {}                                      (sp += 1) */
        lua_newtable(L); /* the meta-table for the request-table     (sp += 1) */        lua_newtable(L); /* the meta-table for the req_env-table     (sp += 1) */
         lua_pushcfunction(L, magnet_cgi_get);                     /* (sp += 1) */          lua_pushcfunction(L, magnet_cgi_get);                     /* (sp += 1) */
         lua_setfield(L, -2, "__index");                           /* (sp -= 1) */          lua_setfield(L, -2, "__index");                           /* (sp -= 1) */
         lua_pushcfunction(L, magnet_cgi_set);                     /* (sp += 1) */          lua_pushcfunction(L, magnet_cgi_set);                     /* (sp += 1) */
Line 945  static handler_t magnet_attract(server *srv, connectio Line 913  static handler_t magnet_attract(server *srv, connectio
         lua_setfield(L, -2, "req_env"); /* content = {}              (sp -= 1) */          lua_setfield(L, -2, "req_env"); /* content = {}              (sp -= 1) */
   
         lua_newtable(L); /*  {}                                      (sp += 1) */          lua_newtable(L); /*  {}                                      (sp += 1) */
        lua_newtable(L); /* the meta-table for the request-table     (sp += 1) */        lua_newtable(L); /* the meta-table for the status-table      (sp += 1) */
         lua_pushcfunction(L, magnet_status_get);                  /* (sp += 1) */          lua_pushcfunction(L, magnet_status_get);                  /* (sp += 1) */
         lua_setfield(L, -2, "__index");                           /* (sp -= 1) */          lua_setfield(L, -2, "__index");                           /* (sp -= 1) */
         lua_pushcfunction(L, magnet_status_set);                  /* (sp += 1) */          lua_pushcfunction(L, magnet_status_set);                  /* (sp += 1) */
         lua_setfield(L, -2, "__newindex");                        /* (sp -= 1) */          lua_setfield(L, -2, "__newindex");                        /* (sp -= 1) */
         lua_pushcfunction(L, magnet_status_pairs);                /* (sp += 1) */          lua_pushcfunction(L, magnet_status_pairs);                /* (sp += 1) */
         lua_setfield(L, -2, "__pairs");                           /* (sp -= 1) */          lua_setfield(L, -2, "__pairs");                           /* (sp -= 1) */
        lua_setmetatable(L, -2); /* tie the metatable to request     (sp -= 1) */        lua_setmetatable(L, -2); /* tie the metatable to statzs      (sp -= 1) */
         lua_setfield(L, -2, "status"); /* content = {}               (sp -= 1) */          lua_setfield(L, -2, "status"); /* content = {}               (sp -= 1) */
   
         /* add empty 'content' and 'header' tables */          /* add empty 'content' and 'header' tables */
Line 968  static handler_t magnet_attract(server *srv, connectio Line 936  static handler_t magnet_attract(server *srv, connectio
         lua_pushcfunction(L, magnet_stat);                        /* (sp += 1) */          lua_pushcfunction(L, magnet_stat);                        /* (sp += 1) */
         lua_setfield(L, -2, "stat"); /* -1 is the env we want to set (sp -= 1) */          lua_setfield(L, -2, "stat"); /* -1 is the env we want to set (sp -= 1) */
   
           /* insert lighty table at index 2 */
           lua_pushvalue(L, -1);
           lua_insert(L, lighty_table_ndx);
   
         lua_setfield(L, -2, "lighty"); /* lighty.*                   (sp -= 1) */          lua_setfield(L, -2, "lighty"); /* lighty.*                   (sp -= 1) */
   
        /* override the default pairs() function to our __pairs capable version */#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
         /* override the default pairs() function to our __pairs capable version;
          * not needed for lua 5.2+
          */
         lua_getglobal(L, "pairs"); /* push original pairs()          (sp += 1) */          lua_getglobal(L, "pairs"); /* push original pairs()          (sp += 1) */
         lua_pushcclosure(L, magnet_pairs, 1);          lua_pushcclosure(L, magnet_pairs, 1);
         lua_setfield(L, -2, "pairs");                             /* (sp -= 1) */          lua_setfield(L, -2, "pairs");                             /* (sp -= 1) */
   #endif
   
         lua_newtable(L); /* the meta-table for the new env           (sp += 1) */          lua_newtable(L); /* the meta-table for the new env           (sp += 1) */
        lua_pushvalue(L, LUA_GLOBALSINDEX);                       /* (sp += 1) */        lua_pushglobaltable(L);                                   /* (sp += 1) */
         lua_setfield(L, -2, "__index"); /* { __index = _G }          (sp -= 1) */          lua_setfield(L, -2, "__index"); /* { __index = _G }          (sp -= 1) */
         lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) (sp -= 1) */          lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) (sp -= 1) */
   
           magnet_setfenv_mainfn(L, 1);                              /* (sp -= 1) */
   
        lua_setfenv(L, -2); /* on the stack should be a modified env (sp -= 1) */        /* pcall will destroy the func value, duplicate it */     /* (sp += 1) */
        lua_pushvalue(L, func_ndx);
        errfunc = push_traceback(L, 0);        {
        if (lua_pcall(L, 0, 1, errfunc)) {                int errfunc = push_traceback(L, 0);
                 int ret = lua_pcall(L, 0, 1, errfunc);
                 lua_remove(L, errfunc);                  lua_remove(L, errfunc);
                 log_error_write(srv, __FILE__, __LINE__,  
                         "ss",  
                         "lua_pcall():",  
                         lua_tostring(L, -1));  
                 lua_pop(L, 1); /* remove the error-msg and the function copy from the stack */  
   
                assert(lua_gettop(L) == 1); /* only the function should be on the stack */                /* reset environment */
                 lua_pushglobaltable(L);                               /* (sp += 1) */
                 magnet_setfenv_mainfn(L, 1);                          /* (sp -= 1) */
   
                con->http_status = 500;                if (0 != ret) {
                con->mode = DIRECT;                        log_error_write(srv, __FILE__, __LINE__,
                                 "ss",
                                 "lua_pcall():",
                                 lua_tostring(L, -1));
                         lua_pop(L, 2); /* remove the error-msg and the lighty table at index 2 */
   
                return HANDLER_FINISHED;                        force_assert(lua_gettop(L) == 1); /* only the function should be on the stack */
        } 
        lua_remove(L, errfunc); 
   
        /* we should have the function-copy and the return value on the stack */                        con->http_status = 500;
        assert(lua_gettop(L) == 2);                        con->mode = DIRECT;
   
        if (lua_isnumber(L, -1)) {                        return HANDLER_FINISHED;
                /* if the ret-value is a number, take it */                }
                lua_return_value = (int)lua_tonumber(L, -1); 
         }          }
         lua_pop(L, 1); /* pop the ret-value */  
   
        magnet_copy_response_header(srv, con, p, L);        /* we should have the function, the lighty table and the return value on the stack */
         force_assert(lua_gettop(L) == 3);
   
        if (lua_return_value > 99) {        lua_return_value = (int) luaL_optinteger(L, -1, -1);
                con->http_status = lua_return_value;        lua_pop(L, 1); /* pop return value */
                con->file_finished = 1; 
   
                /* try { ...*/        magnet_copy_response_header(srv, con, L, lighty_table_ndx);
                if (0 == setjmp(exceptionjmp)) { 
                        magnet_attach_content(srv, con, p, L); 
                        if (!chunkqueue_is_empty(con->write_queue)) { 
                                con->mode = p->id; 
                        } 
                } else { 
                        /* } catch () { */ 
                        con->http_status = 500; 
                        con->mode = DIRECT; 
                } 
   
                assert(lua_gettop(L) == 1); /* only the function should be on the stack */        {
                 handler_t result = HANDLER_GO_ON;
   
                /* we are finished */                if (lua_return_value > 99) {
                return HANDLER_FINISHED;                        con->http_status = lua_return_value;
        } else if (MAGNET_RESTART_REQUEST == lua_return_value) {                        con->file_finished = 1;
                assert(lua_gettop(L) == 1); /* only the function should be on the stack */ 
   
                return HANDLER_COMEBACK;                        /* try { ...*/
        } else {                        if (0 == setjmp(exceptionjmp)) {
                assert(lua_gettop(L) == 1); /* only the function should be on the stack */                                magnet_attach_content(srv, con, L, lighty_table_ndx);
                                 if (!chunkqueue_is_empty(con->write_queue)) {
                                         con->mode = p->id;
                                 }
                         } else {
                                 lua_settop(L, 2); /* remove all but function and lighty table */
                                 /* } catch () { */
                                 con->http_status = 500;
                                 con->mode = DIRECT;
                         }
   
                return HANDLER_GO_ON;                        result = HANDLER_FINISHED;
                 } else if (MAGNET_RESTART_REQUEST == lua_return_value) {
                         result = HANDLER_COMEBACK;
                 }
 
                 lua_pop(L, 1); /* pop the lighty table */
                 force_assert(lua_gettop(L) == 1); /* only the function should remain on the stack */
 
                 return result;
         }          }
 }  }
   
 static handler_t magnet_attract_array(server *srv, connection *con, plugin_data *p, array *files) {  static handler_t magnet_attract_array(server *srv, connection *con, plugin_data *p, array *files) {
         size_t i;          size_t i;
           handler_t ret = HANDLER_GO_ON;
   
         /* no filename set */          /* no filename set */
         if (files->used == 0) return HANDLER_GO_ON;          if (files->used == 0) return HANDLER_GO_ON;
Line 1052  static handler_t magnet_attract_array(server *srv, con Line 1035  static handler_t magnet_attract_array(server *srv, con
         /**          /**
          * execute all files and jump out on the first !HANDLER_GO_ON           * execute all files and jump out on the first !HANDLER_GO_ON
          */           */
        for (i = 0; i < files->used; i++) {        for (i = 0; i < files->used && ret == HANDLER_GO_ON; i++) {
                 data_string *ds = (data_string *)files->data[i];                  data_string *ds = (data_string *)files->data[i];
                 handler_t ret;  
   
                if (buffer_is_empty(ds->value)) continue;                if (buffer_string_is_empty(ds->value)) continue;
   
                 ret = magnet_attract(srv, con, p, ds->value);                  ret = magnet_attract(srv, con, p, ds->value);
           }
   
                if (ret != HANDLER_GO_ON) return ret;        if (con->error_handler_saved_status) {
                 /* retrieve (possibly modified) REDIRECT_STATUS and store as number */
                 unsigned long x;
                 data_string * const ds = (data_string *)array_get_element(con->environment, "REDIRECT_STATUS");
                 if (ds && (x = strtoul(ds->value->ptr, NULL, 10)) < 1000)
                         /*(simplified validity check x < 1000)*/
                         con->error_handler_saved_status =
                           con->error_handler_saved_status > 0 ? (int)x : -(int)x;
         }          }
   
        return HANDLER_GO_ON;        return ret;
 }  }
   
 URIHANDLER_FUNC(mod_magnet_uri_handler) {  URIHANDLER_FUNC(mod_magnet_uri_handler) {
Line 1102  int mod_magnet_plugin_init(plugin *p) { Line 1092  int mod_magnet_plugin_init(plugin *p) {
 }  }
   
 #else  #else
   
   #pragma message("lua is required, but was not found")
   
 int mod_magnet_plugin_init(plugin *p);  int mod_magnet_plugin_init(plugin *p);
 int mod_magnet_plugin_init(plugin *p) {  int mod_magnet_plugin_init(plugin *p) {
         UNUSED(p);          UNUSED(p);

Removed from v.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>