1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "lua_config.h"
19 #include "lua_vmprep.h"
20 
21 APLOG_USE_MODULE(lua);
22 
check_dir_config(lua_State * L,int index)23 static ap_lua_dir_cfg *check_dir_config(lua_State *L, int index)
24 {
25     ap_lua_dir_cfg *cfg;
26     luaL_checkudata(L, index, "Apache2.DirConfig");
27     cfg = (ap_lua_dir_cfg *) lua_unboxpointer(L, index);
28     return cfg;
29 }
30 
check_cmd_parms(lua_State * L,int index)31 static cmd_parms *check_cmd_parms(lua_State *L, int index)
32 {
33     cmd_parms *cmd;
34     luaL_checkudata(L, index, "Apache2.CommandParameters");
35     cmd = (cmd_parms *) lua_unboxpointer(L, index);
36     return cmd;
37 }
38 
apl_toscope(const char * name)39 static int apl_toscope(const char *name)
40 {
41     if (0 == strcmp("once", name))
42         return AP_LUA_SCOPE_ONCE;
43     if (0 == strcmp("request", name))
44         return AP_LUA_SCOPE_REQUEST;
45     if (0 == strcmp("connection", name))
46         return AP_LUA_SCOPE_CONN;
47     if (0 == strcmp("conn", name))
48         return AP_LUA_SCOPE_CONN;
49     if (0 == strcmp("thread", name))
50         return AP_LUA_SCOPE_THREAD;
51     return AP_LUA_SCOPE_ONCE;
52 }
53 
ap_lua_map_handler(ap_lua_dir_cfg * cfg,const char * file,const char * function,const char * pattern,const char * scope)54 apr_status_t ap_lua_map_handler(ap_lua_dir_cfg *cfg,
55                                                  const char *file,
56                                                  const char *function,
57                                                  const char *pattern,
58                                                  const char *scope)
59 {
60     ap_regex_t *uri_pattern;
61     apr_status_t rv;
62     ap_lua_mapped_handler_spec *handler =
63         apr_pcalloc(cfg->pool, sizeof(ap_lua_mapped_handler_spec));
64     handler->uri_pattern = NULL;
65     handler->function_name = NULL;
66 
67     uri_pattern = apr_palloc(cfg->pool, sizeof(ap_regex_t));
68     if ((rv = ap_regcomp(uri_pattern, pattern, 0)) != APR_SUCCESS) {
69         return rv;
70     }
71     handler->file_name = apr_pstrdup(cfg->pool, file);
72     handler->uri_pattern = uri_pattern;
73     handler->scope = apl_toscope(scope);
74 
75     handler->function_name = apr_pstrdup(cfg->pool, function);
76     *(const ap_lua_mapped_handler_spec **) apr_array_push(cfg->mapped_handlers) =
77         handler;
78     return APR_SUCCESS;
79 }
80 
81 /* Change to use ap_lua_map_handler */
cfg_lua_map_handler(lua_State * L)82 static int cfg_lua_map_handler(lua_State *L)
83 {
84     ap_lua_dir_cfg *cfg = check_dir_config(L, 1);
85     ap_lua_mapped_handler_spec *handler =
86         apr_pcalloc(cfg->pool, sizeof(ap_lua_mapped_handler_spec));
87     handler->uri_pattern = NULL;
88     handler->function_name = NULL;
89 
90     luaL_checktype(L, 2, LUA_TTABLE);
91     lua_getfield(L, 2, "file");
92     if (lua_isstring(L, -1)) {
93         const char *file = lua_tostring(L, -1);
94         handler->file_name = apr_pstrdup(cfg->pool, file);
95     }
96     lua_pop(L, 1);
97 
98     lua_getfield(L, 2, "pattern");
99     if (lua_isstring(L, -1)) {
100         const char *pattern = lua_tostring(L, -1);
101 
102         ap_regex_t *uri_pattern = apr_palloc(cfg->pool, sizeof(ap_regex_t));
103         if (ap_regcomp(uri_pattern, pattern, 0) != OK) {
104             return luaL_error(L, "Unable to compile regular expression, '%s'",
105                               pattern);
106         }
107         handler->uri_pattern = uri_pattern;
108     }
109     lua_pop(L, 1);
110 
111     lua_getfield(L, 2, "scope");
112     if (lua_isstring(L, -1)) {
113         const char *scope = lua_tostring(L, -1);
114         handler->scope = apl_toscope(scope);
115     }
116     else {
117         handler->scope = AP_LUA_SCOPE_ONCE;
118     }
119     lua_pop(L, 1);
120 
121     lua_getfield(L, 2, "func");
122     if (lua_isstring(L, -1)) {
123         const char *value = lua_tostring(L, -1);
124         handler->function_name = apr_pstrdup(cfg->pool, value);
125     }
126     else {
127         handler->function_name = "handle";
128     }
129     lua_pop(L, 1);
130 
131 
132     *(const ap_lua_mapped_handler_spec **) apr_array_push(cfg->mapped_handlers) =
133         handler;
134     return 0;
135 }
136 
cfg_directory(lua_State * L)137 static int cfg_directory(lua_State *L)
138 {
139     ap_lua_dir_cfg *cfg = check_dir_config(L, 1);
140     lua_pushstring(L, cfg->dir);
141     return 1;
142 }
143 
144 /*static int cfg_root(lua_State *L) {
145     ap_lua_dir_cfg *cfg = check_dir_config(L, 1);
146     lua_pushstring(L, cfg->root_path);
147     return 1;
148 }*/
149 
150 static const struct luaL_Reg cfg_methods[] = {
151     {"match_handler", cfg_lua_map_handler},
152     {"directory", cfg_directory},
153     /* {"root", cfg_root}, */
154     {NULL, NULL}
155 };
156 
157 /* helper function for the logging functions below */
cmd_log_at(lua_State * L,int level)158 static int cmd_log_at(lua_State *L, int level)
159 {
160     const char *msg;
161     cmd_parms *cmd = check_cmd_parms(L, 1);
162     lua_Debug dbg;
163 
164     lua_getstack(L, 1, &dbg);
165     lua_getinfo(L, "Sl", &dbg);
166 
167     msg = luaL_checkstring(L, 2);
168     ap_log_error(dbg.source, dbg.currentline, APLOG_MODULE_INDEX, level, 0,
169                  cmd->server, "%s", msg);
170     return 0;
171 }
172 
173 /* r:debug(String) and friends which use apache logging */
cmd_emerg(lua_State * L)174 static int cmd_emerg(lua_State *L)
175 {
176     return cmd_log_at(L, APLOG_EMERG);
177 }
cmd_alert(lua_State * L)178 static int cmd_alert(lua_State *L)
179 {
180     return cmd_log_at(L, APLOG_ALERT);
181 }
cmd_crit(lua_State * L)182 static int cmd_crit(lua_State *L)
183 {
184     return cmd_log_at(L, APLOG_CRIT);
185 }
cmd_err(lua_State * L)186 static int cmd_err(lua_State *L)
187 {
188     return cmd_log_at(L, APLOG_ERR);
189 }
cmd_warn(lua_State * L)190 static int cmd_warn(lua_State *L)
191 {
192     return cmd_log_at(L, APLOG_WARNING);
193 }
cmd_notice(lua_State * L)194 static int cmd_notice(lua_State *L)
195 {
196     return cmd_log_at(L, APLOG_NOTICE);
197 }
cmd_info(lua_State * L)198 static int cmd_info(lua_State *L)
199 {
200     return cmd_log_at(L, APLOG_INFO);
201 }
cmd_debug(lua_State * L)202 static int cmd_debug(lua_State *L)
203 {
204     return cmd_log_at(L, APLOG_DEBUG);
205 }
cmd_trace1(lua_State * L)206 static int cmd_trace1(lua_State *L)
207 {
208     return cmd_log_at(L, APLOG_TRACE1);
209 }
cmd_trace2(lua_State * L)210 static int cmd_trace2(lua_State *L)
211 {
212     return cmd_log_at(L, APLOG_TRACE2);
213 }
cmd_trace3(lua_State * L)214 static int cmd_trace3(lua_State *L)
215 {
216     return cmd_log_at(L, APLOG_TRACE3);
217 }
cmd_trace4(lua_State * L)218 static int cmd_trace4(lua_State *L)
219 {
220     return cmd_log_at(L, APLOG_TRACE4);
221 }
cmd_trace5(lua_State * L)222 static int cmd_trace5(lua_State *L)
223 {
224     return cmd_log_at(L, APLOG_TRACE5);
225 }
cmd_trace6(lua_State * L)226 static int cmd_trace6(lua_State *L)
227 {
228     return cmd_log_at(L, APLOG_TRACE6);
229 }
cmd_trace7(lua_State * L)230 static int cmd_trace7(lua_State *L)
231 {
232     return cmd_log_at(L, APLOG_TRACE7);
233 }
cmd_trace8(lua_State * L)234 static int cmd_trace8(lua_State *L)
235 {
236     return cmd_log_at(L, APLOG_TRACE8);
237 }
238 
239 static const struct luaL_Reg cmd_methods[] = {
240     {"trace8", cmd_trace8},
241     {"trace7", cmd_trace7},
242     {"trace6", cmd_trace6},
243     {"trace5", cmd_trace5},
244     {"trace4", cmd_trace4},
245     {"trace3", cmd_trace3},
246     {"trace2", cmd_trace2},
247     {"trace1", cmd_trace1},
248     {"debug", cmd_debug},
249     {"info", cmd_info},
250     {"notice", cmd_notice},
251     {"warn", cmd_warn},
252     {"err", cmd_err},
253     {"crit", cmd_crit},
254     {"alert", cmd_alert},
255     {"emerg", cmd_emerg},
256 
257     {NULL, NULL}
258 };
259 
ap_lua_load_config_lmodule(lua_State * L)260 void ap_lua_load_config_lmodule(lua_State *L)
261 {
262     luaL_newmetatable(L, "Apache2.DirConfig");  /* [metatable] */
263     lua_pushvalue(L, -1);
264 
265     lua_setfield(L, -2, "__index");
266     luaL_register(L, NULL, cfg_methods);        /* [metatable] */
267 
268 
269     luaL_newmetatable(L, "Apache2.CommandParameters");
270     lua_pushvalue(L, -1);
271 
272     lua_setfield(L, -2, "__index");
273     luaL_register(L, NULL, cmd_methods);        /* [metatable] */
274 
275 }
276