diff --git a/include/proto/htx.h b/include/proto/htx.h index e618a20222..296ff4df55 100644 --- a/include/proto/htx.h +++ b/include/proto/htx.h @@ -138,6 +138,17 @@ static inline const struct ist htx_sl_res_reason(const struct htx_sl *sl) 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 */ static inline uint32_t htx_pos_to_idx(const struct htx *htx, uint32_t pos) { @@ -421,6 +432,7 @@ static inline struct ist htx_get_blk_name(const struct htx *htx, const struct ht return ret; } + /* Returns the value of the block , depending on its type. If there is no * value, an empty one is retruned. */ @@ -512,6 +524,7 @@ static inline void htx_reset(struct htx *htx) 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 . */ diff --git a/include/types/htx.h b/include/types/htx.h index c709619710..6d64c132e0 100644 --- a/include/types/htx.h +++ b/include/types/htx.h @@ -152,6 +152,9 @@ struct htx { 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 85118cf4bb..a57e1e8e78 100644 --- a/src/htx.c +++ b/src/htx.c @@ -53,6 +53,10 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk) new++; addr += blksz; + /* update the start-line offset */ + if (htx->sl_off == oldblk->addr) + htx->sl_off = addr; + /* if is defined, set its new location */ if (blk != NULL && blk == oldblk) blk = newblk; @@ -206,12 +210,15 @@ struct htx_blk *htx_add_blk(struct htx *htx, enum htx_blk_type type, uint32_t bl */ 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 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk) } 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 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, 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 @@ static void htx_set_blk_reqline(struct htx *htx, struct htx_blk *blk, const unio 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 @@ static void htx_set_blk_resline(struct htx *htx, struct htx_blk *blk, const unio 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 @@ struct htx_blk *htx_replace_reqline(struct htx *htx, struct htx_blk *blk, 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 @@ struct htx_blk *htx_replace_resline(struct htx *htx, struct htx_blk *blk, 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)