]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux-h1: refactor output processing
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 24 May 2019 13:28:57 +0000 (15:28 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 5 Jun 2019 08:12:11 +0000 (10:12 +0200)
When we format the H1 output, in the loop on the HTX message, instead of
switching on the block types, we now switch on the message state. It is almost
the same, but it will ease futur changes, on trailers and end-of markers.

src/mux_h1.c

index ffec7e852b2317c9bc468cdc6862dd37ca7b0b7d..900382bdeb6b3e3038d75d4acee43829058e743b 100644 (file)
@@ -1456,7 +1456,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
        if (!count)
                goto end;
 
-       chn_htx = htx_from_buf(buf);
+       chn_htx = htxbuf(buf);
        if (htx_is_empty(chn_htx))
                goto end;
 
@@ -1540,13 +1540,13 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                        vlen = count;
                }
 
-               switch (type) {
-                       case HTX_BLK_UNUSED:
-                               break;
+               if (type == HTX_BLK_UNUSED)
+                       goto nextblk;
 
-                       case HTX_BLK_REQ_SL:
-                               h1m_init_req(h1m);
-                               h1m->flags |= (H1_MF_NO_PHDR|H1_MF_CLEAN_CONN_HDR);
+               switch (h1m->state) {
+                       case H1_MSG_RQBEFORE:
+                               if (type != HTX_BLK_REQ_SL)
+                                       goto error;
                                sl = htx_get_blk_ptr(chn_htx, blk);
                                h1s->meth = sl->info.req.meth;
                                h1_parse_req_vsn(h1m, sl);
@@ -1558,9 +1558,9 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                h1m->state = H1_MSG_HDR_FIRST;
                                break;
 
-                       case HTX_BLK_RES_SL:
-                               h1m_init_res(h1m);
-                               h1m->flags |= (H1_MF_NO_PHDR|H1_MF_CLEAN_CONN_HDR);
+                       case H1_MSG_RPBEFORE:
+                               if (type != HTX_BLK_RES_SL)
+                                       goto error;
                                sl = htx_get_blk_ptr(chn_htx, blk);
                                h1s->status = sl->info.res.status;
                                h1_parse_res_vsn(h1m, sl);
@@ -1574,7 +1574,13 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                h1m->state = H1_MSG_HDR_FIRST;
                                break;
 
-                       case HTX_BLK_HDR:
+                       case H1_MSG_HDR_FIRST:
+                       case H1_MSG_HDR_NAME:
+                       case H1_MSG_HDR_L2_LWS:
+                               if (type == HTX_BLK_EOH)
+                                       goto last_lf;
+                               if (type != HTX_BLK_HDR)
+                                       goto error;
                                h1m->state = H1_MSG_HDR_NAME;
                                n = htx_get_blk_name(chn_htx, blk);
                                v = htx_get_blk_value(chn_htx, blk);
@@ -1598,7 +1604,10 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                h1m->state = H1_MSG_HDR_L2_LWS;
                                break;
 
-                       case HTX_BLK_EOH:
+                       case H1_MSG_LAST_LF:
+                               if (type != HTX_BLK_EOH)
+                                       goto error;
+                         last_lf:
                                if (h1m->state != H1_MSG_LAST_LF && process_conn_mode) {
                                        /* There is no "Connection:" header and
                                         * it the conn_mode must be
@@ -1613,6 +1622,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                        process_conn_mode = 0;
                                }
 
+                               h1m->state = H1_MSG_LAST_LF;
                                if ((h1s->meth != HTTP_METH_CONNECT &&
                                     (h1m->flags & (H1_MF_VER_11|H1_MF_RESP|H1_MF_CLEN|H1_MF_CHNK|H1_MF_XFER_LEN)) ==
                                     (H1_MF_VER_11|H1_MF_XFER_LEN)) ||
@@ -1626,7 +1636,6 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                        h1m->flags |= H1_MF_CHNK;
                                }
 
-                               h1m->state = H1_MSG_LAST_LF;
                                if (!chunk_memcat(tmp, "\r\n", 2))
                                        goto copy;
 
@@ -1648,21 +1657,33 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                        h1m->state = H1_MSG_DATA;
                                break;
 
-                       case HTX_BLK_DATA:
+                       case H1_MSG_DATA:
+                               if (type == HTX_BLK_EOD) {
+                                       if (!chunk_memcat(tmp, "0\r\n", 3))
+                                               goto copy;
+                                       h1s->flags |= H1S_F_HAVE_O_EOD;
+                                       h1m->state = H1_MSG_TRAILERS;
+                                       break;
+                               }
+                               if (type == HTX_BLK_TLR)
+                                       goto trailers;
+                               else if (type == HTX_BLK_EOM)
+                                       goto done;
+                               else if (type != HTX_BLK_DATA)
+                                       goto error;
                                v = htx_get_blk_value(chn_htx, blk);
                                v.len = vlen;
                                if (!htx_data_to_h1(v, tmp, !!(h1m->flags & H1_MF_CHNK)))
                                        goto copy;
                                break;
 
-                       case HTX_BLK_EOD:
-                               if (!chunk_memcat(tmp, "0\r\n", 3))
-                                       goto copy;
-                               h1s->flags |= H1S_F_HAVE_O_EOD;
+                       case H1_MSG_TRAILERS:
+                               if (type == HTX_BLK_EOM)
+                                       goto done;
+                               else if (type != HTX_BLK_TLR)
+                                       goto error;
+                         trailers:
                                h1m->state = H1_MSG_TRAILERS;
-                               break;
-
-                       case HTX_BLK_TLR:
                                if (!(h1s->flags & H1S_F_HAVE_O_EOD)) {
                                        if (!chunk_memcat(tmp, "0\r\n", 3))
                                                goto copy;
@@ -1675,7 +1696,11 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                h1s->flags |= H1S_F_HAVE_O_TLR;
                                break;
 
-                       case HTX_BLK_EOM:
+                       case H1_MSG_DONE:
+                               if (type != HTX_BLK_EOM)
+                                       goto error;
+                         done:
+                               h1m->state = H1_MSG_DONE;
                                if ((h1m->flags & H1_MF_CHNK)) {
                                        if (!(h1s->flags & H1S_F_HAVE_O_EOD)) {
                                                if (!chunk_memcat(tmp, "0\r\n", 3))
@@ -1688,13 +1713,15 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                                h1s->flags |= H1S_F_HAVE_O_TLR;
                                        }
                                }
-                               h1m->state = H1_MSG_DONE;
                                break;
 
                        default:
+                         error:
                                h1s->flags |= errflag;
                                break;
                }
+
+         nextblk:
                total += vlen;
                count -= vlen;
                if (sz == vlen)