]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: h2: centralize transfer of decoded frames in h2_rcv_buf()
authorWilly Tarreau <w@1wt.eu>
Mon, 26 Feb 2018 14:50:05 +0000 (15:50 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 20 Jul 2018 17:21:43 +0000 (19:21 +0200)
We still call the parser but it should soon not be needed anymore. The
decode functions don't need the buffer nor the max size anymore. They
must also not touch the CS_FL_EOS or CS_FL_RCV_MORE flags either, so
this is done within h2_rcv_buf() after transmission.

The "flags" argument to h2_frt_decode_headers() and h2_frt_transfer_data()
has been removed since it's not used anymore.

src/mux_h2.c

index cad1ac14463dbdec25db3a4fd70c03e14088eddc..bb535608a858157accf75948e29c42f1e7ed418a 100644 (file)
@@ -2661,7 +2661,7 @@ static void h2_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
  * proceed. Stream errors are reported in h2s->errcode and connection errors
  * in h2c->errcode.
  */
-static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count, int flags)
+static int h2_frt_decode_headers(struct h2s *h2s)
 {
        struct h2c *h2c = h2s->h2c;
        const uint8_t *hdrs = (uint8_t *)b_head(&h2c->dbuf);
@@ -2781,14 +2781,8 @@ static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count,
        if (h2c->dff & H2_F_HEADERS_END_STREAM)
                h2s->flags |= H2_SF_ES_RCVD;
 
-       outlen = b_xfer(buf, csbuf, count);
-
-       if (!b_data(csbuf) && (h2s->flags & H2_SF_ES_RCVD))
-               h2s->cs->flags |= CS_FL_EOS;
-
  leave:
        free_trash_chunk(copy);
-       cs_drop_rxbuf(h2s->cs);
        return outlen;
  fail:
        outlen = 0;
@@ -2809,7 +2803,7 @@ static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count,
  * frame header and ensured that the frame was complete or the buffer full. It
  * changes the frame state to FRAME_A once done.
  */
-static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count, int flags)
+static int h2_frt_transfer_data(struct h2s *h2s)
 {
        struct h2c *h2c = h2s->h2c;
        int block1, block2;
@@ -2843,7 +2837,7 @@ static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count,
        csbuf = h2_get_buf(h2c, &h2s->cs->rxbuf);
        if (!csbuf) {
                h2c->flags |= H2_CF_DEM_SALLOC;
-               goto out;
+               goto fail;
        }
 
        flen = h2c->dfl - h2c->dpl;
@@ -2853,7 +2847,7 @@ static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count,
        if (flen > b_data(&h2c->dbuf)) {
                flen = b_data(&h2c->dbuf);
                if (!flen)
-                       goto leave;
+                       goto fail;
        }
 
        if (unlikely(b_space_wraps(csbuf))) {
@@ -2876,7 +2870,7 @@ static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count,
        if (flen + chklen > b_room(csbuf)) {
                if (chklen >= b_room(csbuf)) {
                        h2c->flags |= H2_CF_DEM_SFULL;
-                       goto leave;
+                       goto fail;
                }
                flen = b_room(csbuf) - chklen;
        }
@@ -2926,7 +2920,7 @@ static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count,
        if (h2c->dfl > h2c->dpl) {
                /* more data available, transfer stalled on stream full */
                h2c->flags |= H2_CF_DEM_SFULL;
-               goto leave;
+               goto fail;
        }
 
  end_transfer:
@@ -2938,7 +2932,7 @@ static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count,
                /* emit the trailing 0 CRLF CRLF */
                if (b_room(csbuf) < 5) {
                        h2c->flags |= H2_CF_DEM_SFULL;
-                       goto leave;
+                       goto fail;
                }
                chklen += 5;
                b_putblk(csbuf, "0\r\n\r\n", 5);
@@ -2952,21 +2946,9 @@ static int h2_frt_transfer_data(struct h2s *h2s, struct buffer *buf, int count,
        if (h2c->dff & H2_F_DATA_END_STREAM)
                h2s->flags |= H2_SF_ES_RCVD;
 
- leave:
-       /* now transfer possibly pending data from the h2s buffer to the stream buffer */
-       flen = b_xfer(buf, csbuf, count);
-
- out:
-       if (csbuf && b_data(csbuf))
-               h2s->cs->flags |= CS_FL_RCV_MORE;
-       else {
-               h2s->cs->flags &= ~CS_FL_RCV_MORE;
-               if (h2s->flags & H2_SF_ES_RCVD)
-                       h2s->cs->flags |= CS_FL_EOS;
-       }
-
-       cs_drop_rxbuf(h2s->cs);
-       return flen;
+       return flen + chklen;
+ fail:
+       return 0;
 }
 
 /*
@@ -2978,6 +2960,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
 {
        struct h2s *h2s = cs->ctx;
        struct h2c *h2c = h2s->h2c;
+       struct buffer *csbuf = &cs->rxbuf;
        size_t ret = 0;
 
        if (h2c->st0 != H2_CS_FRAME_P)
@@ -2991,16 +2974,26 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun
 
        switch (h2c->dft) {
        case H2_FT_HEADERS:
-               ret = h2_frt_decode_headers(h2s, buf, count, flags);
+               ret = h2_frt_decode_headers(h2s);
                break;
 
        case H2_FT_DATA:
-               ret = h2_frt_transfer_data(h2s, buf, count, flags);
+               ret = h2_frt_transfer_data(h2s);
                break;
+       }
 
-       default:
-               ret = 0;
+       /* transfer possibly pending data to the upper layer */
+       ret = b_xfer(buf, csbuf, count);
+
+       if (b_data(csbuf))
+               cs->flags |= CS_FL_RCV_MORE;
+       else {
+               cs->flags &= ~CS_FL_RCV_MORE;
+               if (h2s->flags & H2_SF_ES_RCVD)
+                       cs->flags |= CS_FL_EOS;
        }
+
+       cs_drop_rxbuf(cs);
        return ret;
 }