diff --git a/Makefile b/Makefile index 72b8888b0..73df39738 100644 --- a/Makefile +++ b/Makefile @@ -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 \ diff --git a/Makefile.bsd b/Makefile.bsd index 9fc9b6165..ca00c7b89 100644 --- a/Makefile.bsd +++ b/Makefile.bsd @@ -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 \ diff --git a/Makefile.osx b/Makefile.osx index 9469be965..a251c4ffc 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -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 \ diff --git a/include/common/buffer.h b/include/common/buffer.h new file mode 100644 index 000000000..a51744bb0 --- /dev/null +++ b/include/common/buffer.h @@ -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 +#include +#include + +#include + + +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]; /* 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 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 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 and +, + * and enforces a limit on buf->data + buf->size. 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 , 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 . + * If 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 + * . 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 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 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: + */ diff --git a/include/common/chunk.h b/include/common/chunk.h new file mode 100644 index 000000000..75eb03057 --- /dev/null +++ b/include/common/chunk.h @@ -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 +#include + +#include + + +/* 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: + */ diff --git a/include/proto/buffers.h b/include/proto/channel.h similarity index 60% rename from include/proto/buffers.h rename to include/proto/channel.h index e0d43e979..6b5478d10 100644 --- a/include/proto/buffers.h +++ b/include/proto/channel.h @@ -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 #include #include #include +#include #include #include #include -#include #include 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 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 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 and +, - * and enforces a limit on buf->data + buf->size. 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 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 , 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 . - * If 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 - * . 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 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 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 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: diff --git a/include/proto/dumpstats.h b/include/proto/dumpstats.h index 449ddc183..b6a689c3a 100644 --- a/include/proto/dumpstats.h +++ b/include/proto/dumpstats.h @@ -24,8 +24,7 @@ #define _PROTO_DUMPSTATS_H #include -#include -#include +#include /* Flags for applet.ctx.stats.flags */ #define STAT_FMT_CSV 0x00000001 /* dump the stats in CSV format instead of HTML */ diff --git a/include/types/arg.h b/include/types/arg.h index 2762674ee..666a51f0f 100644 --- a/include/types/arg.h +++ b/include/types/arg.h @@ -24,7 +24,8 @@ #include #include -#include + +#include enum { ARGT_STOP = 0, /* end of the arg list */ diff --git a/include/types/buffers.h b/include/types/channel.h similarity index 90% rename from include/types/buffers.h rename to include/types/channel.h index 200e26cac..cd16d9cb0 100644 --- a/include/types/buffers.h +++ b/include/types/channel.h @@ -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 -#include +#include +#include #include -/* 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]; /* 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: diff --git a/include/types/global.h b/include/types/global.h index b4fa23e0e..b55481bfc 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/include/types/log.h b/include/types/log.h index 20868600b..ac985fc47 100644 --- a/include/types/log.h +++ b/include/types/log.h @@ -26,6 +26,7 @@ #include #include #include +#include #define MAX_SYSLOG_LEN 1024 #define NB_LOG_FACILITIES 24 diff --git a/include/types/proto_http.h b/include/types/proto_http.h index 158f0948d..665ec7529 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -22,9 +22,9 @@ #ifndef _TYPES_PROTO_HTTP_H #define _TYPES_PROTO_HTTP_H +#include #include -#include #include /* These are the flags that are found in txn->flags */ diff --git a/include/types/proxy.h b/include/types/proxy.h index c93edd2fd..13a08a58f 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include -#include #include #include #include diff --git a/include/types/sample.h b/include/types/sample.h index b806a12c5..2f5ce86d5 100644 --- a/include/types/sample.h +++ b/include/types/sample.h @@ -25,8 +25,9 @@ #include #include + +#include #include -#include /* 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 diff --git a/include/types/server.h b/include/types/server.h index c95288551..689441ce4 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -29,7 +29,6 @@ #include #include -#include #include #include #include diff --git a/include/types/session.h b/include/types/session.h index 9180a94b5..cce55a4bf 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index 598561999..87f951e11 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/src/acl.c b/src/acl.c index 1680ac98e..d8e35b246 100644 --- a/src/acl.c +++ b/src/acl.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/backend.c b/src/backend.c index b777cc33d..998e02c1f 100644 --- a/src/backend.c +++ b/src/backend.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -30,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/buffer.c b/src/buffer.c new file mode 100644 index 000000000..764f69284 --- /dev/null +++ b/src/buffer.c @@ -0,0 +1,143 @@ +/* + * Buffer management functions. + * + * Copyright 2000-2012 Willy Tarreau + * + * 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 +#include + +#include +#include + +#include + +/* 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: + */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 44397fcf9..978178345 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -40,7 +41,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/buffers.c b/src/channel.c similarity index 67% rename from src/buffers.c rename to src/channel.c index db4b435de..2789e89be 100644 --- a/src/buffers.c +++ b/src/channel.c @@ -1,7 +1,7 @@ /* - * Buffer management functions. + * Channel management functions. * - * Copyright 2000-2010 Willy Tarreau + * Copyright 2000-2012 Willy Tarreau * * 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 #include -#include +#include +#include #include + +/* 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 , 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 into chunk , 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 into chunk , 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 diff --git a/src/checks.c b/src/checks.c index 2cde26ba1..93f93dfc2 100644 --- a/src/checks.c +++ b/src/checks.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -36,7 +37,6 @@ #include #include -#include #include #include #include diff --git a/src/chunk.c b/src/chunk.c new file mode 100644 index 000000000..a4cbb7d2c --- /dev/null +++ b/src/chunk.c @@ -0,0 +1,133 @@ +/* + * Chunk management functions. + * + * Copyright 2000-2012 Willy Tarreau + * + * 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 +#include +#include +#include + +#include +#include + +/* + * Does an snprintf() at the end of chunk , 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 into chunk , 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 into chunk , 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: + */ diff --git a/src/dumpstats.c b/src/dumpstats.c index f7252a460..f150d9813 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/frontend.c b/src/frontend.c index b07d3d1f8..ad4b9707f 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -22,6 +22,7 @@ #include +#include #include #include #include @@ -32,7 +33,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/haproxy.c b/src/haproxy.c index f1047405b..3427dccf5 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/peers.c b/src/peers.c index c293971e1..894502ac7 100644 --- a/src/peers.c +++ b/src/peers.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/proto_http.c b/src/proto_http.c index de1cec680..a7e7b6e53 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 9ff5b666b..bdab4ab32 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -39,9 +39,8 @@ #include #include -#include +#include #include -//#include #include #include #include @@ -52,7 +51,6 @@ #include #include #include -#include #ifdef CONFIG_HAP_CTTPROXY #include diff --git a/src/raw_sock.c b/src/raw_sock.c index e13749e8f..80c8fb38d 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -22,6 +22,7 @@ #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include -#include #include #include #include diff --git a/src/sample.c b/src/sample.c index f14b99b91..aec94fe2a 100644 --- a/src/sample.c +++ b/src/sample.c @@ -14,10 +14,10 @@ #include #include +#include #include #include -#include #include /* static sample used in sample_process() when

is NULL */ diff --git a/src/session.c b/src/session.c index f2330d6d0..db6dec4da 100644 --- a/src/session.c +++ b/src/session.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/stream_interface.c b/src/stream_interface.c index 764bb3b56..fe80b91c1 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include