From: Christopher Faulet Date: Wed, 5 Apr 2023 08:33:31 +0000 (+0200) Subject: MINOR: http-ana: Add a HTTP_MSGF flag to state the Expect header was checked X-Git-Tag: v2.8-dev7~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ffcffa8e93bcbf376f13b1f6e568ab093ea068bf;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/include/haproxy/http_ana-t.h b/include/haproxy/http_ana-t.h index 3910a4d082..552f78ca0a 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 e319a287d0..f44e851c35 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; }