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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "lua_config.h"
21 #include "apr_file_info.h"
23 APLOG_USE_MODULE(lua);
25 /* forward dec'l from this file */
28 static void pstack_dump(lua_State *L, apr_pool_t *r, int level,
32 int top = lua_gettop(L);
34 ap_log_perror(APLOG_MARK, level, 0, r, "Lua Stack Dump: [%s]", msg);
36 for (i = 1; i <= top; i++) {
37 int t = lua_type(L, i);
40 ap_log_perror(APLOG_MARK, level, 0, r,
41 "%d: '%s'", i, lua_tostring(L, i));
45 ap_log_perror(APLOG_MARK, level, 0, r, "%d: userdata", i);
48 case LUA_TLIGHTUSERDATA:{
49 ap_log_perror(APLOG_MARK, level, 0, r, "%d: lightuserdata",
54 ap_log_perror(APLOG_MARK, level, 0, r, "%d: NIL", i);
58 ap_log_perror(APLOG_MARK, level, 0, r, "%d: None", i);
62 ap_log_perror(APLOG_MARK, level, 0, r,
63 "%d: %s", i, lua_toboolean(L,
69 ap_log_perror(APLOG_MARK, level, 0, r,
70 "%d: %g", i, lua_tonumber(L, i));
74 ap_log_perror(APLOG_MARK, level, 0, r, "%d: <table>", i);
78 ap_log_perror(APLOG_MARK, level, 0, r, "%d: <thread>", i);
82 ap_log_perror(APLOG_MARK, level, 0, r, "%d: <function>", i);
86 ap_log_perror(APLOG_MARK, level, 0, r,
87 "%d: unknown: [%s]", i, lua_typename(L, i));
97 /* BEGIN apache lmodule */
99 AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
101 lua_getglobal(L, "package");
102 lua_getfield(L, -1, "loaded");
104 lua_setfield(L, -2, "apache2");
105 lua_setglobal(L, "apache2");
106 lua_pop(L, 1); /* empty stack */
108 lua_getglobal(L, "apache2");
109 lua_pushinteger(L, OK);
110 lua_setfield(L, -2, "OK");
112 lua_pushinteger(L, DECLINED);
113 lua_setfield(L, -2, "DECLINED");
115 lua_pushinteger(L, DONE);
116 lua_setfield(L, -2, "DONE");
118 lua_pushstring(L, ap_get_server_banner());
119 lua_setfield(L, -2, "version");
121 lua_pushinteger(L, HTTP_MOVED_TEMPORARILY);
122 lua_setfield(L, -2, "HTTP_MOVED_TEMPORARILY");
124 lua_pushinteger(L, PROXYREQ_NONE);
125 lua_setfield(L, -2, "PROXYREQ_NONE");
127 lua_pushinteger(L, PROXYREQ_PROXY);
128 lua_setfield(L, -2, "PROXYREQ_PROXY");
130 lua_pushinteger(L, PROXYREQ_REVERSE);
131 lua_setfield(L, -2, "PROXYREQ_REVERSE");
133 lua_pushinteger(L, PROXYREQ_RESPONSE);
134 lua_setfield(L, -2, "PROXYREQ_RESPONSE");
137 lua_pushinteger(L, HTTP_CONTINUE);
138 lua_setfield(L, -2, "HTTP_CONTINUE");
139 lua_pushinteger(L, HTTP_SWITCHING_PROTOCOLS);
140 lua_setfield(L, -2, "HTTP_SWITCHING_PROTOCOLS");
141 lua_pushinteger(L, HTTP_PROCESSING);
142 lua_setfield(L, -2, "HTTP_PROCESSING");
143 lua_pushinteger(L, HTTP_OK);
144 lua_setfield(L, -2, "HTTP_OK");
145 lua_pushinteger(L, HTTP_CREATED);
146 lua_setfield(L, -2, "HTTP_CREATED");
147 lua_pushinteger(L, HTTP_ACCEPTED);
148 lua_setfield(L, -2, "HTTP_ACCEPTED");
149 lua_pushinteger(L, HTTP_NON_AUTHORITATIVE);
150 lua_setfield(L, -2, "HTTP_NON_AUTHORITATIVE");
151 lua_pushinteger(L, HTTP_NO_CONTENT);
152 lua_setfield(L, -2, "HTTP_NO_CONTENT");
153 lua_pushinteger(L, HTTP_RESET_CONTENT);
154 lua_setfield(L, -2, "HTTP_RESET_CONTENT");
155 lua_pushinteger(L, HTTP_PARTIAL_CONTENT);
156 lua_setfield(L, -2, "HTTP_PARTIAL_CONTENT");
157 lua_pushinteger(L, HTTP_MULTI_STATUS);
158 lua_setfield(L, -2, "HTTP_MULTI_STATUS");
159 lua_pushinteger(L, HTTP_MULTIPLE_CHOICES);
160 lua_setfield(L, -2, "HTTP_MULTIPLE_CHOICES");
161 lua_pushinteger(L, HTTP_MOVED_PERMANENTLY);
162 lua_setfield(L, -2, "HTTP_MOVED_PERMANENTLY");
163 lua_pushinteger(L, HTTP_SEE_OTHER);
164 lua_setfield(L, -2, "HTTP_SEE_OTHER");
165 lua_pushinteger(L, HTTP_NOT_MODIFIED);
166 lua_setfield(L, -2, "HTTP_NOT_MODIFIED");
167 lua_pushinteger(L, HTTP_USE_PROXY);
168 lua_setfield(L, -2, "HTTP_USE_PROXY");
169 lua_pushinteger(L, HTTP_TEMPORARY_REDIRECT);
170 lua_setfield(L, -2, "HTTP_TEMPORARY_REDIRECT");
171 lua_pushinteger(L, HTTP_BAD_REQUEST);
172 lua_setfield(L, -2, "HTTP_BAD_REQUEST");
173 lua_pushinteger(L, HTTP_UNAUTHORIZED);
174 lua_setfield(L, -2, "HTTP_UNAUTHORIZED");
175 lua_pushinteger(L, HTTP_PAYMENT_REQUIRED);
176 lua_setfield(L, -2, "HTTP_PAYMENT_REQUIRED");
177 lua_pushinteger(L, HTTP_FORBIDDEN);
178 lua_setfield(L, -2, "HTTP_FORBIDDEN");
179 lua_pushinteger(L, HTTP_NOT_FOUND);
180 lua_setfield(L, -2, "HTTP_NOT_FOUND");
181 lua_pushinteger(L, HTTP_METHOD_NOT_ALLOWED);
182 lua_setfield(L, -2, "HTTP_METHOD_NOT_ALLOWED");
183 lua_pushinteger(L, HTTP_NOT_ACCEPTABLE);
184 lua_setfield(L, -2, "HTTP_NOT_ACCEPTABLE");
185 lua_pushinteger(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
186 lua_setfield(L, -2, "HTTP_PROXY_AUTHENTICATION_REQUIRED");
187 lua_pushinteger(L, HTTP_REQUEST_TIME_OUT);
188 lua_setfield(L, -2, "HTTP_REQUEST_TIME_OUT");
189 lua_pushinteger(L, HTTP_CONFLICT);
190 lua_setfield(L, -2, "HTTP_CONFLICT");
191 lua_pushinteger(L, HTTP_GONE);
192 lua_setfield(L, -2, "HTTP_GONE");
193 lua_pushinteger(L, HTTP_LENGTH_REQUIRED);
194 lua_setfield(L, -2, "HTTP_LENGTH_REQUIRED");
195 lua_pushinteger(L, HTTP_PRECONDITION_FAILED);
196 lua_setfield(L, -2, "HTTP_PRECONDITION_FAILED");
197 lua_pushinteger(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
198 lua_setfield(L, -2, "HTTP_REQUEST_ENTITY_TOO_LARGE");
199 lua_pushinteger(L, HTTP_REQUEST_URI_TOO_LARGE);
200 lua_setfield(L, -2, "HTTP_REQUEST_URI_TOO_LARGE");
201 lua_pushinteger(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
202 lua_setfield(L, -2, "HTTP_UNSUPPORTED_MEDIA_TYPE");
203 lua_pushinteger(L, HTTP_RANGE_NOT_SATISFIABLE);
204 lua_setfield(L, -2, "HTTP_RANGE_NOT_SATISFIABLE");
205 lua_pushinteger(L, HTTP_EXPECTATION_FAILED);
206 lua_setfield(L, -2, "HTTP_EXPECTATION_FAILED");
207 lua_pushinteger(L, HTTP_UNPROCESSABLE_ENTITY);
208 lua_setfield(L, -2, "HTTP_UNPROCESSABLE_ENTITY");
209 lua_pushinteger(L, HTTP_LOCKED);
210 lua_setfield(L, -2, "HTTP_LOCKED");
211 lua_pushinteger(L, HTTP_FAILED_DEPENDENCY);
212 lua_setfield(L, -2, "HTTP_FAILED_DEPENDENCY");
213 lua_pushinteger(L, HTTP_UPGRADE_REQUIRED);
214 lua_setfield(L, -2, "HTTP_UPGRADE_REQUIRED");
215 lua_pushinteger(L, HTTP_INTERNAL_SERVER_ERROR);
216 lua_setfield(L, -2, "HTTP_INTERNAL_SERVER_ERROR");
217 lua_pushinteger(L, HTTP_NOT_IMPLEMENTED);
218 lua_setfield(L, -2, "HTTP_NOT_IMPLEMENTED");
219 lua_pushinteger(L, HTTP_BAD_GATEWAY);
220 lua_setfield(L, -2, "HTTP_BAD_GATEWAY");
221 lua_pushinteger(L, HTTP_SERVICE_UNAVAILABLE);
222 lua_setfield(L, -2, "HTTP_SERVICE_UNAVAILABLE");
223 lua_pushinteger(L, HTTP_GATEWAY_TIME_OUT);
224 lua_setfield(L, -2, "HTTP_GATEWAY_TIME_OUT");
225 lua_pushinteger(L, HTTP_VERSION_NOT_SUPPORTED);
226 lua_setfield(L, -2, "HTTP_VERSION_NOT_SUPPORTED");
227 lua_pushinteger(L, HTTP_VARIANT_ALSO_VARIES);
228 lua_setfield(L, -2, "HTTP_VARIANT_ALSO_VARIES");
229 lua_pushinteger(L, HTTP_INSUFFICIENT_STORAGE);
230 lua_setfield(L, -2, "HTTP_INSUFFICIENT_STORAGE");
231 lua_pushinteger(L, HTTP_NOT_EXTENDED);
232 lua_setfield(L, -2, "HTTP_NOT_EXTENDED");
236 /* END apache2 lmodule */
238 /* END library functions */
240 /* callback for cleaning up a lua vm when pool is closed */
241 static apr_status_t cleanup_lua(void *l)
243 lua_close((lua_State *) l);
257 * field -> "path" or "cpath"
259 * rep_pat -> "./?.lua"
260 * pool -> lifecycle pool for allocations
261 * paths -> things to add
264 static void munge_path(lua_State *L,
269 apr_array_header_t *paths,
273 const char *parent_dir;
275 const char *modified;
278 lua_getglobal(L, "package");
279 lua_getfield(L, -1, field);
281 current = lua_tostring(L, -1);
283 parent_dir = ap_make_dirstr_parent(pool, file);
285 pattern = apr_pstrcat(pool, parent_dir, sub_pat, NULL);
287 luaL_gsub(L, current, rep_pat, pattern);
288 lua_setfield(L, -3, field);
289 lua_getfield(L, -2, field);
290 modified = lua_tostring(L, -1);
295 part = apr_pstrcat(pool, modified, ";", apr_array_pstrcat(pool, paths, ';'),
298 lua_pushstring(L, part);
299 lua_setfield(L, -2, field);
300 lua_pop(L, 1); /* pop "package" off the stack */
303 #ifdef AP_ENABLE_LUAJIT
304 static int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool) {
305 lua_getglobal(L, "require");
306 lua_pushliteral(L, "jit.");
307 lua_pushvalue(L, -3);
309 if (lua_pcall(L, 1, 1, 0)) {
310 const char *msg = lua_tostring(L, -1);
311 ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01480)
312 "Failed to init LuaJIT: %s", msg);
315 lua_getfield(L, -1, "start");
316 lua_remove(L, -2); /* drop module table */
322 static apr_status_t vm_construct(void **vm, void *params, apr_pool_t *lifecycle_pool)
326 ap_lua_vm_spec *spec = params;
329 #ifdef AP_ENABLE_LUAJIT
333 if (spec->package_paths) {
335 "path", "?.lua", "./?.lua",
340 if (spec->package_cpaths) {
341 munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool,
342 spec->package_cpaths, spec->file);
346 spec->cb(L, lifecycle_pool, spec->cb_arg);
350 if (spec->bytecode && spec->bytecode_len > 0) {
351 luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
352 lua_pcall(L, 0, LUA_MULTRET, 0);
356 ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01481)
357 "loading lua file %s", spec->file);
358 rc = luaL_loadfile(L, spec->file);
360 ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(01482)
361 "Error loading %s: %s", spec->file,
362 rc == LUA_ERRMEM ? "memory allocation error"
363 : lua_tostring(L, 0));
366 lua_pcall(L, 0, LUA_MULTRET, 0);
369 #ifdef AP_ENABLE_LUAJIT
370 loadjitmodule(L, lifecycle_pool);
372 lua_pushlightuserdata(L, lifecycle_pool);
373 lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool");
380 * Function used to create a lua_State instance bound into the web
381 * server in the appropriate scope.
383 AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
384 ap_lua_vm_spec *spec)
388 if (apr_pool_userdata_get((void **)&L, spec->file,
389 lifecycle_pool) == APR_SUCCESS) {
392 ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01483)
393 "creating lua_State with file %s", spec->file);
394 /* not available, so create */
396 if(!vm_construct((void **)&L, spec, lifecycle_pool)) {
397 apr_pool_userdata_set(L,