]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: htx: Change htx_sl to be a struct instead of an union
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 26 Nov 2018 10:13:57 +0000 (11:13 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 1 Dec 2018 16:37:27 +0000 (17:37 +0100)
The HTX start-line is now a struct. It will be easier to extend, if needed. Same
info can be found, of course. In addition it is now possible to set flags on
it. It will be used to set some infos about the message.

Some macros and functions have been added in proto/htx.h to help accessing
different parts of the start-line.

include/proto/htx.h
include/types/htx.h
src/http_htx.c
src/htx.c
src/mux_h1.c

index 3c5c0fa01e477c8d36ec0e8c296ef7b43b092b86..e618a202222fe92ebc7069751cdf642b77902c25 100644 (file)
@@ -59,12 +59,84 @@ struct htx_blk *htx_add_trailer(struct htx *htx, const struct ist tlr);
 struct htx_blk *htx_add_oob(struct htx *htx, const struct ist oob);
 struct htx_blk *htx_add_data_before(struct htx *htx, const struct htx_blk *ref, const struct ist data);
 
-int htx_reqline_to_str(const union htx_sl *sl, struct buffer *chk);
-int htx_stline_to_str(const union htx_sl *sl, struct buffer *chk);
+int htx_reqline_to_str(const struct htx_sl *sl, struct buffer *chk);
+int htx_stline_to_str(const struct htx_sl *sl, struct buffer *chk);
 int htx_hdr_to_str(const struct ist n, const struct ist v, struct buffer *chk);
 int htx_data_to_str(const struct ist data, struct buffer *chk, int chunked);
 int htx_trailer_to_str(const struct ist tlr, struct buffer *chk);
 
+/* Functions and macros to get parts of the start-line or legnth of these
+ * parts
+ */
+#define HTX_SL_LEN(sl) ((sl)->len[0] + (sl)->len[1] + (sl)->len[2])
+
+#define HTX_SL_P1_LEN(sl) ((sl)->len[0])
+#define HTX_SL_P2_LEN(sl) ((sl)->len[1])
+#define HTX_SL_P3_LEN(sl) ((sl)->len[2])
+#define HTX_SL_P1_PTR(sl) ((sl)->l)
+#define HTX_SL_P2_PTR(sl) (HTX_SL_P1_PTR(sl) + HTX_SL_P1_LEN(sl))
+#define HTX_SL_P3_PTR(sl) (HTX_SL_P2_PTR(sl) + HTX_SL_P2_LEN(sl))
+
+#define HTX_SL_REQ_MLEN(sl) HTX_SL_P1_LEN(sl)
+#define HTX_SL_REQ_ULEN(sl) HTX_SL_P2_LEN(sl)
+#define HTX_SL_REQ_VLEN(sl) HTX_SL_P3_LEN(sl)
+#define HTX_SL_REQ_MPTR(sl) HTX_SL_P1_PTR(sl)
+#define HTX_SL_REQ_UPTR(sl) HTX_SL_P2_PTR(sl)
+#define HTX_SL_REQ_VPTR(sl) HTX_SL_P3_PTR(sl)
+
+#define HTX_SL_RES_VLEN(sl) HTX_SL_P1_LEN(sl)
+#define HTX_SL_RES_CLEN(sl) HTX_SL_P2_LEN(sl)
+#define HTX_SL_RES_RLEN(sl) HTX_SL_P3_LEN(sl)
+#define HTX_SL_RES_VPTR(sl) HTX_SL_P1_PTR(sl)
+#define HTX_SL_RES_CPTR(sl) HTX_SL_P2_PTR(sl)
+#define HTX_SL_RES_RPTR(sl) HTX_SL_P3_PTR(sl)
+
+static inline const struct ist htx_sl_p1(const struct htx_sl *sl)
+{
+       return ist2(HTX_SL_P1_PTR(sl), HTX_SL_P1_LEN(sl));
+}
+
+static inline const struct ist htx_sl_p2(const struct htx_sl *sl)
+{
+       return ist2(HTX_SL_P2_PTR(sl), HTX_SL_P2_LEN(sl));
+}
+
+static inline const struct ist htx_sl_p3(const struct htx_sl *sl)
+{
+       return ist2(HTX_SL_P3_PTR(sl), HTX_SL_P3_LEN(sl));
+}
+
+
+static inline const struct ist htx_sl_req_meth(const struct htx_sl *sl)
+{
+       return htx_sl_p1(sl);
+}
+
+static inline const struct ist htx_sl_req_uri(const struct htx_sl *sl)
+{
+       return htx_sl_p2(sl);
+}
+
+static inline const struct ist htx_sl_req_vsn(const struct htx_sl *sl)
+{
+       return htx_sl_p3(sl);
+}
+
+
+static inline const struct ist htx_sl_res_vsn(const struct htx_sl *sl)
+{
+       return htx_sl_p1(sl);
+}
+
+static inline const struct ist htx_sl_res_code(const struct htx_sl *sl)
+{
+       return htx_sl_p2(sl);
+}
+
+static inline const struct ist htx_sl_res_reason(const struct htx_sl *sl)
+{
+       return htx_sl_p3(sl);
+}
 
 /* Returns the array index of a block given its position <pos> */
 static inline uint32_t htx_pos_to_idx(const struct htx *htx, uint32_t pos)
@@ -507,7 +579,7 @@ static inline void htx_dump(struct htx *htx)
                 htx_get_head(htx), htx->tail, htx->front, htx->wrap);
 
         for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
