REORG: buffers: split buffers into chunk,buffer,channel

Many parts of the channel definition still make use of the "buffer" word.
This commit is contained in:
Willy Tarreau 2012-08-24 19:22:53 +02:00 committed by Willy Tarreau
parent c578891112
commit c7e4238df0
34 changed files with 781 additions and 622 deletions

View File

@ -540,7 +540,8 @@ all: haproxy
endif
OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
src/uri_auth.o src/standard.o src/buffers.o src/log.o src/task.o \
src/uri_auth.o src/standard.o src/buffer.o src/log.o src/task.o \
src/chunk.o src/channel.o \
src/time.o src/fd.o src/pipe.o src/regex.o src/cfgparse.o src/server.o \
src/checks.o src/queue.o src/frontend.o src/proxy.o src/peers.o \
src/arg.o src/stick_table.o src/proto_uxst.o src/connection.o \
@ -548,7 +549,7 @@ OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
src/lb_chash.o src/lb_fwlc.o src/lb_fwrr.o src/lb_map.o src/lb_fas.o \
src/stream_interface.o src/dumpstats.o src/proto_tcp.o \
src/session.o src/hdr_idx.o src/ev_select.o src/signal.o \
src/acl.o src/sample.o src/memory.o src/freq_ctr.o src/auth.o
src/acl.o src/sample.o src/memory.o src/freq_ctr.o src/auth.o \
EBTREE_OBJS = $(EBTREE_DIR)/ebtree.o \
$(EBTREE_DIR)/eb32tree.o $(EBTREE_DIR)/eb64tree.o \

View File

@ -106,7 +106,8 @@ CFLAGS = -Wall $(COPTS) $(DEBUG)
LDFLAGS = -g
OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
src/uri_auth.o src/standard.o src/buffers.o src/log.o src/task.o \
src/uri_auth.o src/standard.o src/buffer.o src/log.o src/task.o \
src/chunk.o src/channel.o \
src/time.o src/fd.o src/pipe.o src/regex.o src/cfgparse.o src/server.o \
src/checks.o src/queue.o src/frontend.o src/proxy.o src/proto_uxst.o \
src/proto_http.o src/raw_sock.o src/appsession.o src/backend.o \

View File

@ -103,7 +103,8 @@ CFLAGS = -Wall $(COPTS) $(DEBUG) -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arc
LDFLAGS = -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386 -mmacosx-version-min=10.4
OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
src/uri_auth.o src/standard.o src/buffers.o src/log.o src/task.o \
src/uri_auth.o src/standard.o src/buffer.o src/log.o src/task.o \
src/chunk.o src/channel.o \
src/time.o src/fd.o src/pipe.o src/regex.o src/cfgparse.o src/server.o \
src/checks.o src/queue.o src/frontend.o src/proxy.o src/proto_uxst.o \
src/proto_http.o src/raw_sock.o src/appsession.o src/backend.o \

300
include/common/buffer.h Normal file
View File

