part can be xferred
- HTX_XFER_HDRS_ONLY: Only the headers part is xferred
- - htx_xfer_blks() [DEPRECATED] transfers HTX blocks from an HTX message to
- another, stopping after the first block of a specified type is transferred
- or when a specific amount of bytes, including meta-data, was moved. If the
- tail block is a DATA block, it may be partially moved. All other block are
- transferred at once or kept. This function returns a mixed value, with the
- last block moved, or NULL if nothing was moved, and the amount of data
- transferred. When HEADERS or TRAILERS blocks must be transferred, this
- function transfers all of them. Otherwise, if it is not possible, it
- triggers an error. It is the caller responsibility to transfer all headers
- or trailers at once.
-
- htx_append_msg() append an HTX message to another one. All the message is
copied or nothing. So, if an error occurred, a rollback is performed. This
function returns 1 on success and 0 on error.
return ret;
}
-/* Transfer HTX blocks from <src> to <dst>, stopping once the first block of the
- * type <mark> is transferred (typically EOH or EOT) or when <count> bytes were
- * moved (including payload and meta-data). It returns the number of bytes moved
- * and the last HTX block inserted in <dst>.
- *
- * DEPRECATED
- */
-struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count,
- enum htx_blk_type mark)
-{
- struct htx_blk *blk, *dstblk;
- struct htx_blk *srcref, *dstref;
- struct ist v;
- enum htx_blk_type type;
- uint32_t max, sz, ret;
-
- ret = htx_used_space(dst);
- srcref = dstref = dstblk = NULL;
-
- /* blocks are not removed yet from <src> HTX message to be able to
- * rollback the transfer if all the headers/trailers are not copied.
- */
- for (blk = htx_get_head_blk(src); blk && count; blk = htx_get_next_blk(src, blk)) {
- type = htx_get_blk_type(blk);
- sz = htx_get_blksz(blk);
-
- /* Ignore unused block */
- if (type == HTX_BLK_UNUSED)
- continue;
-
- max = htx_get_max_blksz(dst, count);
- if (!max)
- break;
-
- switch (type) {
- case HTX_BLK_DATA:
- v = htx_get_blk_value(src, blk);
- v = isttrim(v, max);
- v.len = htx_add_data(dst, v);
- if (!v.len)
- goto stop;
- dstblk = htx_get_tail_blk(dst);
- count -= sizeof(*dstblk) + v.len;
- if (v.len != sz) {
- /* Partial xfer: don't remove <blk> from <src> but
- * resize its content */
- htx_cut_data_blk(src, blk, v.len);
- goto stop;
- }
- break;
- default:
- /* Only DATA blocks can be partially xferred */
- if (sz > max)
- goto stop;
- dstblk = htx_add_blk(dst, type, sz);
- if (!dstblk)
- goto stop;
- dstblk->info = blk->info;
- htx_memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz);
- count -= sizeof(*dstblk) + sz;
- break;
- }
-
- /* Save <blk> to <srcref> and <dstblk> to <dstref> when we start
- * to xfer headers or trailers. When EOH/EOT block is reached,
- * both are reset. It is mandatory to be able to rollback a
- * partial transfer.
- */
- if (!srcref && !dstref &&
- (type == HTX_BLK_REQ_SL || type == HTX_BLK_RES_SL || type == HTX_BLK_TLR)) {
- srcref = blk;
- dstref = dstblk;
- }
- else if (type == HTX_BLK_EOH || type == HTX_BLK_EOT)
- srcref = dstref = NULL;
-
- /* <mark> allows a copy of the block which matched, then stop */
- if (type == mark) {
- blk = htx_get_next_blk(src, blk);
- break;
- }
- }
- stop:
- if (unlikely(dstref)) {
- /* Headers or trailers part was partially xferred, so rollback
- * the copy by removing all block between <dstref> and <dstblk>,
- * both included. <dstblk> may be NULL.
- */
- while (dstref && dstref != dstblk)
- dstref = htx_remove_blk(dst, dstref);
- if (dstblk)
- htx_remove_blk(dst, dstblk);
-
- /* <dst> HTX message is empty, it means the headers or trailers
- * part is too big to be copied at once.
- */
- if (htx_is_empty(dst))
- src->flags |= HTX_FL_PARSING_ERROR;
- }
-
- /* Now, remove xferred blocks from <src> htx message */
- if (!blk && !srcref) {
- /* End of src reached, all blocks were consumed, drain all data */
- htx_drain(src, src->data);
- }
- else {
- /* Remove all block from the head to <blk>, or <srcref> if defined, excluded */
- srcref = (srcref ? srcref : blk);
- for (blk = htx_get_head_blk(src); blk && blk != srcref; blk = htx_remove_blk(src, blk));
- }
-
- if (htx_is_empty(src))
- dst->flags |= (src->flags & (HTX_FL_EOM|HTX_FL_PARSING_ERROR|HTX_FL_PROCESSING_ERROR));
-
- ret = htx_used_space(dst) - ret;
- return (struct htx_ret){.ret = ret, .blk = dstblk};
-}
-
/* Replaces an header by a new one. The new header can be smaller or larger than
* the old one. It returns the new block on success, otherwise it returns NULL.
* The header name is always lower cased.