]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http-ana: Add a HTTP_MSGF flag to state the Expect header was checked
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 5 Apr 2023 08:33:31 +0000 (10:33 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 5 Apr 2023 08:33:32 +0000 (10:33 +0200)
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
src/http_ana.c

index 3910a4d082af6e5358bd4c7b15167ec9b3f01bff..552f78ca0abaaea396cfdd4fc18162885a74e842 100644 (file)
@@ -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;
index e319a287d0332b3b906e34d307119f4066ee036e..f44e851c3594b827a7a5f966d44140968cfe736e 100644 (file)
@@ -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;
 }