Hi there,

Our company is using LUA scripting a lot, and I've discovered some missing
functions in the code. We've made a patch to fill these gaps, but I don't
know how to make a pull request. So, I've made a copy of the haproxy
repository and pushed my changes there. It's based on latest development
version.

Here is my commit:
https://github.com/mediahubinc/haproxy/commit/4446ecddce3f5ec71e79f92e1fbc8eb3841f08e4

Added functions:
http:req_get_method()
http:req_get_uri()
http:req_get_path()
http:req_get_query()

Map:del(key)
Map:set(key, value)
Map:clear()
Map:list(offset = 0, limit = 0)
Map:get_unique_id()
Map:get_reference()
Map:store()

core.clear_map(filename)
core.list_map(filename, offset = 0, limit = 0)
core.list_maps()
core.store_map(filename)
diff --git a/include/proto/pattern.h b/include/proto/pattern.h
index 9c93db9..2049d77 100644
--- a/include/proto/pattern.h
+++ b/include/proto/pattern.h
@@ -194,7 +194,7 @@ int pat_ref_delete_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt);
 void pat_ref_prune(struct pat_ref *ref);
 int pat_ref_load(struct pat_ref *ref, struct pattern_expr *expr, int patflags, int soe, char **err);
 void pat_ref_reload(struct pat_ref *ref, struct pat_ref *replace);
-
+int pat_ref_write_to_file_smp(struct pat_ref *ref, const char *filename, char **err);
 
 /*
  * pattern_head manipulation.
diff --git a/include/types/map.h b/include/types/map.h
index cea5aa5..1cbcfa0 100644
--- a/include/types/map.h
+++ b/include/types/map.h
@@ -28,6 +28,7 @@
 struct map_descriptor {
 	struct sample_conv *conv;      /* original converter descriptor */
 	struct pattern_head pat;       /* the pattern matching associated to the map */
+	struct pat_ref * ref;          /* the pattern reference */
 	int do_free;                   /* set if <pat> is the orignal pat and must be freed */
 };
 
diff --git a/src/hlua.c b/src/hlua.c
index 9d81634..9d85de1 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -57,8 +57,8 @@
  * macro is used only for identifying the function that can
  * not return because a longjmp is executed.
  *   __LJMP marks a prototype of hlua file that can use longjmp.
- *   WILL_LJMP() marks an lua function that will use longjmp.
- *   MAY_LJMP() marks an lua function that may use longjmp.
+ *   WILL_LJMP() marks a LUA function that will use longjmp.
+ *   MAY_LJMP() marks a LUA function that may use longjmp.
  */
 #define __LJMP
 #define WILL_LJMP(func) func
@@ -240,7 +240,7 @@ __LJMP static int hlua_http_get_headers(lua_State *L, struct hlua_txn *htxn, str
 			Alert(__fmt, ## __args); \
 	} while (0)
 
-/* Used to check an Lua function type in the stack. It creates and
+/* Used to check a LUA function type in the stack. It creates and
  * returns a reference of the function. This function throws an
  * error if the rgument is not a "function".
  */
@@ -377,7 +377,7 @@ static int hlua_arg2lua(lua_State *L, const struct arg *arg)
 	return 1;
 }
 
-/* This function take one entrie in an LUA stack at the index "ud",
+/* This function take one entrie in a LUA stack at the index "ud",
  * and try to convert it in an HAProxy argument entry. This is useful
  * with sample fetch wrappers. The input arguments are gived to the
  * lua wrapper and converted as arg list by thi function.
@@ -512,7 +512,7 @@ static int hlua_smp2lua_str(lua_State *L, struct sample *smp)
 	return 1;
 }
 
-/* the following functions are used to convert an Lua type in a
+/* the following functions are used to convert a LUA type in a
  * struct sample. This is useful to provide data from a converter
  * to the LUA code.
  */
@@ -758,7 +758,7 @@ __LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
  * The following functions are used to make correspondance between the the
  * executed lua pointer and the "struct hlua *" that contain the context.
  *
