prevblk = htx_get_prev_blk(htx, blk);
nextblk = htx_get_next_blk(htx, blk);
+ /* Move EOM flag on the previous block if any */
+ if (prevblk)
+ prevblk->flags |= (blk->flags & HTX_BLK_FL_EOM);
+
/* There is at least 2 used blocks, so (head != tail and tail > 0) */
type = htx_get_blk_type(blk);
sz = htx_get_blksz(tailblk);
/* Don't try to append data if the last inserted block is not of the
- * same type */
+ * same type or if it is the end of the message */
+ if (tailblk->flags & HTX_BLK_FL_EOM)
+ goto add_new_block;
if (htx_get_blk_type(tailblk) != HTX_BLK_DATA) {
if (htx_get_blk_type(tailblk) > HTX_BLK_DATA)
flags |= HTX_FL_UNORDERED;
goto stop;
}
last_dstblk->flags = blk->flags;
+ if (last_dstblk->flags & HTX_BLK_FL_EOM)
+ dst->flags |= HTX_FL_HAS_EOM;
break;
default:
last_dstblk->flags = blk->flags;
last_dstblk->info = blk->info;
htx_memcpy(htx_get_blk_ptr(dst, last_dstblk), htx_get_blk_ptr(src, blk), sz);
+ if (last_dstblk->flags & HTX_BLK_FL_EOM)
+ dst->flags |= HTX_FL_HAS_EOM;
last_dstblk_sz = sz;
count -= meta_sz + sz;
ret += meta_sz + sz;
}
}
- /* Everything was copied, transfer terminal HTX flags too */
+ /* Everything was copied, transfer HTX error flags too */
if (!blk) {
- dst->flags |= (src->flags & (HTX_FL_HAS_EOM|HTX_FL_PARSING_ERROR|HTX_FL_PROCESSING_ERROR));
+ dst->flags |= (src->flags & (HTX_FL_PARSING_ERROR|HTX_FL_PROCESSING_ERROR));
if (!(flags & HTX_XFER_KEEP_SRC_BLKS))
src->flags = 0;
}
goto rsv_new_block;
/* Don't try to append data if the last inserted block is not of the
- * same type */
+ * same type or if it is the end of the message */
+ if (tailblk->flags & HTX_BLK_FL_EOM)
+ goto rsv_new_block;
if (htx_get_blk_type(tailblk) != HTX_BLK_DATA) {
if (htx_get_blk_type(tailblk) > HTX_BLK_DATA)
flags |= HTX_FL_UNORDERED;
goto add_new_block;
/* Don't try to append data if the last inserted block is not of the
- * same type */
+ * same type or if it is the end of the message */
+ if (tailblk->flags & HTX_BLK_FL_EOM)
+ goto add_new_block;
if (htx_get_blk_type(tailblk) != HTX_BLK_DATA) {
if (htx_get_blk_type(tailblk) > HTX_BLK_DATA)
flags |= HTX_FL_UNORDERED;
return NULL;
for (pblk = htx_get_prev_blk(htx, blk); pblk; pblk = htx_get_prev_blk(htx, pblk)) {
- if (htx_get_blk_type(pblk) <= HTX_BLK_DATA)
+ if (htx_get_blk_type(pblk) <= HTX_BLK_DATA) {
+ blk->flags |= (pblk->flags & HTX_BLK_FL_EOM);
+ pblk->flags &= ~HTX_BLK_FL_EOM;
break;
+ }
/* Swap .addr and .info fields */
blk->flags ^= pblk->flags; pblk->flags ^= blk->flags; blk->flags ^= pblk->flags;
/* Moves the block <blk> just before the block <ref>. Both blocks must be in the
* HTX message <htx> and <blk> must be placed after <ref>. pointer to these
- * blocks are updated to remain valid after the move. */
+ * blocks are updated to remain valid after the move.
+ *
+ * It is the caller responsibility to take care the result remains valid.
+ */
void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk **ref)
{
struct htx_blk *cblk, *pblk;
for (pblk = htx_get_prev_blk(htx, cblk); pblk; pblk = htx_get_prev_blk(htx, pblk)) {
htx->flags |= HTX_FL_UNORDERED;
+ /* transfer EOM to <pblk> before swapping blocs */
+ if (cblk->flags & HTX_BLK_FL_EOM) {
+ pblk->flags |= HTX_BLK_FL_EOM;
+ cblk->flags &= ~HTX_BLK_FL_EOM;
+ }
+
/* Swap .flags, .addr and .info fields */
cblk->flags ^= pblk->flags; pblk->flags ^= cblk->flags; cblk->flags ^= pblk->flags;
cblk->addr ^= pblk->addr; pblk->addr ^= cblk->addr; cblk->addr ^= pblk->addr;
/* Append the HTX message <src> to the HTX message <dst>. It returns 1 on
* success and 0 on error. All the message or nothing is copied. If an error
* occurred, all blocks from <src> already appended to <dst> are truncated.
+ *
+ * It is the caller responsibility to take care the result remains valid.
*/
int htx_append_msg(struct htx *dst, const struct htx *src)
{