/*
 * internal HTTP message
 *
 * Copyright 2018 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <common/chunk.h>
#include <common/htx.h>

struct htx htx_empty = { .size = 0, .data = 0, .used = 0 };

/* Defragments an HTTP message, removing unused blocks and unwrapping blocks and
 * their contents. A temporary message is used to do so. This function never
 * fails. if <blk> is not NULL, we replace it by the new block address, after
 * the defragmentation. The new <blk> is returned.
 */
/* TODO: merge data blocks into one */
struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk)
{
	struct buffer *chunk = get_trash_chunk();
	struct htx *tmp = htxbuf(chunk);
	struct htx_blk *newblk, *oldblk;
	uint32_t new, old, blkpos;
	uint32_t addr, blksz;
	int32_t sl_off = -1;

	if (!htx->used)
		return NULL;

	blkpos = -1;

	new  = 0;
	addr = 0;
	tmp->size = htx->size;

	/* start from the head */
	for (old = htx_get_head(htx); old != -1; old = htx_get_next(htx, old)) {
		oldblk = htx_get_blk(htx, old);
		if (htx_get_blk_type(oldblk) == HTX_BLK_UNUSED) {
			htx->used--;
			continue;
		}

		newblk = htx_get_blk(tmp, new);
		newblk->addr = addr;
		newblk->info = oldblk->info;
		blksz = htx_get_blksz(oldblk);

		/* update the start-line offset */
		if (htx->sl_off == oldblk->addr)
			sl_off = addr;

		/* if <blk> is defined, set its new position */
		if (blk != NULL && blk == oldblk)
			blkpos = new;

		memcpy((void *)tmp->blocks + addr, htx_get_blk_ptr(htx, oldblk), blksz);
		new++;
		addr += blksz;

	} while (new < htx->used);

	htx->sl_off = sl_off;
	htx->wrap = htx->used;
	htx->front = htx->tail = new - 1;
	memcpy((void *)htx->blocks, (void *)tmp->blocks, htx->size);

	return ((blkpos == -1) ? NULL : htx_get_blk(htx, blkpos));
}

/* Reserves a new block in the HTTP message <htx> with a content of <blksz>
 * bytes. If there is not enough space, NULL is returned. Otherwise the reserved
 * block is returned and the HTTP message is updated. Space for this new block
 * is reserved in the HTTP message. But it is the caller responsibility to set
 * right info in the block to reflect the stored data.
 */
