ported mod_cml to lua
git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.3.x@452 152afb58-edef-0310-8abb-c4023f1b3aa9
This commit is contained in:
parent
161ed5530b
commit
1408a4820d
15
configure.in
15
configure.in
|
@ -271,7 +271,20 @@ AC_ARG_WITH(memcache, AC_HELP_STRING([--with-memcache],[memcached storage for mo
|
|||
])
|
||||
],[AC_MSG_RESULT(no)])
|
||||
AC_SUBST(MEMCACHE_LIB)
|
||||
|
||||
|
||||
AC_MSG_CHECKING(for lua)
|
||||
AC_ARG_WITH(lua, AC_HELP_STRING([--with-lua],[lua engine for mod_cml]),
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_CHECK_LIB(lua, lua_open, [
|
||||
AC_CHECK_HEADERS([lua.h],[
|
||||
LUA_LIB="-llua -llualib -lm"
|
||||
AC_DEFINE([HAVE_LUA], [1], [liblua])
|
||||
AC_DEFINE([HAVE_LUA_H], [1])
|
||||
])
|
||||
])
|
||||
],[AC_MSG_RESULT(no)])
|
||||
AC_SUBST(LUA_LIB)
|
||||
|
||||
|
||||
AC_SEARCH_LIBS(socket,socket)
|
||||
AC_SEARCH_LIBS(gethostbyname,nsl socket)
|
||||
|
|
104
doc/cml.txt
104
doc/cml.txt
|
@ -11,10 +11,10 @@ Module: mod_cml
|
|||
:Revision: $Revision: 1.2 $
|
||||
|
||||
:abstract:
|
||||
CML is a Meta language to describe the dependencies of a page at one side and building a page from its fragments on the other side
|
||||
CML is a Meta language to describe the dependencies of a page at one side and building a page from its fragments on the other side using LUA.
|
||||
|
||||
.. meta::
|
||||
:keywords: lighttpd, cml
|
||||
:keywords: lighttpd, cml, lua
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
|
@ -97,14 +97,22 @@ to start PHP for a cache-hit.
|
|||
To transform this example into a CML you need 'index.cml' in the list of indexfiles
|
||||
and the following index.cml file: ::
|
||||
|
||||
output.content-type text/html
|
||||
output_contenttype = "text/html"
|
||||
|
||||
output.include _cache.html
|
||||
b = request["DOCUMENT_ROOT"]
|
||||
cwd = request["CWD"]
|
||||
|
||||
trigger.handler index.php
|
||||
trigger.if file.mtime("../lib/php/menu.csv") > file.mtime("_cache.html")
|
||||
trigger.if file.mtime("templates/jk.tmpl") > file.mtime("_cache.html")
|
||||
trigger.if file.mtime("content.html") > file.mtime("_cache.html")
|
||||
output_include = { b + "_cache.html" }
|
||||
|
||||
trigger_handler = "index.php"
|
||||
|
||||
if file_mtime(b + "../lib/php/menu.csv") > file_mtime(cwd + "_cache.html") or
|
||||
file_mtime(b + "templates/jk.tmpl") > file.mtime(cwd + "_cache.html")
|
||||
file.mtime(b + "content.html") > file.mtime(cwd + "_cache.html") then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
|
||||
Numbers again:
|
||||
|
||||
|
@ -132,15 +140,19 @@ Don't forget: Webserver are built to send out static content, that is what they
|
|||
|
||||
The index.cml for this looks like: ::
|
||||
|
||||
output.content-type text/html
|
||||
output_content_type = "text/html"
|
||||
|
||||
cwd = request["CWD"]
|
||||
|
||||
output.include head.html
|
||||
output.include menu.html
|
||||
output.include spacer.html
|
||||
output.include db-content.html
|
||||
output.include spacer2.html
|
||||
output.include news.html
|
||||
output.include footer.html
|
||||
output_include = { cwd + "head.html",
|
||||
cwd + "menu.html",
|
||||
cwd + "spacer.html",
|
||||
cwd + "db-content.html",
|
||||
cwd + "spacer2.html",
|
||||
cwd + "news.html",
|
||||
cwd + "footer.html" }
|
||||
|
||||
return 0
|
||||
|
||||
Now we get about 10000 req/s instead of 600 req/s.
|
||||
|
||||
|
@ -149,8 +161,66 @@ Options
|
|||
|
||||
:cml.extension:
|
||||
the file extension that is bound to the cml-module
|
||||
:cml.memcache-hosts:
|
||||
hosts for the memcache.* functions
|
||||
:cml.memcache-namespace:
|
||||
(not used yet)
|
||||
|
||||
Language
|
||||
========
|
||||
|
||||
... will come later ...
|
||||
The language used for CML is provided by `LUA <http://www.lua.org/>`_.
|
||||
|
||||
Additionally to the functions provided by lua mod_cml provides: ::
|
||||
|
||||
tables:
|
||||
|
||||
request
|
||||
- REQUEST_URI
|
||||
- SCRIPT_NAME
|
||||
- SCRIPT_FILENAME
|
||||
- DOCUMENT_ROOT
|
||||
- PATH_INFO
|
||||
- CWD
|
||||
- BASEURI
|
||||
|
||||
get
|
||||
- parameters from the query-string
|
||||
|
||||
functions:
|
||||
string md5(string)
|
||||
number file_mtime(string)
|
||||
string memcache_get_string(string)
|
||||
number memcache_get_long(string)
|
||||
boolean memcache_exists(string)
|
||||
|
||||
|
||||
What ever your script does, it has to return either 0 or 1 for ``cache-hit`` or ``cache-miss``.
|
||||
It case a error occures check the error-log, the user will get a error 500. If you don't like
|
||||
the standard error-page use ``server.errorfile-prefix``.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
Using the memcache-udf for MySQL we can do: ::
|
||||
|
||||
output_contenttype = "text/html"
|
||||
output_include = { "cache-hit.html" }
|
||||
|
||||
trigger_handler = "generate.php"
|
||||
|
||||
if get["page"] == memcache_get_string("123") then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
end
|
||||
|
||||
In MySQL you do: ::
|
||||
|
||||
SELECT memcache_set("127.0.0.1:11211", "123", "12");
|
||||
|
||||
or to retrieve a value:
|
||||
|
||||
SELECT memcache_get("127.0.0.1:11211", "123");
|
||||
|
||||
You can get the mysql udf at `jan's mysql page <http://jan.kneschke.de/projects/mysql/udf/>`_.
|
||||
|
|
|
@ -69,9 +69,9 @@ common_libadd =
|
|||
endif
|
||||
|
||||
lib_LTLIBRARIES += mod_cml.la
|
||||
mod_cml_la_SOURCES = mod_cml.c mod_cml_funcs.c mod_cml_logic.c
|
||||
mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c
|
||||
mod_cml_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
|
||||
mod_cml_la_LIBADD = $(MEMCACHE_LIB) $(common_libadd)
|
||||
mod_cml_la_LIBADD = $(MEMCACHE_LIB) $(common_libadd) $(LUA_LIB)
|
||||
|
||||
lib_LTLIBRARIES += mod_trigger_b4_dl.la
|
||||
mod_trigger_b4_dl_la_SOURCES = mod_trigger_b4_dl.c
|
||||
|
|
|
@ -28,11 +28,6 @@ INIT_FUNC(mod_cml_init) {
|
|||
p->session_id = buffer_init();
|
||||
p->trigger_handler = buffer_init();
|
||||
|
||||
p->eval = buffer_array_init();
|
||||
p->trigger_if = buffer_array_init();
|
||||
p->output_include = buffer_array_init();
|
||||
p->params = tnode_val_array_init();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -63,12 +58,6 @@ FREE_FUNC(mod_cml_free) {
|
|||
free(p->config_storage);
|
||||
}
|
||||
|
||||
tnode_val_array_free(p->params);
|
||||
|
||||
buffer_array_free(p->eval);
|
||||
buffer_array_free(p->trigger_if);
|
||||
buffer_array_free(p->output_include);
|
||||
|
||||
buffer_free(p->trigger_handler);
|
||||
buffer_free(p->session_id);
|
||||
buffer_free(p->basedir);
|
||||
|
@ -103,6 +92,9 @@ SETDEFAULTS_FUNC(mod_cml_set_defaults) {
|
|||
s->ext = buffer_init();
|
||||
s->mc_hosts = array_init();
|
||||
s->mc_namespace = buffer_init();
|
||||
#if defined(HAVE_MEMCACHE_H)
|
||||
s->mc = NULL;
|
||||
#endif
|
||||
|
||||
cv[0].destination = s->ext;
|
||||
cv[1].destination = s->mc_hosts;
|
||||
|
@ -322,6 +314,7 @@ URIHANDLER_FUNC(mod_cml_is_handled) {
|
|||
buffer *fn = con->physical.path;
|
||||
plugin_data *p = p_d;
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
if (fn->used == 0) return HANDLER_ERROR;
|
||||
|
||||
|
@ -332,17 +325,11 @@ URIHANDLER_FUNC(mod_cml_is_handled) {
|
|||
mod_cml_patch_connection(srv, con, p, CONST_BUF_LEN(patch));
|
||||
}
|
||||
|
||||
buffer_array_reset(p->output_include);
|
||||
buffer_array_reset(p->eval);
|
||||
buffer_array_reset(p->trigger_if);
|
||||
|
||||
buffer_reset(p->basedir);
|
||||
buffer_reset(p->baseurl);
|
||||
buffer_reset(p->session_id);
|
||||
buffer_reset(p->trigger_handler);
|
||||
|
||||
tnode_val_array_reset(p->params);
|
||||
|
||||
if (buffer_is_empty(p->conf.ext)) return HANDLER_GO_ON;
|
||||
|
||||
ct_len = p->conf.ext->used - 1;
|
||||
|
@ -382,7 +369,9 @@ URIHANDLER_FUNC(mod_cml_is_handled) {
|
|||
|
||||
cache_get_session_id(srv, con, p);
|
||||
|
||||
switch(cache_parse(srv, con, p, fn)) {
|
||||
ret = cache_parse_lua(srv, con, p, fn);
|
||||
|
||||
switch(ret) {
|
||||
case -1:
|
||||
/* error */
|
||||
if (con->conf.log_request_handling) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "response.h"
|
||||
|
||||
#include "stream.h"
|
||||
#include "plugin.h"
|
||||
|
||||
#if defined(HAVE_MEMCACHE_H)
|
||||
#include <memcache.h>
|
||||
|
@ -13,39 +14,6 @@
|
|||
|
||||
#define plugin_data mod_cache_plugin_data
|
||||
|
||||
typedef enum { UNSET, PART, TIMES, MINUS, PLUS, OR, AND, GT, LT, GE, LE, EQ, NE } tnode_op_t;
|
||||
|
||||
typedef enum { T_NODE_VALUE_UNSET, T_NODE_VALUE_LONG, T_NODE_VALUE_STRING } tnode_val_t;
|
||||
|
||||
typedef struct {
|
||||
tnode_val_t type;
|
||||
|
||||
union {
|
||||
buffer *str;
|
||||
long lon;
|
||||
} data;
|
||||
} tnode_val;
|
||||
|
||||
#define VAL_LONG(x) x->value.data.lon
|
||||
#define VAL_STRING(x) x->value.data.str
|
||||
|
||||
#define IS_LONG(x) ((x->op == UNSET) && (x->value.type == T_NODE_VALUE_LONG))
|
||||
#define IS_STRING(x) ((x->op == UNSET) && (x->value.type == T_NODE_VALUE_STRING))
|
||||
|
||||
typedef struct tnode {
|
||||
tnode_val value;
|
||||
tnode_op_t op;
|
||||
|
||||
struct tnode *l, *r;
|
||||
} tnode;
|
||||
|
||||
typedef struct {
|
||||
tnode_val **ptr;
|
||||
|
||||
size_t size;
|
||||
size_t used;
|
||||
} tnode_val_array;
|
||||
|
||||
typedef struct {
|
||||
buffer *ext;
|
||||
|
||||
|
@ -66,40 +34,11 @@ typedef struct {
|
|||
|
||||
buffer *session_id;
|
||||
|
||||
buffer_array *eval;
|
||||
buffer_array *trigger_if;
|
||||
buffer_array *output_include;
|
||||
|
||||
tnode_val_array *params;
|
||||
|
||||
plugin_config **config_storage;
|
||||
|
||||
plugin_config conf;
|
||||
} plugin_data;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
size_t params;
|
||||
int (*func)(server *srv, connection *con, plugin_data *p, tnode *result);
|
||||
} cache_trigger_functions;
|
||||
|
||||
int cache_parse_parameters(server *srv, connection *con, plugin_data *p, const char *params, size_t param_len, tnode_val_array *res);
|
||||
int cache_parse(server *srv, connection *con, plugin_data *p, buffer *fn);
|
||||
int tnode_prepare_long(tnode *t);
|
||||
int tnode_prepare_string(tnode *t);
|
||||
|
||||
tnode_val_array *tnode_val_array_init();
|
||||
void tnode_val_array_free(tnode_val_array *tva);
|
||||
void tnode_val_array_reset(tnode_val_array *tva);
|
||||
|
||||
#define CACHE_FUNC_PROTO(x) int x(server *srv, connection *con, plugin_data *p, tnode *result)
|
||||
|
||||
CACHE_FUNC_PROTO(f_unix_time_now);
|
||||
CACHE_FUNC_PROTO(f_file_mtime);
|
||||
CACHE_FUNC_PROTO(f_memcache_exists);
|
||||
CACHE_FUNC_PROTO(f_memcache_get_string);
|
||||
CACHE_FUNC_PROTO(f_memcache_get_long);
|
||||
CACHE_FUNC_PROTO(f_http_request_get_param);
|
||||
CACHE_FUNC_PROTO(f_crypto_md5);
|
||||
int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "response.h"
|
||||
|
||||
#include "mod_cml.h"
|
||||
#include "mod_cml_funcs.h"
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
# include <openssl/md5.h>
|
||||
|
@ -33,259 +34,174 @@ typedef char HASHHEX[HASHHEXLEN+1];
|
|||
#endif
|
||||
#define OUT
|
||||
|
||||
CACHE_FUNC_PROTO(f_unix_time_now) {
|
||||
UNUSED(srv);
|
||||
UNUSED(con);
|
||||
UNUSED(p);
|
||||
|
||||
VAL_LONG(result) = srv->cur_ts;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_LUA_H
|
||||
|
||||
CACHE_FUNC_PROTO(f_file_mtime) {
|
||||
buffer *b;
|
||||
struct stat st;
|
||||
|
||||
UNUSED(con);
|
||||
|
||||
if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"f_file_mtime: I need a string:",
|
||||
p->params->ptr[0]->type);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
b = buffer_init();
|
||||
|
||||
/* build filename */
|
||||
buffer_copy_string_buffer(b, p->basedir);
|
||||
buffer_append_string_buffer(b, p->params->ptr[0]->data.str);
|
||||
|
||||
if (-1 == stat(b->ptr, &st)) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbs",
|
||||
"trigger.if file.mtime():", b, strerror(errno));
|
||||
|
||||
buffer_free(b);
|
||||
return -1;
|
||||
}
|
||||
buffer_free(b);
|
||||
|
||||
tnode_prepare_long(result);
|
||||
VAL_LONG(result) = st.st_mtime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int split_query_string(server *srv, connection *con, array *vals) {
|
||||
size_t key_start = 0, key_end = 0,
|
||||
value_start = 0;
|
||||
size_t is_key = 1;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < con->uri.query->used; i++) {
|
||||
switch(con->uri.query->ptr[i]) {
|
||||
case '=':
|
||||
if (is_key) {
|
||||
key_end = i - 1;
|
||||
value_start = i + 1;
|
||||
|
||||
is_key = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case '&':
|
||||
case '\0': /* fin symbol */
|
||||
if (!is_key) {
|
||||
data_string *ds;
|
||||
|
||||
/* we need at least a = since the last & */
|
||||
|
||||
if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) {
|
||||
ds = data_string_init();
|
||||
}
|
||||
|
||||
buffer_copy_string_len(ds->key, con->uri.query->ptr + key_start, key_end - key_start);
|
||||
buffer_copy_string_len(ds->value, con->uri.query->ptr + value_start, i - value_start);
|
||||
|
||||
array_insert_unique(vals, (data_unset *)ds);
|
||||
}
|
||||
|
||||
key_start = i + 1;
|
||||
value_start = 0;
|
||||
is_key = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CACHE_FUNC_PROTO(f_http_request_get_param) {
|
||||
array *qry_str;
|
||||
data_string *ds;
|
||||
|
||||
/* fetch data from the con-> request query string */
|
||||
|
||||
if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"f_http_request_get_param: I need a string:",
|
||||
p->params->ptr[0]->type);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
qry_str = array_init();
|
||||
|
||||
split_query_string(srv, con, qry_str);
|
||||
|
||||
tnode_prepare_string(result);
|
||||
|
||||
if (NULL == (ds = (data_string *)array_get_element(qry_str, p->params->ptr[0]->data.str->ptr))) {
|
||||
|
||||
buffer_copy_string(VAL_STRING(result), "");
|
||||
|
||||
array_free(qry_str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer_copy_string_buffer(VAL_STRING(result), ds->value);
|
||||
|
||||
array_free(qry_str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CACHE_FUNC_PROTO(f_crypto_md5) {
|
||||
int f_crypto_md5(lua_State *L) {
|
||||
MD5_CTX Md5Ctx;
|
||||
HASH HA1;
|
||||
buffer b;
|
||||
char hex[33];
|
||||
int n = lua_gettop(L);
|
||||
|
||||
/* fetch data from the con-> request query string */
|
||||
b.ptr = hex;
|
||||
b.used = 0;
|
||||
b.size = sizeof(hex);
|
||||
|
||||
if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"crypto.md5: I need a string:",
|
||||
p->params->ptr[0]->type);
|
||||
|
||||
return -1;
|
||||
if (n != 1) {
|
||||
lua_pushstring(L, "expected one argument");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (!lua_isstring(L, 1)) {
|
||||
lua_pushstring(L, "argument has to be a string");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
MD5_Init(&Md5Ctx);
|
||||
MD5_Update(&Md5Ctx, (unsigned char *)p->params->ptr[0]->data.str->ptr, p->params->ptr[0]->data.str->used - 1);
|
||||
MD5_Update(&Md5Ctx, (unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1));
|
||||
MD5_Final(HA1, &Md5Ctx);
|
||||
|
||||
tnode_prepare_string(result);
|
||||
buffer_copy_string_hex(VAL_STRING(result), (char *)HA1, 16);
|
||||
buffer_copy_string_hex(&b, (char *)HA1, 16);
|
||||
|
||||
return 0;
|
||||
lua_pushstring(L, b.ptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int f_file_mtime(lua_State *L) {
|
||||
struct stat st;
|
||||
int n = lua_gettop(L);
|
||||
|
||||
if (n != 1) {
|
||||
lua_pushstring(L, "expected one argument");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (!lua_isstring(L, 1)) {
|
||||
lua_pushstring(L, "argument has to be a string");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (-1 == stat(lua_tostring(L, 1), &st)) {
|
||||
lua_pushstring(L, "stat failed");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
lua_pushnumber(L, st.st_mtime);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MEMCACHE_H
|
||||
CACHE_FUNC_PROTO(f_memcache_exists) {
|
||||
int f_memcache_exists(lua_State *L) {
|
||||
char *r;
|
||||
int n = lua_gettop(L);
|
||||
struct memcache *mc;
|
||||
|
||||
UNUSED(con);
|
||||
|
||||
if (!p->conf.mc) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"f_memcache_exists: no memcache.hosts set:",
|
||||
p->params->ptr[0]->type);
|
||||
return -1;
|
||||
if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
|
||||
lua_pushstring(L, "where is my userdata ?");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"f_memcache_exists: I need a string:",
|
||||
p->params->ptr[0]->type);
|
||||
|
||||
return -1;
|
||||
mc = lua_touserdata(L, lua_upvalueindex(1));
|
||||
|
||||
if (n != 1) {
|
||||
lua_pushstring(L, "expected one argument");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
tnode_prepare_long(result);
|
||||
if (!lua_isstring(L, 1)) {
|
||||
lua_pushstring(L, "argument has to be a string");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (NULL == (r = mc_aget(p->conf.mc,
|
||||
CONST_BUF_LEN(p->params->ptr[0]->data.str)))) {
|
||||
if (NULL == (r = mc_aget(mc,
|
||||
lua_tostring(L, 1), lua_strlen(L, 1)))) {
|
||||
|
||||
VAL_LONG(result) = 0;
|
||||
return 0;
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(r);
|
||||
|
||||
VAL_LONG(result) = 1;
|
||||
|
||||
return 0;
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
CACHE_FUNC_PROTO(f_memcache_get_string) {
|
||||
int f_memcache_get_string(lua_State *L) {
|
||||
char *r;
|
||||
int n = lua_gettop(L);
|
||||
|
||||
UNUSED(con);
|
||||
struct memcache *mc;
|
||||
|
||||
if (!p->conf.mc) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"f_memcache_get_string: no memcache.hosts set:",
|
||||
p->params->ptr[0]->type);
|
||||
return -1;
|
||||
if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
|
||||
lua_pushstring(L, "where is my userdata ?");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"f_memcache_get_string: I need a string:",
|
||||
p->params->ptr[0]->type);
|
||||
return -1;
|
||||
mc = lua_touserdata(L, lua_upvalueindex(1));
|
||||
|
||||
|
||||
if (n != 1) {
|
||||
lua_pushstring(L, "expected one argument");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (NULL == (r = mc_aget(p->conf.mc,
|
||||
p->params->ptr[0]->data.str->ptr, p->params->ptr[0]->data.str->used - 1))) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sb",
|
||||
"f_memcache_get_string: couldn't find:",
|
||||
p->params->ptr[0]->data.str);
|
||||
return -1;
|
||||
if (!lua_isstring(L, 1)) {
|
||||
lua_pushstring(L, "argument has to be a string");
|
||||
lua_error(L);
|
||||
}
|
||||
tnode_prepare_string(result);
|
||||
buffer_copy_string(VAL_STRING(result), r);
|
||||
|
||||
if (NULL == (r = mc_aget(mc,
|
||||
lua_tostring(L, 1), lua_strlen(L, 1)))) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushstring(L, r);
|
||||
|
||||
free(r);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
CACHE_FUNC_PROTO(f_memcache_get_long) {
|
||||
int f_memcache_get_long(lua_State *L) {
|
||||
char *r;
|
||||
int n = lua_gettop(L);
|
||||
|
||||
UNUSED(con);
|
||||
struct memcache *mc;
|
||||
|
||||
if (!p->conf.mc) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"f_memcache_get_long: no memcache.hosts set:",
|
||||
p->params->ptr[0]->type);
|
||||
return -1;
|
||||
if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
|
||||
lua_pushstring(L, "where is my userdata ?");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (p->params->ptr[0]->type != T_NODE_VALUE_STRING) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"f_memcache_get_long: I need a string:",
|
||||
p->params->ptr[0]->type);
|
||||
return -1;
|
||||
mc = lua_touserdata(L, lua_upvalueindex(1));
|
||||
|
||||
|
||||
if (n != 1) {
|
||||
lua_pushstring(L, "expected one argument");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
if (NULL == (r = mc_aget(p->conf.mc,
|
||||
CONST_BUF_LEN(p->params->ptr[0]->data.str)))) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sb",
|
||||
"f_memcache_get_long: couldn't find:",
|
||||
p->params->ptr[0]->data.str);
|
||||
return -1;
|
||||
if (!lua_isstring(L, 1)) {
|
||||
lua_pushstring(L, "argument has to be a string");
|
||||
lua_error(L);
|
||||
}
|
||||
|
||||
tnode_prepare_long(result);
|
||||
VAL_LONG(result) = strtol(r, NULL, 10);
|
||||
if (NULL == (r = mc_aget(mc,
|
||||
lua_tostring(L, 1), lua_strlen(L, 1)))) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnumber(L, strtol(r, NULL, 10));
|
||||
|
||||
free(r);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue