Browse Source

Add some iterators for mod_magnet (fixes #1307)

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2644 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.24
Stefan Bühler 12 years ago
parent
commit
915a9e3e88
  1. 1
      NEWS
  2. 227
      src/mod_magnet.c

1
NEWS

@ -51,6 +51,7 @@ NEWS
* mod_usertrack: Use T_CONFIG_INT for max-age, solves range problem (#1455)
* mod_accesslog: configurable timestamp logging (fixes #1479)
* always define _GNU_SOURCE
* Add some iterators for mod_magnet (fixes #1307)
- 1.4.23 - 2009-06-19
* Added some extra warning options in cmake and fix the resulting warnings (unused/static functions)

227
src/mod_magnet.c

@ -158,6 +158,80 @@ static int mod_magnet_patch_connection(server *srv, connection *con, plugin_data
}
#undef PATCH
/* 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) {
luaL_checkany(L, 1);
if (luaL_getmetafield(L, 1, "__pairs")) {
lua_insert(L, 1);
lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
return lua_gettop(L);
} else {
lua_pushvalue(L, lua_upvalueindex(1));
lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
return lua_gettop(L);
}
}
/* 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) {
data_unset *du;
data_string *ds;
data_integer *di;
size_t pos = lua_tointeger(L, lua_upvalueindex(1));
array *a = lua_touserdata(L, lua_upvalueindex(2));
lua_settop(L, 0);
if (pos >= a->used) return 0;
if (NULL != (du = a->data[pos])) {
if (du->key->used) {
lua_pushlstring(L, du->key->ptr, du->key->used - 1);
}
else {
lua_pushlstring(L, "", 0);
}
switch (du->type) {
case TYPE_STRING:
ds = (data_string *)du;
if (ds->value && ds->value->used) {
lua_pushlstring(L, ds->value->ptr, ds->value->used - 1);
} else {
lua_pushnil(L);
}
break;
case TYPE_COUNT:
case TYPE_INTEGER:
di = (data_integer *)du;
lua_pushinteger(L, di->value);
break;
default:
lua_pushnil(L);
break;
}
/* Update our positional upval to reflect our new current position */
pos++;
lua_pushinteger(L, pos);
lua_replace(L, lua_upvalueindex(1));
/* Returning 2 items on the stack (key, value) */
return 2;
}
return 0;
}
/* Create the closure necessary to iterate over the array *a with the above function */
static int magnet_array_pairs(lua_State *L, array *a) {
lua_pushinteger(L, 0); /* Push our current pos (the start) into upval 1 */
lua_pushlightuserdata(L, a); /* Push our array *a into upval 2 */
lua_pushcclosure(L, magnet_array_next, 2); /* Push our new closure with 2 upvals */
return 1;
}
static int magnet_print(lua_State *L) {
const char *s = luaL_checkstring(L, 1);
server *srv;
@ -305,6 +379,17 @@ static int magnet_reqhdr_get(lua_State *L) {
return 1;
}
static int magnet_reqhdr_pairs(lua_State *L) {
connection *con;
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);
}
static int magnet_status_get(lua_State *L) {
data_integer *di;
server *srv;
@ -341,6 +426,17 @@ static int magnet_status_set(lua_State *L) {
return 0;
}
static int magnet_status_pairs(lua_State *L) {
server *srv;
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);
}
typedef struct {
const char *name;
enum {
@ -362,33 +458,32 @@ typedef struct {
MAGNET_ENV_REQUEST_PATH_INFO,
MAGNET_ENV_REQUEST_REMOTE_IP,
MAGNET_ENV_REQUEST_PROTOCOL
} type;
} type;
} magnet_env_t;
static buffer *magnet_env_get_buffer(server *srv, connection *con, const char *key) {
buffer *dest = NULL;
size_t i;
static const magnet_env_t magnet_env[] = {
{ "physical.path", MAGNET_ENV_PHYICAL_PATH },
{ "physical.rel-path", MAGNET_ENV_PHYICAL_REL_PATH },
{ "physical.doc-root", MAGNET_ENV_PHYICAL_DOC_ROOT },
const magnet_env_t env[] = {
{ "physical.path", MAGNET_ENV_PHYICAL_PATH },
{ "physical.rel-path", MAGNET_ENV_PHYICAL_REL_PATH },
{ "physical.doc-root", MAGNET_ENV_PHYICAL_DOC_ROOT },
{ "uri.path", MAGNET_ENV_URI_PATH },
{ "uri.path-raw", MAGNET_ENV_URI_PATH_RAW },
{ "uri.scheme", MAGNET_ENV_URI_SCHEME },
{ "uri.authority", MAGNET_ENV_URI_AUTHORITY },
{ "uri.query", MAGNET_ENV_URI_QUERY },
{ "request.method", MAGNET_ENV_REQUEST_METHOD },
{ "request.uri", MAGNET_ENV_REQUEST_URI },
{ "request.orig-uri", MAGNET_ENV_REQUEST_ORIG_URI },
{ "request.path-info", MAGNET_ENV_REQUEST_PATH_INFO },
{ "request.remote-ip", MAGNET_ENV_REQUEST_REMOTE_IP },
{ "request.protocol", MAGNET_ENV_REQUEST_PROTOCOL },
{ NULL, MAGNET_ENV_UNSET }
};
{ "uri.path", MAGNET_ENV_URI_PATH },
{ "uri.path-raw", MAGNET_ENV_URI_PATH_RAW },
{ "uri.scheme", MAGNET_ENV_URI_SCHEME },
{ "uri.authority", MAGNET_ENV_URI_AUTHORITY },
{ "uri.query", MAGNET_ENV_URI_QUERY },
{ "request.method", MAGNET_ENV_REQUEST_METHOD },
{ "request.uri", MAGNET_ENV_REQUEST_URI },
{ "request.orig-uri", MAGNET_ENV_REQUEST_ORIG_URI },
{ "request.path-info", MAGNET_ENV_REQUEST_PATH_INFO },
{ "request.remote-ip", MAGNET_ENV_REQUEST_REMOTE_IP },
{ "request.protocol", MAGNET_ENV_REQUEST_PROTOCOL },
{ NULL, MAGNET_ENV_UNSET }
};
static buffer *magnet_env_get_buffer_by_id(server *srv, connection *con, int id) {
buffer *dest = NULL;
UNUSED(srv);
@ -397,11 +492,7 @@ static buffer *magnet_env_get_buffer(server *srv, connection *con, const char *k
*
*/
for (i = 0; env[i].name; i++) {
if (0 == strcmp(key, env[i].name)) break;
}
switch (env[i].type) {
switch (id) {
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_DOC_ROOT: dest = con->physical.doc_root; break;
@ -431,6 +522,16 @@ static buffer *magnet_env_get_buffer(server *srv, connection *con, const char *k
return dest;
}
static buffer *magnet_env_get_buffer(server *srv, connection *con, const char *key) {
size_t i;
for (i = 0; magnet_env[i].name; i++) {
if (0 == strcmp(key, magnet_env[i].name)) break;
}
return magnet_env_get_buffer_by_id(srv, con, magnet_env[i].type);
}
static int magnet_env_get(lua_State *L) {
server *srv;
connection *con;
@ -488,6 +589,50 @@ static int magnet_env_set(lua_State *L) {
return 0;
}
static int magnet_env_next(lua_State *L) {
server *srv;
connection *con;
int pos = lua_tointeger(L, lua_upvalueindex(1));
buffer *dest;
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);
lua_settop(L, 0);
if (NULL == magnet_env[pos].name) return 0; /* end of list */
lua_pushstring(L, magnet_env[pos].name);
dest = magnet_env_get_buffer_by_id(srv, con, magnet_env[pos].type);
if (dest && dest->used) {
lua_pushlstring(L, dest->ptr, dest->used - 1);
} else {
lua_pushnil(L);
}
/* Update our positional upval to reflect our new current position */
pos++;
lua_pushinteger(L, pos);
lua_replace(L, lua_upvalueindex(1));
/* Returning 2 items on the stack (key, value) */
return 2;
}
static int magnet_env_pairs(lua_State *L) {
lua_pushinteger(L, 0); /* Push our current pos (the start) into upval 1 */
lua_pushcclosure(L, magnet_env_next, 1); /* Push our new closure with 1 upvals */
return 1;
}
static int magnet_cgi_get(lua_State *L) {
connection *con;
@ -524,6 +669,17 @@ static int magnet_cgi_set(lua_State *L) {
return 0;
}
static int magnet_cgi_pairs(lua_State *L) {
connection *con;
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);
}
static int magnet_copy_response_header(server *srv, connection *con, plugin_data *p, lua_State *L) {
UNUSED(p);
@ -733,6 +889,8 @@ static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, bu
lua_newtable(L); /* the meta-table for the request-table (sp += 1) */
lua_pushcfunction(L, magnet_reqhdr_get); /* (sp += 1) */
lua_setfield(L, -2, "__index"); /* (sp -= 1) */
lua_pushcfunction(L, magnet_reqhdr_pairs); /* (sp += 1) */
lua_setfield(L, -2, "__pairs"); /* (sp -= 1) */
lua_setmetatable(L, -2); /* tie the metatable to request (sp -= 1) */
lua_setfield(L, -2, "request"); /* content = {} (sp -= 1) */
@ -742,6 +900,8 @@ static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, bu
lua_setfield(L, -2, "__index"); /* (sp -= 1) */
lua_pushcfunction(L, magnet_env_set); /* (sp += 1) */
lua_setfield(L, -2, "__newindex"); /* (sp -= 1) */
lua_pushcfunction(L, magnet_env_pairs); /* (sp += 1) */
lua_setfield(L, -2, "__pairs"); /* (sp -= 1) */
lua_setmetatable(L, -2); /* tie the metatable to request (sp -= 1) */
lua_setfield(L, -2, "env"); /* content = {} (sp -= 1) */
@ -751,6 +911,8 @@ static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, bu
lua_setfield(L, -2, "__index"); /* (sp -= 1) */
lua_pushcfunction(L, magnet_cgi_set); /* (sp += 1) */
lua_setfield(L, -2, "__newindex"); /* (sp -= 1) */
lua_pushcfunction(L, magnet_cgi_pairs); /* (sp += 1) */
lua_setfield(L, -2, "__pairs"); /* (sp -= 1) */
lua_setmetatable(L, -2); /* tie the metatable to req_env (sp -= 1) */
lua_setfield(L, -2, "req_env"); /* content = {} (sp -= 1) */
@ -760,6 +922,8 @@ static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, bu
lua_setfield(L, -2, "__index"); /* (sp -= 1) */
lua_pushcfunction(L, magnet_status_set); /* (sp += 1) */
lua_setfield(L, -2, "__newindex"); /* (sp -= 1) */
lua_pushcfunction(L, magnet_status_pairs); /* (sp += 1) */
lua_setfield(L, -2, "__pairs"); /* (sp -= 1) */
lua_setmetatable(L, -2); /* tie the metatable to request (sp -= 1) */
lua_setfield(L, -2, "status"); /* content = {} (sp -= 1) */
@ -778,6 +942,11 @@ static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, bu
lua_setfield(L, -2, "lighty"); /* lighty.* (sp -= 1) */
/* override the default pairs() function to our __pairs capable version */
lua_getglobal(L, "pairs"); /* push original pairs() (sp += 1) */
lua_pushcclosure(L, magnet_pairs, 1);
lua_setfield(L, -2, "pairs"); /* (sp -= 1) */
lua_newtable(L); /* the meta-table for the new env (sp += 1) */
lua_pushvalue(L, LUA_GLOBALSINDEX); /* (sp += 1) */
lua_setfield(L, -2, "__index"); /* { __index = _G } (sp -= 1) */

Loading…
Cancel
Save