-               union htx_sl      *sl;
+               struct htx_sl     *sl;
                 struct htx_blk    *blk  = htx_get_blk(htx, pos);
                 enum htx_blk_type  type = htx_get_blk_type(blk);
                 enum htx_phdr_type phdr = htx_get_blk_phdr(blk);
@@ -517,21 +589,13 @@ static inline void htx_dump(struct htx *htx)
                 n = htx_get_blk_name(htx, blk);
                 v = htx_get_blk_value(htx, blk);
 
-                if (type == HTX_BLK_REQ_SL) {
-                       sl = htx_get_blk_ptr(htx, blk);
-                        fprintf(stderr, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u\t%.*s %.*s %.*s\n",
-                                pos, htx_blk_type_str(type), sz, blk->addr,
-                                (int)sl->rq.m_len, sl->rq.l,
-                                (int)sl->rq.u_len, sl->rq.l + sl->rq.m_len,
-                                (int)sl->rq.v_len, sl->rq.l + sl->rq.m_len + sl->rq.u_len);
-               }
-                else if (type == HTX_BLK_RES_SL) {
+                if (type == HTX_BLK_REQ_SL || type == HTX_BLK_RES_SL) {
                        sl = htx_get_blk_ptr(htx, blk);
                         fprintf(stderr, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u\t%.*s %.*s %.*s\n",
                                 pos, htx_blk_type_str(type), sz, blk->addr,
-                                (int)sl->st.v_len, sl->st.l,
-                                (int)sl->st.c_len, sl->st.l + sl->st.v_len,
-                                (int)sl->st.r_len, sl->st.l + sl->rq.v_len + sl->st.c_len);
+                                HTX_SL_P1_LEN(sl), HTX_SL_P1_PTR(sl),
+                                HTX_SL_P2_LEN(sl), HTX_SL_P2_PTR(sl),
+                                HTX_SL_P3_LEN(sl), HTX_SL_P3_PTR(sl));
                }
                 else if (type == HTX_BLK_HDR)
                         fprintf(stderr, "\t\t[%u] type=%-17s - size=%-6u - addr=%-6u\t%.*s: %.*s\n",
index 8f3280fa08a4e66a11485ff24cc9e6bae65b6ca7..c70961971063029e7b79221cb2143756dc1ab8b6 100644 (file)
  *
  */
 
+/*HTX start-line flags */
+#define HTX_SL_F_NONE          0x00000000
+#define HTX_SL_F_IS_RESP       0x00000001 /* It is the response start-line (unset means the request one) */
+#define HTX_SL_F_XFER_LEN      0x00000002 /* The message xfer size can be dertermined */
+#define HTX_SL_F_XFER_ENC      0x00000004 /* The transfer-encoding header was found in message */
+#define HTX_SL_F_CLEN          0x00000008 /* The content-length header was found in message */
+#define HTX_SL_F_CHNK          0x00000010 /* The message payload is chunked */
+#define HTX_SL_F_VER_11        0x00000020 /* The message indicates version 1.1 or above */
+
 /* HTX flags */
 #define HTX_FL_NONE              0x00000000
 #define HTX_FL_PARSING_ERROR     0x00000001
@@ -111,21 +120,21 @@ struct htx_ret {
        struct htx_blk *blk;
 };
 
-union htx_sl {
-       struct {
-               enum http_meth_t meth; /* method */
-               int m_len;             /* METHOD length */
-               int u_len;             /* URI length */
-               int v_len;             /* VERSION length */
-               char l[0];
-       } rq;                          /* request line : field, length, data */
-       struct {
-               uint16_t status;       /* status code */
-               int v_len;             /* VERSION length */
-               int c_len;             /* CODE length */
-               int r_len;             /* REASON length */
-               char l[0];
-       } st;                          /* status line : field, length, data */
+struct htx_sl {
+       unsigned int flags; /* HTX_SL_F_* */
+       union {
+               struct {
+                       enum http_meth_t meth;   /* method */
+               } req;
+               struct {
+                       uint16_t         status; /* status code */
+               } res;
+       } info;
+
+       /* XXX 2 bytes unused */
+
+       unsigned int len[3]; /* length of differnt parts of the start-line */
+       char         l[0];
 };
 
 /* Internal representation of an HTTP message */
index c3027f948498d524bcfdbed64a8e289ff719ce8b..1a8e5bb9e947545804a95e39fbe87f68aee183da 100644 (file)
@@ -22,7 +22,7 @@
  */
 union h1_sl http_find_stline(const struct htx *htx)
 {
-       union htx_sl *htx_sl;
+       struct htx_sl *htx_sl;
        union h1_sl sl;
        int32_t pos;
 
@@ -32,19 +32,19 @@ union h1_sl http_find_stline(const struct htx *htx)
 
                if (type == HTX_BLK_REQ_SL) {
                        htx_sl = htx_get_blk_ptr(htx, blk);
-                       sl.rq.meth = htx_sl->rq.meth;
-                       sl.rq.m = ist2(htx_sl->rq.l, htx_sl->rq.m_len);
-                       sl.rq.u = ist2(htx_sl->rq.l + htx_sl->rq.m_len, htx_sl->rq.u_len);
-                       sl.rq.v = ist2(htx_sl->rq.l + htx_sl->rq.m_len + htx_sl->rq.u_len, htx_sl->rq.v_len);
+                       sl.rq.meth = htx_sl->info.req.meth;
+                       sl.rq.m = htx_sl_req_meth(htx_sl);
+                       sl.rq.u = htx_sl_req_uri(htx_sl);
+                       sl.rq.v = htx_sl_req_vsn(htx_sl);
                        return sl;
                }
 
                if (type == HTX_BLK_RES_SL) {
                        htx_sl = htx_get_blk_ptr(htx, blk);
-                       sl.st.status = htx_sl->st.status;
-                       sl.st.v = ist2(htx_sl->st.l, htx_sl->st.v_len);
-                       sl.st.c = ist2(htx_sl->st.l + htx_sl->st.v_len, htx_sl->st.c_len);
-                       sl.st.r = ist2(htx_sl->st.l + htx_sl->st.v_len + htx_sl->st.c_len, htx_sl->st.r_len);
+                       sl.st.status = htx_sl->info.res.status;
+                       sl.st.v = htx_sl_res_vsn(htx_sl);
+                       sl.st.c = htx_sl_res_code(htx_sl);
+                       sl.st.r = htx_sl_res_reason(htx_sl);
                        return sl;
                }
 
index 0c9646739d67f55fa92bd51ac0338cf165436e2c..85118cf4bb5664f0cba8ff37433889fb039626aa 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -573,35 +573,35 @@ struct htx_blk *htx_replace_header(struct htx *htx, struct htx_blk *blk,
 
 static void htx_set_blk_reqline(struct htx *htx, struct htx_blk *blk, const union h1_sl sl)
 {
-       union htx_sl *htx_sl;
+       struct htx_sl *htx_sl;
 
        htx_sl = htx_get_blk_ptr(htx, blk);
-       htx_sl->rq.meth = sl.rq.meth;
+       htx_sl->info.req.meth = sl.rq.meth;
 
-       htx_sl->rq.m_len = sl.rq.m.len;
-       htx_sl->rq.u_len = sl.rq.u.len;
-       htx_sl->rq.v_len = sl.rq.v.len;
+       HTX_SL_REQ_MLEN(htx_sl) = sl.rq.m.len;
+       HTX_SL_REQ_ULEN(htx_sl) = sl.rq.u.len;
+       HTX_SL_REQ_VLEN(htx_sl) = sl.rq.v.len;
 
-       memcpy(htx_sl->rq.l,                             sl.rq.m.ptr, sl.rq.m.len);
-       memcpy(htx_sl->rq.l + sl.rq.m.len,               sl.rq.u.ptr, sl.rq.u.len);
-       memcpy(htx_sl->rq.l + sl.rq.m.len + sl.rq.u.len, sl.rq.v.ptr, sl.rq.v.len);
+       memcpy(HTX_SL_REQ_MPTR(htx_sl), sl.rq.m.ptr, sl.rq.m.len);
+       memcpy(HTX_SL_REQ_UPTR(htx_sl), sl.rq.u.ptr, sl.rq.u.len);
+       memcpy(HTX_SL_REQ_VPTR(htx_sl), sl.rq.v.ptr, sl.rq.v.len);
 }
 
 
 static void htx_set_blk_resline(struct htx *htx, struct htx_blk *blk, const union h1_sl sl)
 {
-       union htx_sl *htx_sl;
+       struct htx_sl *htx_sl;
 
        htx_sl = htx_get_blk_ptr(htx, blk);
-       htx_sl->st.status = sl.st.status;
+       htx_sl->info.res.status = sl.st.status;
 
-       htx_sl->st.v_len = sl.st.v.len;
-       htx_sl->st.c_len = sl.st.c.len;
-       htx_sl->st.r_len = sl.st.r.len;
+       HTX_SL_RES_VLEN(htx_sl) = sl.st.v.len;
+       HTX_SL_RES_CLEN(htx_sl) = sl.st.c.len;
+       HTX_SL_RES_RLEN(htx_sl) = sl.st.r.len;
 
-       memcpy(htx_sl->st.l,                             sl.st.v.ptr, sl.st.v.len);
-       memcpy(htx_sl->st.l + sl.st.v.len,               sl.st.c.ptr, sl.st.c.len);
-       memcpy(htx_sl->st.l + sl.st.v.len + sl.st.c.len, sl.st.r.ptr, sl.st.r.len);
+       memcpy(HTX_SL_RES_VPTR(htx_sl), sl.st.v.ptr, sl.st.v.len);
+       memcpy(HTX_SL_RES_CPTR(htx_sl), sl.st.c.ptr, sl.st.c.len);
+       memcpy(HTX_SL_RES_RPTR(htx_sl), sl.st.r.ptr, sl.st.r.len);
 }
 
 /* Replaces the request start line a new one. It returns the new block on
@@ -617,7 +617,7 @@ struct htx_blk *htx_replace_reqline(struct htx *htx, struct htx_blk *blk,
         if (type != HTX_BLK_REQ_SL)
                 return NULL;
 
-       size = sizeof(union htx_sl) + sl.rq.m.len + sl.rq.u.len + sl.rq.v.len;
+       size = sizeof(struct htx_sl) + sl.rq.m.len + sl.rq.u.len + sl.rq.v.len;
        blk = htx_new_blk_value(htx, blk, size);
        if (!blk)
                return NULL;
@@ -640,7 +640,7 @@ struct htx_blk *htx_replace_resline(struct htx *htx, struct htx_blk *blk,
         if (type != HTX_BLK_RES_SL)
                 return NULL;
 
-       size = sizeof(union htx_sl) + sl.rq.m.len + sl.rq.u.len + sl.rq.v.len;
+       size = sizeof(struct htx_sl) + sl.rq.m.len + sl.rq.u.len + sl.rq.v.len;
        blk = htx_new_blk_value(htx, blk, size);
        if (!blk)
                return NULL;
@@ -659,7 +659,7 @@ struct htx_blk *htx_add_reqline(struct htx *htx, const union h1_sl sl)
         struct htx_blk *blk;
        uint32_t size;
 
-       size = sizeof(union htx_sl) + sl.rq.m.len + sl.rq.u.len + sl.rq.v.len;
+       size = sizeof(struct htx_sl) + sl.rq.m.len + sl.rq.u.len + sl.rq.v.len;
 
         /* FIXME: check size (< 256MB) */
         blk = htx_add_blk(htx, HTX_BLK_REQ_SL, size);
@@ -679,7 +679,7 @@ struct htx_blk *htx_add_resline(struct htx *htx, const union h1_sl sl)
         struct htx_blk *blk;
        uint32_t size;
 
-       size = sizeof(union htx_sl) + sl.st.v.len + sl.st.c.len + sl.st.r.len;
+       size = sizeof(struct htx_sl) + sl.st.v.len + sl.st.c.len + sl.st.r.len;
 
         /* FIXME: check size (< 256MB) */
         blk = htx_add_blk(htx, HTX_BLK_RES_SL, size);
@@ -824,16 +824,16 @@ struct htx_blk *htx_add_data_before(struct htx *htx, const struct htx_blk *ref,
  * chunk <chk>. It returns 1 if data are successfully appended, otherwise it
  * returns 0.
  */
-int htx_reqline_to_str(const union htx_sl *sl, struct buffer *chk)
+int htx_reqline_to_str(const struct htx_sl *sl, struct buffer *chk)
 {
-       if (sl->rq.m_len + sl->rq.u_len + sl->rq.v_len + 4 > b_room(chk))
+       if (HTX_SL_LEN(sl) + 4 > b_room(chk))
                return 0;
 
-       chunk_memcat(chk, sl->rq.l, sl->rq.m_len);
+       chunk_memcat(chk, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl));
        chunk_memcat(chk, " ", 1);
-       chunk_memcat(chk, sl->rq.l + sl->rq.m_len, sl->rq.u_len);
+       chunk_memcat(chk, HTX_SL_REQ_UPTR(sl), HTX_SL_REQ_ULEN(sl));
        chunk_memcat(chk, " ", 1);
-       chunk_memcat(chk, sl->rq.l + sl->rq.m_len + sl->rq.u_len, sl->rq.v_len);
+       chunk_memcat(chk, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl));
        chunk_memcat(chk, "\r\n", 2);
 
        return 1;
@@ -843,16 +843,16 @@ int htx_reqline_to_str(const union htx_sl *sl, struct buffer *chk)
  * <chk>. It returns 1 if data are successfully appended, otherwise it
  * returns 0.
  */
-int htx_stline_to_str(const union htx_sl *sl, struct buffer *chk)
+int htx_stline_to_str(const struct htx_sl *sl, struct buffer *chk)
 {
-       if (sl->st.v_len + sl->st.c_len + sl->st.r_len + 4 > b_size(chk))
+       if (HTX_SL_LEN(sl) + 4 > b_size(chk))
                return 0;
 
-       chunk_memcat(chk, sl->st.l, sl->st.v_len);
+       chunk_memcat(chk, HTX_SL_RES_VPTR(sl), HTX_SL_RES_VLEN(sl));
        chunk_memcat(chk, " ", 1);
-       chunk_memcat(chk, sl->st.l + sl->st.v_len, sl->st.c_len);
+       chunk_memcat(chk, HTX_SL_RES_CPTR(sl), HTX_SL_RES_CLEN(sl));
        chunk_memcat(chk, " ", 1);
-       chunk_memcat(chk, sl->st.l + sl->st.v_len + sl->st.c_len, sl->st.r_len);
+       chunk_memcat(chk, HTX_SL_RES_RPTR(sl), HTX_SL_RES_RLEN(sl));
        chunk_memcat(chk, "\r\n", 2);
 
        return 1;
index 4d9db7fba4d9e70b324121d27ce4197eae3da9a3..37c0f8883b379989db55c9ec685a38783f19d10a 100644 (file)
@@ -432,11 +432,11 @@ static void h1_release(struct connection *conn)
 /* Parse the request version and set H1_MF_VER_11 on <h1m> if the version is
  * greater or equal to 1.1
  */
-static void h1_parse_req_vsn(struct h1m *h1m, const union htx_sl *sl)
+static void h1_parse_req_vsn(struct h1m *h1m, const struct htx_sl *sl)
 {
-       const char *p = sl->rq.l + sl->rq.m_len + sl->rq.u_len;
+       const char *p = HTX_SL_REQ_VPTR(sl);
 
-       if ((sl->rq.v_len == 8) &&
+       if ((HTX_SL_REQ_VLEN(sl) == 8) &&
            (*(p + 5) > '1' ||
             (*(p + 5) == '1' && *(p + 7) >= '1')))
                h1m->flags |= H1_MF_VER_11;
@@ -445,11 +445,11 @@ static void h1_parse_req_vsn(struct h1m *h1m, const union htx_sl *sl)
 /* Parse the response version and set H1_MF_VER_11 on <h1m> if the version is
  * greater or equal to 1.1
  */
-static void h1_parse_res_vsn(struct h1m *h1m, const union htx_sl *sl)
+static void h1_parse_res_vsn(struct h1m *h1m, const struct htx_sl *sl)
 {
-       const char *p = sl->rq.l;
+       const char *p = HTX_SL_RES_VPTR(sl);
 
-       if ((sl->st.v_len == 8) &&
+       if ((HTX_SL_RES_VLEN(sl) == 8) &&
            (*(p + 5) > '1' ||
             (*(p + 5) == '1' && *(p + 7) >= '1')))
                h1m->flags |= H1_MF_VER_11;
@@ -1205,7 +1205,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
 
        blk = htx_get_head_blk(chn_htx);
        while (!(h1s->flags & errflag) && blk) {
-               union htx_sl *sl;
+               struct htx_sl *sl;
                struct ist n, v;
                uint32_t sz = htx_get_blksz(blk);
 
@@ -1220,7 +1220,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                h1m_init_req(h1m);
                                h1m->flags |= H1_MF_NO_PHDR;
                                sl = htx_get_blk_ptr(chn_htx, blk);
-                               h1s->meth = sl->rq.meth;
+                               h1s->meth = sl->info.req.meth;
                                h1_parse_req_vsn(h1m, sl);
                                if (!htx_reqline_to_str(sl, tmp))
                                        goto copy;
@@ -1232,7 +1232,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
                                h1m_init_res(h1m);
                                h1m->flags |= H1_MF_NO_PHDR;
                                sl = htx_get_blk_ptr(chn_htx, blk);
-                               h1s->status = sl->st.status;
+                               h1s->status = sl->info.res.status;
                                h1_parse_res_vsn(h1m, sl);
                                if (!htx_stline_to_str(sl, tmp))
                                        goto copy;