enabled block processing properly.
[httpd-crcsyncproxy.git] / modules / lua / lua_vmprep.c
blob1d139a5be07a042949da73642de531cfeaa04a8c
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
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.
17 #include "mod_lua.h"
18 #include "http_log.h"
19 #include "apr_reslist.h"
20 #include "apr_uuid.h"
21 #include "lua_config.h"
22 #include "apr_file_info.h"
24 /* forward dec'l from this file */
26 #if 0
27 static void pstack_dump(lua_State *L, apr_pool_t *r, int level,
28 const char *msg)
30 int i;
31 int top = lua_gettop(L);
33 ap_log_perror(APLOG_MARK, level, 0, r, "Lua Stack Dump: [%s]", msg);
35 for (i = 1; i <= top; i++) {
36 int t = lua_type(L, i);
37 switch (t) {
38 case LUA_TSTRING:{
39 ap_log_perror(APLOG_MARK, level, 0, r,
40 "%d: '%s'", i, lua_tostring(L, i));
41 break;
43 case LUA_TUSERDATA:{
44 ap_log_perror(APLOG_MARK, level, 0, r, "%d: userdata", i);
45 break;
47 case LUA_TLIGHTUSERDATA:{
48 ap_log_perror(APLOG_MARK, level, 0, r, "%d: lightuserdata",
49 i);
50 break;
52 case LUA_TNIL:{
53 ap_log_perror(APLOG_MARK, level, 0, r, "%d: NIL", i);
54 break;
56 case LUA_TNONE:{
57 ap_log_perror(APLOG_MARK, level, 0, r, "%d: None", i);
58 break;
60 case LUA_TBOOLEAN:{
61 ap_log_perror(APLOG_MARK, level, 0, r,
62 "%d: %s", i, lua_toboolean(L,
63 i) ? "true" :
64 "false");
65 break;
67 case LUA_TNUMBER:{
68 ap_log_perror(APLOG_MARK, level, 0, r,
69 "%d: %g", i, lua_tonumber(L, i));
70 break;
72 case LUA_TTABLE:{
73 ap_log_perror(APLOG_MARK, level, 0, r, "%d: <table>", i);
74 break;
76 case LUA_TTHREAD:{
77 ap_log_perror(APLOG_MARK, level, 0, r, "%d: <thread>", i);
78 break;
80 case LUA_TFUNCTION:{
81 ap_log_perror(APLOG_MARK, level, 0, r, "%d: <function>", i);
82 break;
84 default:{
85 ap_log_perror(APLOG_MARK, level, 0, r,
86 "%d: unkown: [%s]", i, lua_typename(L, i));
87 break;
92 #endif
94 /* BEGIN modules*/
96 /* BEGIN apache lmodule */
98 void apl_load_apache2_lmodule(lua_State *L)
100 lua_getglobal(L, "package");
101 lua_getfield(L, -1, "loaded");
102 lua_newtable(L);
103 lua_setfield(L, -2, "apache2");
104 lua_setglobal(L, "apache2");
105 lua_pop(L, 1); /* empty stack */
107 lua_getglobal(L, "apache2");
108 lua_pushinteger(L, OK);
109 lua_setfield(L, -2, "OK");
111 lua_pushinteger(L, DECLINED);
112 lua_setfield(L, -2, "DECLINED");
114 lua_pushinteger(L, DONE);
115 lua_setfield(L, -2, "DONE");
117 lua_pushstring(L, ap_get_server_banner());
118 lua_setfield(L, -2, "version");
120 lua_pushinteger(L, HTTP_MOVED_TEMPORARILY);
121 lua_setfield(L, -2, "HTTP_MOVED_TEMPORARILY");
124 lua_pushinteger(L, HTTP_CONTINUE);
125 lua_setfield(L, -2, "HTTP_CONTINUE");
126 lua_pushinteger(L, HTTP_SWITCHING_PROTOCOLS);
127 lua_setfield(L, -2, "HTTP_SWITCHING_PROTOCOLS");
128 lua_pushinteger(L, HTTP_PROCESSING);
129 lua_setfield(L, -2, "HTTP_PROCESSING");
130 lua_pushinteger(L, HTTP_OK);
131 lua_setfield(L, -2, "HTTP_OK");
132 lua_pushinteger(L, HTTP_CREATED);
133 lua_setfield(L, -2, "HTTP_CREATED");
134 lua_pushinteger(L, HTTP_ACCEPTED);
135 lua_setfield(L, -2, "HTTP_ACCEPTED");
136 lua_pushinteger(L, HTTP_NON_AUTHORITATIVE);
137 lua_setfield(L, -2, "HTTP_NON_AUTHORITATIVE");
138 lua_pushinteger(L, HTTP_NO_CONTENT);
139 lua_setfield(L, -2, "HTTP_NO_CONTENT");
140 lua_pushinteger(L, HTTP_RESET_CONTENT);
141 lua_setfield(L, -2, "HTTP_RESET_CONTENT");
142 lua_pushinteger(L, HTTP_PARTIAL_CONTENT);
143 lua_setfield(L, -2, "HTTP_PARTIAL_CONTENT");
144 lua_pushinteger(L, HTTP_MULTI_STATUS);
145 lua_setfield(L, -2, "HTTP_MULTI_STATUS");
146 lua_pushinteger(L, HTTP_MULTIPLE_CHOICES);
147 lua_setfield(L, -2, "HTTP_MULTIPLE_CHOICES");
148 lua_pushinteger(L, HTTP_MOVED_PERMANENTLY);
149 lua_setfield(L, -2, "HTTP_MOVED_PERMANENTLY");
150 lua_pushinteger(L, HTTP_SEE_OTHER);
151 lua_setfield(L, -2, "HTTP_SEE_OTHER");
152 lua_pushinteger(L, HTTP_NOT_MODIFIED);
153 lua_setfield(L, -2, "HTTP_NOT_MODIFIED");
154 lua_pushinteger(L, HTTP_USE_PROXY);
155 lua_setfield(L, -2, "HTTP_USE_PROXY");
156 lua_pushinteger(L, HTTP_TEMPORARY_REDIRECT);
157 lua_setfield(L, -2, "HTTP_TEMPORARY_REDIRECT");
158 lua_pushinteger(L, HTTP_BAD_REQUEST);
159 lua_setfield(L, -2, "HTTP_BAD_REQUEST");
160 lua_pushinteger(L, HTTP_UNAUTHORIZED);
161 lua_setfield(L, -2, "HTTP_UNAUTHORIZED");
162 lua_pushinteger(L, HTTP_PAYMENT_REQUIRED);
163 lua_setfield(L, -2, "HTTP_PAYMENT_REQUIRED");
164 lua_pushinteger(L, HTTP_FORBIDDEN);
165 lua_setfield(L, -2, "HTTP_FORBIDDEN");
166 lua_pushinteger(L, HTTP_NOT_FOUND);
167 lua_setfield(L, -2, "HTTP_NOT_FOUND");
168 lua_pushinteger(L, HTTP_METHOD_NOT_ALLOWED);
169 lua_setfield(L, -2, "HTTP_METHOD_NOT_ALLOWED");
170 lua_pushinteger(L, HTTP_NOT_ACCEPTABLE);
171 lua_setfield(L, -2, "HTTP_NOT_ACCEPTABLE");
172 lua_pushinteger(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
173 lua_setfield(L, -2, "HTTP_PROXY_AUTHENTICATION_REQUIRED");
174 lua_pushinteger(L, HTTP_REQUEST_TIME_OUT);
175 lua_setfield(L, -2, "HTTP_REQUEST_TIME_OUT");
176 lua_pushinteger(L, HTTP_CONFLICT);
177 lua_setfield(L, -2, "HTTP_CONFLICT");
178 lua_pushinteger(L, HTTP_GONE);
179 lua_setfield(L, -2, "HTTP_GONE");
180 lua_pushinteger(L, HTTP_LENGTH_REQUIRED);
181 lua_setfield(L, -2, "HTTP_LENGTH_REQUIRED");
182 lua_pushinteger(L, HTTP_PRECONDITION_FAILED);
183 lua_setfield(L, -2, "HTTP_PRECONDITION_FAILED");
184 lua_pushinteger(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
185 lua_setfield(L, -2, "HTTP_REQUEST_ENTITY_TOO_LARGE");
186 lua_pushinteger(L, HTTP_REQUEST_URI_TOO_LARGE);
187 lua_setfield(L, -2, "HTTP_REQUEST_URI_TOO_LARGE");
188 lua_pushinteger(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
189 lua_setfield(L, -2, "HTTP_UNSUPPORTED_MEDIA_TYPE");
190 lua_pushinteger(L, HTTP_RANGE_NOT_SATISFIABLE);
191 lua_setfield(L, -2, "HTTP_RANGE_NOT_SATISFIABLE");
192 lua_pushinteger(L, HTTP_EXPECTATION_FAILED);
193 lua_setfield(L, -2, "HTTP_EXPECTATION_FAILED");
194 lua_pushinteger(L, HTTP_UNPROCESSABLE_ENTITY);
195 lua_setfield(L, -2, "HTTP_UNPROCESSABLE_ENTITY");
196 lua_pushinteger(L, HTTP_LOCKED);
197 lua_setfield(L, -2, "HTTP_LOCKED");
198 lua_pushinteger(L, HTTP_FAILED_DEPENDENCY);
199 lua_setfield(L, -2, "HTTP_FAILED_DEPENDENCY");
200 lua_pushinteger(L, HTTP_UPGRADE_REQUIRED);
201 lua_setfield(L, -2, "HTTP_UPGRADE_REQUIRED");
202 lua_pushinteger(L, HTTP_INTERNAL_SERVER_ERROR);
203 lua_setfield(L, -2, "HTTP_INTERNAL_SERVER_ERROR");
204 lua_pushinteger(L, HTTP_NOT_IMPLEMENTED);
205 lua_setfield(L, -2, "HTTP_NOT_IMPLEMENTED");
206 lua_pushinteger(L, HTTP_BAD_GATEWAY);
207 lua_setfield(L, -2, "HTTP_BAD_GATEWAY");
208 lua_pushinteger(L, HTTP_SERVICE_UNAVAILABLE);
209 lua_setfield(L, -2, "HTTP_SERVICE_UNAVAILABLE");
210 lua_pushinteger(L, HTTP_GATEWAY_TIME_OUT);
211 lua_setfield(L, -2, "HTTP_GATEWAY_TIME_OUT");
212 lua_pushinteger(L, HTTP_VERSION_NOT_SUPPORTED);
213 lua_setfield(L, -2, "HTTP_VERSION_NOT_SUPPORTED");
214 lua_pushinteger(L, HTTP_VARIANT_ALSO_VARIES);
215 lua_setfield(L, -2, "HTTP_VARIANT_ALSO_VARIES");
216 lua_pushinteger(L, HTTP_INSUFFICIENT_STORAGE);
217 lua_setfield(L, -2, "HTTP_INSUFFICIENT_STORAGE");
218 lua_pushinteger(L, HTTP_NOT_EXTENDED);
219 lua_setfield(L, -2, "HTTP_NOT_EXTENDED");
223 /* END apache2 lmodule */
225 /* END library functions */
227 /* callback for cleaning up a lua vm when pool is closed */
228 static apr_status_t cleanup_lua(void *l)
230 lua_close((lua_State *) l);
231 return APR_SUCCESS;
234 static void munge_path(lua_State *L,
235 const char *field,
236 const char *sub_pat,
237 const char *rep_pat,
238 apr_pool_t *pool,
239 apr_array_header_t *paths,
240 const char *file)
242 const char *current;
243 const char *parent_dir;
244 const char *pattern;
245 const char *modified;
246 char *part;
247 int i;
249 lua_getglobal(L, "package");
250 lua_getfield(L, -1, field);
251 current = lua_tostring(L, -1);
252 parent_dir = ap_make_dirstr_parent(pool, file);
253 pattern = apr_pstrcat(pool, parent_dir, sub_pat, NULL);
254 luaL_gsub(L, current, rep_pat, pattern);
255 lua_setfield(L, -3, field);
256 lua_getfield(L, -2, field);
257 modified = lua_tostring(L, -1);
258 lua_pop(L, 2);
260 part = apr_pstrdup(pool, modified);
261 for (i = 0; i < paths->nelts; i++) {
262 const char *new_path = ((const char **) paths->elts)[i];
263 part = apr_pstrcat(pool, part, ";", new_path, NULL);
265 lua_pushstring(L, part);
266 lua_setfield(L, -2, field);
267 lua_pop(L, 1); /* pop "package" off the stack */
270 #ifdef AP_ENABLE_LUAJIT
271 static int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool) {
272 lua_getglobal(L, "require");
273 lua_pushliteral(L, "jit.");
274 lua_pushvalue(L, -3);
275 lua_concat(L, 2);
276 if (lua_pcall(L, 1, 1, 0)) {
277 const char *msg = lua_tostring(L, -1);
278 ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool,
279 "Failed to init LuaJIT: %s", msg);
280 return 1;
282 lua_getfield(L, -1, "start");
283 lua_remove(L, -2); /* drop module table */
284 return 0;
287 #endif
289 lua_State *apl_get_lua_state(apr_pool_t *lifecycle_pool,
290 apl_vm_spec *spec,
291 apr_array_header_t *package_paths,
292 apr_array_header_t *package_cpaths,
293 apl_lua_state_open_callback cb, void *btn)
296 lua_State *L;
298 if (!apr_pool_userdata_get((void **) &L, spec->file, lifecycle_pool)) {
299 ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool,
300 "creating lua_State with file %s", spec->file);
301 /* not available, so create */
302 L = luaL_newstate();
303 #ifdef AP_ENABLE_LUAJIT
304 luaopen_jit(L);
305 #endif
306 luaL_openlibs(L);
307 if (package_paths) {
308 munge_path(L, "path", "?.lua", "./?.lua", lifecycle_pool,
309 package_paths, spec->file);
311 if (package_cpaths) {
312 munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool,
313 package_cpaths, spec->file);
316 if (cb) {
317 cb(L, lifecycle_pool, btn);
320 apr_pool_userdata_set(L, spec->file, &cleanup_lua, lifecycle_pool);
322 if (spec->bytecode && spec->bytecode_len > 0) {
323 luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
324 lua_pcall(L, 0, LUA_MULTRET, 0);
326 else {
327 luaL_loadfile(L, spec->file);
328 lua_pcall(L, 0, LUA_MULTRET, 0);
331 #ifdef AP_ENABLE_LUAJIT
332 loadjitmodule(L, lifecycle_pool);
333 #endif
334 lua_pushlightuserdata(L, lifecycle_pool);
335 lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool");
338 return L;