#define HLUA_FLT_CB_ARG_CHN 0x00000004
#define HLUA_FLT_CB_ARG_HTTP_MSG 0x00000008
-#define HLUA_FLT_CTX_FL_PAYLOAD 0x00000001
+#define HLUA_FLT_CTX_FL_REQ_PAYLOAD 0x00000001
+#define HLUA_FLT_CTX_FL_RES_PAYLOAD 0x00000002
+#define HLUA_FLT_CTX_FL_PAYLOAD_BIT(idx) ((idx) ? HLUA_FLT_CTX_FL_RES_PAYLOAD : HLUA_FLT_CTX_FL_REQ_PAYLOAD)
const char *hlua_filter_cls_name = "lua";
DECLARE_STATIC_TYPED_POOL(pool_head_hlua_flt_ctx, "hlua_flt_ctx", struct hlua_flt_ctx);
-static int hlua_filter_from_payload(struct filter *filter);
+static int hlua_filter_from_payload(struct filter *filter, struct channel *chn);
/* This is the chained list of struct hlua_flt referenced
* for haproxy filters. It is used for a post-initialisation control.
filter = lua_touserdata (L, -1);
flt_ctx = filter->ctx;
- if (hlua_filter_from_payload(filter)) {
+ if (hlua_filter_from_payload(filter, chn)) {
*offset = flt_ctx->cur_off[CHN_IDX(chn)];
*len = flt_ctx->cur_len[CHN_IDX(chn)];
}
input = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &output, &input);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
offset = output;
input = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &output, &input);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
offset = output;
len = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &offset, &len);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
if (!ci_data(chn) && channel_input_closed(chn)) {
len = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &offset, &len);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
if (!ci_data(chn) && channel_input_closed(chn)) {
len = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &offset, &len);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
if (!ci_data(chn) && channel_input_closed(chn)) {
len = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &offset, &len);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
ret = _hlua_channel_insert(chn, L, ist2(str, sz), offset);
len = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &offset, &len);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
ret = _hlua_channel_insert(chn, L, ist2(str, sz), offset);
input = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &output, &input);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
offset = output;
input = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &output, &input);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
offset = output;
input = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &output, &input);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
offset = output;
len = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &offset, &len);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
len = ci_data(chn);
filter = hlua_channel_filter(L, 1, chn, &offset, &len);
- if (filter && !hlua_filter_from_payload(filter))
+ if (filter && !hlua_filter_from_payload(filter, chn))
WILL_LJMP(lua_error(L));
max = fwd - l;
WILL_LJMP(lua_error(L));
filter = hlua_http_msg_filter(L, 1, msg, &output, &input);
- if (!filter || !hlua_filter_from_payload(filter))
+ if (!filter || !hlua_filter_from_payload(filter, msg->chn))
WILL_LJMP(lua_error(L));
if (!ci_data(msg->chn) && channel_input_closed(msg->chn)) {
str = MAY_LJMP(luaL_checklstring(L, 2, &sz));
filter = hlua_http_msg_filter(L, 1, msg, &offset, &len);
- if (!filter || !hlua_filter_from_payload(filter))
+ if (!filter || !hlua_filter_from_payload(filter, msg->chn))
WILL_LJMP(lua_error(L));
ret = _hlua_http_msg_insert(msg, filter, ist2(str, sz), offset+len);
str = MAY_LJMP(luaL_checklstring(L, 2, &sz));
filter = hlua_http_msg_filter(L, 1, msg, &offset, &len);
- if (!filter || !hlua_filter_from_payload(filter))
+ if (!filter || !hlua_filter_from_payload(filter, msg->chn))
WILL_LJMP(lua_error(L));
ret = _hlua_http_msg_insert(msg, filter, ist2(str, sz), offset);
str = MAY_LJMP(luaL_checklstring(L, 2, &sz));
filter = hlua_http_msg_filter(L, 1, msg, &output, &input);
- if (!filter || !hlua_filter_from_payload(filter))
+ if (!filter || !hlua_filter_from_payload(filter, msg->chn))
WILL_LJMP(lua_error(L));
offset = output;
WILL_LJMP(lua_error(L));
filter = hlua_http_msg_filter(L, 1, msg, &output, &input);
- if (!filter || !hlua_filter_from_payload(filter))
+ if (!filter || !hlua_filter_from_payload(filter, msg->chn))
WILL_LJMP(lua_error(L));
offset = output;
str = MAY_LJMP(luaL_checklstring(L, 2, &sz));
filter = hlua_http_msg_filter(L, 1, msg, &output, &input);
- if (!filter || !hlua_filter_from_payload(filter))
+ if (!filter || !hlua_filter_from_payload(filter, msg->chn))
WILL_LJMP(lua_error(L));
offset = output;
str = MAY_LJMP(luaL_checklstring(L, 2, &sz));
filter = hlua_http_msg_filter(L, 1, msg, &offset, &len);
- if (!filter || !hlua_filter_from_payload(filter))
+ if (!filter || !hlua_filter_from_payload(filter, msg->chn))
WILL_LJMP(lua_error(L));
/* Return an error if the channel's output is closed */
fwd = MAY_LJMP(luaL_checkinteger(L, 2));
filter = hlua_http_msg_filter(L, 1, msg, &offset, &len);
- if (!filter || !hlua_filter_from_payload(filter))
+ if (!filter || !hlua_filter_from_payload(filter, msg->chn))
WILL_LJMP(lua_error(L));
/* Nothing to do, just return */
filter->ctx = NULL;
}
-static int hlua_filter_from_payload(struct filter *filter)
+/* Returns true if the filter is currently processing the payload of the
+ * channel <chn>, from its http_payload or tcp_payload callback. This is the
+ * only context where the data of a channel may be manipulated from lua. The
+ * payload-processing phase is tracked per channel: when a filter processes
+ * the payload of the request, it must not be allowed to manipulate the data
+ * of the response while it is analyzed, and reciprocally.
+ */
+static int hlua_filter_from_payload(struct filter *filter, struct channel *chn)
{
struct hlua_flt_ctx *flt_ctx = filter->ctx;
- return (flt_ctx && !!(flt_ctx->flags & HLUA_FLT_CTX_FL_PAYLOAD));
+ return (flt_ctx && !!(flt_ctx->flags & HLUA_FLT_CTX_FL_PAYLOAD_BIT(CHN_IDX(chn))));
}
static int hlua_filter_callback(struct stream *s, struct filter *filter, const char *fun,
{
struct hlua_flt_ctx *flt_ctx = filter->ctx;
- flt_ctx->flags = 0;
+ flt_ctx->flags &= ~HLUA_FLT_CTX_FL_PAYLOAD_BIT(CHN_IDX(chn));
return hlua_filter_callback(s, filter, "start_analyze",
(!(chn->flags & CF_ISRESP) ? SMP_OPT_DIR_REQ : SMP_OPT_DIR_RES),
(HLUA_FLT_CB_FINAL | HLUA_FLT_CB_RETVAL | HLUA_FLT_CB_ARG_CHN));
{
struct hlua_flt_ctx *flt_ctx = filter->ctx;
- flt_ctx->flags &= ~HLUA_FLT_CTX_FL_PAYLOAD;
+ flt_ctx->flags &= ~HLUA_FLT_CTX_FL_PAYLOAD_BIT(CHN_IDX(chn));
return hlua_filter_callback(s, filter, "end_analyze",
(!(chn->flags & CF_ISRESP) ? SMP_OPT_DIR_REQ : SMP_OPT_DIR_RES),
(HLUA_FLT_CB_FINAL | HLUA_FLT_CB_RETVAL | HLUA_FLT_CB_ARG_CHN));
{
struct hlua_flt_ctx *flt_ctx = filter->ctx;
- flt_ctx->flags &= ~HLUA_FLT_CTX_FL_PAYLOAD;
+ flt_ctx->flags &= ~HLUA_FLT_CTX_FL_PAYLOAD_BIT(CHN_IDX(msg->chn));
return hlua_filter_callback(s, filter, "http_headers",
(!(msg->chn->flags & CF_ISRESP) ? SMP_OPT_DIR_REQ : SMP_OPT_DIR_RES),
(HLUA_FLT_CB_FINAL | HLUA_FLT_CB_RETVAL | HLUA_FLT_CB_ARG_HTTP_MSG));
flt_hlua = flt_ctx->hlua[idx];
flt_ctx->cur_off[idx] = offset;
flt_ctx->cur_len[idx] = len;
- flt_ctx->flags |= HLUA_FLT_CTX_FL_PAYLOAD;
+ flt_ctx->flags |= HLUA_FLT_CTX_FL_PAYLOAD_BIT(idx);
ret = hlua_filter_callback(s, filter, "http_payload", dir, (HLUA_FLT_CB_FINAL | HLUA_FLT_CB_ARG_HTTP_MSG));
if (ret != -1) {
ret = flt_ctx->cur_len[idx];
{
struct hlua_flt_ctx *flt_ctx = filter->ctx;
- flt_ctx->flags &= ~HLUA_FLT_CTX_FL_PAYLOAD;
+ flt_ctx->flags &= ~HLUA_FLT_CTX_FL_PAYLOAD_BIT(CHN_IDX(msg->chn));
return hlua_filter_callback(s, filter, "http_end",
(!(msg->chn->flags & CF_ISRESP) ? SMP_OPT_DIR_REQ : SMP_OPT_DIR_RES),
(HLUA_FLT_CB_FINAL | HLUA_FLT_CB_RETVAL | HLUA_FLT_CB_ARG_HTTP_MSG));
flt_hlua = flt_ctx->hlua[idx];
flt_ctx->cur_off[idx] = offset;
flt_ctx->cur_len[idx] = len;
- flt_ctx->flags |= HLUA_FLT_CTX_FL_PAYLOAD;
+ flt_ctx->flags |= HLUA_FLT_CTX_FL_PAYLOAD_BIT(idx);
ret = hlua_filter_callback(s, filter, "tcp_payload", dir, (HLUA_FLT_CB_FINAL | HLUA_FLT_CB_ARG_CHN));
if (ret != -1) {
ret = flt_ctx->cur_len[idx];