]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stream-int: Try to read data even if channel's buffer seems to be full
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 11 Oct 2018 13:29:21 +0000 (15:29 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 11 Nov 2018 09:18:37 +0000 (10:18 +0100)
Before calling the mux to get incoming data, we get the amount of space
available at the input of the buffer. If there is no space, we don't try to read
more data. This is good enough when raw data are stored in the buffer. But this
info has no meaning when structured data are stored. Because with the HTTP
refactoring, such kind of data will be stored in buffers, it is a bit annoying.

So, to avoid any problems, we always call the mux. It is the mux's responsiblity
to notify the stream interface it needs more space to store more data. This must
be done by setting the flag CS_FL_RCV_MORE on the conn_stream.

This is exactly what we do in the pass-through mux when <count> is null.

src/mux_pt.c
src/stream_interface.c

index beca8c2ea614693e4ef28db3544488d9e3129571..4195ec2505624e32a9a4480ac37a1eaa05170383 100644 (file)
@@ -116,6 +116,11 @@ static size_t mux_pt_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t
 {
        size_t ret;
 
+       if (!count) {
+               cs->flags |= CS_FL_RCV_MORE;
+               return 0;
+       }
+       cs->flags &= ~CS_FL_RCV_MORE;
        ret = cs->conn->xprt->rcv_buf(cs->conn, buf, count, flags);
        if (conn_xprt_read0_pending(cs->conn))
                cs->flags |= CS_FL_EOS;
index 46fc9ebf1cd82aea7674338a9a9132bd720bfce7..65d2c6120c74d16e84e5d4335a1a672bcf68413a 100644 (file)
@@ -1226,13 +1226,11 @@ int si_cs_recv(struct conn_stream *cs)
         */
        while (!(conn->flags & (CO_FL_ERROR | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE)) &&
               !(cs->flags & (CS_FL_ERROR|CS_FL_EOS)) && !(ic->flags & CF_SHUTR)) {
+               /* <max> may be null. This is the mux responsibility to set
+                * CS_FL_RCV_MORE on the CS if more space is needed.
+                */
                max = channel_recv_max(ic);
 
-               if (!max) {
-                       si_cant_put(si);
-                       break;
-               }
-
                ret = cs->conn->mux->rcv_buf(cs, &ic->buf, max, co_data(ic) ? CO_RFL_BUF_WET : 0);
                if (cs->flags & CS_FL_RCV_MORE)
                        si_cant_put(si);