static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz)
{
	struct htx_blk *blk, *prevblk, *headblk, *frtblk;
	uint32_t used;
	uint32_t tail;
	uint32_t prev;
	uint32_t wrap;
	uint32_t head;
	int32_t headroom, tailroom;

	if (blksz > htx_free_data_space(htx))
		return NULL; /* full */

	if (!htx->used) {
		/* Empty message */
		htx->front = htx->tail = 0;
		htx->wrap  = htx->used = 1;
		blk = htx_get_blk(htx, htx->tail);
		blk->addr = 0;
		htx->data = blksz;
		return blk;
	}

	used = htx->used + 1;
	tail = htx->tail + 1;
	prev = htx->tail;
	wrap = htx->wrap;
	head = htx_get_head(htx);

	if (tail == wrap) {
		frtblk = htx_get_blk(htx, htx->front);

		/* Blocks don't wrap for now. We either need to push the new one
		 * on top of others or to defragement the table. */
		if (sizeof(htx->blocks[0]) * htx_pos_to_idx(htx, wrap+1) >= frtblk->addr + htx_get_blksz(frtblk))
			wrap++;
		else if (tail >= used) /* There is hole at the beginning */
			tail = 0;
		else {
			/* No more room, tail hits data. We have to realign the
			 * whole message. */
			goto defrag;
		}
	}
	else if (used >= wrap) {
		/* We have hit the tail, we need to reorganize the blocks. */
		goto defrag;
	}

	/* Now we have updated tail, used and wrap, we know that there is some
	 * available room at least from the protocol's perspective. This space
	 * is split in two areas :
	 *
	 *   1: the space between the beginning of the blocks table and the
	 *      front data's address. This space will only be used if data don't
	 *      wrap yet.

	 *   2: If the previous tail was the front block, the space between the
	 *      beginning of the message and the head data's address.
	 *      Otherwise, the space between the tail data's address and the
	 *      tail's one.
	 */
	prevblk = htx_get_blk(htx, prev);
	headblk = htx_get_blk(htx, head);
	if (prevblk->addr >= headblk->addr) {
		/* the area was contiguous */
		frtblk = htx_get_blk(htx, htx->front);
		tailroom = sizeof(htx->blocks[0]) * htx_pos_to_idx(htx, wrap) - (frtblk->addr + htx_get_blksz(frtblk));
		headroom = headblk->addr;

		if (tailroom >= (int32_t)blksz) {
			/* install upfront and update ->front */
			blk = htx_get_blk(htx, tail);
			blk->addr = frtblk->addr + htx_get_blksz(frtblk);
			htx->front = tail;
		}
		else if (headroom >= (int32_t)blksz) {
			blk = htx_get_blk(htx, tail);
			blk->addr = 0;
		}
		else {
			/* need to defragment the table before inserting upfront */
			goto defrag;
		}
	}
	else {
		/* it's already wrapped so we can't store anything in the tailroom */
		headroom = headblk->addr - (prevblk->addr + htx_get_blksz(prevblk));

		if (headroom >= (int32_t)blksz) {
			blk = htx_get_blk(htx, tail);
			blk->addr = prevblk->addr + htx_get_blksz(prevblk);
		}
		else {
		  defrag:
			/* need to defragment the table before inserting upfront */
			htx_defrag(htx, NULL);
			frtblk = htx_get_blk(htx, htx->front);
			wrap = htx->wrap + 1;
			tail = htx->tail + 1;
			used = htx->used + 1;
			blk = htx_get_blk(htx, tail);
			blk->addr = frtblk->addr + htx_get_blksz(frtblk);
			htx->front = tail;
		}
	}

	htx->wrap  = wrap;
	htx->tail  = tail;
	htx->used  = used;
	htx->data += blksz;
	return blk;
}

/* Adds a new block of type <type> in the HTTP message <htx>. Its content size
 * is passed but it is the caller responsibility to do the copy.
 */
struct htx_blk *htx_add_blk(struct htx *htx, enum htx_blk_type type, uint32_t blksz)
{
	struct htx_blk *blk;

	blk = htx_reserve_nxblk(htx, blksz);
	if (!blk)
		return NULL;

	blk->info = (type << 28);
	return blk;
}

/* Removes the block <blk> from the HTTP message <htx>. The function returns the
 * block following <blk> or NULL if <blk> is the last block or the last
 * inserted one.
 */
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 (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 */
	if (htx->used == 1/* || !htx->data */) {
		htx->front = htx->tail = 0;
		htx->wrap  = htx->used = 0;
		htx->data = 0;
		return NULL;
	}

	/* There is at least 2 blocks, so tail is always >= 0 */
	pos  = htx_get_blk_pos(htx, blk);
	head = htx_get_head(htx);
	blk  = NULL;
	next = pos + 1; /* By default retrun the next block */
	if (htx->tail + 1 == htx->wrap) {
		/* The HTTP message doesn't wrap */
		if (pos == head) {
			/* remove the head, so just return the new head */
			htx->used--;
			next = htx_get_head(htx);
		}
		else if (pos == htx->tail) {
			/* remove the tail. this was the last inserted block so
			 * return NULL. */
			htx->wrap--;
			htx->tail--;
			htx->used--;
			goto end;
		}
	}
	else {
		/* The HTTP message wraps */
		if (pos == htx->tail) {
			/* remove the tail. try to unwrap the message (pos == 0)
			 * and return NULL. */
			htx->tail = ((pos == 0) ? htx->wrap-1 : htx->tail-1);
			htx->used--;
			goto end;
		}
		else if (pos == head) {
			/* remove the head, try to unwrap the message (pos+1 ==
			 * wrap) and return the new head */
			htx->used--;
			if (pos + 1 == htx->wrap)
				htx->wrap = htx->tail + 1;
			next = htx_get_head(htx);
		}
	}

	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);
	return blk;
}

/* Truncate all blocks after the one containing the offset <offset>. This last
 * one is truncated too.
 */