- *  - hlua_gethlua : return the hlua context associated with an lua_State.
+ *  - hlua_gethlua : return the hlua context associated with a LUA_State.
  *  - hlua_sethlua : create the association between hlua context and lua_state.
  */
 static inline struct hlua *hlua_gethlua(lua_State *L)
@@ -829,7 +829,7 @@ __LJMP void hlua_yieldk(lua_State *L, int nresults, int ctx,
 
 /* This function initialises the Lua environment stored in the stream.
  * It must be called at the start of the stream. This function creates
- * an LUA coroutine. It can not be use to crete the main LUA context.
+ * a LUA coroutine. It can not be use to crete the main LUA context.
  *
  * This function is particular. it initialises a new Lua thread. If the
  * initialisation fails (example: out of memory error), the lua function
@@ -1175,7 +1175,7 @@ __LJMP static int hlua_done(lua_State *L)
 	return 0;
 }
 
-/* This function is an LUA binding. It provides a function
+/* This function is a LUA binding. It provides a function
  * for deleting ACL from a referenced ACL file.
  */
 __LJMP static int hlua_del_acl(lua_State *L)
@@ -1197,10 +1197,10 @@ __LJMP static int hlua_del_acl(lua_State *L)
 	return 0;
 }
 
-/* This function is an LUA binding. It provides a function
+/* This function is a LUA binding. It provides a function
  * for deleting map entry from a referenced map file.
  */
-static int hlua_del_map(lua_State *L)
+__LJMP static int hlua_del_map(lua_State *L)
 {
 	const char *name;
 	const char *key;
@@ -1219,10 +1219,10 @@ static int hlua_del_map(lua_State *L)
 	return 0;
 }
 
-/* This function is an LUA binding. It provides a function
+/* This function is a LUA binding. It provides a function
  * for adding ACL pattern from a referenced ACL file.
  */
-static int hlua_add_acl(lua_State *L)
+__LJMP static int hlua_add_acl(lua_State *L)
 {
 	const char *name;
 	const char *key;
@@ -1242,11 +1242,11 @@ static int hlua_add_acl(lua_State *L)
 	return 0;
 }
 
-/* This function is an LUA binding. It provides a function
+/* This function is a LUA binding. It provides a function
  * for setting map pattern and sample from a referenced map
  * file.
  */
-static int hlua_set_map(lua_State *L)
+__LJMP static int hlua_set_map(lua_State *L)
 {
 	const char *name;
 	const char *key;
@@ -1270,9 +1270,195 @@ static int hlua_set_map(lua_State *L)
 	return 0;
 }
 