@ -0,0 +1,300 @@
/*
* include/common/buffer.h
* Buffer management definitions, macros and inline functions.
*
* Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _COMMON_BUFFER_H
#define _COMMON_BUFFER_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <common/config.h>
struct buffer {
char *p; /* buffer's start pointer, separates in and out data */
unsigned int size; /* buffer size in bytes */
unsigned int i; /* number of input bytes pending for analysis in the buffer */
unsigned int o; /* number of out bytes the sender can consume from this buffer */
char data[0]; /* <size> bytes */
};
void buffer_dump(FILE *o, struct buffer *b, int from, int to);
void buffer_slow_realign(struct buffer *buf);
void buffer_bounce_realign(struct buffer *buf);
/*****************************************************************/
/* These functions are used to compute various buffer area sizes */
/*****************************************************************/
/* Returns an absolute pointer for a position relative to the current buffer's
* pointer. It is written so that it is optimal when <ofs> is a const. It is
* written as a macro instead of an inline function so that the compiler knows
* when it can optimize out the sign test on <ofs> when passed an unsigned int.
*/
#define b_ptr(b, ofs) \
({ \
char *__ret = (b)->p + (ofs); \
if ((ofs) > 0 && __ret >= (b)->data + (b)->size) \
__ret -= (b)->size; \
else if ((ofs) < 0 && __ret < (b)->data) \
__ret += (b)->size; \
__ret; \
})
/* Returns the start of the input data in a buffer */
static inline char *bi_ptr(const struct buffer *b)
{
return b->p;
}
/* Returns the end of the input data in a buffer (pointer to next
* insertion point).
*/
static inline char *bi_end(const struct buffer *b)
{
char *ret = b->p + b->i;
if (ret >= b->data + b->size)
ret -= b->size;
return ret;
}
/* Returns the amount of input data that can contiguously be read at once */
static inline int bi_contig_data(const struct buffer *b)
{
int data = b->data + b->size - b->p;
if (data > b->i)
data = b->i;
return data;
}
/* Returns the start of the output data in a buffer */
static inline char *bo_ptr(const struct buffer *b)
{
char *ret = b->p - b->o;
if (ret < b->data)
ret += b->size;
return ret;
}
/* Returns the end of the output data in a buffer */
static inline char *bo_end(const struct buffer *b)
{
return b->p;
}
/* Returns the amount of output data that can contiguously be read at once */
static inline int bo_contig_data(const struct buffer *b)
{
char *beg = b->p - b->o;
if (beg < b->data)
return b->data - beg;
return b->o;
}
/* Return the buffer's length in bytes by summing the input and the output */
static inline int buffer_len(const struct buffer *buf)
{
return buf->i + buf->o;
}
/* Return non-zero only if the buffer is not empty */
static inline int buffer_not_empty(const struct buffer *buf)
{
return buf->i | buf->o;
}
/* Return non-zero only if the buffer is empty */
static inline int buffer_empty(const struct buffer *buf)
{
return !buffer_not_empty(buf);
}
/* Normalizes a pointer after a subtract */
static inline char *buffer_wrap_sub(const struct buffer *buf, char *ptr)
{
if (ptr < buf->data)
ptr += buf->size;
return ptr;
}
/* Normalizes a pointer after an addition */
static inline char *buffer_wrap_add(const struct buffer *buf, char *ptr)
{
if (ptr - buf->size >= buf->data)
ptr -= buf->size;
return ptr;
}
/* Return the maximum amount of bytes that can be written into the buffer,
* including reserved space which may be overwritten.
*/
static inline int buffer_total_space(const struct buffer *buf)
{
return buf->size - buffer_len(buf);
}
/* Returns the number of contiguous bytes between <start> and <start>+<count>,
* and enforces a limit on buf->data + buf->size. <start> must be within the
* buffer.
*/
static inline int buffer_contig_area(const struct buffer *buf, const char *start, int count)
{
if (count > buf->data - start + buf->size)
count = buf->data - start + buf->size;
return count;
}
/* Return the amount of bytes that can be written into the buffer at once,
* including reserved space which may be overwritten.
*/
static inline int buffer_contig_space(const struct buffer *buf)
{
const char *left, *right;
if (buf->data + buf->o <= buf->p)
right = buf->data + buf->size;
else
right = buf->p + buf->size - buf->o;
left = buffer_wrap_add(buf, buf->p + buf->i);
return right - left;
}
/* Return the amount of bytes that can be written into the buffer at once,
* excluding the amount of reserved space passed in <res>, which is
* preserved.
*/
static inline int buffer_contig_space_with_res(const struct buffer *buf, int res)
{
/* Proceed differently if the buffer is full, partially used or empty.
* The hard situation is when it's partially used and either data or
* reserved space wraps at the end.
*/
int spare = buf->size - res;
if (buffer_len(buf) >= spare)
spare = 0;
else if (buffer_len(buf)) {
spare = buffer_contig_space(buf) - res;
if (spare < 0)
spare = 0;
}
return spare;
}
/* Normalizes a pointer which is supposed to be relative to the beginning of a
* buffer, so that wrapping is correctly handled. The intent is to use this
* when increasing a pointer. Note that the wrapping test is only performed
* once, so the original pointer must be between ->data-size and ->data+2*size-1,
* otherwise an invalid pointer might be returned.
*/
static inline const char *buffer_pointer(const struct buffer *buf, const char *ptr)
{
if (ptr < buf->data)
ptr += buf->size;
else if (ptr - buf->size >= buf->data)
ptr -= buf->size;
return ptr;
}
/* Returns the distance between two pointers, taking into account the ability
* to wrap around the buffer's end.
*/
static inline int buffer_count(const struct buffer *buf, const char *from, const char *to)
{
int count = to - from;
if (count < 0)
count += buf->size;
return count;
}
/* returns the amount of pending bytes in the buffer. It is the amount of bytes
* that is not scheduled to be sent.
*/
static inline int buffer_pending(const struct buffer *buf)
{
return buf->i;
}
/* Returns the size of the working area which the caller knows ends at <end>.
* If <end> equals buf->r (modulo size), then it means that the free area which
* follows is part of the working area. Otherwise, the working area stops at
* <end>. It always starts at buf->p. The work area includes the
* reserved area.
*/
static inline int buffer_work_area(const struct buffer *buf, const char *end)
{
end = buffer_pointer(buf, end);
if (end == buffer_wrap_add(buf, buf->p + buf->i))
/* pointer exactly at end, lets push forwards */
end = buffer_wrap_sub(buf, buf->p - buf->o);
return buffer_count(buf, buf->p, end);
}
/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
static inline int buffer_almost_full(const struct buffer *buf)
{
if (buffer_total_space(buf) < buf->size / 4)
return 1;
return 0;
}
/* Cut the first <n> pending bytes in a contiguous buffer. It is illegal to
* call this function with remaining data waiting to be sent (o > 0). The
* caller must ensure that <n> is smaller than the actual buffer's length.
* This is mainly used to remove empty lines at the beginning of a request
* or a response.
*/
static inline void bi_fast_delete(struct buffer *buf, int n)
{
buf->i -= n;
buf->p += n;
}
/*
* Tries to realign the given buffer, and returns how many bytes can be written
* there at once without overwriting anything.
*/
static inline int buffer_realign(struct buffer *buf)
{
if (!(buf->i | buf->o)) {
/* let's realign the buffer to optimize I/O */
buf->p = buf->data;
}
return buffer_contig_space(buf);
}
#endif /* _COMMON_BUFFER_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

131
include/common/chunk.h Normal file
View File

@ -0,0 +1,131 @@
/*
* include/common/chunk.h
* Chunk management definitions, macros and inline functions.
*
* Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, version 2.1
* exclusively.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _TYPES_CHUNK_H
#define _TYPES_CHUNK_H
#include <stdlib.h>
#include <string.h>
#include <common/config.h>
/* describes a chunk of string */
struct chunk {
char *str; /* beginning of the string itself. Might not be 0-terminated */
int size; /* total size of the buffer, 0 if the *str is read-only */
int len; /* current size of the string from first to last char. <0 = uninit. */
};
/* function prototypes */
int chunk_printf(struct chunk *chk, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
int chunk_htmlencode(struct chunk *dst, struct chunk *src);
int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
static inline void chunk_init(struct chunk *chk, char *str, size_t size)
{
chk->str = str;
chk->len = 0;
chk->size = size;
}
/* report 0 in case of error, 1 if OK. */
static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, int len)
{
if (size && len > size)
return 0;
chk->str = str;
chk->len = len;
chk->size = size;
return 1;
}
static inline void chunk_initstr(struct chunk *chk, char *str)
{
chk->str = str;
chk->len = strlen(str);
chk->size = 0; /* mark it read-only */
}
static inline int chunk_strcpy(struct chunk *chk, const char *str)
{
size_t len;
len = strlen(str);
if (unlikely(len > chk->size))
return 0;
chk->len = len;
memcpy(chk->str, str, len);
return 1;
}
static inline void chunk_reset(struct chunk *chk)
{
chk->str = NULL;
chk->len = -1;
chk->size = 0;
}
static inline void chunk_destroy(struct chunk *chk)
{
if (!chk->size)
return;
if (chk->str)
free(chk->str);
chunk_reset(chk);
}
/*
* frees the destination chunk if already allocated, allocates a new string,
* and copies the source into it. The pointer to the destination string is
* returned, or NULL if the allocation fails or if any pointer is NULL..
*/
static inline char *chunk_dup(struct chunk *dst, const struct chunk *src)
{
if (!dst || !src || !src->str)
return NULL;
if (dst->str)
free(dst->str);
dst->len = src->len;
dst->str = (char *)malloc(dst->len);
memcpy(dst->str, src->str, dst->len);
return dst->str;
}
#endif /* _TYPES_CHUNK_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

