From: Christopher Faulet Date: Mon, 26 Feb 2024 07:36:58 +0000 (+0100) Subject: MEDIUM: htx/http-ana: No longer close connection on early HAProxy response X-Git-Tag: v3.0-dev5~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60fcc275779fb2ac76f93a14be1c69e60cd17a98;p=thirdparty%2Fhaproxy.git MEDIUM: htx/http-ana: No longer close connection on early HAProxy response When a response was returned by HAProxy, a dedicated HTX flag was set. Thanks to this flag, it was possible to add a "connection: close" header to the response if the request was not fully received and to close the connection. In the same way, when a redirect rule was applied, keep-alive was forcefully disabled for unfinished requests. All these mechanisms are now useless because the H1 mux is able to drain the response. So HTX_FL_PROXY_RESP flag is removed and no special processing is performed on HAProxy response when the request is unfinished. --- diff --git a/include/haproxy/htx-t.h b/include/haproxy/htx-t.h index 2ea6bc8b2b..7d49808c23 100644 --- a/include/haproxy/htx-t.h +++ b/include/haproxy/htx-t.h @@ -177,7 +177,7 @@ static forceinline char *hsl_show_flags(char *buf, size_t len, const char *delim #define HTX_FL_PARSING_ERROR 0x00000001 /* Set when a parsing error occurred */ #define HTX_FL_PROCESSING_ERROR 0x00000002 /* Set when a processing error occurred */ #define HTX_FL_FRAGMENTED 0x00000004 /* Set when the HTX buffer is fragmented */ -#define HTX_FL_PROXY_RESP 0x00000008 /* Set when the response was generated by HAProxy */ +/* 0x00000008 unused */ #define HTX_FL_EOM 0x00000010 /* Set when end-of-message is reached from the HTTP point of view * (at worst, on the EOM block is missing) */ @@ -192,7 +192,7 @@ static forceinline char *htx_show_flags(char *buf, size_t len, const char *delim _(0); /* flags */ _(HTX_FL_PARSING_ERROR, _(HTX_FL_PROCESSING_ERROR, - _(HTX_FL_FRAGMENTED, _(HTX_FL_PROXY_RESP, _(HTX_FL_EOM))))); + _(HTX_FL_FRAGMENTED, _(HTX_FL_EOM)))); /* epilogue */ _(~0U); return buf; diff --git a/src/http_ana.c b/src/http_ana.c index 035351270e..25123265fa 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -2236,7 +2236,7 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc struct buffer *chunk; struct ist status, reason, location; unsigned int flags; - int ret = 1, close = 0; /* Try to keep the connection alive byt default */ + int ret = 1; chunk = alloc_trash_chunk(); if (!chunk) { @@ -2409,9 +2409,6 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc break; } - if (!(txn->req.flags & HTTP_MSGF_BODYLESS) && txn->req.msg_state != HTTP_MSG_DONE) - close = 1; - htx = htx_from_buf(&res->buf); /* Trim any possible response */ channel_htx_truncate(&s->res, htx); @@ -2422,9 +2419,6 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc sl->info.res.status = rule->code; s->txn->status = rule->code; - if (close && !htx_add_header(htx, ist("Connection"), ist("close"))) - goto fail; - if (!htx_add_header(htx, ist("Content-length"), ist("0")) || !htx_add_header(htx, ist("Location"), location)) goto fail; @@ -4191,7 +4185,6 @@ void http_perform_server_redirect(struct stream *s, struct stconn *sc) s->txn->status = 302; if (!htx_add_header(htx, ist("Cache-Control"), ist("no-cache")) || - !htx_add_header(htx, ist("Connection"), ist("close")) || !htx_add_header(htx, ist("Content-length"), ist("0")) || !htx_add_header(htx, ist("Location"), location)) goto fail; @@ -4473,7 +4466,8 @@ int http_forward_proxy_resp(struct stream *s, int final) size_t data; if (final) { - htx->flags |= HTX_FL_PROXY_RESP; + if (s->txn->server_status == -1) + s->txn->server_status = 0; if (!htx_is_empty(htx) && !http_eval_after_res_rules(s)) return 0; diff --git a/src/http_fetch.c b/src/http_fetch.c index 1f3e4a05de..6e27c66304 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -314,7 +314,7 @@ struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, struct che else { if (txn->status == -1) txn->status = sl->info.res.status; - if (!(htx->flags & HTX_FL_PROXY_RESP) && txn->server_status == -1) + if (txn->server_status == -1) txn->server_status = sl->info.res.status; } if (sl->flags & HTX_SL_F_VER_11) diff --git a/src/mux_h1.c b/src/mux_h1.c index 581e59d729..343c23e086 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -2528,13 +2528,7 @@ static size_t h1_make_eoh(struct h1s *h1s, struct h1m *h1m, struct htx *htx, siz /* Deal with "Connection" header */ if (!(h1s->flags & H1S_F_HAVE_O_CONN)) { - if ((htx->flags & HTX_FL_PROXY_RESP) && h1s->req.state != H1_MSG_DONE) { - /* If the reply comes from haproxy while the request is - * not finished, we force the connection close. */ - h1s->flags = (h1s->flags & ~H1S_F_WANT_MSK) | H1S_F_WANT_CLO; - TRACE_STATE("force close mode (resp)", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1s->h1c->conn, h1s); - } - else if ((h1m->flags & (H1_MF_XFER_ENC|H1_MF_CLEN)) == (H1_MF_XFER_ENC|H1_MF_CLEN)) { + if ((h1m->flags & (H1_MF_XFER_ENC|H1_MF_CLEN)) == (H1_MF_XFER_ENC|H1_MF_CLEN)) { /* T-E + C-L: force close */ h1s->flags = (h1s->flags & ~H1S_F_WANT_MSK) | H1S_F_WANT_CLO; h1m->flags &= ~H1_MF_CLEN;