void htx_truncate(struct htx *htx, uint32_t offset)
{
	struct htx_blk *blk;
	struct htx_ret htxret;

	htxret = htx_find_blk(htx, offset);
	blk = htxret.blk;
	if (blk && htxret.ret) {
		uint32_t sz = htx_get_blksz(blk);

		htx_set_blk_value_len(blk, sz - htxret.ret);
		blk = htx_get_next_blk(htx, blk);
	}
	while (blk)
		blk = htx_remove_blk(htx, blk);
}

/* Drain <count> bytes from the HTX message <htx>. DATA blocks will be cut if
 * necessary. Others blocks will be removed at once if <count> is large
 * enough. The function returns an htx_ret with the first block remaing in the
 * messsage and the amount of data drained. If everything is removed,
 * htx_ret.blk is set to NULL.
 */
struct htx_ret htx_drain(struct htx *htx, uint32_t count)
{
	struct htx_blk *blk;
	struct htx_ret htxret = { .blk = NULL, .ret = 0 };

	blk = htx_get_head_blk(htx);
	while (count && blk) {
		uint32_t sz = htx_get_blksz(blk);
		enum htx_blk_type type = htx_get_blk_type(blk);

		/* Ingore unused block */
		if (type == HTX_BLK_UNUSED)
			goto next;

		if (sz > count) {
			if (type == HTX_BLK_DATA) {
				htx_cut_data_blk(htx, blk, count);
				htxret.ret += count;
			}
			break;
		}
		count -= sz;
		htxret.ret += sz;
	  next:
		blk = htx_remove_blk(htx, blk);
	}
	htxret.blk = blk;

	return htxret;
}

/* Tries to append data to the last inserted block, if the type matches and if
 * there is enough non-wrapping space. Only DATA content can be appended. If the
 * append fails, a new block is inserted. If an error occurred, NULL is
 * returned. Otherwise, on success, the updated block (or the new one) is
 * returned.
*/
static struct htx_blk *htx_append_blk_value(struct htx *htx, enum htx_blk_type type,
					    const struct ist data)
{
	struct htx_blk *blk, *tailblk, *headblk, *frtblk;
	struct ist v;
	int32_t room;

	if (!htx->used)
		goto add_new_block;

	/* Not enough space to store data */
	if (data.len > htx_free_data_space(htx))
		return NULL;

	/* Append only DATA */
	if (type != HTX_BLK_DATA)
		goto add_new_block;

	/* get the tail and head block */
	tailblk = htx_get_tail_blk(htx);
	headblk = htx_get_head_blk(htx);
	if (tailblk == NULL || headblk == NULL)
		goto add_new_block;

	/* Don't try to append data if the last inserted block is not of the
	 * same type */
	if (type != htx_get_blk_type(tailblk))
		goto add_new_block;

	/*
	 * Same type and enough space: append data
	 */
	frtblk = htx_get_blk(htx, htx->front);
	if (tailblk->addr >= headblk->addr) {
		if (htx->tail != htx->front)
			goto add_new_block;
		room = sizeof(htx->blocks[0]) * htx_pos_to_idx(htx, htx->tail) - (frtblk->addr + htx_get_blksz(frtblk));
	}
	else
		room = headblk->addr - (tailblk->addr + htx_get_blksz(tailblk));

	if (room < (int32_t)data.len)
		tailblk = htx_defrag(htx, tailblk);

  append_data:
	/* get the value of the tail block */
	/* FIXME: check v.len + data.len < 256MB */
	v = htx_get_blk_value(htx, tailblk);

	/* Append data and update the block itself */
	memcpy(v.ptr + v.len, data.ptr, data.len);
	htx_set_blk_value_len(tailblk, v.len + data.len);

	/* Update HTTP message */
	htx->data += data.len;

	return tailblk;

  add_new_block:
	/* FIXME: check tlr.len (< 256MB) */
	blk = htx_add_blk(htx, type, data.len);
	if (!blk)
		return NULL;

	blk->info += data.len;
	memcpy(htx_get_blk_ptr(htx, blk), data.ptr, data.len);
	return blk;
}

/* Replaces a value part of a block by a new one. The new part can be smaller or
 * larger than the old one. This function works for any kind of block with
 * attached data. It returns the new block on success, otherwise it returns
 * NULL.
 */
struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk,
				      const struct ist old, const struct ist new)
{
	struct buffer *tmp;
	struct ist n, v;
	int32_t delta;

	n = htx_get_blk_name(htx, blk);
	v = htx_get_blk_value(htx, blk);

	delta = new.len - old.len;

	/* easy case, new data are smaller, so replace it in-place */
	if (delta <= 0) {
		memcpy(old.ptr, new.ptr, new.len);
		if (old.len != v.len)
			memmove(old.ptr + new.len, old.ptr + old.len, (v.ptr + v.len) - (old.ptr + old.len));
		htx_set_blk_value_len(blk, v.len + delta);
		htx->data += delta;
		return blk;
	}

	/* we need to allocate more space to store the new header value */
	if (delta > htx_free_space(htx))
		return NULL; /* not enough space */

	/*
	 * Copy the new header in a temp buffer
	 */
	tmp = get_trash_chunk();

	/*     1. copy the header name */
	chunk_memcat(tmp, n.ptr, n.len);

	/*     2. copy value before old part, if any */
	if (old.ptr != v.ptr)
		chunk_memcat(tmp, v.ptr, old.ptr - v.ptr);

	/*     3. copy new value */
	chunk_memcat(tmp, new.ptr, new.len);

	/*     4. copy value after old part if any */
	if (old.len != v.len)
		chunk_memcat(tmp, old.ptr + old.len, (v.ptr + v.len) - (old.ptr + old.len));


	/* Expand the block size. But data are not copied yet. Then defragment
	 * the HTX message.
	 */
	htx_set_blk_value_len(blk, v.len + delta);
	htx->data += delta;
	blk = htx_defrag(htx, blk);

	/* Finaly, copy data. */
	memcpy(htx_get_blk_ptr(htx, blk), tmp->area, tmp->data);

	return blk;
}

/* Transfer HTX blocks from <src> to <dst>, stopping on the first block of the
 * type <mark> (typically EOH, EOD or EOM) or when <count> bytes of data were
 * moved. It returns the number of bytes of data moved and the last HTX block
 * inserted in <dst>.
 */
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;
	enum htx_blk_type type;
	uint32_t	  info, max, sz, ret;

	ret = 0;
	blk = htx_get_blk(src, htx_get_head(src));
	dstblk = NULL;
	while (blk && ret <= count) {
		type = htx_get_blk_type(blk);

		/* Ingore unused block */
		if (type == HTX_BLK_UNUSED)
			goto next;

		sz = htx_get_blksz(blk);
		if (!sz) {
			dstblk = htx_reserve_nxblk(dst, 0);
			if (!dstblk)
				break;
			dstblk->info = blk->info;
			goto next;
		}

		info = blk->info;
		max = htx_free_data_space(dst);
		if (max > count - ret)
			max = count - ret;
		if (sz > max) {
			sz = max;
			info = (type << 28) + sz;
			/* Headers and pseudo headers must be fully copied  */
			if (type != HTX_BLK_DATA || !sz)
				break;
		}

		dstblk = htx_reserve_nxblk(dst, sz);
		if (!dstblk)
			break;
		dstblk->info = info;
		memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz);

		ret += sz;
		if (blk->info != info) {
			/* Partial move: don't remove <blk> from <src> but
			 * resize its content */
			blk->addr += sz;
			htx_set_blk_value_len(blk, htx_get_blksz(blk) - sz);
			src->data -= sz;
			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)
			break;

	}

	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.
 */
struct htx_blk *htx_replace_header(struct htx *htx, struct htx_blk *blk,
				   const struct ist name, const struct ist value)
{
	enum htx_blk_type type;
	int32_t delta;

	type = htx_get_blk_type(blk);
	if (type != HTX_BLK_HDR)
		return NULL;

	delta = name.len + value.len - htx_get_blksz(blk);

	/* easy case, new value is smaller, so replace it in-place */
	if (delta <= 0) {
		blk->info = (type << 28) + (value.len << 8) + name.len;
		htx->data += delta;
		goto copy;
	}

	/* we need to allocate more space to store the new value */
	if (delta > htx_free_space(htx))
		return NULL; /* not enough space */

	/* Expand the block size. But data are not copied yet. Then defragment
	 * the HTX message.
	 */
	blk->info = (type << 28) + (value.len << 8) + name.len;
	htx->data += delta;
	blk = htx_defrag(htx, blk);

  copy:
	/* Finaly, copy data. */
	ist2bin_lc(htx_get_blk_ptr(htx, blk), name);
	memcpy(htx_get_blk_ptr(htx, blk) + name.len, value.ptr, value.len);
	return blk;
}

