]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: htx: Add a flag on a HTX message when no more data are expected
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 22 Jul 2020 14:20:34 +0000 (16:20 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 22 Jul 2020 14:43:32 +0000 (16:43 +0200)
The HTX_FL_EOI flag must now be set on a HTX message when no more data are
expected. Most of time, it must be set before adding the EOM block. Thus, if
there is no space for the EOM, there is still an information to know all data
were received and pushed in the HTX message. There is only an exception for the
HTTP replies (deny, return...). For these messages, the flag is set after all
blocks are pushed in the message, including the EOM block, because, on error,
we remove all inserted data.

include/haproxy/htx-t.h
include/haproxy/htx.h
src/cache.c
src/h1_htx.c
src/hlua.c
src/http_ana.c
src/mux_h2.c
src/stats.c
src/tcpcheck.c

index d9c08c8f36d3f885aecf850d494816030b23e1ea..d57404a9d9f3e358017817cd53bce32f74eb528b 100644 (file)
 #define HTX_FL_PROCESSING_ERROR  0x00000002 /* Set when a processing error occurred */
 #define HTX_FL_UPGRADE           0x00000004 /* Set when an upgrade is in progress */
 #define HTX_FL_PROXY_RESP        0x00000008 /* Set when the response was generated by HAProxy */
-
+#define HTX_FL_EOI               0x00000010 /* Set when end-of-input is reached from the HTX point of view
+                                            * (at worst, on the EOM block is missing)
+                                            */
 
 /* HTX block's type (max 15). */
 enum htx_blk_type {
index a849f12557e765871d04468a2d0c3fb2a308097a..5ede1a3ecb30068d87a93fbf3dc5db3a144320d8 100644 (file)
@@ -585,6 +585,15 @@ static inline int htx_is_not_empty(const struct htx *htx)
        return (htx->head != -1);
 }
 
+/* Returns 1 if no more data are expected for the message <htx>. Otherwise it
+ * returns 0. Note that it is illegal to call this with htx == NULL. Note also
+ * the EOM block may be missing.
+ */
+static inline int htx_expect_more(const struct htx *htx)
+{
+       return !(htx->flags & HTX_FL_EOI);
+}
+
 /* Copy an HTX message stored in the buffer <msg> to <htx>. We take care to
  * not overwrite existing data. All the message is copied or nothing. It returns
  * 1 on success and 0 on error.
index 6fc1c1487cdd381d513b268a4531850f994f9543..533b902bf6d332655e836964ed741885a77f9677 100644 (file)
@@ -926,6 +926,7 @@ static void http_cache_io_handler(struct appctx *appctx)
        }
 
        if (appctx->st0 == HTX_CACHE_EOM) {
+               res_htx->flags |= HTX_FL_EOI; /* no more data are expected. Only EOM remains to add now */
                if (!htx_add_endof(res_htx, HTX_BLK_EOM)) {
                        si_rx_room_blk(si);
                        goto out;
index 351980b8a1fc1d116b96dd36ec9576b299749ee6..a2ee5108d39ef6dd83d008296a4fff110c2e93e3 100644 (file)
@@ -616,6 +616,8 @@ int h1_parse_msg_eom(struct h1m *h1m, struct htx *dsthtx, size_t max)
                dsthtx->flags |= HTX_FL_PARSING_ERROR;
                return 0;
        }
+
+       dsthtx->flags |= HTX_FL_EOI; /* no more data are expected. Only EOM remains to add now */
        if (max < sizeof(struct htx_blk) + 1 || !htx_add_endof(dsthtx, HTX_BLK_EOM))
                return 0;
 
index 254c2a33d179f4e7f7b9256fd43e0358636e84da..556de4210d820e87a1e3dd8d3dc8c0a08d5a4b9f 100644 (file)
@@ -4582,6 +4582,7 @@ __LJMP static int hlua_applet_http_send_response(lua_State *L)
        }
 
        /* Finalize headers. */