View File

@ -1,6 +1,6 @@
/*
* include/proto/buffers.h
* Buffer management definitions, macros and inline functions.
* include/proto/channel.h
* Channel management definitions, macros and inline functions.
*
* Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
*
@ -19,19 +19,19 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _PROTO_BUFFERS_H
#define _PROTO_BUFFERS_H
#ifndef _PROTO_CHANNEL_H
#define _PROTO_CHANNEL_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <common/config.h>
#include <common/chunk.h>
#include <common/memory.h>
#include <common/ticks.h>
#include <common/time.h>
#include <types/buffers.h>
#include <types/global.h>
extern struct pool_head *pool2_buffer;
@ -47,9 +47,6 @@ int bo_getline(struct channel *buf, char *str, int len);
int bo_getblk(struct channel *buf, char *blk, int len, int offset);
int buffer_replace2(struct channel *b, char *pos, char *end, const char *str, int len);
int buffer_insert_line2(struct channel *b, char *pos, const char *str, int len);
void buffer_dump(FILE *o, struct buffer *b, int from, int to);
void buffer_slow_realign(struct buffer *buf);
void buffer_bounce_realign(struct buffer *buf);
unsigned long long buffer_forward(struct channel *buf, unsigned long long bytes);
/* Initialize all fields in the buffer. The BF_OUT_EMPTY flags is set. */
@ -70,109 +67,6 @@ static inline void buffer_init(struct channel *buf)
/* These functions are used to compute various buffer area sizes */
/*****************************************************************/
/* Returns an absolute pointer for a position relative to the current buffer's
* pointer. It is written so that it is optimal when <ofs> is a const. It is
* written as a macro instead of an inline function so that the compiler knows
* when it can optimize out the sign test on <ofs> when passed an unsigned int.
*/
#define b_ptr(b, ofs) \
({ \
char *__ret = (b)->p + (ofs); \
if ((ofs) > 0 && __ret >= (b)->data + (b)->size) \
__ret -= (b)->size; \
else if ((ofs) < 0 && __ret < (b)->data) \
__ret += (b)->size; \
__ret; \
})
/* Returns the start of the input data in a buffer */
static inline char *bi_ptr(const struct buffer *b)
{
return b->p;
}
/* Returns the end of the input data in a buffer (pointer to next
* insertion point).
*/
static inline char *bi_end(const struct buffer *b)
{
char *ret = b->p + b->i;
if (ret >= b->data + b->size)
ret -= b->size;
return ret;
}
/* Returns the amount of input data that can contiguously be read at once */
static inline int bi_contig_data(const struct buffer *b)
{
int data = b->data + b->size - b->p;
if (data > b->i)
data = b->i;
return data;
}
/* Returns the start of the output data in a buffer */
static inline char *bo_ptr(const struct buffer *b)
{
char *ret = b->p - b->o;
if (ret < b->data)
ret += b->size;
return ret;
}
/* Returns the end of the output data in a buffer */
static inline char *bo_end(const struct buffer *b)
{
return b->p;
}
/* Returns the amount of output data that can contiguously be read at once */
static inline int bo_contig_data(const struct buffer *b)
{
char *beg = b->p - b->o;
if (beg < b->data)
return b->data - beg;
return b->o;
}
/* Return the buffer's length in bytes by summing the input and the output */
static inline int buffer_len(const struct buffer *buf)
{
return buf->i + buf->o;
}
/* Return non-zero only if the buffer is not empty */
static inline int buffer_not_empty(const struct buffer *buf)
{
return buf->i | buf->o;
}
/* Return non-zero only if the buffer is empty */
static inline int buffer_empty(const struct buffer *buf)
{
return !buffer_not_empty(buf);
}
/* Normalizes a pointer after a subtract */
static inline char *buffer_wrap_sub(const struct buffer *buf, char *ptr)
{
if (ptr < buf->data)
ptr += buf->size;
return ptr;
}
/* Normalizes a pointer after an addition */
static inline char *buffer_wrap_add(const struct buffer *buf, char *ptr)
{
if (ptr - buf->size >= buf->data)
ptr -= buf->size;
return ptr;
}
/* Return the number of reserved bytes in the buffer, which ensures that once
* all pending data are forwarded, the buffer still has global.tune.maxrewrite
* bytes free. The result is between 0 and global.maxrewrite, which is itself
@ -254,41 +148,6 @@ static inline int bi_avail(const struct channel *b)
return 0;
}
/* Return the maximum amount of bytes that can be written into the buffer,
* including reserved space which may be overwritten.
*/
static inline int buffer_total_space(const struct buffer *buf)
{
return buf->size - buffer_len(buf);
}
/* Returns the number of contiguous bytes between <start> and <start>+<count>,
* and enforces a limit on buf->data + buf->size. <start> must be within the
* buffer.
*/
static inline int buffer_contig_area(const struct buffer *buf, const char *start, int count)
{
if (count > buf->data - start + buf->size)
count = buf->data - start + buf->size;
return count;
}
/* Return the amount of bytes that can be written into the buffer at once,
* including reserved space which may be overwritten.
*/
static inline int buffer_contig_space(const struct buffer *buf)
{
const char *left, *right;
if (buf->data + buf->o <= buf->p)
right = buf->data + buf->size;
else
right = buf->p + buf->size - buf->o;
left = buffer_wrap_add(buf, buf->p + buf->i);
return right - left;
}
/* Advances the buffer by <adv> bytes, which means that the buffer
* pointer advances, and that as many bytes from in are transferred
* to out. The caller is responsible for ensuring that adv is always
@ -316,29 +175,6 @@ static inline void b_rew(struct channel *b, unsigned int adv)
b->buf.p = b_ptr(&b->buf, (int)-adv);
}
/* Return the amount of bytes that can be written into the buffer at once,
* excluding the amount of reserved space passed in <res>, which is
* preserved.
*/
static inline int buffer_contig_space_with_res(const struct buffer *buf, int res)
{
/* Proceed differently if the buffer is full, partially used or empty.
* The hard situation is when it's partially used and either data or
* reserved space wraps at the end.
*/
int spare = buf->size - res;
if (buffer_len(buf) >= spare)
spare = 0;
else if (buffer_len(buf)) {
spare = buffer_contig_space(buf) - res;
if (spare < 0)
spare = 0;
}
return spare;
}
/* Return the amount of bytes that can be written into the buffer at once,
* excluding reserved space, which is preserved.
*/
@ -347,63 +183,6 @@ static inline int buffer_contig_space_res(const struct channel *chn)
return buffer_contig_space_with_res(&chn->buf, buffer_reserved(chn));
}
/* Normalizes a pointer which is supposed to be relative to the beginning of a
* buffer, so that wrapping is correctly handled. The intent is to use this
* when increasing a pointer. Note that the wrapping test is only performed
* once, so the original pointer must be between ->data-size and ->data+2*size-1,
* otherwise an invalid pointer might be returned.
*/
static inline const char *buffer_pointer(const struct buffer *buf, const char *ptr)
{
if (ptr < buf->data)
ptr += buf->size;
else if (ptr - buf->size >= buf->data)
ptr -= buf->size;
return ptr;
}
/* Returns the distance between two pointers, taking into account the ability
* to wrap around the buffer's end.
*/
static inline int buffer_count(const struct buffer *buf, const char *from, const char *to)
{
int count = to - from;
if (count < 0)
count += buf->size;
return count;
}
/* returns the amount of pending bytes in the buffer. It is the amount of bytes
* that is not scheduled to be sent.
*/
static inline int buffer_pending(const struct buffer *buf)
{
return buf->i;
}
/* Returns the size of the working area which the caller knows ends at <end>.
* If <end> equals buf->r (modulo size), then it means that the free area which
* follows is part of the working area. Otherwise, the working area stops at
* <end>. It always starts at buf->p. The work area includes the
* reserved area.
*/
static inline int buffer_work_area(const struct buffer *buf, const char *end)
{
end = buffer_pointer(buf, end);
if (end == buffer_wrap_add(buf, buf->p + buf->i))
/* pointer exactly at end, lets push forwards */
end = buffer_wrap_sub(buf, buf->p - buf->o);
return buffer_count(buf, buf->p, end);
}
/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
static inline int buffer_almost_full(const struct buffer *buf)
{
if (buffer_total_space(buf) < buf->size / 4)
return 1;
return 0;
}
/* Returns true if the buffer's input is already closed */
static inline int buffer_input_closed(struct channel *buf)
{
@ -485,18 +264,6 @@ static inline void bi_erase(struct channel *buf)
buf->flags |= BF_FULL;
}
/* Cut the first <n> pending bytes in a contiguous buffer. It is illegal to
* call this function with remaining data waiting to be sent (o > 0). The
* caller must ensure that <n> is smaller than the actual buffer's length.
* This is mainly used to remove empty lines at the beginning of a request
* or a response.
*/
static inline void bi_fast_delete(struct buffer *buf, int n)
{
buf->i -= n;
buf->p += n;
}
/* marks the buffer as "shutdown" ASAP for reads */
static inline void buffer_shutr_now(struct channel *buf)
{
@ -574,19 +341,6 @@ static inline void buffer_dont_read(struct channel *buf)
buf->flags |= BF_DONT_READ;
}
/*
* Tries to realign the given buffer, and returns how many bytes can be written
* there at once without overwriting anything.
*/
static inline int buffer_realign(struct buffer *buf)
{
if (!(buf->i | buf->o)) {
/* let's realign the buffer to optimize I/O */
buf->p = buf->data;
}
return buffer_contig_space(buf);
}
/*
* Advance the buffer's read pointer by <len> bytes. This is useful when data
* have been read directly from the buffer. It is illegal to call this function
@ -669,91 +423,8 @@ static inline int buffer_replace(struct channel *b, char *pos, char *end, const
return buffer_replace2(b, pos, end, str, strlen(str));
}
/*
*
* Functions below are used to manage chunks
*
*/
static inline void chunk_init(struct chunk *chk, char *str, size_t size) {
chk->str = str;
chk->len = 0;
chk->size = size;
}
/* report 0 in case of error, 1 if OK. */
static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, int len) {
if (size && len > size)
return 0;
chk->str = str;
chk->len = len;
chk->size = size;
return 1;
}
static inline void chunk_initstr(struct chunk *chk, char *str) {
chk->str = str;
chk->len = strlen(str);
chk->size = 0; /* mark it read-only */
}
static inline int chunk_strcpy(struct chunk *chk, const char *str) {
size_t len;
len = strlen(str);
if (unlikely(len > chk->size))
return 0;
chk->len = len;
memcpy(chk->str, str, len);
return 1;
}
int chunk_printf(struct chunk *chk, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
int chunk_htmlencode(struct chunk *dst, struct chunk *src);
int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
static inline void chunk_reset(struct chunk *chk) {
chk->str = NULL;
chk->len = -1;
chk->size = 0;
}
static inline void chunk_destroy(struct chunk *chk) {
if (!chk->size)
return;
if (chk->str)
free(chk->str);
chunk_reset(chk);
}
/*
* frees the destination chunk if already allocated, allocates a new string,
* and copies the source into it. The pointer to the destination string is
* returned, or NULL if the allocation fails or if any pointer is NULL..
*/
static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
if (!dst || !src || !src->str)
return NULL;
if (dst->str)
free(dst->str);
dst->len = src->len;
dst->str = (char *)malloc(dst->len);
memcpy(dst->str, src->str, dst->len);
return dst->str;
}
#endif /* _PROTO_BUFFERS_H */
#endif /* _PROTO_CHANNEL_H */
/*
* Local variables:

View File

@ -24,8 +24,7 @@
#define _PROTO_DUMPSTATS_H
#include <common/config.h>
#include <types/buffers.h>
#include <types/session.h>
#include <types/stream_interface.h>
/* Flags for applet.ctx.stats.flags */
#define STAT_FMT_CSV 0x00000001 /* dump the stats in CSV format instead of HTML */

