mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
MINOR: stream: Save the last filter evaluated interrupting the processing
It is very similar to the last evaluated rule. When a filter returns an error that interrupts the processing, it is saved in the stream, in the last_entity field, with the type 2. The pointer on filter config is saved. This pointer never changes during runtime and is part of the proxy's structure. It is an element of the filter_configs list in the proxy structure. "last_entity" sample fetch was update accordingly. The filter identifier is returned, if defined. Otherwise the save pointer.
This commit is contained in:
parent
c9fa78e747
commit
53de6da1c0
@ -292,7 +292,7 @@ struct stream {
|
||||
|
||||
struct {
|
||||
void *ptr; /* Pointer on the entity (def: NULL) */
|
||||
int type; /* entity type (0: undef, 1: rule) */
|
||||
int type; /* entity type (0: undef, 1: rule, 2: filter) */
|
||||
} last_entity; /* last evaluated entity that interrupted processing */
|
||||
|
||||
unsigned int stream_epoch; /* copy of stream_epoch when the stream was created */
|
||||
|
@ -72,7 +72,11 @@ static int handle_analyzer_result(struct stream *s, struct channel *chn, unsigne
|
||||
|
||||
#define BREAK_EXECUTION(strm, chn, label) \
|
||||
do { \
|
||||
strm_flt(strm)->current[CHN_IDX(chn)] = filter; \
|
||||
if (ret < 0) { \
|
||||
(strm)->last_entity.type = 2; \
|
||||
(strm)->last_entity.ptr = filter; \
|
||||
} \
|
||||
strm_flt(strm)->current[CHN_IDX(chn)] = filter; \
|
||||
goto label; \
|
||||
} while (0)
|
||||
|
||||
@ -556,8 +560,11 @@ flt_set_stream_backend(struct stream *s, struct proxy *be)
|
||||
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
|
||||
if (FLT_OPS(filter)->stream_set_backend) {
|
||||
filter->calls++;
|
||||
if (FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0)
|
||||
if (FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0) {
|
||||
s->last_entity.type = 2;
|
||||
s->last_entity.ptr = filter;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (be->be_req_ana & AN_REQ_FLT_START_BE) {
|
||||
@ -693,8 +700,11 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)
|
||||
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
|
||||
filter->calls++;
|
||||
ret = FLT_OPS(filter)->http_payload(s, filter, msg, out + offset, data - offset);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
s->last_entity.type = 2;
|
||||
s->last_entity.ptr = filter;
|
||||
goto end;
|
||||
}
|
||||
data = ret + *flt_off - *strm_off;
|
||||
*flt_off += ret;
|
||||
}
|
||||
@ -832,8 +842,11 @@ flt_post_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
|
||||
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
|
||||
filter->calls++;
|
||||
ret = FLT_OPS(filter)->channel_post_analyze(s, filter, chn, an_bit);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
s->last_entity.type = 2;
|
||||
s->last_entity.ptr = filter;
|
||||
break;
|
||||
}
|
||||
filter->post_analyzers &= ~an_bit;
|
||||
}
|
||||
}
|
||||
@ -986,8 +999,11 @@ flt_tcp_payload(struct stream *s, struct channel *chn, unsigned int len)
|
||||
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
|
||||
filter->calls++;
|
||||
ret = FLT_OPS(filter)->tcp_payload(s, filter, chn, out + offset, data - offset);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
s->last_entity.type = 2;
|
||||
s->last_entity.ptr = filter;
|
||||
goto end;
|
||||
}
|
||||
data = ret + *flt_off - *strm_off;
|
||||
*flt_off += ret;
|
||||
}
|
||||
|
15
src/stream.c
15
src/stream.c
@ -4137,6 +4137,21 @@ static int smp_fetch_last_entity(const struct arg *args, struct sample *smp, con
|
||||
trash->data = snprintf(trash->area, trash->size, "%s:%d", rule->conf.file, rule->conf.line);
|
||||
smp->data.u.str = *trash;
|
||||
}
|
||||
else if (smp->strm->last_entity.type == 2) {
|
||||
struct filter *filter = smp->strm->last_entity.ptr;
|
||||
|
||||
if (FLT_ID(filter)) {
|
||||
smp->flags |= SMP_F_CONST;
|
||||
smp->data.u.str.area = (char *)FLT_ID(filter);
|
||||
smp->data.u.str.data = strlen(FLT_ID(filter));
|
||||
}
|
||||
else {
|
||||
struct buffer *trash = get_trash_chunk();
|
||||
|
||||
trash->data = snprintf(trash->area, trash->size, "%p", filter->config);
|
||||
smp->data.u.str = *trash;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user