-/* A class is a lot of memory that contain data. This data can be a table,
+/* This function is a LUA binding. It provides a function
+ * for clearing all map patterns and samples from a referenced map
+ * file.
+ */
+__LJMP static int hlua_clear_map(lua_State *L)
+{
+	const char *name;
+	struct pat_ref *ref;
+
+	MAY_LJMP(check_args(L, 1, "clear"));
+
+	name = MAY_LJMP(luaL_checkstring(L, 1));
+
+	ref = pat_ref_lookup(name);
+	if (!ref)
+		WILL_LJMP(luaL_error(L, "'clear': unknown map file '%s'", name));
+
+	pat_ref_prune(ref);
+	return 0;
+}
+
+/* This function is a LUA binding. It provides a function
+ * for storing all map patterns and samples to a referenced map
+ * file.
+ */
+__LJMP static int hlua_store_map(lua_State *L)
+{
+	const char *name;
+	struct pat_ref *ref;
+	char *err = NULL;
+
+	MAY_LJMP(check_args(L, 1, "store_map"));
+
+	name = MAY_LJMP(luaL_checkstring(L, 1));
+
+	ref = pat_ref_lookup(name);
+	if (!ref)
+		WILL_LJMP(luaL_error(L, "'store_map': unknown map file '%s'", name));
+
+	if (!pat_ref_write_to_file_smp(ref, name, &err)) {
+		/* error case: we cant use luaL_error because we must
+		 * free the err variable.
+		 */
+		luaL_where(L, 1);
+		lua_pushfstring(L, "'store_map': %s.", err);
+		lua_concat(L, 2);
+		free(err);
+		WILL_LJMP(lua_error(L));
+	}
+	return 0;
+}
+
+static int _hlua_map_list(lua_State *L, struct pat_ref *ref, lua_Integer start, lua_Integer length)
+{
+	struct pat_ref_elt *elt;
+
+	lua_newtable(L);
+
+	if (start == 0) {
+		if (length == 0) {
+			list_for_each_entry(elt, &ref->head, list) {
+				lua_pushstring(L, elt->pattern);
+				lua_pushstring(L, elt->sample);
+				lua_rawset(L, -3);
+			}
+		} else if (length > 0) {
+			list_for_each_entry(elt, &ref->head, list) {
+				lua_pushstring(L, elt->pattern);
+				lua_pushstring(L, elt->sample);
+				lua_rawset(L, -3);
+				length--;
+				if (length == 0)
+					break;
+			}
+		}
+	} else if (start > 0) {
+		if (length == 0) {
+			list_for_each_entry(elt, &ref->head, list) {
+				if (start > 0) {
+					start--;
+					continue;
+				}
+				lua_pushstring(L, elt->pattern);
+				lua_pushstring(L, elt->sample);
+				lua_rawset(L, -3);
+			}
+		} else if (length > 0) {
+			list_for_each_entry(elt, &ref->head, list) {
+				if (start > 0) {
+					start--;
+					continue;
+				}
+				lua_pushstring(L, elt->pattern);
+				lua_pushstring(L, elt->sample);
+				lua_rawset(L, -3);
+				length--;
+				if (length == 0)
+					break;
+			}
+		}
+	}
+
+	return 1;
+}
+
+/* This function is a LUA binding. It provides a function
+ * for listing map patterns and samples to a referenced map
+ * file.
+ * If first argument (start) is non-negative, the returned table will start
+ * at the start'th position, counting from zero.
+ * If second argument (length) is given and is positive, the table returned
+ * will contain at most length elements beginning from start.
+ */
+__LJMP static int hlua_list_map(lua_State *L)
+{
+	const char *name;
+	lua_Integer start;
+	lua_Integer length;
+	struct pat_ref *ref;
+
+	if (lua_gettop(L) < 1 || lua_gettop(L) > 3)
+		WILL_LJMP(luaL_error(L, "'list_map' needs at least 1 argument."));
+
+	name = MAY_LJMP(luaL_checkstring(L, 1));
+	start = MAY_LJMP(luaL_optinteger(L, 2, 0));
+	length = MAY_LJMP(luaL_optinteger(L, 3, 0));
+
+	ref = pat_ref_lookup(name);
+	if (!ref)
+		WILL_LJMP(luaL_error(L, "'list_map': unknown map file '%s'", name));
+
+	return _hlua_map_list(L, ref, start, length);
+}
+
+void _hlua_table_ref(lua_State *L, struct pat_ref *ref) {
+	lua_pushstring(L, "reference");
+	lua_pushstring(L, ref->reference);
+	lua_rawset(L, -3);
+
+	lua_pushstring(L, "id");
+	lua_pushnumber(L, ref->unique_id);
+	lua_rawset(L, -3);
+
+	lua_pushstring(L, "flags");
+	lua_pushnumber(L, ref->flags);
+	lua_rawset(L, -3);
+}
+
+/* This function is a LUA binding. It provides a function
+ * for listing registered maps and their properties.
+ * If argument is given and not nil, function will return a map with
+ * provided unique identifier or associated filename. Returns nil if
+ * requested map does not exist.
+ * If argument is omitted or nil, all maps will be returned as a table.
+ */
+__LJMP static int hlua_list_maps(lua_State *L)
+{
+	struct pat_ref *ref;
+
+	if (lua_gettop(L) > 1)
+		WILL_LJMP(luaL_error(L, "'list_maps' needs at most 1 argument."));
+
+	if (lua_gettop(L) == 1 && !lua_isnil(L, 1)) {
+			ref = lua_isnumber(L, 1) ?
+				pat_ref_lookupid(MAY_LJMP(luaL_checkinteger(L, 1))) :
+				pat_ref_lookup(MAY_LJMP(luaL_checkstring(L, 1)));
+
+		if (ref) {
+			lua_newtable(L);
+			_hlua_table_ref(L, ref);
+		} else {
+			lua_pushnil(L);
+		}
+	} else {
+		lua_newtable(L);
+		list_for_each_entry(ref, &pattern_reference, list) {
+			lua_pushnumber(L, ref->unique_id);
+			lua_newtable(L);
+			_hlua_table_ref(L, ref);
+			lua_rawset(L, -3);
+		}
+	}
+
+	return 1;
+}
+
+/* A class is a lot of memory that contains 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
+ * metatable has 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
@@ -1506,6 +1692,136 @@ __LJMP static int hlua_map_slookup(struct lua_State *L)
 	return _hlua_map_lookup(L, 1);
 }
 
+/* This function sets a map entry value.
+ */
+__LJMP static int hlua_map_set(lua_State *L)
+{
+	struct map_descriptor *desc;
+	const char *key;
+	const char *value;
+
+	MAY_LJMP(check_args(L, 3, "set"));
+
+	desc = MAY_LJMP(hlua_checkmap(L, 1));
+	key = MAY_LJMP(luaL_checkstring(L, 2));
+	value = MAY_LJMP(luaL_checkstring(L, 3));
+
+	if (pat_ref_find_elt(desc->ref, key) != NULL)
+		pat_ref_set(desc->ref, key, value, NULL);
+	else
+		pat_ref_add(desc->ref, key, value, NULL);
+	return 0;
+}
+
+/* This function deletes a map entry.
+ */
+__LJMP static int hlua_map_del(lua_State *L)
+{
+	struct map_descriptor *desc;
+	const char *key;
+
+	MAY_LJMP(check_args(L, 2, "del"));
+
+	desc = MAY_LJMP(hlua_checkmap(L, 1));
+	key = MAY_LJMP(luaL_checkstring(L, 2));
+
+	pat_ref_delete(desc->ref, key);
+	return 0;
+}
+
+/* This function clears all map patterns and samples.
+ */
+__LJMP static int hlua_map_clear(lua_State *L)
+{
+	struct map_descriptor *desc;
+
+	MAY_LJMP(check_args(L, 1, "clear"));
+
+	desc = MAY_LJMP(hlua_checkmap(L, 1));
+
+	pat_ref_prune(desc->ref);
+	return 0;
+}
+
+/* This function stores all patterns and samples to specified or referenced map
+ * file.
+ */
+__LJMP static int hlua_map_store(lua_State *L)
+{
+	struct map_descriptor *desc;
+	const char *filename;
+	char *err = NULL;
+
+	if (lua_gettop(L) < 1 || lua_gettop(L) > 2)
+		WILL_LJMP(luaL_error(L, "'store' needs at least 1 argument."));
+
+	desc = MAY_LJMP(hlua_checkmap(L, 1));
+	filename = MAY_LJMP(luaL_optstring(L, 2, desc->ref->reference));
+
+	if (!pat_ref_write_to_file_smp(desc->ref, filename, &err)) {
+		/* error case: we cant use luaL_error because we must
+		 * free the err variable.
+		 */
+		luaL_where(L, 1);
+		lua_pushfstring(L, "'store': %s.", err);
+		lua_concat(L, 2);
+		free(err);
+		WILL_LJMP(lua_error(L));
+	}
+
+	return 0;
+}
+
+/* This function returns a unique map identifier.
+ */
+__LJMP static int hlua_map_get_id(lua_State *L)
+{
+	struct map_descriptor *desc;
+
+	MAY_LJMP(check_args(L, 1, "get_id"));
+
+	desc = MAY_LJMP(hlua_checkmap(L, 1));
+
+	lua_pushinteger(L, desc->ref->unique_id);
+	return 1;
+}
+
+/* This function returns a referenced map file.
+ */
+__LJMP static int hlua_map_get_reference(lua_State *L)
+{
+	struct map_descriptor *desc;
+
+	MAY_LJMP(check_args(L, 1, "get_reference"));
+
+	desc = MAY_LJMP(hlua_checkmap(L, 1));
+
+	lua_pushstring(L, desc->ref->reference);
+	return 1;
+}
+
+/* This function allows listing patterns and samples of the map object.
+ * If first argument (start) is non-negative, the returned table will start
+ * at the start'th position, counting from zero.
+ * If second argument (length) is given and is positive, the table returned
+ * will contain at most length elements beginning from start.
+ */
+__LJMP static int hlua_map_list(lua_State *L)
+{
+	struct map_descriptor *desc;
+	lua_Integer start;
+	lua_Integer length;
+
+	if (lua_gettop(L) < 1 || lua_gettop(L) > 3)
+		WILL_LJMP(luaL_error(L, "'list' needs at least 1 argument."));
+
+	desc = MAY_LJMP(hlua_checkmap(L, 1));
+	start = MAY_LJMP(luaL_optinteger(L, 2, 0));
+	length = MAY_LJMP(luaL_optinteger(L, 3, 0));
+
+	return _hlua_map_list(L, desc->ref, start, length);
+}
+
 /*
  *
  *
@@ -2919,7 +3235,7 @@ static int hlua_fetches_new(lua_State *L, struct hlua_txn *txn, unsigned int fla
 	return 1;
 }
 
-/* This function is an LUA binding. It is called with each sample-fetch.
+/* This function is a LUA binding. It is called with each sample-fetch.
  * It uses closure argument to store the associated sample-fetch. It
  * returns only one argument or throws an error. An error is thrown
  * only if an error is encountered during the argument parsing. If
@@ -3033,7 +3349,7 @@ static int hlua_converters_new(lua_State *L, struct hlua_txn *txn, unsigned int
 	return 1;
 }
 
-/* This function is an LUA binding. It is called with each converter.
+/* This function is a LUA binding. It is called with each converter.
  * It uses closure argument to store the associated converter. It
  * returns only one argument or throws an error. An error is thrown
  * only if an error is encountered during the argument parsing. If
@@ -4443,7 +4759,7 @@ static int hlua_http_res_set_hdr(lua_State *L)
 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->rsp);
 }
 
-/* This function set the method. */
+/* This function sets the method. */
 static int hlua_http_req_set_meth(lua_State *L)
 {
 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
@@ -4460,7 +4776,19 @@ static int hlua_http_req_set_meth(lua_State *L)
 	return 1;
 }
 