+       htx->flags |= HTX_FL_EOI; /* no more data are expected. Only EOM remains to add now */
        if (!htx_add_endof(htx, HTX_BLK_EOH)) {
                hlua_pusherror(L, "Lua applet http '%s': Failed create the response.\n",
                               appctx->appctx->rule->arg.hlua_rule->fcn.name);
index b77bf2aec7dfcc5c6dcc9c97142c80a3db590ac7..7c1a1a164bbd751dae7e4508316fc9558614b528 100644 (file)
@@ -4577,6 +4577,7 @@ int http_forward_proxy_resp(struct stream *s, int final)
                channel_auto_close(res);
                channel_shutr_now(res);
                res->flags |= CF_EOI; /* The response is terminated, add EOI */
+               htxbuf(&res->buf)->flags |= HTX_FL_EOI; /* no more data are expected */
        }
        else {
                /* Send ASAP informational messages. Rely on CF_EOI for final
index 4b790e61411eb806d66d60803c9b94fcabaf9e82..44955ba8fccfca332dcca4f0fbd5a8a4a836708d 100644 (file)
@@ -4452,6 +4452,7 @@ next_frame:
 
        if ((h2c->dff & H2_F_HEADERS_END_STREAM)) {
                /* Mark the end of message using EOM */
+               htx->flags |= HTX_FL_EOI; /* no more data are expected. Only EOM remains to add now */
                if (!htx_add_endof(htx, HTX_BLK_EOM)) {
                        TRACE_STATE("failed to append HTX EOM block into rxbuf", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_H2S_ERR, h2c->conn);
                        goto fail;
@@ -4587,6 +4588,7 @@ try_again:
         */
 
        if (h2c->dff & H2_F_DATA_END_STREAM) {
+               htx->flags |= HTX_FL_EOI; /* no more data are expected. Only EOM remains to add now */
                if (!htx_add_endof(htx, HTX_BLK_EOM)) {
                        TRACE_STATE("h2s rxbuf is full, failed to add EOM", H2_EV_RX_FRAME|H2_EV_RX_DATA|H2_EV_H2S_BLK, h2c->conn, h2s);
                        h2c->flags |= H2_CF_DEM_SFULL;
@@ -5778,6 +5780,8 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
                if (htx_is_empty(buf_htx))
                        cs->flags |= CS_FL_EOI;
        }
+       else if (htx_is_empty(h2s_htx))
+               buf_htx->flags |= (h2s_htx->flags & HTX_FL_EOI);
 
        buf_htx->extra = (h2s_htx->extra ? (h2s_htx->data + h2s_htx->extra) : 0);
        htx_to_buf(buf_htx, buf);
index d69c76462c23ffc7bfede70811ab4a8def46fb0c..562cd82733a50f4db734f6fc5477aa4fb4f14917 100644 (file)
@@ -3339,6 +3339,7 @@ static void http_stats_io_handler(struct appctx *appctx)
 
        if (appctx->st0 == STAT_HTTP_DONE) {
                /* Don't add TLR because mux-h1 will take care of it */
+               res_htx->flags |= HTX_FL_EOI; /* no more data are expected. Only EOM remains to add now */
                if (!htx_add_endof(res_htx, HTX_BLK_EOM)) {
                        si_rx_room_blk(si);
                        goto out;
index e83b915b9cad6aa8b472947e01445ba7fc4adb12..fc64a10bb0841115e5f0cc87fa3fae3a098954be 100644 (file)
@@ -1335,8 +1335,11 @@ enum tcpcheck_eval_ret tcpcheck_eval_send(struct check *check, struct tcpcheck_r
 
 
                if (!htx_add_endof(htx, HTX_BLK_EOH) ||
-                   (istlen(body) && !htx_add_data_atonce(htx, body)) ||
-                   !htx_add_endof(htx, HTX_BLK_EOM))
+                   (istlen(body) && !htx_add_data_atonce(htx, body)))
+                       goto error_htx;
+
+               htx->flags |= HTX_FL_EOI; /* no more data are expected. Only EOM remains to add now */
+               if (!htx_add_endof(htx, HTX_BLK_EOM))
                        goto error_htx;
 
                htx_to_buf(htx, &check->bo);