From: Christopher Faulet Date: Wed, 19 Jun 2019 11:48:09 +0000 (+0200) Subject: DOC: htx: Update comments in HTX files X-Git-Tag: v2.1-dev2~382 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b21972061754a9e099b984aa4eb10dd9045aa64;p=thirdparty%2Fhaproxy.git DOC: htx: Update comments in HTX files This patch may be backported to 2.0 to have accurate comments. --- diff --git a/include/common/htx.h b/include/common/htx.h index ca2309b00a..27f0e5e64a 100644 --- a/include/common/htx.h +++ b/include/common/htx.h @@ -31,54 +31,104 @@ #include /* - * The internal representation of an HTTP message is a contiguous array - * containing both the blocks (htx_blk) and their contents. Blocks are stored - * starting from the end of the array while their contents are stored at the - * beginning. + * The internal representation of an HTTP message, called HTX, is a structure + * with useful information on the message followed by a contiguous array + * containing parts of the message, called blocks. A block is composed of + * metadata (htx_blk) and the associated payload. Blocks' metadata are stored + * starting from the end of the array while their payload are stored at the + * beginning. Blocks' metadata are often simply called blocks. it is a misuse of + * language that's simplify explainations. * - * As data are sent to the peer, blocks and contents are released at the - * edges. This free space is reused when no more space left. So blocks and - * contents may wrap, not necessarily the same time. * - * An HTTP block is as well a header as a body part or a trailer part. For all - * these types of block, a content is attached to the block. It can also be a - * mark, like the end-of-headers or end-of-message. For these blocks, there is - * no content but it count for a byte. It is important to not skip it when data - * are forwarded. An HTTP block is composed of 2 fields: + * +-----+---------------+------------------------------+--------------+ + * | HTX | PAYLOADS ==> | | <== HTX_BLKs | + * +-----+---------------+------------------------------+--------------+ + * ^ + * blocks[] (the beginning of the bocks array) + * + * + * The blocks part remains linear and sorted. You may think about it as an array + * with negative indexes. But, instead of using negative indexes, we use + * positive positions to identify a block. This position is then converted to a + * address relatively to the beginning of the blocks array. + * + * + * .....--+------------------------------+-----+-----+ + * | ... | BLK | BLK | + * .....--+------------------------------+-----+-----+ + * ^ ^ + * Addr of the block Addr of the block + * at the position 1 at the position 0 + * + * + * The payloads part is a raw space that may wrap. You never access to a block's + * payload directly. Instead you get a block to retrieve the address of its + * payload. When no more space left between blocks and payloads parts, the free + * space at the beginning, if any, is used. + * + * + * +----------- WRAPPING ------------------------+ + * | | + * V | + * +-----+-------------+---------------+---------------++--------------+ + * | HTX | PAYLOAD ==> | | PAYLOADS ==X || X== HTX_BLKs | + * +-----+-------------+---------------+---------------++--------------+ + * + * + * The blocks part, on its side, never wrap. If we have no space to allocate a + * new block and if there is a hole at the beginning of the blocks part (so at + * the end of the blocks array), we move back all blocks.x + * + * + * ...+--------------+----------+ blocks ...+----------+--------------+ + * | X== HTX_BLKS | | defrag | | <== HTX_BLKS | + * ...+--------------+----------+ =====> ...+----------+--------------+ + * + * + * At the end, if payload wrapping or blocks defragmenation is not enough, some + * free space may be get back with a full defragmenation. This way, the holes in + * the middle are not reusable but count in the available free space. The only + * way to reuse this lost space is to fully defragmenate the HTX message. + * + * - * - + * + * An HTX block is as well a header as a body part or a trailer. For all these + * types of block, a payload is attached to the block. It can also be a mark, + * like the end-of-headers or end-of-message. For these blocks, there is no + * payload but it count for a byte. It is important to not skip it when data are + * forwarded. Metadata of an HTX block are composed of 2 fields : * * - .info : It a 32 bits field containing the block's type on 4 bits - * followed by content' length. See below for details. + * followed by the payload length. See below for details. * - * - .addr : The content's address, if any, relatively to the beginning the - * array used to store the HTTP message itself. + * - .addr : The payload's address, if any, relatively to the beginning the + * array used to store the HTX message itself. * - * htx_blk.info representation: + * htx_blk.info representation : * * 0b 0000 0000 0000 0000 0000 0000 0000 0000 * ---- ------------------------ --------- - * type value (1 MB max) name length (header) + * type value (1 MB max) name length (header/trailer) * ---------------------------------- * data length (256 MB max) - * (body, method, path, version, status, reason, trailers) + * (body, method, path, version, status, reason) * - * types: + * types : * - 0000 = request start-line * - 0001 = response start-line * - 0010 = header * - 0011 = pseudo-header ou "special" header * - 0100 = end-of-headers * - 0101 = data - * - 0110 = end-of-data - * - 0111 = trailer + * - 0110 = trailer + * - 0111 = end-of-trailers * - 1000 = end-of-message * ... - * - 1101 = out-of-band - * - 1110 = error * - 1111 = unused * */ -/*HTX start-line flags */ +/* HTX start-line flags */ #define HTX_SL_F_NONE 0x00000000 #define HTX_SL_F_IS_RESP 0x00000001 /* It is the response start-line (unset means the request one) */ #define HTX_SL_F_XFER_LEN 0x00000002 /* The message xfer size can be dertermined */ @@ -93,11 +143,11 @@ /* HTX flags */ #define HTX_FL_NONE 0x00000000 -#define HTX_FL_PARSING_ERROR 0x00000001 -#define HTX_FL_UPGRADE 0x00000002 +#define HTX_FL_PARSING_ERROR 0x00000001 /* Set when a parsing error occurred */ +#define HTX_FL_UPGRADE 0x00000002 /* Set when an upgrade is in progress */ -/* HTTP block's type (max 15). */ +/* HTX block's type (max 15). */ enum htx_blk_type { HTX_BLK_REQ_SL = 0, /* Request start-line */ HTX_BLK_RES_SL = 1, /* Response start-line */ @@ -111,17 +161,19 @@ enum htx_blk_type { HTX_BLK_UNUSED = 15, /* unused/removed block */ }; -/* One HTTP block descriptor */ +/* One HTX block descriptor */ struct htx_blk { - uint32_t addr; /* relative storage address of a data block */ - uint32_t info; /* information about data stored */ + uint32_t addr; /* relative storage address of the block's payload */ + uint32_t info; /* information about the block (type, length) */ }; +/* Composite return value used by some HTX functions */ struct htx_ret { - int32_t ret; - struct htx_blk *blk; + int32_t ret; /* A numerical value */ + struct htx_blk *blk; /* An HTX block */ }; +/* HTX start-line */ struct htx_sl { unsigned int flags; /* HTX_SL_F_* */ union { @@ -135,8 +187,9 @@ struct htx_sl { /* XXX 2 bytes unused */ - int32_t hdrs_bytes; /* Bytes held by all headers from this start-line - * to the corresponding EOH. -1 if unknown */ + int32_t hdrs_bytes; /* Bytes held by all headers, as seen by the mux + * during parsing, from this start-line to the + * corresponding EOH. -1 if unknown */ unsigned int len[3]; /* length of differnt parts of the start-line */ char l[0]; @@ -150,8 +203,8 @@ struct htx { * i.e. [ used * sizeof(struct htx_blk *) ] */ uint32_t used; /* number of blocks in use */ - uint32_t tail; /* last inserted block */ - uint32_t head; /* older inserted block */ + uint32_t tail; /* newest inserted block. -1 if the HTX message is empty */ + uint32_t head; /* oldest inserted block. -1 if the HTX message is empty */ uint32_t tail_addr; /* start address of the free space in front of the the blocks table */ uint32_t head_addr; /* start address of the free space at the beginning */ @@ -205,7 +258,7 @@ int htx_hdr_to_h1(const struct ist n, const struct ist v, struct buffer *chk); int htx_data_to_h1(const struct ist data, struct buffer *chk, int chunked); /* Functions and macros to get parts of the start-line or legnth of these - * parts + * parts. Request and response start-lines are both composed of 3 parts. */ #define HTX_SL_LEN(sl) ((sl)->len[0] + (sl)->len[1] + (sl)->len[2]) @@ -276,19 +329,21 @@ static inline struct ist htx_sl_res_reason(const struct htx_sl *sl) return htx_sl_p3(sl); } -/* Returns the array index of a block given its position */ +/* Converts a position to the corresponding relative address */ static inline uint32_t htx_pos_to_idx(const struct htx *htx, uint32_t pos) { return ((htx->size / sizeof(htx->blocks[0])) - pos - 1); } -/* Returns the position of the block */ +/* Returns the position of the block . It is the caller responsibility to + * be sure is part of . */ static inline uint32_t htx_get_blk_pos(const struct htx *htx, const struct htx_blk *blk) { return (htx->blocks + (htx->size / sizeof(htx->blocks[0])) - blk - 1); } -/* Returns the block at the position */ +/* Returns the block at the position . It is the caller responsibility to + * be sure the block at the position exists. */ static inline struct htx_blk *htx_get_blk(const struct htx *htx, uint32_t pos) { return ((struct htx_blk *)(htx->blocks) + htx_pos_to_idx(htx, pos)); @@ -532,8 +587,8 @@ static inline void *htx_get_blk_ptr(const struct htx *htx, const struct htx_blk return ((void *)htx->blocks + blk->addr); } -/* Returns the name of the block , only if it is a header. Otherwise it - * returns an empty name. +/* Returns the name of the block , only if it is a header or a + * trailer. Otherwise it returns an empty string. */ static inline struct ist htx_get_blk_name(const struct htx *htx, const struct htx_blk *blk) { @@ -555,7 +610,7 @@ static inline struct ist htx_get_blk_name(const struct htx *htx, const struct ht /* Returns the value of the block , depending on its type. If there is no - * value, an empty one is retruned. + * value (for end-of blocks), an empty one is retruned. */ static inline struct ist htx_get_blk_value(const struct htx *htx, const struct htx_blk *blk) { @@ -604,7 +659,7 @@ static inline uint32_t htx_meta_space(const struct htx *htx) return (htx->used * sizeof(htx->blocks[0])); } -/* Returns the space used (data + metadata) in */ +/* Returns the space used (payload + metadata) in */ static inline uint32_t htx_used_space(const struct htx *htx) { return (htx->data + htx_meta_space(htx)); @@ -650,6 +705,7 @@ static inline int htx_almost_full(const struct htx *htx) return 0; } +/* Resets an HTX message */ static inline void htx_reset(struct htx *htx) { htx->data = htx->used = htx->tail = htx->head = 0; @@ -659,7 +715,7 @@ static inline void htx_reset(struct htx *htx) htx->first = -1; } -/* returns the available room for raw data in buffer once HTX overhead is +/* Returns the available room for raw data in buffer once HTX overhead is * taken into account (one HTX header and two blocks). The purpose is to figure * the optimal fill length to avoid copies. */ @@ -678,9 +734,11 @@ static inline size_t buf_room_for_htx_data(const struct buffer *buf) /* Returns an HTX message using the buffer . Unlike htx_from_buf(), this - * function does not update to the buffer. - * Note that it always returns a valid pointer, either to an initialized buffer - * or to the empty buffer. + * function does not update the buffer. So if the HTX message is updated, the + * caller must call htx_to_buf() to be sure to also update the underlying buffer + * accordingly. Note that it always returns a valid pointer, either to an + * initialized buffer or to the empty buffer. This function must always be + * called with a buffer containing an HTX message (or an empty buffer). */ static inline struct htx *htxbuf(const struct buffer *buf) { @@ -697,9 +755,11 @@ static inline struct htx *htxbuf(const struct buffer *buf) } /* Returns an HTX message using the buffer . is updated to appear as - * full. It is the caller responsibility to call htx_to_buf() when it finish to - * manipulate the HTX message to update accordingly. The returned pointer - * is always valid. + * full. It should be used when you want to add something into the HTX message, + * so the call to htx_to_buf() may be skipped. But, it is the caller + * responsibility to call htx_to_buf() to reset if it is relevant. The + * returned pointer is always valid. This function must always be called with a + * buffer containing an HTX message (or an empty buffer). * * The caller can call htxbuf() function to avoid any update of the buffer. */ @@ -711,7 +771,7 @@ static inline struct htx *htx_from_buf(struct buffer *buf) return htx; } -/* Upate accordingly to the HTX message */ +/* Update accordingly to the HTX message */ static inline void htx_to_buf(struct htx *htx, struct buffer *buf) { if (!htx->used && !(htx->flags & (HTX_FL_PARSING_ERROR|HTX_FL_UPGRADE))) { @@ -755,6 +815,7 @@ static inline const char *htx_blk_type_str(enum htx_blk_type type) }; } +/* For debugging purpose */ static inline void htx_dump(struct htx *htx) { int32_t pos; diff --git a/src/htx.c b/src/htx.c index 502184aff4..c29a66d784 100644 --- a/src/htx.c +++ b/src/htx.c @@ -15,10 +15,10 @@ 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 is not NULL, we replace it by the new block address, after - * the defragmentation. The new is returned. +/* Defragments an HTX message. It removes unused blocks and unwraps the payloads + * part. A temporary buffer is used to do so. This function never fails. if + * is not NULL, we replace it by the new block address, after the + * defragmentation. The new is returned. */ /* TODO: merge data blocks into one */ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk) @@ -54,7 +54,7 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk) if (htx->first == old) first = new; - /* if is defined, set its new position */ + /* if is defined, save its new position */ if (blk != NULL && blk == oldblk) blkpos = new; @@ -75,6 +75,10 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk) return ((blkpos == -1) ? NULL : htx_get_blk(htx, blkpos)); } +/* Degragments HTX blocks of an HTX message. Payloads part is keep untouched + * here. This function will move back all blocks starting at the position 0, + * removing unused blocks. It must never be called with an empty message. + */ static void htx_defrag_blks(struct htx *htx) { int32_t pos, new; @@ -103,11 +107,11 @@ static void htx_defrag_blks(struct htx *htx) htx->tail = new - 1; } -/* Reserves a new block in the HTTP message with a content of +/* Reserves a new block in the HTX message with a content of * 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. + * block is returned and the HTX message is updated. Space for this new block is + * reserved in the HTX 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) { @@ -175,7 +179,7 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz) } else { defrag: - /* need to defragment the table before inserting upfront */ + /* need to defragment the message before inserting upfront */ htx_defrag(htx, NULL); tail = htx->tail + 1; used = htx->used + 1; @@ -203,12 +207,12 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz) * expanded by bytes and we need find where this expansion will be * performed. It can be a compression if is negative. This function only * updates all addresses. The caller have the responsibility to performe the - * expansion and update the block and the HTX message accordingly. No error msut - * occurre. It returns following values: + * expansion and update the block and the HTX message accordingly. No error must + * occurr. It returns following values: * * 0: The expansion cannot be performed, there is not enough space. * - * 1: the expansion must be performed in place, there is enought space after + * 1: the expansion must be performed in place, there is enougth space after * the block's payload to handle it. This is especially true if it is a * compression and not an expension. * @@ -299,8 +303,8 @@ static int htx_prepare_blk_expansion(struct htx *htx, struct htx_blk *blk, int32 return ret; } -/* Adds a new block of type in the HTTP message . Its content size - * is passed but it is the caller responsibility to do the copy. +/* Adds a new block of type in the HTX message . 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) { @@ -315,9 +319,9 @@ struct htx_blk *htx_add_blk(struct htx *htx, enum htx_blk_type type, uint32_t bl return blk; } -/* Removes the block from the HTTP message . The function returns the - * block following or NULL if is the last block or the last - * inserted one. +/* Removes the block from the HTX message . The function returns the + * block following or NULL if is the last block or the last inserted + * one. */ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk) { @@ -340,7 +344,7 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk) blk->info = ((uint32_t)HTX_BLK_UNUSED << 28); } - /* There is at least 2 blocks, so tail is always >= 0 */ + /* There is at least 2 blocks, so tail is always > 0 */ if (pos == htx->head) { /* move the head forward */ htx->used--; @@ -391,8 +395,8 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk) return blk; } -/* Truncate all blocks after the one containing the offset . This last - * one is truncated too. +/* Removes all blocks after the one containing the offset . This last + * one may be truncated if it is a DATA block. */ void htx_truncate(struct htx *htx, uint32_t offset) { @@ -414,11 +418,11 @@ void htx_truncate(struct htx *htx, uint32_t offset) blk = htx_remove_blk(htx, blk); } -/* Drain bytes from the HTX message . DATA blocks will be cut if - * necessary. Others blocks will be removed at once if 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. +/* Drains bytes from the HTX message . If the last block is a DATA + * block, it will be cut if necessary. Others blocks will be removed at once if + * 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) { @@ -565,19 +569,19 @@ struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk, htx_set_blk_value_len(blk, v.len + delta); htx->data += delta; - if (ret == 1) { + if (ret == 1) { /* Replace in place */ if (delta <= 0) { - /* compression: copy new data first */ + /* compression: copy new data first then move the end */ memcpy(old.ptr, new.ptr, new.len); memmove(old.ptr + new.len, old.ptr + old.len, (v.ptr + v.len) - (old.ptr + old.len)); } else { - /* expansion: move the end first */ + /* expansion: move the end first then copy new data */ memmove(old.ptr + new.len, old.ptr + old.len, (v.ptr + v.len) - (old.ptr + old.len)); memcpy(old.ptr, new.ptr, new.len); } } - else if (ret == 2) { + else if (ret == 2) { /* New address but no defrag */ void *ptr = htx_get_blk_ptr(htx, blk); /* Copy the name, if any */ @@ -595,7 +599,7 @@ struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk, /* Copy value after old part, if any */ memcpy(ptr, old.ptr + old.len, (v.ptr + v.len) - (old.ptr + old.len)); } - else { + else { /* Do a degrag first */ struct buffer *tmp = get_trash_chunk(); /* Copy the header name, if any */ @@ -671,7 +675,7 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, if (!max) break; if (sz > max) { - /* Headers must be fully copied */ + /* Only DATA blocks can be partially xferred */ if (type != HTX_BLK_DATA) break; sz = max; @@ -686,7 +690,7 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, count -= sizeof(dstblk) + sz; if (blk->info != info) { - /* Partial move: don't remove from but + /* Partial xfer: don't remove from but * resize its content */ htx_cut_data_blk(src, blk, sz); break; @@ -695,7 +699,6 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, blk = htx_remove_blk(src, blk); if (type == mark) break; - } end: @@ -728,6 +731,9 @@ struct htx_blk *htx_replace_header(struct htx *htx, struct htx_blk *blk, blk->info = (type << 28) + (value.len << 8) + name.len; htx->data += delta; + /* Replace in place or at a new address is the same. We replace all the + * header (name+value). Only take care to defrag the message if + * necessary. */ if (ret == 3) blk = htx_defrag(htx, blk); @@ -772,6 +778,8 @@ struct htx_sl *htx_replace_stline(struct htx *htx, struct htx_blk *blk, const st htx_set_blk_value_len(blk, sz+delta); htx->data += delta; + /* Replace in place or at a new address is the same. We replace all the + * start-line. Only take care to defrag the message if necessary. */ if (ret == 3) blk = htx_defrag(htx, blk); @@ -848,7 +856,7 @@ struct htx_blk *htx_add_header(struct htx *htx, const struct ist name, } /* Adds an HTX block of type TLR in . It returns the new block on - * success. Otherwise, it returns NULL. The header name is always lower cased. + * success. Otherwise, it returns NULL. The trailer name is always lower cased. */ struct htx_blk *htx_add_trailer(struct htx *htx, const struct ist name, const struct ist value) @@ -882,6 +890,9 @@ struct htx_blk *htx_add_blk_type_size(struct htx *htx, enum htx_blk_type type, u return blk; } +/* Add all headers from the list into the HTX message , followed by + * the EOH. On sucess, it returns the last block inserted (the EOH), otherwise + * NULL is returned. */ struct htx_blk *htx_add_all_headers(struct htx *htx, const struct http_hdr *hdrs) { int i; @@ -893,6 +904,9 @@ struct htx_blk *htx_add_all_headers(struct htx *htx, const struct http_hdr *hdrs return htx_add_endof(htx, HTX_BLK_EOH); } +/* Add all trailers from the list into the HTX message , followed by + * the EOT. On sucess, it returns the last block inserted (the EOT), otherwise + * NULL is returned. */ struct htx_blk *htx_add_all_trailers(struct htx *htx, const struct http_hdr *hdrs) { int i; @@ -904,7 +918,7 @@ struct htx_blk *htx_add_all_trailers(struct htx *htx, const struct http_hdr *hdr return htx_add_endof(htx, HTX_BLK_EOT); } -/* Adds an HTX block of type EOH or EOM in . It returns the new block +/* Adds an HTX block of type EOH, EOT, or EOM in . 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) @@ -1047,9 +1061,8 @@ void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk * *ref = pblk; } -/* Appends the H1 representation of the request line block to the - * chunk . It returns 1 if data are successfully appended, otherwise it - * returns 0. +/* Appends the H1 representation of the request line to the chunk . 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) { @@ -1070,9 +1083,8 @@ int htx_reqline_to_h1(const struct htx_sl *sl, struct buffer *chk) return 1; } -/* Appends the H1 representation of the status line block to the chunk - * . It returns 1 if data are successfully appended, otherwise it - * returns 0. +/* Appends the H1 representation of the status line to the chunk . 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) { @@ -1092,9 +1104,9 @@ int htx_stline_to_h1(const struct htx_sl *sl, struct buffer *chk) return 1; } -/* Appends the H1 representation of the header block to the chunk - * . It returns 1 if data are successfully appended, otherwise it returns - * 0. +/* Appends the H1 representation of the header witht the value to the + * chunk . 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) { @@ -1109,9 +1121,9 @@ int htx_hdr_to_h1(const struct ist n, const struct ist v, struct buffer *chk) return 1; } -/* Appends the H1 representation of the data block to the chunk - * . If is non-zero, it emits HTTP/1 chunk-encoded data. It - * returns 1 if data are successfully appended, otherwise it returns 0. +/* Appends the H1 representation of the data to the chunk . If + * 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) {