-/* This function set the method. */
+/* This function gets the method. */
+static int hlua_http_req_get_meth(lua_State *L)
+{
+	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
+	struct stream *s = htxn->s;
+	struct http_txn *txn = s->txn;
+	const char *path = s->req.buf->p;
+
+	lua_pushlstring(L, path, txn->req.sl.rq.m_l);
+	return 1;
+}
+
+/* This function sets the path. */
 static int hlua_http_req_set_path(lua_State *L)
 {
 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
@@ -4477,7 +4805,26 @@ static int hlua_http_req_set_path(lua_State *L)
 	return 1;
 }
 
-/* This function set the query-string. */
+/* This function gets the path. */
+static int hlua_http_req_get_path(lua_State *L)
+{
+	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
+	struct http_txn *txn = htxn->s->txn;
+	const char *path;
+	const char *end;
+	const char *p;
+
+	path = http_get_path(txn);
+	end = txn->req.chn->buf->p + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
+	p = path;
+	while (p < end && *p != '?')
+		p++;
+
+	lua_pushlstring(L, path, p - path);
+	return 1;
+}
+
+/* This function sets the query-string. */
 static int hlua_http_req_set_query(lua_State *L)
 {
 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
@@ -4506,7 +4853,27 @@ static int hlua_http_req_set_query(lua_State *L)
 	return 1;
 }
 
