Skip to content

Commit c9fa78e

Browse files
committed
MINOR: stream: Replace last_rule_file/line fields by a more generic field
The last evaluated rule is now saved in a generic structure, named last_entity, with a type to identify it. The idea is to be able to store other kind of entity that may interrupt a specific processing. The type of the last evaluated rule is set to 1. It will be replace later by an enum to be more explicit. In addition, the pointer to the rule itself is saved instead of its location. The sample fetch "last_entity" was added to retrieve the information about it. In this case, it is the rule localtion, the config file containing the rule followed by the line where the rule is defined, separated by a colon. This sample fetch is not documented yet.
1 parent dcf3341 commit c9fa78e

File tree

4 files changed

+115
-85
lines changed

4 files changed

+115
-85
lines changed

include/haproxy/stream-t.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,11 @@ struct stream {
289289
void *current_rule; /* this is used to store the current rule to be resumed. */
290290
int rules_exp; /* expiration date for current rules execution */
291291
int tunnel_timeout;
292-
const char *last_rule_file; /* last evaluated final rule's file (def: NULL) */
293-
int last_rule_line; /* last evaluated final rule's line (def: 0) */
292+
293+
struct {
294+
void *ptr; /* Pointer on the entity (def: NULL) */
295+
int type; /* entity type (0: undef, 1: rule) */
296+
} last_entity; /* last evaluated entity that interrupted processing */
294297

295298
unsigned int stream_epoch; /* copy of stream_epoch when the stream was created */
296299
struct hlua *hlua[2]; /* lua runtime context (0: global, 1: per-thread) */

src/http_ana.c

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2739,48 +2739,48 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
27392739
break;
27402740
case ACT_RET_STOP:
27412741
rule_ret = HTTP_RULE_RES_STOP;
2742-
s->last_rule_file = rule->conf.file;
2743-
s->last_rule_line = rule->conf.line;
2742+
s->last_entity.type = 1;
2743+
s->last_entity.ptr = rule;
27442744
goto end;
27452745
case ACT_RET_YIELD:
27462746
s->current_rule = rule;
27472747
if (act_opts & ACT_OPT_FINAL) {
27482748
send_log(s->be, LOG_WARNING,
27492749
"Internal error: action yields while it is no long allowed "
27502750
"for the http-request actions.");
2751-
s->last_rule_file = rule->conf.file;
2752-
s->last_rule_line = rule->conf.line;
2751+
s->last_entity.type = 1;
2752+
s->last_entity.ptr = rule;
27532753
rule_ret = HTTP_RULE_RES_ERROR;
27542754
goto end;
27552755
}
27562756
rule_ret = HTTP_RULE_RES_YIELD;
27572757
goto end;
27582758
case ACT_RET_ERR:
27592759
rule_ret = HTTP_RULE_RES_ERROR;
2760-
s->last_rule_file = rule->conf.file;
2761-
s->last_rule_line = rule->conf.line;
2760+
s->last_entity.type = 1;
2761+
s->last_entity.ptr = rule;
27622762
goto end;
27632763
case ACT_RET_DONE:
27642764
rule_ret = HTTP_RULE_RES_DONE;
2765-
s->last_rule_file = rule->conf.file;
2766-
s->last_rule_line = rule->conf.line;
2765+
s->last_entity.type = 1;
2766+
s->last_entity.ptr = rule;
27672767
goto end;
27682768
case ACT_RET_DENY:
27692769
if (txn->status == -1)
27702770
txn->status = 403;
27712771
rule_ret = HTTP_RULE_RES_DENY;
2772-
s->last_rule_file = rule->conf.file;
2773-
s->last_rule_line = rule->conf.line;
2772+
s->last_entity.type = 1;
2773+
s->last_entity.ptr = rule;
27742774
goto end;
27752775
case ACT_RET_ABRT:
27762776
rule_ret = HTTP_RULE_RES_ABRT;
2777-
s->last_rule_file = rule->conf.file;
2778-
s->last_rule_line = rule->conf.line;
2777+
s->last_entity.type = 1;
2778+
s->last_entity.ptr = rule;
27792779
goto end;
27802780
case ACT_RET_INV:
27812781
rule_ret = HTTP_RULE_RES_BADREQ;
2782-
s->last_rule_file = rule->conf.file;
2783-
s->last_rule_line = rule->conf.line;
2782+
s->last_entity.type = 1;
2783+
s->last_entity.ptr = rule;
27842784
goto end;
27852785
}
27862786
continue; /* eval the next rule */
@@ -2790,25 +2790,25 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
27902790
switch (rule->action) {
27912791
case ACT_ACTION_ALLOW:
27922792
rule_ret = HTTP_RULE_RES_STOP;
2793-
s->last_rule_file = rule->conf.file;
2794-
s->last_rule_line = rule->conf.line;
2793+
s->last_entity.type = 1;
2794+
s->last_entity.ptr = rule;
27952795
goto end;
27962796

27972797
case ACT_ACTION_DENY:
27982798
txn->status = rule->arg.http_reply->status;
27992799
txn->http_reply = rule->arg.http_reply;
28002800
rule_ret = HTTP_RULE_RES_DENY;
2801-
s->last_rule_file = rule->conf.file;
2802-
s->last_rule_line = rule->conf.line;
2801+
s->last_entity.type = 1;
2802+
s->last_entity.ptr = rule;
28032803
goto end;
28042804

28052805
case ACT_HTTP_REQ_TARPIT:
28062806
txn->flags |= TX_CLTARPIT;
28072807
txn->status = rule->arg.http_reply->status;
28082808
txn->http_reply = rule->arg.http_reply;
28092809
rule_ret = HTTP_RULE_RES_DENY;
2810-
s->last_rule_file = rule->conf.file;
2811-
s->last_rule_line = rule->conf.line;
2810+
s->last_entity.type = 1;
2811+
s->last_entity.ptr = rule;
28122812
goto end;
28132813

28142814
case ACT_HTTP_REDIR: {
@@ -2818,8 +2818,8 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
28182818
break;
28192819

28202820
rule_ret = ret ? HTTP_RULE_RES_ABRT : HTTP_RULE_RES_ERROR;
2821-
s->last_rule_file = rule->conf.file;
2822-
s->last_rule_line = rule->conf.line;
2821+
s->last_entity.type = 1;
2822+
s->last_entity.ptr = rule;
28232823
goto end;
28242824
}
28252825

@@ -2913,48 +2913,48 @@ static enum rule_result http_res_get_intercept_rule(struct proxy *px, struct lis
29132913
break;
29142914
case ACT_RET_STOP:
29152915
rule_ret = HTTP_RULE_RES_STOP;
2916-
s->last_rule_file = rule->conf.file;
2917-
s->last_rule_line = rule->conf.line;
2916+
s->last_entity.type = 1;
2917+
s->last_entity.ptr = rule;
29182918
goto end;
29192919
case ACT_RET_YIELD:
29202920
s->current_rule = rule;
29212921
if (act_opts & ACT_OPT_FINAL) {
29222922
send_log(s->be, LOG_WARNING,
29232923
"Internal error: action yields while it is no long allowed "
29242924
"for the http-response/http-after-response actions.");
2925-
s->last_rule_file = rule->conf.file;
2926-
s->last_rule_line = rule->conf.line;
2925+
s->last_entity.type = 1;
2926+
s->last_entity.ptr = rule;
29272927
rule_ret = HTTP_RULE_RES_ERROR;
29282928
goto end;
29292929
}
29302930
rule_ret = HTTP_RULE_RES_YIELD;
29312931
goto end;
29322932
case ACT_RET_ERR:
29332933
rule_ret = HTTP_RULE_RES_ERROR;
2934-
s->last_rule_file = rule->conf.file;
2935-
s->last_rule_line = rule->conf.line;
2934+
s->last_entity.type = 1;
2935+
s->last_entity.ptr = rule;
29362936
goto end;
29372937
case ACT_RET_DONE:
29382938
rule_ret = HTTP_RULE_RES_DONE;
2939-
s->last_rule_file = rule->conf.file;
2940-
s->last_rule_line = rule->conf.line;
2939+
s->last_entity.type = 1;
2940+
s->last_entity.ptr = rule;
29412941
goto end;
29422942
case ACT_RET_DENY:
29432943
if (txn->status == -1)
29442944
txn->status = 502;
29452945
rule_ret = HTTP_RULE_RES_DENY;
2946-
s->last_rule_file = rule->conf.file;
2947-
s->last_rule_line = rule->conf.line;
2946+
s->last_entity.type = 1;
2947+
s->last_entity.ptr = rule;
29482948
goto end;
29492949
case ACT_RET_ABRT:
29502950
rule_ret = HTTP_RULE_RES_ABRT;
2951-
s->last_rule_file = rule->conf.file;
2952-
s->last_rule_line = rule->conf.line;
2951+
s->last_entity.type = 1;
2952+
s->last_entity.ptr = rule;
29532953
goto end;
29542954
case ACT_RET_INV:
29552955
rule_ret = HTTP_RULE_RES_BADREQ;
2956-
s->last_rule_file = rule->conf.file;
2957-
s->last_rule_line = rule->conf.line;
2956+
s->last_entity.type = 1;
2957+
s->last_entity.ptr = rule;
29582958
goto end;
29592959
}
29602960
continue; /* eval the next rule */
@@ -2964,16 +2964,16 @@ static enum rule_result http_res_get_intercept_rule(struct proxy *px, struct lis
29642964
switch (rule->action) {
29652965
case ACT_ACTION_ALLOW:
29662966
rule_ret = HTTP_RULE_RES_STOP; /* "allow" rules are OK */
2967-
s->last_rule_file = rule->conf.file;
2968-
s->last_rule_line = rule->conf.line;
2967+
s->last_entity.type = 1;
2968+
s->last_entity.ptr = rule;
29692969
goto end;
29702970

29712971
case ACT_ACTION_DENY:
29722972
txn->status = rule->arg.http_reply->status;
29732973
txn->http_reply = rule->arg.http_reply;
29742974
rule_ret = HTTP_RULE_RES_DENY;
2975-
s->last_rule_file = rule->conf.file;
2976-
s->last_rule_line = rule->conf.line;
2975+
s->last_entity.type = 1;
2976+
s->last_entity.ptr = rule;
29772977
goto end;
29782978

29792979
case ACT_HTTP_REDIR: {
@@ -2983,8 +2983,8 @@ static enum rule_result http_res_get_intercept_rule(struct proxy *px, struct lis
29832983
break;
29842984

29852985
rule_ret = ret ? HTTP_RULE_RES_ABRT : HTTP_RULE_RES_ERROR;
2986-
s->last_rule_file = rule->conf.file;
2987-
s->last_rule_line = rule->conf.line;
2986+
s->last_entity.type = 1;
2987+
s->last_entity.ptr = rule;
29882988
goto end;
29892989
}
29902990
/* other flags exists, but normally, they never be matched. */

src/stream.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,8 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer
389389
s->current_rule_list = NULL;
390390
s->current_rule = NULL;
391391
s->rules_exp = TICK_ETERNITY;
392-
s->last_rule_file = NULL;
393-
s->last_rule_line = 0;
392+
s->last_entity.type = 0;
393+
s->last_entity.ptr = NULL;
394394

395395
s->stkctr = NULL;
396396
if (pool_head_stk_ctr) {
@@ -4095,25 +4095,51 @@ static int smp_fetch_cur_tunnel_timeout(const struct arg *args, struct sample *s
40954095

40964096
static int smp_fetch_last_rule_file(const struct arg *args, struct sample *smp, const char *km, void *private)
40974097
{
4098+
struct act_rule *rule;
4099+
40984100
smp->flags = SMP_F_VOL_TXN;
40994101
smp->data.type = SMP_T_STR;
4100-
if (!smp->strm || !smp->strm->last_rule_file)
4102+
if (!smp->strm || smp->strm->last_entity.type != 1)
41014103
return 0;
41024104

4105+
rule = smp->strm->last_entity.ptr;
41034106
smp->flags |= SMP_F_CONST;
4104-
smp->data.u.str.area = (char *)smp->strm->last_rule_file;
4105-
smp->data.u.str.data = strlen(smp->strm->last_rule_file);
4107+
smp->data.u.str.area = (char *)rule->conf.file;
4108+
smp->data.u.str.data = strlen(rule->conf.file);
41064109
return 1;
41074110
}
41084111

41094112
static int smp_fetch_last_rule_line(const struct arg *args, struct sample *smp, const char *km, void *private)
41104113
{
4114+
struct act_rule *rule;
4115+
41114116
smp->flags = SMP_F_VOL_TXN;
41124117
smp->data.type = SMP_T_SINT;
4113-
if (!smp->strm || !smp->strm->last_rule_line)
4118+
if (!smp->strm || smp->strm->last_entity.type != 1)
4119+
return 0;
4120+
4121+
rule = smp->strm->last_entity.ptr;
4122+
smp->data.u.sint = rule->conf.line;
4123+
return 1;
4124+
}
4125+
4126+
static int smp_fetch_last_entity(const struct arg *args, struct sample *smp, const char *km, void *private)
4127+
{
4128+
smp->flags = SMP_F_VOL_TXN;
4129+
smp->data.type = SMP_T_STR;
4130+
if (!smp->strm)
4131+
return 0;
4132+
4133+
if (smp->strm->last_entity.type == 1) {
4134+
struct act_rule *rule = smp->strm->last_entity.ptr;
4135+
struct buffer *trash = get_trash_chunk();
4136+
4137+
trash->data = snprintf(trash->area, trash->size, "%s:%d", rule->conf.file, rule->conf.line);
4138+
smp->data.u.str = *trash;
4139+
}
4140+
else
41144141
return 0;
41154142

4116-
smp->data.u.sint = smp->strm->last_rule_line;
41174143
return 1;
41184144
}
41194145

@@ -4178,6 +4204,7 @@ static struct sample_fetch_kw_list smp_kws = {ILH, {
41784204
{ "cur_client_timeout", smp_fetch_cur_client_timeout, 0, NULL, SMP_T_SINT, SMP_USE_FTEND, },
41794205
{ "cur_server_timeout", smp_fetch_cur_server_timeout, 0, NULL, SMP_T_SINT, SMP_USE_BKEND, },
41804206
{ "cur_tunnel_timeout", smp_fetch_cur_tunnel_timeout, 0, NULL, SMP_T_SINT, SMP_USE_BKEND, },
4207+
{ "last_entity", smp_fetch_last_entity, 0, NULL, SMP_T_STR, SMP_USE_INTRN, },
41814208
{ "last_rule_file", smp_fetch_last_rule_file, 0, NULL, SMP_T_STR, SMP_USE_INTRN, },
41824209
{ "last_rule_line", smp_fetch_last_rule_line, 0, NULL, SMP_T_SINT, SMP_USE_INTRN, },
41834210
{ "txn.conn_retries", smp_fetch_conn_retries, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV, },

0 commit comments

Comments
 (0)