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.
This commit is contained in:
Christopher Faulet 2024-02-26 08:36:58 +01:00
parent 077906da14
commit 60fcc27577
4 changed files with 7 additions and 19 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;