-/* This function set the uri. */
+/* This function gets the query-string. */
+static int hlua_http_req_get_query(lua_State *L)
+{
+	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
+	struct http_txn *txn = htxn->s->txn;
+	const char *path;
+	const char *end;
+	const char *p;
+
+	path = http_get_path(txn);
+	end = txn->req.chn->buf->p + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
+	p = path;
+	while (p < end && *p != '?')
+		p++;
+	if (*p == '?')
+		p++;
+	lua_pushlstring(L, p, end - p);
+	return 1;
+}
+
+/* This function sets the uri. */
 static int hlua_http_req_set_uri(lua_State *L)
 {
 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
@@ -4523,7 +4890,19 @@ static int hlua_http_req_set_uri(lua_State *L)
 	return 1;
 }
 
-/* This function set the response code. */
+/* This function sets the uri. */
+static int hlua_http_req_get_uri(lua_State *L)
+{
+	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
+	struct stream *s = htxn->s;
+	struct http_txn *txn = s->txn;
+	const char *path = s->req.buf->p + txn->req.sl.rq.u;
+
+	lua_pushlstring(L, path, txn->req.sl.rq.u_l);
+	return 1;
+}
+
+/* This function sets the response code. */
 static int hlua_http_res_set_status(lua_State *L)
 {
 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
@@ -4849,7 +5228,7 @@ __LJMP static int hlua_txn_set_mark(lua_State *L)
 	return 0;
 }
 
