mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-05 02:49:01 +00:00
DOC: htx: Update comments in HTX files
This patch may be backported to 2.0 to have accurate comments.
This commit is contained in:
parent
c63231df55
commit
3b21972061
@ -31,54 +31,104 @@
|
||||
#include <common/standard.h>
|
||||
|
||||
/*
|
||||
* 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 <pos> */
|
||||
/* 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 <blk> */
|
||||
/* Returns the position of the block <blk>. It is the caller responsibility to
|
||||
* be sure <blk> is part of <htx>. */
|
||||
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 <pos> */
|
||||
/* Returns the block at the position <pos>. It is the caller responsibility to
|
||||
* be sure the block at the position <pos> 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 <blk>, only if it is a header. Otherwise it
|
||||
* returns an empty name.
|
||||
/* Returns the name of the block <blk>, 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 <blk>, 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 <htx> */
|
||||
/* Returns the space used (payload + metadata) in <htx> */
|
||||
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 <buf> once HTX overhead is
|
||||
/* Returns the available room for raw data in buffer <buf> 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 <buf>. 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 <buf>. <buf> 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 <buf> 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 <buf> 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 <buf> accordingly to the HTX message <htx> */
|
||||
/* Update <buf> accordingly to the HTX message <htx> */
|
||||
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;
|
||||
|
108
src/htx.c
108
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 <blk> is not NULL, we replace it by the new block address, after
|
||||
* the defragmentation. The new <blk> 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
|
||||
* <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)
|
||||
@ -54,7 +54,7 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk)
|
||||
if (htx->first == old)
|
||||
first = new;
|
||||
|
||||
/* if <blk> is defined, set its new position */
|
||||
/* if <blk> 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 <htx> with a content of <blksz>
|
||||
/* Reserves a new block in the HTX 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.
|
||||
* 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 <delta> bytes and we need find where this expansion will be
|
||||
* performed. It can be a compression if <delta> 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 <type> in the HTTP message <htx>. Its content size
|
||||
* is passed but it is the caller responsibility to do the copy.
|
||||
/* Adds a new block of type <type> in the HTX 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)
|
||||
{
|
||||
@ -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 <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.
|
||||
/* Removes the block <blk> from the HTX 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)
|
||||
{
|
||||
@ -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 <offset>. This last
|
||||
* one is truncated too.
|
||||
/* Removes all blocks after the one containing the offset <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 <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.
|
||||
/* Drains <count> bytes from the HTX message <htx>. If the last block is a DATA
|
||||
* block, it 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)
|
||||
{
|
||||
@ -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 <blk> from <src> but
|
||||
/* Partial xfer: don't remove <blk> from <src> 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 <htx>. 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 <hdrs> into the HTX message <htx>, 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 <hdrs> into the HTX message <htx>, 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 <htx>. It returns the new block
|
||||
/* Adds an HTX block of type EOH, EOT, 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)
|
||||
@ -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 <blk> to the
|
||||
* chunk <chk>. It returns 1 if data are successfully appended, otherwise it
|
||||
* returns 0.
|
||||
/* Appends the H1 representation of the request line <sl> 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)
|
||||
{
|
||||
@ -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 <blk> to the chunk
|
||||
* <chk>. It returns 1 if data are successfully appended, otherwise it
|
||||
* returns 0.
|
||||
/* Appends the H1 representation of the status line <sl> 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)
|
||||
{
|
||||
@ -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 <blk> to the chunk
|
||||
* <chk>. It returns 1 if data are successfully appended, otherwise it returns
|
||||
* 0.
|
||||
/* Appends the H1 representation of the header <n> witht the value <v> 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)
|
||||
{
|
||||
@ -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 <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.
|
||||
/* Appends the H1 representation of the data <data> 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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user