diff --git a/include/types/http_ana.h b/include/types/http_ana.h index 316a2716d..1b9891c41 100644 --- a/include/types/http_ana.h +++ b/include/types/http_ana.h @@ -31,7 +31,8 @@ /* These are the flags that are found in txn->flags */ /* action flags */ -/* Unusued: 0x00000001..0x00000008 */ +/* Unusued: 0x00000001..0x00000004 */ +#define TX_CONST_REPLY 0x00000008 /* The http reply must not be rewritten (don't eval after-response ruleset) */ #define TX_CLTARPIT 0x00000010 /* the transaction is tarpitted (anti-dos) */ /* transaction flags dedicated to cookies : bits values 0x20 to 0x80 (0-7 shift 5) */ diff --git a/src/http_ana.c b/src/http_ana.c index 6ff6ada1f..e6a43ea13 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -3174,6 +3174,10 @@ int http_eval_after_res_rules(struct stream *s) struct session *sess = s->sess; enum rule_result ret = HTTP_RULE_RES_CONT; + /* Eval after-response ruleset only if the reply is not const */ + if (s->txn->flags & TX_CONST_REPLY) + goto end; + /* prune the request variables if not already done and swap to the response variables. */ if (s->vars_reqres.scope != SCOPE_RES) { if (!LIST_ISEMPTY(&s->vars_reqres.head)) @@ -3185,6 +3189,7 @@ int http_eval_after_res_rules(struct stream *s) if ((ret == HTTP_RULE_RES_CONT || ret == HTTP_RULE_RES_STOP) && sess->fe != s->be) ret = http_res_get_intercept_rule(sess->fe, &sess->fe->http_after_res_rules, s); + end: /* All other codes than CONTINUE, STOP or DONE are forbidden */ return (ret == HTTP_RULE_RES_CONT || ret == HTTP_RULE_RES_STOP || ret == HTTP_RULE_RES_DONE); } @@ -4591,9 +4596,8 @@ static void http_end_response(struct stream *s) /* Forward a response generated by HAProxy (error/redirect/return). This * function forwards all pending incoming data. If is set to 0, nothing * more is performed. It is used for 1xx informational messages. Otherwise, the - * transaction is terminated and the request is emptied. if is greater - * than 1, it means after-response ruleset must not be evaluated. On success 1 - * is returned. If an error occurred, 0 is returned. + * transaction is terminated and the request is emptied. On success 1 is + * returned. If an error occurred, 0 is returned. */ int http_forward_proxy_resp(struct stream *s, int final) { @@ -4604,7 +4608,8 @@ int http_forward_proxy_resp(struct stream *s, int final) if (final) { htx->flags |= HTX_FL_PROXY_RESP; - if (final == 1 && !http_eval_after_res_rules(s)) + + if (!http_eval_after_res_rules(s)) return 0; channel_auto_read(req); @@ -4637,9 +4642,6 @@ void http_server_error(struct stream *s, struct stream_interface *si, int err, void http_reply_and_close(struct stream *s, short status, const struct buffer *msg) { - int final = 1; - - retry: channel_auto_read(&s->req); channel_abort(&s->req); channel_auto_close(&s->req); @@ -4661,17 +4663,17 @@ void http_reply_and_close(struct stream *s, short status, const struct buffer *m FLT_STRM_CB(s, flt_http_reply(s, s->txn->status, msg)); htx = htx_from_buf(&chn->buf); if (channel_htx_copy_msg(chn, htx, msg)) { - if (!http_forward_proxy_resp(s, final)) { + if (!http_forward_proxy_resp(s, 1)) { /* On error, return a 500 error message, but * don't rewrite it if it is already an internal * error. */ if (s->txn->status == 500) - final++; + s->txn->flags |= TX_CONST_REPLY; s->txn->status = 500; - msg = http_error_message(s); - goto retry; - } + s->txn->errmsg = NULL; + return http_reply_and_close(s, s->txn->status, http_error_message(s)); + } } } }