-/* This function is an Lua binding that send pending data
+/* This function is a LUA binding that send pending data
  * to the client, and close the stream interface.
  */
 __LJMP static int hlua_txn_done(lua_State *L)
@@ -5003,7 +5382,7 @@ __LJMP static int hlua_msleep(lua_State *L)
 	return 0;
 }
 
-/* This functionis an LUA binding. it permits to give back
+/* This functionis a LUA binding. it permits to give back
  * the hand at the HAProxy scheduler. It is used when the
  * LUA processing consumes a lot of time.
  */
@@ -5104,7 +5483,7 @@ static struct task *hlua_process_task(struct task *task)
 	return NULL;
 }
 
-/* This function is an LUA binding that register LUA function to be
+/* This function is a LUA binding that register LUA function to be
  * executed after the HAProxy configuration parsing and before the
  * HAProxy scheduler starts. This function expect only one LUA
  * argument that is a function. This function returns nothing, but
@@ -5128,7 +5507,7 @@ __LJMP static int hlua_register_init(lua_State *L)
 	return 0;
 }
 
-/* This functio is an LUA binding. It permits to register a task
+/* This functio is a LUA binding. It permits to register a task
  * executed in parallel of the main HAroxy activity. The task is
  * created and it is set in the HAProxy scheduler. It can be called
  * from the "init" section, "post init" or during the runtime.
@@ -5168,7 +5547,7 @@ static int hlua_register_task(lua_State *L)
 	return 0;
 }
 
-/* Wrapper called by HAProxy to execute an LUA converter. This wrapper
+/* Wrapper called by HAProxy to execute a LUA converter. This wrapper
  * doesn't allow "yield" functions because the HAProxy engine cannot
  * resume converters.
  */
@@ -5394,9 +5773,9 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp
 	}
 }
 
-/* This function is an LUA binding used for registering
+/* This function is a LUA binding used for registering
  * "sample-conv" functions. It expects a converter name used
- * in the haproxy configuration file, and an LUA function.
+ * in the haproxy configuration file, and a LUA function.
  */
 __LJMP static int hlua_register_converters(lua_State *L)
 {
@@ -5451,9 +5830,9 @@ __LJMP static int hlua_register_converters(lua_State *L)
 	return 0;
 }
 
-/* This fucntion is an LUA binding used for registering
+/* This fucntion is a LUA binding used for registering
  * "sample-fetch" functions. It expects a converter name used
- * in the haproxy configuration file, and an LUA function.
+ * in the haproxy configuration file, and a LUA function.
  */
 __LJMP static int hlua_register_fetches(lua_State *L)
 {
@@ -6107,9 +6486,9 @@ static void hlua_applet_http_release(struct appctx *ctx)
 }
 
 /* global {tcp|http}-request parser. Return ACT_RET_PRS_OK in
- * succes case, else return ACT_RET_PRS_ERR.
+ * success case, else return ACT_RET_PRS_ERR.
  *
- * This function can fail with an abort() due to an Lua critical error.
+ * This function can fail with an abort() due to a LUA critical error.
  * We are in the configuration parsing process of HAProxy, this abort() is
  * tolerated.
  */
@@ -6176,9 +6555,9 @@ static enum act_parse_ret action_register_service_http(const char **args, int *c
 	return ACT_RET_PRS_OK;
 }
 