/* Replaces the parts of the start-line. It returns the new start-line on
 * success, otherwise it returns NULL. It is the caller responsibility to update
 * sl->info, if necessary.
 */
struct htx_sl *htx_replace_stline(struct htx *htx, struct htx_blk *blk, const struct ist p1,
				  const struct ist p2, const struct ist p3)
{
	struct htx_sl *sl;
	struct htx_sl tmp; /* used to save sl->info and sl->flags */
	enum htx_blk_type type;
	uint32_t size;
	int32_t delta;

	type = htx_get_blk_type(blk);
	if (type != HTX_BLK_REQ_SL && type != HTX_BLK_RES_SL)
		return NULL;

	/* Save start-line info and flags */
	sl = htx_get_blk_ptr(htx, blk);
	tmp.info = sl->info;
	tmp.flags = sl->flags;
	if (htx->sl_off == blk->addr)
		htx->sl_off = -1;


	size = sizeof(*sl) + p1.len + p2.len + p3.len;
	delta = size - htx_get_blksz(blk);

	/* easy case, new data are smaller, so replace it in-place */
	if (delta <= 0) {
		htx_set_blk_value_len(blk, size);
		htx->data += delta;
		goto copy;
	}

	/* we need to allocate more space to store the new value */
	if (delta > htx_free_space(htx))
		return NULL; /* not enough space */

	/* Expand the block size. But data are not copied yet. Then defragment
	 * the HTX message.
	 */
	htx_set_blk_value_len(blk, size);
	htx->data += delta;
	blk = htx_defrag(htx, blk);

  copy:
	/* Restore start-line info and flags and copy parts of the start-line */
	sl = htx_get_blk_ptr(htx, blk);
	sl->info = tmp.info;
	sl->flags = tmp.flags;
	if (htx->sl_off == -1)
		htx->sl_off = blk->addr;

	HTX_SL_P1_LEN(sl) = p1.len;
	HTX_SL_P2_LEN(sl) = p2.len;
	HTX_SL_P3_LEN(sl) = p3.len;

	memcpy(HTX_SL_P1_PTR(sl), p1.ptr, p1.len);
	memcpy(HTX_SL_P2_PTR(sl), p2.ptr, p2.len);
	memcpy(HTX_SL_P3_PTR(sl), p3.ptr, p3.len);

	return sl;
}

/* Add a new start-line. It returns it on success, otherwise it returns NULL. It
 * is the caller responsibility to set sl->info, if necessary.
 */
struct htx_sl *htx_add_stline(struct htx *htx, enum htx_blk_type type, unsigned int flags,
			      const struct ist p1, const struct ist p2, const struct ist p3)
{
	struct htx_blk *blk;
	struct htx_sl  *sl;
	uint32_t size;

	if (type != HTX_BLK_REQ_SL && type != HTX_BLK_RES_SL)
		return NULL;

	size = sizeof(*sl) + p1.len + p2.len + p3.len;

	/* FIXME: check size (< 256MB) */
	blk = htx_add_blk(htx, type, size);
	if (!blk)
		return NULL;
	blk->info += size;

	sl = htx_get_blk_ptr(htx, blk);
	if (htx->sl_off == -1)
		htx->sl_off = blk->addr;

	sl->flags = flags;

	HTX_SL_P1_LEN(sl) = p1.len;
	HTX_SL_P2_LEN(sl) = p2.len;
	HTX_SL_P3_LEN(sl) = p3.len;

	memcpy(HTX_SL_P1_PTR(sl), p1.ptr, p1.len);
	memcpy(HTX_SL_P2_PTR(sl), p2.ptr, p2.len);
	memcpy(HTX_SL_P3_PTR(sl), p3.ptr, p3.len);

	return sl;
}

/* Adds an HTX block of type HDR in <htx>. It returns the new block on
 * success. Otherwise, it returns NULL. The header name is always lower cased.
 */
