diff --git a/include/haproxy/htx-t.h b/include/haproxy/htx-t.h index d9c08c8f3..d57404a9d 100644 --- a/include/haproxy/htx-t.h +++ b/include/haproxy/htx-t.h @@ -145,7 +145,9 @@ #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 { diff --git a/include/haproxy/htx.h b/include/haproxy/htx.h index a849f1255..5ede1a3ec 100644 --- a/include/haproxy/htx.h +++ b/include/haproxy/htx.h @@ -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 . 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 to . We take care to * not overwrite existing data. All the message is copied or nothing. It returns * 1 on success and 0 on error. diff --git a/src/cache.c b/src/cache.c index 6fc1c1487..533b902bf 100644 --- a/src/cache.c +++ b/src/cache.c @@ -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; diff --git a/src/h1_htx.c b/src/h1_htx.c index 351980b8a..a2ee5108d 100644 --- a/src/h1_htx.c +++ b/src/h1_htx.c @@ -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; diff --git a/src/hlua.c b/src/hlua.c index 254c2a33d..556de4210 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -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); diff --git a/src/http_ana.c b/src/http_ana.c index b77bf2aec..7c1a1a164 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -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 diff --git a/src/mux_h2.c b/src/mux_h2.c index 4b790e614..44955ba8f 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -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); diff --git a/src/stats.c b/src/stats.c index d69c76462..562cd8273 100644 --- a/src/stats.c +++ b/src/stats.c @@ -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; diff --git a/src/tcpcheck.c b/src/tcpcheck.c index e83b915b9..fc64a10bb 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -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);