MINOR: htx: Add the start-line offset for the HTX message in the HTX structure

If there is no start-line, this offset is set to -1. Otherwise, it is the
relative address where the start-line is stored in the data block. When the
start-line is added, replaced or removed, this offset is updated accordingly. On
remove, if the start-line is no set and if the next block is a start-line, the
offset is updated. Finally, when an HTX structure is defragmented, the offset is
also updated accordingly.
diff --git a/include/proto/htx.h b/include/proto/htx.h
index e618a20..296ff4d 100644
--- a/include/proto/htx.h
+++ b/include/proto/htx.h
@@ -138,6 +138,17 @@
 	return htx_sl_p3(sl);
 }
 
+/* Returns the HTX start-line if set, otherwise it returns NULL. */
+static inline struct htx_sl *htx_get_stline(struct htx *htx)
+{
+	struct htx_sl *sl = NULL;
+
+	if (htx->sl_off != -1)
+		sl = ((void *)htx->blocks + htx->sl_off);
+
+	return 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)
 {
@@ -421,6 +432,7 @@
         return ret;
 }
 
+
 /* Returns the value of the block <blk>, depending on its type. If there is no
  * value, an empty one is retruned.
  */
@@ -512,6 +524,7 @@
         htx->data = htx->used = htx->tail = htx->wrap  = htx->front = 0;
 	htx->extra = 0;
 	htx->flags = HTX_FL_NONE;
+	htx->sl_off = -1;
 }
 
 /* Returns an HTX message using the buffer <buf>. */
diff --git a/include/types/htx.h b/include/types/htx.h
index c709619..6d64c13 100644
--- a/include/types/htx.h
+++ b/include/types/htx.h
@@ -152,6 +152,9 @@
 	uint64_t extra;  /* known bytes amount remaining to receive */
 	uint32_t flags;  /* HTX_FL_* */
 
+	int32_t sl_off; /* Offset of the start-line of the HTTP message relatively to the beginning the
+			   data block. -1 if unset */
+
 	struct htx_blk blocks[0]; /* Blocks representing the HTTP message itself */
 };
 
diff --git a/src/htx.c b/src/htx.c
index 85118cf..a57e1e8 100644
--- a/src/htx.c
+++ b/src/htx.c
@@ -53,6 +53,10 @@
                 new++;
                 addr += blksz;
 
+		/* update the start-line offset */
+		if (htx->sl_off == oldblk->addr)
+			htx->sl_off = addr;
+
                 /* if <blk> is defined, set its new location */
                 if (blk != NULL && blk == oldblk)
                         blk = newblk;
@@ -206,12 +210,15 @@
  */
 struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk)
 {
+	enum htx_blk_type type = htx_get_blk_type(blk);
         uint32_t next, head, pos;
 
-        if (htx_get_blk_type(blk) != HTX_BLK_UNUSED) {
+        if (type != HTX_BLK_UNUSED) {
                 /* Mark the block as unused, decrement allocated size */
                 htx->data -= htx_get_blksz(blk);
                 blk->info = ((uint32_t)HTX_BLK_UNUSED << 28);
+		if (htx->sl_off == blk->addr)
+			htx->sl_off = -1;
         }
 
         /* This is the last block in use */
@@ -263,6 +270,12 @@
         }
 
         blk = htx_get_blk(htx, next);
+	if (htx->sl_off == -1) {
+		/* Try to update the start-line offset, if possible */
+		type = htx_get_blk_type(blk);
+		if (type == HTX_BLK_REQ_SL || type == HTX_BLK_RES_SL)
+			htx->sl_off = blk->addr;
+	}
   end:
         if (pos == htx->front)
                 htx->front = htx_find_front(htx);
@@ -487,6 +500,8 @@
 			break;
 		}
 
+		if (dst->sl_off == -1 && src->sl_off == blk->addr)
+			dst->sl_off = dstblk->addr;
 	  next:
 		blk = htx_remove_blk(src, blk);
 		if (type == mark)
@@ -578,6 +593,9 @@
 	htx_sl = htx_get_blk_ptr(htx, blk);
 	htx_sl->info.req.meth = sl.rq.meth;
 
+	if (htx->sl_off == -1)
+		htx->sl_off = blk->addr;
+
 	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;
@@ -595,6 +613,9 @@
 	htx_sl = htx_get_blk_ptr(htx, blk);
 	htx_sl->info.res.status = sl.st.status;
 
+	if (htx->sl_off == -1)
+		htx->sl_off = blk->addr;
+
 	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;
@@ -617,6 +638,9 @@
         if (type != HTX_BLK_REQ_SL)
                 return NULL;
 
+	if (htx->sl_off == blk->addr)
+		htx->sl_off = -1;
+
 	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)
@@ -640,6 +664,9 @@
         if (type != HTX_BLK_RES_SL)
                 return NULL;
 
+	if (htx->sl_off == blk->addr)
+		htx->sl_off = -1;
+
 	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)