/* Forward a response generated by HAProxy (error/redirect/return). This
* function forwards all pending incoming data. If <final> 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. On success 1 is
- * returned. If an error occurred, 0 is returned.
+ * transaction is terminated and the request is emptied. if <final> 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.
*/
int http_forward_proxy_resp(struct stream *s, int final)
{
if (final) {
htx->flags |= HTX_FL_PROXY_RESP;
- if (!http_eval_after_res_rules(s))
+ if (final == 1 && !http_eval_after_res_rules(s))
return 0;
channel_auto_read(req);
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);
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, 1) && s->txn->status != 500) {
+ if (!http_forward_proxy_resp(s, final)) {
+ /* 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->status = 500;
- http_reply_and_close(s, s->txn->status, http_error_message(s));
+ msg = http_error_message(s);
+ goto retry;
}
}
}