View File

@ -24,7 +24,8 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <types/buffers.h>
#include <common/chunk.h>
enum {
ARGT_STOP = 0, /* end of the arg list */

View File

@ -1,8 +1,8 @@
/*
* include/types/buffers.h
* Buffer management definitions, macros and inline functions.
* include/types/channel.h
* Channel management definitions, macros and inline functions.
*
* Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
* Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -19,15 +19,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _TYPES_BUFFERS_H
#define _TYPES_BUFFERS_H
#ifndef _TYPES_CHANNEL_H
#define _TYPES_CHANNEL_H
#include <common/config.h>
#include <common/memory.h>
#include <common/chunk.h>
#include <common/buffer.h>
#include <types/stream_interface.h>
/* The BF_* macros designate Buffer Flags, which may be ORed in the bit field
* member 'flags' in struct channel. Here we have several types of flags :
/* The BF_* macros designate Channel Flags (originally "Buffer Flags"), which
* may be ORed in the bit field member 'flags' in struct channel. Here we have
* several types of flags :
*
* - pure status flags, reported by the lower layer, which must be cleared
* before doing further I/O :
@ -47,8 +49,8 @@
*
* The flags have been arranged for readability, so that the read and write
* bits have the same position in a byte (read being the lower byte and write
* the second one). All flag names are relative to the buffer. For instance,
* 'write' indicates the direction from the buffer to the stream interface.
* the second one). All flag names are relative to the channel. For instance,
* 'write' indicates the direction from the channel to the stream interface.
*/
#define BF_READ_NULL 0x000001 /* last read detected on producer side */
@ -57,7 +59,7 @@
#define BF_READ_ERROR 0x000008 /* unrecoverable error on producer side */
#define BF_READ_ACTIVITY (BF_READ_NULL|BF_READ_PARTIAL|BF_READ_ERROR)
#define BF_FULL 0x000010 /* buffer cannot accept any more data (l >= max len) */
#define BF_FULL 0x000010 /* channel cannot accept any more data (l >= max len) */
#define BF_SHUTR 0x000020 /* producer has already shut down */
#define BF_SHUTR_NOW 0x000040 /* the producer must shut down for reads ASAP */
#define BF_READ_NOEXP 0x000080 /* producer should not expire */
@ -107,7 +109,7 @@
#define BF_HIJACK 0x040000 /* the producer is temporarily replaced by ->hijacker */
#define BF_ANA_TIMEOUT 0x080000 /* the analyser timeout has expired */
#define BF_READ_ATTACHED 0x100000 /* the read side is attached for the first time */
#define BF_KERN_SPLICING 0x200000 /* kernel splicing desired for this buffer */
#define BF_KERN_SPLICING 0x200000 /* kernel splicing desired for this channel */
#define BF_READ_DONTWAIT 0x400000 /* wake the task up after every read (eg: HTTP request) */
#define BF_AUTO_CONNECT 0x800000 /* consumer may attempt to establish a new connection */
@ -116,7 +118,7 @@
#define BF_SEND_DONTWAIT 0x4000000 /* don't wait for sending data (one-shoot) */
#define BF_NEVER_WAIT 0x8000000 /* never wait for sending data (permanent) */
#define BF_WAKE_ONCE 0x10000000 /* pretend there is activity on this buffer (one-shoot) */
#define BF_WAKE_ONCE 0x10000000 /* pretend there is activity on this channel (one-shoot) */
/* Use these masks to clear the flags before going back to lower layers */
#define BF_CLEAR_READ (~(BF_READ_NULL|BF_READ_PARTIAL|BF_READ_ERROR|BF_READ_ATTACHED))
@ -130,7 +132,7 @@
#define BF_MASK_STATIC (BF_OUT_EMPTY|BF_FULL|BF_SHUTR|BF_SHUTW|BF_SHUTR_NOW|BF_SHUTW_NOW)
/* Analysers (buffer->analysers).
/* Analysers (channel->analysers).
* Those bits indicate that there are some processing to do on the buffer
* contents. It will probably evolve into a linked list later. Those
* analysers could be compared to higher level processors.
@ -164,24 +166,9 @@
/* Magic value to forward infinite size (TCP, ...), used with ->to_forward */
#define BUF_INFINITE_FORWARD MAX_RANGE(int)
/* describes a chunk of string */
struct chunk {
char *str; /* beginning of the string itself. Might not be 0-terminated */
int size; /* total size of the buffer, 0 if the *str is read-only */
int len; /* current size of the string from first to last char. <0 = uninit. */
};
/* needed for a declaration below */
struct session;
struct buffer {
char *p; /* buffer's start pointer, separates in and out data */
unsigned int size; /* buffer size in bytes */
unsigned int i; /* number of input bytes pending for analysis in the buffer */
unsigned int o; /* number of out bytes the sender can consume from this buffer */
char data[0]; /* <size> bytes */
};
struct channel {
unsigned int flags; /* BF_* */
int rex; /* expiration date for a read, in ticks */
@ -189,14 +176,14 @@ struct channel {
int rto; /* read timeout, in ticks */
int wto; /* write timeout, in ticks */
unsigned int to_forward; /* number of bytes to forward after out without a wake-up */
unsigned int analysers; /* bit field indicating what to do on the buffer */
unsigned int analysers; /* bit field indicating what to do on the channel */
int analyse_exp; /* expiration date for current analysers (if set) */
void (*hijacker)(struct session *, struct channel *); /* alternative content producer */
unsigned char xfer_large; /* number of consecutive large xfers */
unsigned char xfer_small; /* number of consecutive small xfers */
unsigned long long total; /* total data read */
struct stream_interface *prod; /* producer attached to this buffer */
struct stream_interface *cons; /* consumer attached to this buffer */
struct stream_interface *prod; /* producer attached to this channel */
struct stream_interface *cons; /* consumer attached to this channel */
struct pipe *pipe; /* non-NULL only when data present */
struct buffer buf; /* embedded buffer for now, will move */
};
@ -291,7 +278,7 @@ struct channel {
long.
*/
#endif /* _TYPES_BUFFERS_H */
#endif /* _TYPES_CHANNEL_H */
/*
* Local variables:

View File

@ -25,6 +25,7 @@
#include <netinet/in.h>
#include <common/config.h>
#include <types/freq_ctr.h>
#include <types/log.h>
#include <types/protocols.h>
#include <types/proxy.h>

View File

@ -26,6 +26,7 @@
#include <sys/un.h>
#include <netinet/in.h>
#include <common/config.h>
#include <common/mini-clist.h>
#define MAX_SYSLOG_LEN 1024
#define NB_LOG_FACILITIES 24

View File

@ -22,9 +22,9 @@
#ifndef _TYPES_PROTO_HTTP_H
#define _TYPES_PROTO_HTTP_H
#include <common/chunk.h>
#include <common/config.h>
#include <types/buffers.h>
#include <types/hdr_idx.h>
/* These are the flags that are found in txn->flags */

View File

@ -28,6 +28,7 @@
#include <arpa/inet.h>
#include <common/appsession.h>
#include <common/chunk.h>
#include <common/config.h>
#include <common/mini-clist.h>
#include <common/regex.h>
@ -37,7 +38,6 @@
#include <types/acl.h>
#include <types/backend.h>
#include <types/buffers.h>
#include <types/counters.h>
#include <types/freq_ctr.h>
#include <types/log.h>

View File

@ -25,8 +25,9 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <common/chunk.h>
#include <types/arg.h>
#include <types/buffers.h>
/* input and output sample types */
enum {
@ -78,6 +79,9 @@ enum {
SMP_F_VOLATILE = (1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6), /* any volatility condition */
};
/* needed below */
struct session;
/* a sample context might be used by any sample fetch function in order to
* store information needed across multiple calls (eg: restart point for a
* next occurrence). By definition it may store up to 8 pointers, or any

View File

@ -29,7 +29,6 @@
#include <common/mini-clist.h>
#include <eb32tree.h>
#include <types/buffers.h>
#include <types/connection.h>
#include <types/counters.h>
#include <types/freq_ctr.h>

View File

@ -31,7 +31,7 @@
#include <common/config.h>
#include <common/mini-clist.h>
#include <types/buffers.h>
#include <types/channel.h>
#include <types/proto_http.h>
#include <types/proxy.h>
#include <types/queue.h>

View File

@ -25,7 +25,7 @@
#include <stdlib.h>
#include <sys/socket.h>
#include <types/buffers.h>
#include <types/channel.h>
#include <types/connection.h>
#include <common/config.h>

View File

@ -24,7 +24,7 @@
#include <proto/acl.h>
#include <proto/arg.h>
#include <proto/auth.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/log.h>
#include <proto/proxy.h>
#include <proto/stick_table.h>

View File

@ -19,6 +19,7 @@
#include <ctype.h>
#include <sys/types.h>
#include <common/buffer.h>
#include <common/compat.h>
#include <common/config.h>
#include <common/debug.h>
@ -30,7 +31,7 @@
#include <proto/acl.h>
#include <proto/arg.h>
#include <proto/backend.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/frontend.h>
#include <proto/lb_chash.h>
#include <proto/lb_fas.h>

143
src/buffer.c Normal file
View File

@ -0,0 +1,143 @@
/*
* Buffer management functions.
*
* Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
*
* 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 <stdio.h>
#include <string.h>
#include <common/config.h>
#include <common/buffer.h>
#include <types/global.h>
/* This function realigns input data in a possibly wrapping buffer so that it
* becomes contiguous and starts at the beginning of the buffer area. The
* function may only be used when the buffer's output is empty.
*/
void buffer_slow_realign(struct buffer *buf)
{
/* two possible cases :
* - the buffer is in one contiguous block, we move it in-place
* - the buffer is in two blocks, we move it via the swap_buffer
*/
if (buf->i) {
int block1 = buf->i;
int block2 = 0;
if (buf->p + buf->i > buf->data + buf->size) {
/* non-contiguous block */
block1 = buf->data + buf->size - buf->p;
block2 = buf->p + buf->i - (buf->data + buf->size);
}
if (block2)
memcpy(swap_buffer, buf->data, block2);
memmove(buf->data, buf->p, block1);
if (block2)
memcpy(buf->data + block1, swap_buffer, block2);
}
buf->p = buf->data;
}
/* Realigns a possibly non-contiguous buffer by bouncing bytes from source to
* destination. It does not use any intermediate buffer and does the move in
* place, though it will be slower than a simple memmove() on contiguous data,
* so it's desirable to use it only on non-contiguous buffers. No pointers are
* changed, the caller is responsible for that.
*/
void buffer_bounce_realign(struct buffer *buf)
{
int advance, to_move;
char *from, *to;
from = bo_ptr(buf);
advance = buf->data + buf->size - from;
if (!advance)
return;
to_move = buffer_len(buf);
while (to_move) {
char last, save;
last = *from;
to = from + advance;
if (to >= buf->data + buf->size)
to -= buf->size;
while (1) {
save = *to;
*to = last;
last = save;
to_move--;
if (!to_move)
break;
/* check if we went back home after rotating a number of bytes */
if (to == from)
break;
/* if we ended up in the empty area, let's walk to next place. The
* empty area is either between buf->r and from or before from or
* after buf->r.
*/
if (from > bi_end(buf)) {
if (to >= bi_end(buf) && to < from)
break;
} else if (from < bi_end(buf)) {
if (to < from || to >= bi_end(buf))
break;
}
/* we have overwritten a byte of the original set, let's move it */
to += advance;
if (to >= buf->data + buf->size)
to -= buf->size;
}
from++;
if (from >= buf->data + buf->size)
from -= buf->size;
}
}
/*
* Dumps part or all of a buffer.
*/
void buffer_dump(FILE *o, struct buffer *b, int from, int to)
{
fprintf(o, "Dumping buffer %p\n", b);
fprintf(o, " data=%p o=%d i=%d p=%p\n",
b->data, b->o, b->i, b->p);
if (!to || to > buffer_len(b))
to = buffer_len(b);
fprintf(o, "Dumping contents from byte %d to byte %d\n", from, to);
for (; from < to; from++) {
if ((from & 15) == 0)
fprintf(o, " %04x: ", from);
fprintf(o, "%02x ", b->data[from]);
if ((from & 15) == 7)
fprintf(o, "- ");
else if (((from & 15) == 15) && (from != to-1))
fprintf(o, "\n");
}
fprintf(o, "\n--\n");
}
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

View File

@ -26,6 +26,7 @@
#include <netinet/tcp.h>
#include <common/cfgparse.h>
#include <common/chunk.h>
#include <common/config.h>
#include <common/errors.h>
#include <common/memory.h>
@ -40,7 +41,7 @@
#include <proto/acl.h>
#include <proto/auth.h>
#include <proto/backend.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/checks.h>
#include <proto/dumpstats.h>
#include <proto/frontend.h>

View File

@ -1,7 +1,7 @@
/*
* Buffer management functions.
* Channel management functions.
*
* Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
* Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,9 +17,14 @@
#include <common/config.h>
#include <common/memory.h>
#include <proto/buffers.h>
#include <common/buffer.h>
#include <proto/channel.h>
#include <types/global.h>
/* Note: this code has not yet been completely cleaned up and still refers to
* the word "buffer" when "channel" is meant instead.
*/
struct pool_head *pool2_buffer;
@ -385,228 +390,6 @@ int buffer_insert_line2(struct channel *b, char *pos, const char *str, int len)
return delta;
}
/* This function realigns input data in a possibly wrapping buffer so that it
* becomes contiguous and starts at the beginning of the buffer area. The
* function may only be used when the buffer's output is empty.
*/
void buffer_slow_realign(struct buffer *buf)
{
/* two possible cases :
* - the buffer is in one contiguous block, we move it in-place
* - the buffer is in two blocks, we move it via the swap_buffer
*/
if (buf->i) {
int block1 = buf->i;
int block2 = 0;
if (buf->p + buf->i > buf->data + buf->size) {
/* non-contiguous block */
block1 = buf->data + buf->size - buf->p;
block2 = buf->p + buf->i - (buf->data + buf->size);
}
if (block2)
memcpy(swap_buffer, buf->data, block2);
memmove(buf->data, buf->p, block1);
if (block2)
memcpy(buf->data + block1, swap_buffer, block2);
}
buf->p = buf->data;
}
/* Realigns a possibly non-contiguous buffer by bouncing bytes from source to
* destination. It does not use any intermediate buffer and does the move in
* place, though it will be slower than a simple memmove() on contiguous data,
* so it's desirable to use it only on non-contiguous buffers. No pointers are
* changed, the caller is responsible for that.
*/
void buffer_bounce_realign(struct buffer *buf)
{
int advance, to_move;
char *from, *to;
from = bo_ptr(buf);
advance = buf->data + buf->size - from;
if (!advance)
return;
to_move = buffer_len(buf);
while (to_move) {
char last, save;
last = *from;
to = from + advance;
if (to >= buf->data + buf->size)
to -= buf->size;
while (1) {
save = *to;
*to = last;
last = save;
to_move--;
if (!to_move)
break;
/* check if we went back home after rotating a number of bytes */
if (to == from)
break;
/* if we ended up in the empty area, let's walk to next place. The
* empty area is either between buf->r and from or before from or
* after buf->r.
*/
if (from > bi_end(buf)) {
if (to >= bi_end(buf) && to < from)
break;
} else if (from < bi_end(buf)) {
if (to < from || to >= bi_end(buf))
break;
}
/* we have overwritten a byte of the original set, let's move it */
to += advance;
if (to >= buf->data + buf->size)
to -= buf->size;
}
from++;
if (from >= buf->data + buf->size)
from -= buf->size;
}
}
/*
* Does an snprintf() at the end of chunk <chk>, respecting the limit of
* at most chk->size chars. If the chk->len is over, nothing is added. Returns
* the new chunk size.
*/
int chunk_printf(struct chunk *chk, const char *fmt, ...)
{
va_list argp;
int ret;
if (!chk->str || !chk->size)
return 0;
va_start(argp, fmt);
ret = vsnprintf(chk->str + chk->len, chk->size - chk->len, fmt, argp);
if (ret >= chk->size - chk->len)
/* do not copy anything in case of truncation */
chk->str[chk->len] = 0;
else
chk->len += ret;
va_end(argp);
return chk->len;
}
/*
* Encode chunk <src> into chunk <dst>, respecting the limit of at most
* chk->size chars. Replace non-printable or special chracters with "&#%d;".
* If the chk->len is over, nothing is added. Returns the new chunk size.
*/
int chunk_htmlencode(struct chunk *dst, struct chunk *src) {
int i, l;
int olen, free;
char c;
olen = dst->len;
for (i = 0; i < src->len; i++) {
free = dst->size - dst->len;
if (!free) {
dst->len = olen;
return dst->len;
}
c = src->str[i];
if (!isascii(c) || !isprint((unsigned char)c) || c == '&' || c == '"' || c == '\'' || c == '<' || c == '>') {
l = snprintf(dst->str + dst->len, free, "&#%u;", (unsigned char)c);
if (free < l) {
dst->len = olen;
return dst->len;
}
dst->len += l;
} else {
dst->str[dst->len] = c;
dst->len++;
}
}
return dst->len;
}
/*
* Encode chunk <src> into chunk <dst>, respecting the limit of at most
* chk->size chars. Replace non-printable or char passed in qc with "<%02X>".
* If the chk->len is over, nothing is added. Returns the new chunk size.
*/
int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc) {
int i, l;
int olen, free;
char c;
olen = dst->len;
for (i = 0; i < src->len; i++) {
free = dst->size - dst->len;
if (!free) {
dst->len = olen;
return dst->len;
}
c = src->str[i];
if (!isascii(c) || !isprint((unsigned char)c) || c == '<' || c == '>' || c == qc) {
l = snprintf(dst->str + dst->len, free, "<%02X>", (unsigned char)c);
if (free < l) {
dst->len = olen;
return dst->len;
}
dst->len += l;
} else {
dst->str[dst->len] = c;
dst->len++;
}
}
return dst->len;
}
/*
* Dumps part or all of a buffer.
*/
void buffer_dump(FILE *o, struct buffer *b, int from, int to)
{
fprintf(o, "Dumping buffer %p\n", b);
fprintf(o, " data=%p o=%d i=%d p=%p\n",
b->data, b->o, b->i, b->p);
if (!to || to > buffer_len(b))
to = buffer_len(b);
fprintf(o, "Dumping contents from byte %d to byte %d\n", from, to);
for (; from < to; from++) {
if ((from & 15) == 0)
fprintf(o, " %04x: ", from);
fprintf(o, "%02x ", b->data[from]);
if ((from & 15) == 7)
fprintf(o, "- ");
else if (((from & 15) == 15) && (from != to-1))
fprintf(o, "\n");
}
fprintf(o, "\n--\n");
}
/*
* Local variables:
* c-indent-level: 8

View File

@ -26,6 +26,7 @@
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <common/chunk.h>
#include <common/compat.h>
#include <common/config.h>
#include <common/mini-clist.h>
@ -36,7 +37,6 @@
#include <proto/backend.h>
#include <proto/checks.h>
#include <proto/buffers.h>
#include <proto/fd.h>
#include <proto/log.h>
#include <proto/queue.h>

133
src/chunk.c Normal file
View File

@ -0,0 +1,133 @@
/*
* Chunk management functions.
*
* Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
*
* 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 <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <common/config.h>
#include <common/chunk.h>
/*
* Does an snprintf() at the end of chunk <chk>, respecting the limit of
* at most chk->size chars. If the chk->len is over, nothing is added. Returns
* the new chunk size.
*/
int chunk_printf(struct chunk *chk, const char *fmt, ...)
{
va_list argp;
int ret;
if (!chk->str || !chk->size)
return 0;
va_start(argp, fmt);
ret = vsnprintf(chk->str + chk->len, chk->size - chk->len, fmt, argp);
if (ret >= chk->size - chk->len)
/* do not copy anything in case of truncation */
chk->str[chk->len] = 0;
else
chk->len += ret;
va_end(argp);
return chk->len;
}
/*
* Encode chunk <src> into chunk <dst>, respecting the limit of at most
* chk->size chars. Replace non-printable or special chracters with "&#%d;".
* If the chk->len is over, nothing is added. Returns the new chunk size.
*/
int chunk_htmlencode(struct chunk *dst, struct chunk *src)
{
int i, l;
int olen, free;
char c;
olen = dst->len;
for (i = 0; i < src->len; i++) {
free = dst->size - dst->len;
if (!free) {
dst->len = olen;
return dst->len;
}
c = src->str[i];
if (!isascii(c) || !isprint((unsigned char)c) || c == '&' || c == '"' || c == '\'' || c == '<' || c == '>') {
l = snprintf(dst->str + dst->len, free, "&#%u;", (unsigned char)c);
if (free < l) {
dst->len = olen;
return dst->len;
}
dst->len += l;
} else {
dst->str[dst->len] = c;
dst->len++;
}
}
return dst->len;
}
/*
* Encode chunk <src> into chunk <dst>, respecting the limit of at most
* chk->size chars. Replace non-printable or char passed in qc with "<%02X>".
* If the chk->len is over, nothing is added. Returns the new chunk size.
*/
int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc)
{
int i, l;
int olen, free;
char c;
olen = dst->len;
for (i = 0; i < src->len; i++) {
free = dst->size - dst->len;
if (!free) {
dst->len = olen;
return dst->len;
}
c = src->str[i];
if (!isascii(c) || !isprint((unsigned char)c) || c == '<' || c == '>' || c == qc) {
l = snprintf(dst->str + dst->len, free, "<%02X>", (unsigned char)c);
if (free < l) {
dst->len = olen;
return dst->len;
}
dst->len += l;
} else {
dst->str[dst->len] = c;
dst->len++;
}
}
return dst->len;
}
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

View File

@ -40,7 +40,7 @@
#include <types/global.h>
#include <proto/backend.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/checks.h>
#include <proto/dumpstats.h>
#include <proto/fd.h>

View File

@ -22,6 +22,7 @@
#include <netinet/tcp.h>
#include <common/chunk.h>
#include <common/compat.h>
#include <common/config.h>
#include <common/debug.h>
@ -32,7 +33,7 @@
#include <proto/acl.h>
#include <proto/arg.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/fd.h>
#include <proto/frontend.h>
#include <proto/log.h>

View File

@ -52,6 +52,7 @@
#include <common/appsession.h>
#include <common/base64.h>
#include <common/cfgparse.h>
#include <common/chunk.h>
#include <common/compat.h>
#include <common/config.h>
#include <common/defaults.h>
@ -73,7 +74,7 @@
#include <proto/auth.h>
#include <proto/acl.h>
#include <proto/backend.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/checks.h>
#include <proto/fd.h>
#include <proto/hdr_idx.h>

View File

@ -28,7 +28,7 @@
#include <types/peers.h>
#include <proto/acl.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/fd.h>
#include <proto/log.h>
#include <proto/hdr_idx.h>

View File

@ -27,6 +27,7 @@
#include <common/appsession.h>
#include <common/base64.h>
#include <common/chunk.h>
#include <common/compat.h>
#include <common/config.h>
#include <common/debug.h>
@ -45,7 +46,7 @@
#include <proto/arg.h>
#include <proto/auth.h>
#include <proto/backend.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/checks.h>
#include <proto/dumpstats.h>
#include <proto/fd.h>

View File

@ -39,9 +39,8 @@
#include <proto/acl.h>
#include <proto/arg.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/connection.h>
//#include <proto/frontend.h>
#include <proto/log.h>
#include <proto/port_range.h>
#include <proto/protocols.h>
@ -52,7 +51,6 @@
#include <proto/stick_table.h>
#include <proto/stream_interface.h>
#include <proto/task.h>
#include <proto/buffers.h>
#ifdef CONFIG_HAP_CTTPROXY
#include <import/ip_tproxy.h>

View File

@ -22,6 +22,7 @@
#include <netinet/tcp.h>
#include <common/buffer.h>
#include <common/compat.h>
#include <common/config.h>
#include <common/debug.h>
@ -29,7 +30,6 @@
#include <common/ticks.h>
#include <common/time.h>
#include <proto/buffers.h>
#include <proto/connection.h>
#include <proto/fd.h>
#include <proto/freq_ctr.h>

View File

@ -14,10 +14,10 @@
#include <string.h>
#include <arpa/inet.h>
#include <common/chunk.h>
#include <common/standard.h>
#include <proto/arg.h>
#include <proto/buffers.h>
#include <proto/sample.h>
/* static sample used in sample_process() when <p> is NULL */

View File

@ -24,7 +24,7 @@
#include <proto/acl.h>
#include <proto/arg.h>
#include <proto/backend.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/checks.h>
#include <proto/connection.h>
#include <proto/dumpstats.h>

View File

@ -26,7 +26,7 @@
#include <common/ticks.h>
#include <common/time.h>
#include <proto/buffers.h>
#include <proto/channel.h>
#include <proto/connection.h>
#include <proto/fd.h>
#include <proto/frontend.h>