-/* This function is an LUA binding used for registering
+/* This function is a LUA binding used for registering
  * "sample-conv" functions. It expects a converter name used
- * in the haproxy configuration file, and an LUA function.
+ * in the haproxy configuration file, and a LUA function.
  */
 __LJMP static int hlua_register_action(lua_State *L)
 {
@@ -6285,9 +6664,9 @@ static enum act_parse_ret action_register_service_tcp(const char **args, int *cu
 	return 0;
 }
 
-/* This function is an LUA binding used for registering
+/* This function is a LUA binding used for registering
  * "sample-conv" functions. It expects a converter name used
- * in the haproxy configuration file, and an LUA function.
+ * in the haproxy configuration file, and a LUA function.
  */
 __LJMP static int hlua_register_service(lua_State *L)
 {
@@ -6429,7 +6808,7 @@ static int hlua_parse_maxmem(char **args, int section_type, struct proxy *curpx,
 
 
 /* This function is called by the main configuration key "lua-load". It loads and
- * execute an lua file during the parsing of the HAProxy configuration file. It is
+ * execute a LUA file during the parsing of the HAProxy configuration file. It is
  * the main lua entry point.
  *
  * This funtion runs with the HAProxy keywords API. It returns -1 if an error is
@@ -6438,7 +6817,7 @@ static int hlua_parse_maxmem(char **args, int section_type, struct proxy *curpx,
  * In some error case, LUA set an error message in top of the stack. This function
  * returns this error message in the HAProxy logs and pop it from the stack.
  *
- * This function can fail with an abort() due to an Lua critical error.
+ * This function can fail with an abort() due to a LUA critical error.
  * We are in the configuration parsing process of HAProxy, this abort() is
  * tolerated.
  */
@@ -6496,7 +6875,7 @@ static struct cfg_kw_list cfg_kws = {{ },{
 	{ 0, NULL, NULL },
 }};
 
-/* This function can fail with an abort() due to an Lua critical error.
+/* This function can fail with an abort() due to a LUA critical error.
  * We are in the initialisation process of HAProxy, this abort() is
  * tolerated.
  */
@@ -6580,7 +6959,7 @@ static void *hlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
 	return ptr;
 }
 
-/* Ithis function can fail with an abort() due to an Lua critical error.
+/* Ithis function can fail with an abort() due to a LUA critical error.
  * We are in the initialisation process of HAProxy, this abort() is
  * tolerated.
  */
@@ -6668,6 +7047,10 @@ void hlua_init(void)
 	hlua_class_function(gL.T, "del_acl", hlua_del_acl);
 	hlua_class_function(gL.T, "set_map", hlua_set_map);
 	hlua_class_function(gL.T, "del_map", hlua_del_map);
+	hlua_class_function(gL.T, "clear_map", hlua_clear_map);
+	hlua_class_function(gL.T, "store_map", hlua_store_map);
+	hlua_class_function(gL.T, "list_map", hlua_list_map);
+	hlua_class_function(gL.T, "list_maps", hlua_list_maps);
 	hlua_class_function(gL.T, "tcp", hlua_socket_new);
 	hlua_class_function(gL.T, "log", hlua_log);
 	hlua_class_function(gL.T, "Debug", hlua_log_debug);
@@ -6692,19 +7075,30 @@ void hlua_init(void)
 	for (i=0; i<PAT_MATCH_NUM; i++)
 		hlua_class_const_int(gL.T, pat_match_names[i], i);
 
+	hlua_class_const_int(gL.T, "FLAG_MAP", PAT_REF_MAP);
+	hlua_class_const_int(gL.T, "FLAG_ACL", PAT_REF_ACL);
+	hlua_class_const_int(gL.T, "FLAG_SMP", PAT_REF_SMP);
+
 	/* register constructor. */
 	hlua_class_function(gL.T, "new", hlua_map_new);
 
 	/* Create and fill the metatable. */
 	lua_newtable(gL.T);
 
-	/* Create and fille the __index entry. */
+	/* Create and fill the __index entry. */
 	lua_pushstring(gL.T, "__index");
 	lua_newtable(gL.T);
 
 	/* Register . */
 	hlua_class_function(gL.T, "lookup", hlua_map_lookup);
 	hlua_class_function(gL.T, "slookup", hlua_map_slookup);
+	hlua_class_function(gL.T, "set", hlua_map_set);
+	hlua_class_function(gL.T, "del", hlua_map_del);
+	hlua_class_function(gL.T, "clear", hlua_map_clear);
+	hlua_class_function(gL.T, "store", hlua_map_store);
+	hlua_class_function(gL.T, "get_id", hlua_map_get_id);
+	hlua_class_function(gL.T, "get_reference", hlua_map_get_reference);
+	hlua_class_function(gL.T, "list", hlua_map_list);
 
 	lua_rawset(gL.T, -3);
 
@@ -6864,9 +7258,13 @@ void hlua_init(void)
 	hlua_class_function(gL.T, "req_add_header", hlua_http_req_add_hdr);
 	hlua_class_function(gL.T, "req_set_header", hlua_http_req_set_hdr);
 	hlua_class_function(gL.T, "req_set_method", hlua_http_req_set_meth);
+	hlua_class_function(gL.T, "req_get_method", hlua_http_req_get_meth);
 	hlua_class_function(gL.T, "req_set_path",   hlua_http_req_set_path);
+	hlua_class_function(gL.T, "req_get_path",   hlua_http_req_get_path);
 	hlua_class_function(gL.T, "req_set_query",  hlua_http_req_set_query);
+	hlua_class_function(gL.T, "req_get_query",  hlua_http_req_get_query);
 	hlua_class_function(gL.T, "req_set_uri",    hlua_http_req_set_uri);
+	hlua_class_function(gL.T, "req_get_uri",    hlua_http_req_get_uri);
 
 	hlua_class_function(gL.T, "res_get_headers",hlua_http_res_get_headers);
 	hlua_class_function(gL.T, "res_del_header", hlua_http_res_del_hdr);
diff --git a/src/map.c b/src/map.c
index ac1c00a..a8c1c4b 100644
--- a/src/map.c
+++ b/src/map.c
@@ -135,8 +135,10 @@ int sample_load_map(struct arg *arg, struct sample_conv *conv,
 	                            1, err, file, line))
 		return 0;
 
-	/* the maps of type IP have a string as defaultvalue. This
-	 * string canbe anipv4 or an ipv6, we must convert it.
+	desc->ref = pat_ref_lookup(arg[0].data.str.str);
+
+	/* the maps of type IP have a string as default value. This
+	 * string can be an ipv4 or an ipv6, we must convert it.
 	 */
 	if (desc->conv->out_type == SMP_T_ADDR) {
 		struct sample_data data;
diff --git a/src/pattern.c b/src/pattern.c
index 60fe462..a9d3f17 100644
--- a/src/pattern.c
+++ b/src/pattern.c
@@ -2201,6 +2201,38 @@ int pat_ref_read_from_file_smp(struct pat_ref *ref, const char *filename, char *
 	return ret;
 }
 
+/* Writes patterns to a file. If <err_msg> is non-NULL, an error message will
+ * be returned there on errors and the caller will have to free it.
+ *
+ * Return non-zero in case of succes, otherwise 0.
+ */
+int pat_ref_write_to_file_smp(struct pat_ref *ref, const char *filename, char **err)
+{
+	struct pat_ref_elt *elt;
+	FILE *file;
+	int ret = 0;
+
+	file = fopen(filename, "w");
+	if (!file) {
+		memprintf(err, "failed to open pattern file <%s>", filename);
+		return 0;
+	}
+
+	list_for_each_entry(elt, &ref->head, list) {
+		if (fprintf(file, "%s\t%s\n", elt->pattern, elt->sample) <= 0) {
+			memprintf(err, "failed to write to pattern file <%s>", filename);
+			goto out_close;
+		}
+	}
+
+	/* succes */
+	ret = 1;
+
+ out_close:
+	fclose(file);
+	return ret;
+}
+
 /* Reads patterns from a file. If <err_msg> is non-NULL, an error message will
  * be returned there on errors and the caller will have to free it.
  */

Reply via email to