struct htx_blk *htx_add_header(struct htx *htx, const struct ist name,
			       const struct ist value)
{
	struct htx_blk *blk;

	/* FIXME: check name.len (< 256B) and value.len (< 1MB) */
	blk = htx_add_blk(htx, HTX_BLK_HDR, name.len + value.len);
	if (!blk)
		return NULL;

	blk->info += (value.len << 8) + name.len;
	ist2bin_lc(htx_get_blk_ptr(htx, blk), name);
	memcpy(htx_get_blk_ptr(htx, blk)  + name.len, value.ptr, value.len);
	return blk;
}

/* Adds an HTX block of type <type> in <htx>, of size <blksz>. It returns the
 * new block on success. Otherwise, it returns NULL. The caller is responsible
 * for filling the block itself.
 */
struct htx_blk *htx_add_blk_type_size(struct htx *htx, enum htx_blk_type type, uint32_t blksz)
{
	struct htx_blk *blk;

	blk = htx_add_blk(htx, type, blksz);
	if (!blk)
		return NULL;

	blk->info += blksz;
	return blk;
}

struct htx_blk *htx_add_all_headers(struct htx *htx, const struct http_hdr *hdrs)
{
	int i;

	for (i = 0; hdrs[i].n.len; i++) {
		if (!htx_add_header(htx, hdrs[i].n, hdrs[i].v))
			return NULL;
	}
	return htx_add_endof(htx, HTX_BLK_EOH);
}
/* Adds an HTX block of type PHDR in <htx>. It returns the new block on
 * success. Otherwise, it returns NULL.
 */
struct htx_blk *htx_add_pseudo_header(struct htx *htx,  enum htx_phdr_type phdr,
				      const struct ist value)
{
	struct htx_blk *blk;

	/* FIXME: check value.len ( < 1MB) */
	blk = htx_add_blk(htx, HTX_BLK_PHDR, value.len);
	if (!blk)
		return NULL;

	blk->info += (value.len << 8) + phdr;
	memcpy(htx_get_blk_ptr(htx, blk), value.ptr, value.len);
	return blk;
}

/* Adds an HTX block of type EOH,EOD or EOM in <htx>. It returns the new block
 * on success. Otherwise, it returns NULL.
 */
struct htx_blk *htx_add_endof(struct htx *htx, enum htx_blk_type type)
{
	struct htx_blk *blk;

	blk = htx_add_blk(htx, type, 1);
	if (!blk)
		return NULL;

	blk->info += 1;
	return blk;
}


/* Adds an HTX block of type DATA in <htx>. It first tries to append data if
 * possible. It returns the new block on success. Otherwise, it returns NULL.
 */
struct htx_blk *htx_add_data(struct htx *htx, const struct ist data)
{
	return htx_append_blk_value(htx, HTX_BLK_DATA, data);
}

/* Adds an HTX block of type TLR in <htx>. It returns the new block on
 * success. Otherwise, it returns NULL.
 */
struct htx_blk *htx_add_trailer(struct htx *htx, const struct ist tlr)
{
	struct htx_blk *blk;

	/* FIXME: check tlr.len (< 256MB) */
	blk = htx_add_blk(htx, HTX_BLK_TLR, tlr.len);
	if (!blk)
		return NULL;

	blk->info += tlr.len;
	memcpy(htx_get_blk_ptr(htx, blk), tlr.ptr, tlr.len);
	return blk;
}

struct htx_blk *htx_add_data_before(struct htx *htx, const struct htx_blk *ref,
				    const struct ist data)
{
	struct htx_blk *blk;
	int32_t prev;

	/* FIXME: check data.len (< 256MB) */
	blk = htx_add_blk(htx, HTX_BLK_DATA, data.len);
	if (!blk)
		return NULL;

	blk->info += data.len;
	memcpy(htx_get_blk_ptr(htx, blk), data.ptr, data.len);

	for (prev = htx_get_prev(htx, htx->tail); prev != -1; prev = htx_get_prev(htx, prev)) {
		struct htx_blk *pblk = htx_get_blk(htx, prev);

		/* Swap .addr and .info fields */
		blk->addr ^= pblk->addr; pblk->addr ^= blk->addr; blk->addr ^= pblk->addr;
		blk->info ^= pblk->info; pblk->info ^= blk->info; blk->info ^= pblk->info;

		if (blk->addr == pblk->addr)
			blk->addr += htx_get_blksz(pblk);
		htx->front = prev;

		if (pblk == ref)
			break;
		blk = pblk;
	}

	if (htx_get_blk_pos(htx, blk) != htx->front)
		htx_defrag(htx, NULL);

	return blk;
}

