BUG/MEDIUM: lua: the function txn_done() from sample fetches can crash

The function txn_done() ends a transaction. It does not make
sense to call this function from a lua sample-fetch wrapper,
because the role of a sample-fetch is not to terminate a
transaction.

This patch modify the role of the fucntion txn_done() if it
is called from a sample-fetch wrapper, now it just ends the
execution of the Lua code like the done() function.

Must be backported in 1.6
diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst
index 2bca4d0..dccf415 100644
--- a/doc/lua-api/index.rst
+++ b/doc/lua-api/index.rst
@@ -1460,6 +1460,11 @@
   session. It can be used when a critical error is detected or to terminate
   processing after some data have been returned to the client (eg: a redirect).
 
+  *Warning*: It not make sense to call this function from sample-fetches. In
+  this case the behaviour of this one is the same than core.done(): it quit
+  the Lua execution. The transaction is really aborted only from an action
+  registered function.
+
   :param class_txn txn: The class txn object containing the data.
 
 .. js:function:: TXN.set_loglevel(txn, loglevel)
diff --git a/include/types/hlua.h b/include/types/hlua.h
index 43e9f1a..b22e03e 100644
--- a/include/types/hlua.h
+++ b/include/types/hlua.h
@@ -35,6 +35,8 @@
 #define HLUA_F_AS_STRING    0x01
 #define HLUA_F_MAY_USE_HTTP 0x02
 
+#define HLUA_TXN_NOTERM 0x00000001
+
 #define HLUA_CONCAT_BLOCSZ 2048
 
 enum hlua_exec {
@@ -109,6 +111,7 @@
 	struct stream *s;
 	struct proxy *p;
 	int dir;                /* SMP_OPT_DIR_{REQ,RES} */
+	int flags;
 };
 
 /* This struct contains the applet context. */
diff --git a/src/hlua.c b/src/hlua.c
index 953c219..f9a317d 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -4601,7 +4601,7 @@
  * return 0 if the stack does not contains free slots,
  * otherwise it returns 1.
  */
-static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, int dir)
+static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, int dir, int flags)
 {
 	struct hlua_txn *htxn;
 
@@ -4621,6 +4621,7 @@
 	htxn->s = s;
 	htxn->p = p;
 	htxn->dir = dir;
+	htxn->flags = flags;
 
 	/* Create the "f" field that contains a list of fetches. */
 	lua_pushstring(L, "f");
@@ -4814,6 +4815,15 @@
 	MAY_LJMP(check_args(L, 1, "close"));
 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
 
+	/* If the flags NOTERM is set, we cannot terminate the http
+	 * session, so we just end the execution of the current
+	 * lua code.
+	 */
+	if (htxn->flags & HLUA_TXN_NOTERM) {
+		WILL_LJMP(hlua_done(L));
+		return 0;
+	}
+
 	ic = &htxn->s->req;
 	oc = &htxn->s->res;
 
@@ -5265,7 +5275,8 @@
 		lua_rawgeti(stream->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
 
 		/* push arguments in the stack. */
-		if (!hlua_txn_new(stream->hlua.T, stream, smp->px, smp->opt & SMP_OPT_DIR)) {
+		if (!hlua_txn_new(stream->hlua.T, stream, smp->px, smp->opt & SMP_OPT_DIR,
+		                  HLUA_TXN_NOTERM)) {
 			SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
 			RESET_SAFE_LJMP(stream->hlua.T);
 			return 0;
@@ -5511,7 +5522,7 @@
 		lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn.function_ref);
 
 		/* Create and and push object stream in the stack. */
-		if (!hlua_txn_new(s->hlua.T, s, px, dir)) {
+		if (!hlua_txn_new(s->hlua.T, s, px, dir, 0)) {
 			SEND_ERR(px, "Lua function '%s': full stack.\n",
 			         rule->arg.hlua_rule->fcn.name);
 			RESET_SAFE_LJMP(s->hlua.T);