From: Daniel Gruno Date: Fri, 28 Mar 2014 18:38:41 +0000 (+0000) Subject: mod_lua: Redesign the table construction/access mechanism, so we pass on a struct... X-Git-Tag: 2.5.0-alpha~4379 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d38e1b6e830761a3c828c174f437f3f8e7cd7b3e;p=apache mod_lua: Redesign the table construction/access mechanism, so we pass on a struct with the request_rec, the table pointer and the table name instead of just the table pointer. This allows us to use the request_rec for logging/editing purposes, as well as inform the user which exact table in the request_rec was modified. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1582858 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index 1492ccd552..c7726ec82a 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -2614 +2615 diff --git a/modules/lua/lua_apr.c b/modules/lua/lua_apr.c index 867a370078..70158fad79 100644 --- a/modules/lua/lua_apr.c +++ b/modules/lua/lua_apr.c @@ -17,17 +17,18 @@ #include "mod_lua.h" #include "lua_apr.h" +APLOG_USE_MODULE(lua); -apr_table_t *ap_lua_check_apr_table(lua_State *L, int index) +req_table_t *ap_lua_check_apr_table(lua_State *L, int index) { - apr_table_t *t; + req_table_t* t; luaL_checkudata(L, index, "Apr.Table"); t = lua_unboxpointer(L, index); return t; } -void ap_lua_push_apr_table(lua_State *L, apr_table_t *t) +void ap_lua_push_apr_table(lua_State *L, req_table_t *t) { lua_boxpointer(L, t); luaL_getmetatable(L, "Apr.Table"); @@ -36,26 +37,35 @@ void ap_lua_push_apr_table(lua_State *L, apr_table_t *t) static int lua_table_set(lua_State *L) { - apr_table_t *t = ap_lua_check_apr_table(L, 1); + req_table_t *t = ap_lua_check_apr_table(L, 1); const char *key = luaL_checkstring(L, 2); const char *val = luaL_checkstring(L, 3); - - /* Prevent response/header splitting by not allowing newlines in tables. - * At this stage, we don't have the request_rec handy, and we can't change - * a const char*, so we'll redirect to a standard error value instead. - */ - if (ap_strchr_c(val, '\n')) { - val = "[ERROR: Value contains newline, ignored.]"; + /* Unless it's the 'notes' table, check for newline chars */ + if (strcmp(t->n, "notes") && ap_strchr_c(val, '\n')) { + char *badchar; + char *replacement = apr_pstrdup(t->r->pool, val); + badchar = replacement; + while ( (badchar = ap_strchr(badchar, '\n')) ) { + *badchar = ' '; + } + if (t->r != NULL) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, t->r, + APLOGNO(02614) "mod_lua: Value for '%s' in table '%s' contains newline!", + key, t->n); + } + apr_table_set(t->t, key, replacement); + } + else { + apr_table_set(t->t, key, val); } - apr_table_set(t, key, val); return 0; } static int lua_table_get(lua_State *L) { - apr_table_t *t = ap_lua_check_apr_table(L, 1); + req_table_t *t = ap_lua_check_apr_table(L, 1); const char *key = luaL_checkstring(L, 2); - const char *val = apr_table_get(t, key); + const char *val = apr_table_get(t->t, key); lua_pushstring(L, val); return 1; } diff --git a/modules/lua/lua_apr.h b/modules/lua/lua_apr.h index 8a1428ffbb..c194f11cbb 100644 --- a/modules/lua/lua_apr.h +++ b/modules/lua/lua_apr.h @@ -30,7 +30,7 @@ int ap_lua_init(lua_State *L, apr_pool_t * p); -apr_table_t *ap_lua_check_apr_table(lua_State *L, int index); -void ap_lua_push_apr_table(lua_State *L, apr_table_t *t); +req_table_t *ap_lua_check_apr_table(lua_State *L, int index); +void ap_lua_push_apr_table(lua_State *L, req_table_t *t); #endif /* !_LUA_APR_H_ */ diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c index 83ecd88cff..fd8e208cc2 100644 --- a/modules/lua/lua_request.c +++ b/modules/lua/lua_request.c @@ -44,7 +44,7 @@ APLOG_USE_MODULE(lua); typedef char *(*req_field_string_f) (request_rec * r); typedef int (*req_field_int_f) (request_rec * r); -typedef apr_table_t *(*req_field_apr_table_f) (request_rec * r); +typedef req_table_t *(*req_field_apr_table_f) (request_rec * r); void ap_lua_rstack_dump(lua_State *L, request_rec *r, const char *msg) @@ -644,29 +644,49 @@ static int req_assbackwards_field(request_rec *r) return r->assbackwards; } -static apr_table_t* req_headers_in(request_rec *r) +static req_table_t* req_headers_in(request_rec *r) { - return r->headers_in; + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); + t->r = r; + t->t = r->headers_in; + t->n = "headers_in"; + return t; } -static apr_table_t* req_headers_out(request_rec *r) +static req_table_t* req_headers_out(request_rec *r) { - return r->headers_out; + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); + t->r = r; + t->t = r->headers_out; + t->n = "headers_out"; + return t; } -static apr_table_t* req_err_headers_out(request_rec *r) +static req_table_t* req_err_headers_out(request_rec *r) { - return r->err_headers_out; + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); + t->r = r; + t->t = r->err_headers_out; + t->n = "err_headers_out"; + return t; } -static apr_table_t* req_subprocess_env(request_rec *r) +static req_table_t* req_subprocess_env(request_rec *r) { - return r->subprocess_env; + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); + t->r = r; + t->t = r->subprocess_env; + t->n = "subprocess_env"; + return t; } -static apr_table_t* req_notes(request_rec *r) +static req_table_t* req_notes(request_rec *r) { - return r->notes; + req_table_t* t = apr_palloc(r->pool, sizeof(req_table_t)); + t->r = r; + t->t = r->notes; + t->n = "notes"; + return t; } static int req_ssl_is_https_field(request_rec *r) @@ -1788,7 +1808,7 @@ static int req_dispatch(lua_State *L) if (rft) { switch (rft->type) { case APL_REQ_FUNTYPE_TABLE:{ - apr_table_t *rs; + req_table_t *rs; req_field_apr_table_f func = (req_field_apr_table_f)rft->fun; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01486) "request_rec->dispatching %s -> apr table", @@ -2858,12 +2878,17 @@ void ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p) void ap_lua_push_connection(lua_State *L, conn_rec *c) { + req_table_t* t; lua_boxpointer(L, c); luaL_getmetatable(L, "Apache2.Connection"); lua_setmetatable(L, -2); luaL_getmetatable(L, "Apache2.Connection"); - ap_lua_push_apr_table(L, c->notes); + t = apr_pcalloc(c->pool, sizeof(req_table_t)); + t->t = c->notes; + t->r = NULL; + t->n = "notes"; + ap_lua_push_apr_table(L, t); lua_setfield(L, -2, "notes"); lua_pushstring(L, c->client_ip); diff --git a/modules/lua/lua_request.h b/modules/lua/lua_request.h index b5ed3e5fc0..a39f4b97b1 100644 --- a/modules/lua/lua_request.h +++ b/modules/lua/lua_request.h @@ -38,6 +38,15 @@ typedef struct int type; } req_fun_t; + +/* Struct to use as userdata for request_rec tables */ +typedef struct +{ + request_rec *r; /* Request_rec */ + apr_table_t *t; /* apr_table_t* */ + const char *n; /* name of table */ +} req_table_t; + typedef struct { int type; size_t size;