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.
This commit is contained in:
Christopher Faulet 2023-04-05 10:33:31 +02:00
parent 620382af2f
commit ffcffa8e93
2 changed files with 7 additions and 3 deletions

View 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_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_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 /* 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 * below any single-bit flag addition above in the same order via the
* __APPEND_FLAG macro. The new end of the buffer is returned. * __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 */ /* flags */
_(HTTP_MSGF_CNT_LEN, _(HTTP_MSGF_TE_CHNK, _(HTTP_MSGF_XFER_LEN, _(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_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 */ /* epilogue */
_(~0U); _(~0U);
return buf; return buf;

View 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)) if (txn->meth == HTTP_METH_CONNECT || (msg->flags & HTTP_MSGF_BODYLESS))
goto end; 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) { if (http_handle_expect_hdr(s, htx, msg) == -1) {
ret = HTTP_RULE_RES_ERROR; ret = HTTP_RULE_RES_ERROR;
goto end; 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, /* 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. * 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))) { (msg->flags & (HTTP_MSGF_CNT_LEN|HTTP_MSGF_TE_CHNK))) {
struct ist hdr = { .ptr = "Expect", .len = 6 }; struct ist hdr = { .ptr = "Expect", .len = 6 };
struct http_hdr_ctx ctx; 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); http_remove_header(htx, &ctx);
} }
} }
msg->flags |= HTTP_MSGF_EXPECT_CHECKED;
return 0; return 0;
} }