From ffcffa8e93bcbf376f13b1f6e568ab093ea068bf Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 5 Apr 2023 10:33:31 +0200 Subject: [PATCH] MINOR: http-ana: Add a HTTP_MSGF flag to state the Expect header was checked HTTP_MSGF_EXPECT_CHECKED is now set on the request message to know the "Expect: " header was already handled, if any. The flag is set from the moment we try to handle the header to send a "100-continue" response, whether it was found or not. This way, when we are waiting for the request payload, thanks to this flag, we only try to handle "Expect: " header only once. Before it was performed by changing the message state from BODY to DATA. But this has some side effects and it is no accurate. So, it is better to rely on a flag to do so. --- include/haproxy/http_ana-t.h | 4 +++- src/http_ana.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/haproxy/http_ana-t.h b/include/haproxy/http_ana-t.h index 3910a4d08..552f78ca0 100644 --- a/include/haproxy/http_ana-t.h +++ b/include/haproxy/http_ana-t.h @@ -130,6 +130,8 @@ static forceinline char *txn_show_flags(char *buf, size_t len, const char *delim #define HTTP_MSGF_BODYLESS 0x00000040 /* The message has no body (content-length = 0) */ #define HTTP_MSGF_CONN_UPG 0x00000080 /* The message contains "Connection: Upgrade" header */ +#define HTTP_MSGF_EXPECT_CHECKED 0x00000100 /* Expect header was already handled, if any */ + /* This function is used to report flags in debugging tools. Please reflect * below any single-bit flag addition above in the same order via the * __APPEND_FLAG macro. The new end of the buffer is returned. @@ -142,7 +144,7 @@ static forceinline char *hmsg_show_flags(char *buf, size_t len, const char *deli /* flags */ _(HTTP_MSGF_CNT_LEN, _(HTTP_MSGF_TE_CHNK, _(HTTP_MSGF_XFER_LEN, _(HTTP_MSGF_VER_11, _(HTTP_MSGF_SOFT_RW, _(HTTP_MSGF_COMPRESSING, - _(HTTP_MSGF_BODYLESS, _(HTTP_MSGF_CONN_UPG)))))))); + _(HTTP_MSGF_BODYLESS, _(HTTP_MSGF_CONN_UPG, _(HTTP_MSGF_EXPECT_CHECKED))))))))); /* epilogue */ _(~0U); return buf; diff --git a/src/http_ana.c b/src/http_ana.c index e319a287d..f44e851c3 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -4049,7 +4049,7 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn, if (txn->meth == HTTP_METH_CONNECT || (msg->flags & HTTP_MSGF_BODYLESS)) goto end; - if (!(chn->flags & CF_ISRESP) && msg->msg_state < HTTP_MSG_DATA) { + if (!(chn->flags & CF_ISRESP)) { if (http_handle_expect_hdr(s, htx, msg) == -1) { ret = HTTP_RULE_RES_ERROR; goto end; @@ -4749,7 +4749,8 @@ static int http_handle_expect_hdr(struct stream *s, struct htx *htx, struct http /* If we have HTTP/1.1 message with a body and Expect: 100-continue, * then we must send an HTTP/1.1 100 Continue intermediate response. */ - if (msg->msg_state == HTTP_MSG_BODY && (msg->flags & HTTP_MSGF_VER_11) && + if (!(msg->flags & HTTP_MSGF_EXPECT_CHECKED) && + (msg->flags & HTTP_MSGF_VER_11) && (msg->flags & (HTTP_MSGF_CNT_LEN|HTTP_MSGF_TE_CHNK))) { struct ist hdr = { .ptr = "Expect", .len = 6 }; struct http_hdr_ctx ctx; @@ -4763,6 +4764,7 @@ static int http_handle_expect_hdr(struct stream *s, struct htx *htx, struct http http_remove_header(htx, &ctx); } } + msg->flags |= HTTP_MSGF_EXPECT_CHECKED; return 0; }