lua_vmprep.c revision 679c5329c641e9de6ae65ad1e5b6cb4c9d0ed4b6
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/**
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Licensed to the Apache Software Foundation (ASF) under one or more
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * contributor license agreements. See the NOTICE file distributed with
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * this work for additional information regarding copyright ownership.
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * The ASF licenses this file to You under the Apache License, Version 2.0
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * (the "License"); you may not use this file except in compliance with
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the License. You may obtain a copy of the License at
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * http://www.apache.org/licenses/LICENSE-2.0
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Unless required by applicable law or agreed to in writing, software
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * distributed under the License is distributed on an "AS IS" BASIS,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * See the License for the specific language governing permissions and
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * limitations under the License.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "mod_lua.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "http_log.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "apr_uuid.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "lua_config.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "apr_file_info.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "mod_auth.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "util_mutex.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fieldingAPLOG_USE_MODULE(lua);
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#if APR_HAS_THREADS
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_proc_mutex_t *ap_lua_mutex;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
64185f9824e42f21ca7b9ae6c004484215c031a7rbbint ap_lua_register_mutex(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding ap_mutex_register(p, "lua-shm", NULL, APR_LOCK_DEFAULT, 0);
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding}
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fieldingvoid ap_lua_init_mutex(apr_pool_t *pool, server_rec *s)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding{
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding ap_proc_mutex_create(&ap_lua_mutex, NULL, "lua-shm", NULL, s, pool, 0);
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding}
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#endif
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding/* forward dec'l from this file */
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#if 0
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void pstack_dump(lua_State *L, apr_pool_t *r, int level,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *msg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding int i;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding int top = lua_gettop(L);
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "Lua Stack Dump: [%s]", msg);
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding for (i = 1; i <= top; i++) {
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding int t = lua_type(L, i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding switch (t) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TSTRING:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "%d: '%s'", i, lua_tostring(L, i));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TUSERDATA:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "%d: userdata", i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TLIGHTUSERDATA:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "%d: lightuserdata",
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TNIL:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "%d: NIL", i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TNONE:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "%d: None", i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TBOOLEAN:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "%d: %s", i, lua_toboolean(L,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding i) ? "true" :
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "false");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TNUMBER:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "%d: %g", i, lua_tonumber(L, i));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TTABLE:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "%d: <table>", i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TTHREAD:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "%d: <thread>", i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding case LUA_TFUNCTION:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r, "%d: <function>", i);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding default:{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, level, 0, r,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "%d: unknown: [%s]", i, lua_typename(L, i));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding break;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* BEGIN modules*/
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* BEGIN apache lmodule */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#define makeintegerfield(L, n) lua_pushinteger(L, n); lua_setfield(L, -2, #n)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingAP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_getglobal(L, "package");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_getfield(L, -1, "loaded");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_newtable(L);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_setfield(L, -2, "apache2");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_setglobal(L, "apache2");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pop(L, 1); /* empty stack */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_getglobal(L, "apache2");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pushstring(L, ap_get_server_banner());
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_setfield(L, -2, "version");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, OK);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, DECLINED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, DONE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, PROXYREQ_NONE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, PROXYREQ_PROXY);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, PROXYREQ_REVERSE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, PROXYREQ_RESPONSE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, PROXYREQ_RESPONSE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, AUTHZ_DENIED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, AUTHZ_GRANTED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, AUTHZ_NEUTRAL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, AUTHZ_GENERAL_ERROR);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, AUTHZ_DENIED_NO_USER);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_CONTINUE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_SWITCHING_PROTOCOLS);
9625528fcf4fa27288f3be080a1979c8ef60d7dfrbb makeintegerfield(L, HTTP_PROCESSING);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_OK);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_CREATED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_ACCEPTED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_NON_AUTHORITATIVE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_NO_CONTENT);
032b8a34c3911bbc5ad5385ca40af65af273bff9wrowe makeintegerfield(L, HTTP_RESET_CONTENT);
032b8a34c3911bbc5ad5385ca40af65af273bff9wrowe makeintegerfield(L, HTTP_PARTIAL_CONTENT);
9625528fcf4fa27288f3be080a1979c8ef60d7dfrbb makeintegerfield(L, HTTP_MULTI_STATUS);
9625528fcf4fa27288f3be080a1979c8ef60d7dfrbb makeintegerfield(L, HTTP_ALREADY_REPORTED);
9625528fcf4fa27288f3be080a1979c8ef60d7dfrbb makeintegerfield(L, HTTP_IM_USED);
5fac45c1ef49924141fe28497deb350cf031b377trawick makeintegerfield(L, HTTP_MULTIPLE_CHOICES);
5fac45c1ef49924141fe28497deb350cf031b377trawick makeintegerfield(L, HTTP_MOVED_PERMANENTLY);
5fac45c1ef49924141fe28497deb350cf031b377trawick makeintegerfield(L, HTTP_MOVED_TEMPORARILY);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_SEE_OTHER);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_NOT_MODIFIED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_USE_PROXY);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_TEMPORARY_REDIRECT);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_PERMANENT_REDIRECT);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_BAD_REQUEST);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_UNAUTHORIZED);
3d96ee83babeec32482c9082c9426340cee8c44dwrowe makeintegerfield(L, HTTP_PAYMENT_REQUIRED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_FORBIDDEN);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_NOT_FOUND);
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick makeintegerfield(L, HTTP_METHOD_NOT_ALLOWED);
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick makeintegerfield(L, HTTP_NOT_ACCEPTABLE);
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick makeintegerfield(L, HTTP_PROXY_AUTHENTICATION_REQUIRED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_REQUEST_TIME_OUT);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_CONFLICT);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm makeintegerfield(L, HTTP_GONE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_LENGTH_REQUIRED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_PRECONDITION_FAILED);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm makeintegerfield(L, HTTP_REQUEST_ENTITY_TOO_LARGE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_REQUEST_URI_TOO_LARGE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_UNSUPPORTED_MEDIA_TYPE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_RANGE_NOT_SATISFIABLE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_EXPECTATION_FAILED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_UNPROCESSABLE_ENTITY);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_LOCKED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_FAILED_DEPENDENCY);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_UPGRADE_REQUIRED);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm makeintegerfield(L, HTTP_PRECONDITION_REQUIRED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_TOO_MANY_REQUESTS);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_INTERNAL_SERVER_ERROR);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_NOT_IMPLEMENTED);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm makeintegerfield(L, HTTP_BAD_GATEWAY);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_SERVICE_UNAVAILABLE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_GATEWAY_TIME_OUT);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_VERSION_NOT_SUPPORTED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_VARIANT_ALSO_VARIES);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_INSUFFICIENT_STORAGE);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_LOOP_DETECTED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_NOT_EXTENDED);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding makeintegerfield(L, HTTP_NETWORK_AUTHENTICATION_REQUIRED);
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick/* END apache2 lmodule */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* END library functions */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* callback for cleaning up a lua vm when pool is closed */
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawickstatic apr_status_t cleanup_lua(void *l)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick AP_DEBUG_ASSERT(l != NULL);
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick lua_close((lua_State *) l);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return APR_SUCCESS;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic apr_status_t server_cleanup_lua(void *resource)
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_lua_server_spec* spec = (ap_lua_server_spec*) resource;
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick AP_DEBUG_ASSERT(spec != NULL);
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick if (spec->L != NULL) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_close((lua_State *) spec->L);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return APR_SUCCESS;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding munge_path(L,
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick "path",
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick "?.lua",
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick "./?.lua",
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick lifecycle_pool,
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick spec->package_paths,
ba09062ce0c7e0d6904a53aaf99896f5924b3989trawick spec->file);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding*/
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/**
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * field -> "path" or "cpath"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * sub_pat -> "?.lua"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * rep_pat -> "./?.lua"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * pool -> lifecycle pool for allocations
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * paths -> things to add
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * file -> ???
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void munge_path(lua_State *L,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *field,
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm const char *sub_pat,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *rep_pat,
066877f1a045103acfdd376d48cdd473c33f409bdougm apr_pool_t *pool,
066877f1a045103acfdd376d48cdd473c33f409bdougm apr_array_header_t *paths,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *file)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *current;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *parent_dir;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *pattern;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *modified;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char *part;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_getglobal(L, "package");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_getfield(L, -1, field);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding current = lua_tostring(L, -1);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding parent_dir = ap_make_dirstr_parent(pool, file);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding pattern = apr_pstrcat(pool, parent_dir, sub_pat, NULL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding luaL_gsub(L, current, rep_pat, pattern);
b79b743d4cff02d6a830bb7118826a2fd608742amartin lua_setfield(L, -3, field);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_getfield(L, -2, field);
000b67449410515eac43e76ef6667915bfd4d2abgstein modified = lua_tostring(L, -1);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pop(L, 2);
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding part = apr_pstrcat(pool, modified, ";", apr_array_pstrcat(pool, paths, ';'),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding NULL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pushstring(L, part);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_setfield(L, -2, field);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pop(L, 1); /* pop "package" off the stack */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef AP_ENABLE_LUAJIT
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool) {
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm lua_getglobal(L, "require");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pushliteral(L, "jit.");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pushvalue(L, -3);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_concat(L, 2);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (lua_pcall(L, 1, 1, 0)) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *msg = lua_tostring(L, -1);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01480)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "Failed to init LuaJIT: %s", msg);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return 1;
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_getfield(L, -1, "start");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_remove(L, -2); /* drop module table */
066877f1a045103acfdd376d48cdd473c33f409bdougm return 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic apr_status_t vm_construct(lua_State **vm, void *params, apr_pool_t *lifecycle_pool)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_State* L;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_lua_vm_spec *spec = params;
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm L = luaL_newstate();
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifdef AP_ENABLE_LUAJIT
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding luaopen_jit(L);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding luaL_openlibs(L);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (spec->package_paths) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding munge_path(L,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "path", "?.lua", "./?.lua",
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lifecycle_pool,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding spec->package_paths,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding spec->file);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (spec->package_cpaths) {
f54da7877f9e092465df38bfda142f3e71dbb7aawrowe munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding spec->package_cpaths, spec->file);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (spec->cb) {
d9f2c22804bcbc9ad07d4ec18fbb8aa7c042dcd0bjh spec->cb(L, lifecycle_pool, spec->cb_arg);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (spec->bytecode && spec->bytecode_len > 0) {
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pcall(L, 0, LUA_MULTRET, 0);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int rc;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01481)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "loading lua file %s", spec->file);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding rc = luaL_loadfile(L, spec->file);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (rc != 0) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(01482)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding "Error loading %s: %s", spec->file,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding rc == LUA_ERRMEM ? "memory allocation error"
b79b743d4cff02d6a830bb7118826a2fd608742amartin : lua_tostring(L, 0));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return APR_EBADF;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pcall(L, 0, LUA_MULTRET, 0);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm#ifdef AP_ENABLE_LUAJIT
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding loadjitmodule(L, lifecycle_pool);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_pushlightuserdata(L, lifecycle_pool);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *vm = L;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return APR_SUCCESS;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingap_lua_vm_spec* copy_vm_spec(apr_pool_t* pool, ap_lua_vm_spec* spec)
85bea52867bd1a8c81080ba415b5cd5b771ce5f7gstein{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_lua_vm_spec* copied_spec = apr_pcalloc(pool, sizeof(ap_lua_vm_spec));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding copied_spec->bytecode_len = spec->bytecode_len;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding copied_spec->bytecode = spec->bytecode ? apr_pstrdup(pool, spec->bytecode) : 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding copied_spec->cb = spec->cb;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding copied_spec->cb_arg = NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding copied_spec->file = spec->file ? apr_pstrdup(pool, spec->file) : 0;
066877f1a045103acfdd376d48cdd473c33f409bdougm copied_spec->package_cpaths = apr_array_copy(pool, spec->package_cpaths);
1465b960f95b4afba4f4221054dd09e11509bd40rbb copied_spec->package_paths = apr_array_copy(pool, spec->package_paths);
1c65e34ff5b278afbc676c99cff3bf6c4fce2733wrowe copied_spec->pool = pool;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding copied_spec->scope = AP_LUA_SCOPE_SERVER;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding copied_spec->codecache = spec->codecache;
b79b743d4cff02d6a830bb7118826a2fd608742amartin return copied_spec;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
000b67449410515eac43e76ef6667915bfd4d2abgstein
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic apr_status_t server_vm_construct(lua_State **resource, void *params, apr_pool_t *pool)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding lua_State* L;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_lua_server_spec* spec = apr_pcalloc(pool, sizeof(ap_lua_server_spec));
066877f1a045103acfdd376d48cdd473c33f409bdougm if (vm_construct(&L, params, pool) == APR_SUCCESS) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding spec->finfo = apr_pcalloc(pool, sizeof(ap_lua_finfo));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (L != NULL) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding spec->L = L;
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowe *resource = (void*) spec;
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowe lua_pushlightuserdata(L, spec);
577a76180006add04a166b12f1ad130aeedeaa5estoddard lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Lua.server_spec");
b980ad7fdc218b4855cde9f75a747527f50c554dwrowe return APR_SUCCESS;
577a76180006add04a166b12f1ad130aeedeaa5estoddard }
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowe }
3d96ee83babeec32482c9082c9426340cee8c44dwrowe return APR_EGENERAL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
577a76180006add04a166b12f1ad130aeedeaa5estoddard
577a76180006add04a166b12f1ad130aeedeaa5estoddard/**
577a76180006add04a166b12f1ad130aeedeaa5estoddard * Function used to create a lua_State instance bound into the web
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * server in the appropriate scope.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmAP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
577a76180006add04a166b12f1ad130aeedeaa5estoddard ap_lua_vm_spec *spec, request_rec* r)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
lua_State *L = NULL;
ap_lua_finfo *cache_info;
int tryCache = 0;
if (spec->scope == AP_LUA_SCOPE_SERVER) {
char *hash;
apr_reslist_t* reslist = NULL;
ap_lua_server_spec* sspec = NULL;
hash = apr_psprintf(r->pool, "reslist:%s", spec->file);
#if APR_HAS_THREADS
apr_proc_mutex_lock(ap_lua_mutex);
#endif
if (apr_pool_userdata_get((void **)&reslist, hash,
r->server->process->pool) == APR_SUCCESS) {
if (reslist != NULL) {
if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
L = sspec->L;
cache_info = sspec->finfo;
}
}
}
if (L == NULL) {
ap_lua_vm_spec* server_spec = copy_vm_spec(r->server->process->pool, spec);
apr_reslist_create(&reslist, spec->vm_min, spec->vm_max, spec->vm_max, 0,
(apr_reslist_constructor) server_vm_construct,
(apr_reslist_destructor) server_cleanup_lua,
server_spec, r->server->process->pool);
apr_pool_userdata_set(reslist, hash, NULL,
r->server->process->pool);
if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
L = sspec->L;
cache_info = sspec->finfo;
}
}
#if APR_HAS_THREADS
apr_proc_mutex_unlock(ap_lua_mutex);
#endif
}
else {
if (apr_pool_userdata_get((void **)&L, spec->file,
lifecycle_pool) != APR_SUCCESS) {
L = NULL;
}
}
if(L==NULL) {
ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01483)
"creating lua_State with file %s", spec->file);
/* not available, so create */
if(!vm_construct(&L, spec, lifecycle_pool)) {
AP_DEBUG_ASSERT(L != NULL);
apr_pool_userdata_set(L,
spec->file,
cleanup_lua,
lifecycle_pool);
}
}
if (spec->codecache == AP_LUA_CACHE_FOREVER || (spec->bytecode && spec->bytecode_len > 0)) {
tryCache = 1;
}
else {
char* mkey;
if (spec->scope != AP_LUA_SCOPE_SERVER) {
mkey = apr_psprintf(r->pool, "ap_lua_modified:%s", spec->file);
apr_pool_userdata_get((void **)&cache_info, mkey, lifecycle_pool);
if (cache_info == NULL) {
cache_info = apr_pcalloc(lifecycle_pool, sizeof(ap_lua_finfo));
}
}
if (spec->codecache == AP_LUA_CACHE_STAT) {
apr_finfo_t lua_finfo;
apr_stat(&lua_finfo, spec->file, APR_FINFO_MTIME|APR_FINFO_SIZE, lifecycle_pool);
/* On first visit, modified will be zero, but that's fine - The file is
loaded in the vm_construct function.
*/
if ((cache_info->modified == lua_finfo.mtime && cache_info->size == lua_finfo.size) \
|| cache_info->modified == 0) {
tryCache = 1;
}
cache_info->modified = lua_finfo.mtime;
cache_info->size = lua_finfo.size;
}
else if (spec->codecache == AP_LUA_CACHE_NEVER) {
if (cache_info->runs == 0) tryCache = 1;
}
cache_info->runs++;
if (spec->scope != AP_LUA_SCOPE_SERVER) {
apr_pool_userdata_set((void*) cache_info, mkey, NULL, lifecycle_pool);
}
}
if (tryCache == 0 && spec->scope != AP_LUA_SCOPE_ONCE) {
int rc;
ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01481)
"(re)loading lua file %s", spec->file);
rc = luaL_loadfile(L, spec->file);
if (rc != 0) {
ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(01482)
"Error loading %s: %s", spec->file,
rc == LUA_ERRMEM ? "memory allocation error"
: lua_tostring(L, 0));
return 0;
}
lua_pcall(L, 0, LUA_MULTRET, 0);
}
return L;
}