/* Appends the H1 representation of the request line block <blk> to the
 * chunk <chk>. It returns 1 if data are successfully appended, otherwise it
 * returns 0.
 */
int htx_reqline_to_h1(const struct htx_sl *sl, struct buffer *chk)
{
	if (HTX_SL_LEN(sl) + 4 > b_room(chk))
		return 0;

	chunk_memcat(chk, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl));
	chunk_memcat(chk, " ", 1);
	chunk_memcat(chk, HTX_SL_REQ_UPTR(sl), HTX_SL_REQ_ULEN(sl));
	chunk_memcat(chk, " ", 1);
	if (sl->flags & HTX_SL_F_VER_11)
		chunk_memcat(chk, "HTTP/1.1", 8);
	else
		chunk_memcat(chk, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl));

	chunk_memcat(chk, "\r\n", 2);

	return 1;
}

/* Appends the H1 representation of the status line block <blk> to the chunk
 * <chk>. It returns 1 if data are successfully appended, otherwise it
 * returns 0.
 */
int htx_stline_to_h1(const struct htx_sl *sl, struct buffer *chk)
{
	if (HTX_SL_LEN(sl) + 4 > b_size(chk))
		return 0;

	if (sl->flags & HTX_SL_F_VER_11)
		chunk_memcat(chk, "HTTP/1.1", 8);
	else
		chunk_memcat(chk, HTX_SL_RES_VPTR(sl), HTX_SL_RES_VLEN(sl));
	chunk_memcat(chk, " ", 1);
	chunk_memcat(chk, HTX_SL_RES_CPTR(sl), HTX_SL_RES_CLEN(sl));
	chunk_memcat(chk, " ", 1);
	chunk_memcat(chk, HTX_SL_RES_RPTR(sl), HTX_SL_RES_RLEN(sl));
	chunk_memcat(chk, "\r\n", 2);

	return 1;
}

/* Appends the H1 representation of the header block <blk> to the chunk
 * <chk>. It returns 1 if data are successfully appended, otherwise it returns
 * 0.
 */
int htx_hdr_to_h1(const struct ist n, const struct ist v, struct buffer *chk)
{
	if (n.len + v.len + 4 > b_room(chk))
		return 0;

	chunk_memcat(chk, n.ptr, n.len);
	chunk_memcat(chk, ": ", 2);
	chunk_memcat(chk, v.ptr, v.len);
	chunk_memcat(chk, "\r\n", 2);

	return 1;
}

/* Appends the H1 representation of the data block <blk> to the chunk
 * <chk>. If <chunked> is non-zero, it emits HTTP/1 chunk-encoded data. It
 * returns 1 if data are successfully appended, otherwise it returns 0.
 */
int htx_data_to_h1(const struct ist data, struct buffer *chk, int chunked)
{
	if (chunked) {
		uint32_t chksz;
		char     tmp[10];
		char    *beg, *end;

		chksz = data.len;

		beg = end = tmp+10;
		*--beg = '\n';
		*--beg = '\r';
		do {
			*--beg = hextab[chksz & 0xF];
		} while (chksz >>= 4);

		if (data.len + (end - beg) + 2 > b_room(chk))
			return 0;
		chunk_memcat(chk, beg, end - beg);
		chunk_memcat(chk, data.ptr, data.len);
		chunk_memcat(chk, "\r\n", 2);
	}
	else {
		if (!chunk_memcat(chk, data.ptr, data.len))
			return 0;
	}

	return 1;
}

/* Appends the h1 representation of the trailer block <blk> to the chunk
 * <chk>. It returns 1 if data are successfully appended, otherwise it returns
 * 0.
 */
int htx_trailer_to_h1(const struct ist tlr, struct buffer *chk)
{
	/* FIXME: be sure the CRLF is here or remove it when inserted */
	if (!chunk_memcat(chk, tlr.ptr, tlr.len))
		return 0;
	return 1;
}
