REORG: buffers: split buffers into chunk,buffer,channel
Many parts of the channel definition still make use of the "buffer" word.
diff --git a/Makefile b/Makefile
index 72b8888..73df397 100644
--- a/Makefile
+++ b/Makefile
@@ -540,7 +540,8 @@
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 @@
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 9fc9b61..ca00c7b 100644
--- a/Makefile.bsd
+++ b/Makefile.bsd
@@ -106,7 +106,8 @@
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 9469be9..a251c4f 100644
--- a/Makefile.osx
+++ b/Makefile.osx
@@ -103,7 +103,8 @@
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 0000000..a51744b
--- /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 <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:
+ */
diff --git a/include/common/chunk.h b/include/common/chunk.h
new file mode 100644
index 0000000..75eb030
--- /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 <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:
+ */
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 e0d43e9..6b5478d 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 <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_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 @@
/* 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 @@
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
@@ -317,29 +176,6 @@
}
/* 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.
*/
static inline int buffer_contig_space_res(const struct channel *chn)
@@ -347,63 +183,6 @@
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 @@
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)
{
@@ -575,19 +342,6 @@
}
/*
- * 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
* with <len> causing a wrapping at the end of the buffer. It's the caller's
@@ -669,91 +423,8 @@
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 449ddc1..b6a689c 100644
--- a/include/proto/dumpstats.h
+++ b/include/proto/dumpstats.h
@@ -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 */
diff --git a/include/types/arg.h b/include/types/arg.h
index 2762674..666a51f 100644
--- a/include/types/arg.h
+++ b/include/types/arg.h
@@ -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 */
diff --git a/include/types/buffers.h b/include/types/channel.h
similarity index 89%
rename from include/types/buffers.h
rename to include/types/channel.h
index 200e26c..cd16d9c 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 <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 @@
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 @@
long.
*/
-#endif /* _TYPES_BUFFERS_H */
+#endif /* _TYPES_CHANNEL_H */
/*
* Local variables:
diff --git a/include/types/global.h b/include/types/global.h
index b4fa23e..b55481b 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -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>
diff --git a/include/types/log.h b/include/types/log.h
index 2086860..ac985fc 100644
--- a/include/types/log.h
+++ b/include/types/log.h
@@ -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
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
index 158f094..665ec75 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 <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 */
diff --git a/include/types/proxy.h b/include/types/proxy.h
index c93edd2..13a08a5 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -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>
diff --git a/include/types/sample.h b/include/types/sample.h
index b806a12..2f5ce86 100644
--- a/include/types/sample.h
+++ b/include/types/sample.h
@@ -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 @@
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 c952885..689441c 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -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>
diff --git a/include/types/session.h b/include/types/session.h
index 9180a94..cce55a4 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -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>
diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h
index 5985619..87f951e 100644
--- a/include/types/stream_interface.h
+++ b/include/types/stream_interface.h
@@ -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>
diff --git a/src/acl.c b/src/acl.c
index 1680ac9..d8e35b2 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -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>
diff --git a/src/backend.c b/src/backend.c
index b777cc3..998e02c 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -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>
diff --git a/src/buffer.c b/src/buffer.c
new file mode 100644
index 0000000..764f692
--- /dev/null
+++ b/src/buffer.c
@@ -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:
+ */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 44397fc..9781783 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -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>
diff --git a/src/buffers.c b/src/channel.c
similarity index 67%
rename from src/buffers.c
rename to src/channel.c
index db4b435..2789e89 100644
--- a/src/buffers.c
+++ b/src/channel.c
@@ -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,229 +390,7 @@
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
* c-basic-offset: 8
diff --git a/src/checks.c b/src/checks.c
index 2cde26b..93f93df 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -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>
diff --git a/src/chunk.c b/src/chunk.c
new file mode 100644
index 0000000..a4cbb7d
--- /dev/null
+++ b/src/chunk.c
@@ -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:
+ */
diff --git a/src/dumpstats.c b/src/dumpstats.c
index f7252a4..f150d98 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -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>
diff --git a/src/frontend.c b/src/frontend.c
index b07d3d1..ad4b970 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -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>
diff --git a/src/haproxy.c b/src/haproxy.c
index f104740..3427dcc 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -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>
diff --git a/src/peers.c b/src/peers.c
index c293971..894502a 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -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>
diff --git a/src/proto_http.c b/src/proto_http.c
index de1cec6..a7e7b6e 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -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>
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 9ff5b66..bdab4ab 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -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>
diff --git a/src/raw_sock.c b/src/raw_sock.c
index e13749e..80c8fb3 100644
--- a/src/raw_sock.c
+++ b/src/raw_sock.c
@@ -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>
diff --git a/src/sample.c b/src/sample.c
index f14b99b..aec94fe 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -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 */
diff --git a/src/session.c b/src/session.c
index f2330d6..db6dec4 100644
--- a/src/session.c
+++ b/src/session.c
@@ -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>
diff --git a/src/stream_interface.c b/src/stream_interface.c
index 764bb3b..fe80b91 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -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>