MINOR: lua: txn: create class TXN associated with the transaction.
This class of functions permit to access to all the functions associated with the transaction like http header, HAProxy internal fetches, etc ... This patch puts the skeleton of this class. The class will be enhanced later.
This commit is contained in:
parent
55da165301
commit
65f34c6367
|
@ -4,6 +4,9 @@
|
|||
#include <lua.h>
|
||||
|
||||
#define CLASS_CORE "Core"
|
||||
#define CLASS_TXN "TXN"
|
||||
|
||||
struct session;
|
||||
|
||||
enum hlua_state {
|
||||
HLUA_STOP = 0,
|
||||
|
@ -49,4 +52,15 @@ struct hlua_init_function {
|
|||
int function_ref;
|
||||
};
|
||||
|
||||
/* This struct contains the pointer provided on the most
|
||||
* of internal HAProxy calls during the processing of
|
||||
* rules, converters and sample-fetches. This struct is
|
||||
* associated with the lua object called "TXN".
|
||||
*/
|
||||
struct hlua_txn {
|
||||
struct session *s;
|
||||
struct proxy *p;
|
||||
void *l7;
|
||||
};
|
||||
|
||||
#endif /* _TYPES_HLUA_H */
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#include <types/channel.h>
|
||||
#include <types/compression.h>
|
||||
|
||||
#ifdef USE_LUA
|
||||
#include <types/hlua.h>
|
||||
#endif
|
||||
#include <types/obj_type.h>
|
||||
#include <types/proto_http.h>
|
||||
#include <types/proxy.h>
|
||||
|
@ -160,6 +163,10 @@ struct session {
|
|||
/* These two pointers are used to resume the execution of the rule lists. */
|
||||
struct list *current_rule_list; /* this is used to store the current executed rule list. */
|
||||
struct list *current_rule; /* this is used to store the current rule to be resumed. */
|
||||
|
||||
#ifdef USE_LUA
|
||||
struct hlua hlua; /* lua runtime context */
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _TYPES_SESSION_H */
|
||||
|
|
157
src/hlua.c
157
src/hlua.c
|
@ -7,6 +7,7 @@
|
|||
#include <common/cfgparse.h>
|
||||
|
||||
#include <types/hlua.h>
|
||||
#include <types/proto_tcp.h>
|
||||
#include <types/proxy.h>
|
||||
|
||||
#include <proto/arg.h>
|
||||
|
@ -45,6 +46,7 @@ struct eb_root hlua_ctx = EB_ROOT_UNIQUE;
|
|||
* associated with an object.
|
||||
*/
|
||||
static int class_core_ref;
|
||||
static int class_txn_ref;
|
||||
|
||||
/* These functions converts types between HAProxy internal args or
|
||||
* sample and LUA types. Another function permits to check if the
|
||||
|
@ -675,6 +677,141 @@ static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* A class is a lot of memory that contain data. This data can be a table,
|
||||
* an integer or user data. This data is associated with a metatable. This
|
||||
* metatable have an original version registred in the global context with
|
||||
* the name of the object (_G[<name>] = <metable> ).
|
||||
*
|
||||
* A metable is a table that modify the standard behavior of a standard
|
||||
* access to the associated data. The entries of this new metatable are
|
||||
* defined as is:
|
||||
*
|
||||
* http://lua-users.org/wiki/MetatableEvents
|
||||
*
|
||||
* __index
|
||||
*
|
||||
* we access an absent field in a table, the result is nil. This is
|
||||
* true, but it is not the whole truth. Actually, such access triggers
|
||||
* the interpreter to look for an __index metamethod: If there is no
|
||||
* such method, as usually happens, then the access results in nil;
|
||||
* otherwise, the metamethod will provide the result.
|
||||
*
|
||||
* Control 'prototype' inheritance. When accessing "myTable[key]" and
|
||||
* the key does not appear in the table, but the metatable has an __index
|
||||
* property:
|
||||
*
|
||||
* - if the value is a function, the function is called, passing in the
|
||||
* table and the key; the return value of that function is returned as
|
||||
* the result.
|
||||
*
|
||||
* - if the value is another table, the value of the key in that table is
|
||||
* asked for and returned (and if it doesn't exist in that table, but that
|
||||
* table's metatable has an __index property, then it continues on up)
|
||||
*
|
||||
* - Use "rawget(myTable,key)" to skip this metamethod.
|
||||
*
|
||||
* http://www.lua.org/pil/13.4.1.html
|
||||
*
|
||||
* __newindex
|
||||
*
|
||||
* Like __index, but control property assignment.
|
||||
*
|
||||
* __mode - Control weak references. A string value with one or both
|
||||
* of the characters 'k' and 'v' which specifies that the the
|
||||
* keys and/or values in the table are weak references.
|
||||
*
|
||||
* __call - Treat a table like a function. When a table is followed by
|
||||
* parenthesis such as "myTable( 'foo' )" and the metatable has
|
||||
* a __call key pointing to a function, that function is invoked
|
||||
* (passing any specified arguments) and the return value is
|
||||
* returned.
|
||||
*
|
||||
* __metatable - Hide the metatable. When "getmetatable( myTable )" is
|
||||
* called, if the metatable for myTable has a __metatable
|
||||
* key, the value of that key is returned instead of the
|
||||
* actual metatable.
|
||||
*
|
||||
* __tostring - Control string representation. When the builtin
|
||||
* "tostring( myTable )" function is called, if the metatable
|
||||
* for myTable has a __tostring property set to a function,
|
||||
* that function is invoked (passing myTable to it) and the
|
||||
* return value is used as the string representation.
|
||||
*
|
||||
* __len - Control table length. When the table length is requested using
|
||||
* the length operator ( '#' ), if the metatable for myTable has
|
||||
* a __len key pointing to a function, that function is invoked
|
||||
* (passing myTable to it) and the return value used as the value
|
||||
* of "#myTable".
|
||||
*
|
||||
* __gc - Userdata finalizer code. When userdata is set to be garbage
|
||||
* collected, if the metatable has a __gc field pointing to a
|
||||
* function, that function is first invoked, passing the userdata
|
||||
* to it. The __gc metamethod is not called for tables.
|
||||
* (See http://lua-users.org/lists/lua-l/2006-11/msg00508.html)
|
||||
*
|
||||
* Special metamethods for redefining standard operators:
|
||||
* http://www.lua.org/pil/13.1.html
|
||||
*
|
||||
* __add "+"
|
||||
* __sub "-"
|
||||
* __mul "*"
|
||||
* __div "/"
|
||||
* __unm "!"
|
||||
* __pow "^"
|
||||
* __concat ".."
|
||||
*
|
||||
* Special methods for redfining standar relations
|
||||
* http://www.lua.org/pil/13.2.html
|
||||
*
|
||||
* __eq "=="
|
||||
* __lt "<"
|
||||
* __le "<="
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Class TXN
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* Returns a struct hlua_session if the stack entry "ud" is
|
||||
* a class session, otherwise it throws an error.
|
||||
*/
|
||||
__LJMP static struct hlua_txn *hlua_checktxn(lua_State *L, int ud)
|
||||
{
|
||||
return (struct hlua_txn *)MAY_LJMP(hlua_checkudata(L, ud, class_txn_ref));
|
||||
}
|
||||
|
||||
/* Create stack entry containing a class TXN. This function
|
||||
* return 0 if the stack does not contains free slots,
|
||||
* otherwise it returns 1.
|
||||
*/
|
||||
static int hlua_txn_new(lua_State *L, struct session *s, struct proxy *p, void *l7)
|
||||
{
|
||||
struct hlua_txn *hs;
|
||||
|
||||
/* Check stack size. */
|
||||
if (!lua_checkstack(L, 2))
|
||||
return 0;
|
||||
|
||||
/* NOTE: The allocation never fails. The failure
|
||||
* throw an error, and the function never returns.
|
||||
* if the throw is not avalaible, the process is aborted.
|
||||
*/
|
||||
hs = lua_newuserdata(L, sizeof(struct hlua_txn));
|
||||
hs->s = s;
|
||||
hs->p = p;
|
||||
hs->l7 = l7;
|
||||
|
||||
/* Pop a class sesison metatable and affect it to the userdata. */
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, class_txn_ref);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This function is used as a calback of a task. It is called by the
|
||||
* HAProxy task subsystem when the task is awaked. The LUA runtime can
|
||||
* return an E_AGAIN signal, the emmiter of this signal must set a
|
||||
|
@ -940,4 +1077,24 @@ void hlua_init(void)
|
|||
/* Create new object with class Core. */
|
||||
lua_setmetatable(gL.T, -2);
|
||||
lua_setglobal(gL.T, "core");
|
||||
|
||||
/*
|
||||
*
|
||||
* Register class TXN
|
||||
*
|
||||
*/
|
||||
|
||||
/* Create and fill the metatable. */
|
||||
lua_newtable(gL.T);
|
||||
|
||||
/* Create and fille the __index entry. */
|
||||
lua_pushstring(gL.T, "__index");
|
||||
lua_newtable(gL.T);
|
||||
|
||||
lua_settable(gL.T, -3);
|
||||
|
||||
/* Register previous table in the registry with reference and named entry. */
|
||||
lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
|
||||
lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_TXN); /* register class session. */
|
||||
class_txn_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
|
||||
}
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
#include <proto/freq_ctr.h>
|
||||
#include <proto/frontend.h>
|
||||
#include <proto/hdr_idx.h>
|
||||
#ifdef USE_LUA
|
||||
#include <proto/hlua.h>
|
||||
#endif
|
||||
#include <proto/listener.h>
|
||||
#include <proto/log.h>
|
||||
#include <proto/raw_sock.h>
|
||||
|
@ -541,6 +544,11 @@ int session_complete(struct session *s)
|
|||
txn->req.chn = s->req;
|
||||
txn->rsp.chn = s->rep;
|
||||
|
||||
#ifdef USE_LUA
|
||||
if (!hlua_ctx_init(&s->hlua, s->task))
|
||||
goto out_free_rep;
|
||||
#endif
|
||||
|
||||
/* finish initialization of the accepted file descriptor */
|
||||
conn_data_want_recv(conn);
|
||||
|
||||
|
@ -549,7 +557,7 @@ int session_complete(struct session *s)
|
|||
* finished (=0, eg: monitoring), in both situations,
|
||||
* we can release everything and close.
|
||||
*/
|
||||
goto out_free_rep;
|
||||
goto out_free_lua;
|
||||
}
|
||||
|
||||
/* if logs require transport layer information, note it on the connection */
|
||||
|
@ -567,6 +575,11 @@ int session_complete(struct session *s)
|
|||
return 1;
|
||||
|
||||
/* Error unrolling */
|
||||
out_free_lua:
|
||||
#ifdef USE_LUA
|
||||
hlua_ctx_destroy(&s->hlua);
|
||||
#endif
|
||||
|
||||
out_free_rep:
|
||||
pool_free2(pool2_channel, s->rep);
|
||||
out_free_req:
|
||||
|
@ -628,6 +641,10 @@ static void session_free(struct session *s)
|
|||
if (!LIST_ISEMPTY(&buffer_wq))
|
||||
session_offer_buffers();
|
||||
|
||||
#ifdef USE_LUA
|
||||
hlua_ctx_destroy(&s->hlua);
|
||||
#endif
|
||||
|
||||
pool_free2(pool2_channel, s->req);
|
||||
pool_free2(pool2_channel, s->rep);
|
||||
|
||||
|
|
Loading…
Reference in New Issue