BUG/MEDIUM: stats: Be sure to never set EOM flag on an empty HTX message
During the last call to the stats I/O handle, it is possible to have nothing to dump. It may happen for many reasons. For instance, all remaining proxies are disabled or they don't match the specified scope. In HTML or in JSON, it is not really an issue because there is a footer. So there are still some data to push in the response channel buffer. In CSV, it is a problem because there is no footer. It means it is possible to finish the response with no payload at all in the HTX message. Thus, the EOM flag may be added on an empty message. When this happens, a shutdown is performed on an empty HTX message. Because there is nothing to send, the mux on the client side is not notified that the message was properly finished and interprets the shutdown as an abort. The response is chunked. So an abort at this stage means the last CRLF is never sent to the client. All data were sent but the message is invalid because the response chunking is not finished. If the reponse is compressed, because of a similar bug in the comppression filter, the compression is also aborted and the content is truncated because some data a lost in the compression filter. It is design issue with the HTX. It must be addressed. And there is an opportunity to do so with the recent conn-stream refactoring. It must be carefully evaluated first. But it is possible. In the means time and to also fix stable versions, to workaround the bug, a end-of-trailer HTX block is systematically added at the end of the message when the EOM flag is set if the HTX message is empty. This way, there are always some data to send when the EOM flag is set. Note that with a H2 client, it is only a problem when the response is compressed. This patch should fix the issue #1478. It must be backported as far as 2.4. On previous versions there is still the EOM block.
This commit is contained in:
parent
d057960769
commit
08b45cb8fd
13
src/stats.c
13
src/stats.c
@ -4316,7 +4316,18 @@ static void http_stats_io_handler(struct appctx *appctx)
|
||||
}
|
||||
|
||||
if (appctx->st0 == STAT_HTTP_DONE) {
|
||||
/* no more data are expected. Don't add TLR because mux-h1 will take care of it */
|
||||
/* no more data are expected. If the response buffer is empty,
|
||||
* be sure to add something (EOT block in this case) to have
|
||||
* something to send. It is important to be sure the EOM flags
|
||||
* will be handled by the endpoint.
|
||||
*/
|
||||
if (htx_is_empty(res_htx)) {
|
||||
if (!htx_add_endof(res_htx, HTX_BLK_EOT)) {
|
||||
si_rx_room_blk(si);
|
||||
goto out;
|
||||
}
|
||||
channel_add_input(res, 1);
|
||||
}
|
||||
res_htx->flags |= HTX_FL_EOM;
|
||||
si->cs->flags |= CS_FL_EOI;
|
||||
res->flags |= CF_EOI;
|
||||
|
Loading…
x
Reference in New Issue
Block a user