aboutsummaryrefslogtreecommitdiffstats
path: root/main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch')
-rw-r--r--main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch6095
1 files changed, 6095 insertions, 0 deletions
diff --git a/main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch b/main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch
new file mode 100644
index 0000000000..7380ce5ce8
--- /dev/null
+++ b/main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch
@@ -0,0 +1,6095 @@
+From 6afad87d2ed66a48cda2a7c01dbcc59023774b73 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
+Date: Sun, 8 Feb 2015 12:37:10 +0000
+Subject: [PATCH 15/29] fix buffer, chunk and http_chunk API
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+ * remove unused structs and functions
+ (buffer_array, read_buffer)
+ * change return type from int to void for many functions,
+ as the return value (indicating error/success) was never checked,
+ and the function would only fail on programming errors and not on
+ invalid input; changed functions to use force_assert instead of
+ returning an error.
+ * all "len" parameters now are the real size of the memory to be read.
+ the length of strings is given always without the terminating 0.
+ * the "buffer" struct still counts the terminating 0 in ->used,
+ provide buffer_string_length() to get the length of a string in a
+ buffer.
+ unset config "strings" have used == 0, which is used in some places
+ to distinguish unset values from "" (empty string) values.
+ * most buffer usages should now use it as string container.
+ * optimise some buffer copying by "moving" data to other buffers
+ * use (u)intmax_t for generic int-to-string functions
+ * remove unused enum values: UNUSED_CHUNK, ENCODING_UNSET
+ * converted BUFFER_APPEND_SLASH to inline function (no macro feature
+ needed)
+ * refactor: create chunkqueue_steal: moving (partial) chunks into another
+ queue
+ * http_chunk: added separate function to terminate chunked body instead of
+ magic handling in http_chunk_append_mem().
+ http_chunk_append_* now handle empty chunks, and never terminate the
+ chunked body.
+
+From: Stefan Bühler <stbuehler@web.de>
+
+git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2975 152afb58-edef-0310-8abb-c4023f1b3aa9
+---
+ NEWS | 1 +
+ src/array.c | 2 +-
+ src/buffer.c | 752 ++++++++++++++++++----------------------------
+ src/buffer.h | 170 ++++++-----
+ src/chunk.c | 244 +++++++--------
+ src/chunk.h | 18 +-
+ src/configfile-glue.c | 16 +-
+ src/configfile.c | 26 +-
+ src/configparser.y | 26 +-
+ src/connections.c | 28 +-
+ src/data_array.c | 2 +-
+ src/data_config.c | 4 +-
+ src/data_count.c | 2 +-
+ src/data_fastcgi.c | 4 +-
+ src/data_integer.c | 2 +-
+ src/data_string.c | 8 +-
+ src/etag.c | 10 +-
+ src/http-header-glue.c | 6 +-
+ src/http_auth.c | 14 +-
+ src/http_chunk.c | 71 ++---
+ src/http_chunk.h | 8 +-
+ src/log.c | 16 +-
+ src/mod_access.c | 2 +-
+ src/mod_accesslog.c | 22 +-
+ src/mod_alias.c | 6 +-
+ src/mod_auth.c | 6 +-
+ src/mod_cgi.c | 49 ++-
+ src/mod_cml.c | 10 +-
+ src/mod_cml_lua.c | 14 +-
+ src/mod_compress.c | 20 +-
+ src/mod_dirlisting.c | 17 +-
+ src/mod_evhost.c | 8 +-
+ src/mod_expire.c | 2 +-
+ src/mod_fastcgi.c | 219 ++++----------
+ src/mod_flv_streaming.c | 4 +-
+ src/mod_indexfile.c | 6 +-
+ src/mod_magnet.c | 8 +-
+ src/mod_magnet_cache.c | 4 +-
+ src/mod_mysql_vhost.c | 18 +-
+ src/mod_proxy.c | 77 +----
+ src/mod_redirect.c | 2 +-
+ src/mod_rewrite.c | 4 +-
+ src/mod_rrdtool.c | 12 +-
+ src/mod_scgi.c | 135 +++------
+ src/mod_secure_download.c | 14 +-
+ src/mod_setenv.c | 8 +-
+ src/mod_simple_vhost.c | 26 +-
+ src/mod_ssi.c | 33 +-
+ src/mod_ssi_expr.c | 4 +-
+ src/mod_staticfile.c | 16 +-
+ src/mod_status.c | 50 +--
+ src/mod_trigger_b4_dl.c | 10 +-
+ src/mod_uploadprogress.c | 10 +-
+ src/mod_userdir.c | 20 +-
+ src/mod_usertrack.c | 16 +-
+ src/mod_webdav.c | 62 ++--
+ src/network.c | 28 +-
+ src/plugin.c | 2 +-
+ src/request.c | 6 +-
+ src/response.c | 32 +-
+ src/server.c | 2 +-
+ src/stat_cache.c | 26 +-
+ 62 files changed, 1044 insertions(+), 1396 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index fd537e8..ddb370d 100644
+--- a/NEWS
++++ b/NEWS
+@@ -15,6 +15,7 @@ NEWS
+ * [network] fix compile break in calculation of sockaddr_un size if SUN_LEN is not defined (fixes #2609)
+ * [connections] fix bug in connection state handling
+ * print backtrace in assert logging with libunwind
++ * major refactoring of internal buffer/chunk handling
+
+ - 1.4.35 - 2014-03-12
+ * [network/ssl] fix build error if TLSEXT is disabled
+diff --git a/src/array.c b/src/array.c
+index c9af995..9a15abd 100644
+--- a/src/array.c
++++ b/src/array.c
+@@ -188,7 +188,7 @@ int array_insert_unique(array *a, data_unset *str) {
+
+ /* generate unique index if neccesary */
+ if (str->key->used == 0 || str->is_index_key) {
+- buffer_copy_long(str->key, a->unique_ndx++);
++ buffer_copy_int(str->key, a->unique_ndx++);
+ str->is_index_key = 1;
+ }
+
+diff --git a/src/buffer.c b/src/buffer.c
+index b4bd415..caaa5bb 100644
+--- a/src/buffer.c
++++ b/src/buffer.c
+@@ -7,12 +7,6 @@
+ #include <assert.h>
+ #include <ctype.h>
+
+-#if defined HAVE_STDINT_H
+-# include <stdint.h>
+-#elif defined HAVE_INTTYPES_H
+-# include <inttypes.h>
+-#endif
+-
+ static const char hex_chars[] = "0123456789abcdef";
+
+
+@@ -34,177 +28,160 @@ buffer* buffer_init(void) {
+ return b;
+ }
+
+-buffer *buffer_init_buffer(buffer *src) {
++buffer *buffer_init_buffer(const buffer *src) {
+ buffer *b = buffer_init();
+- buffer_copy_string_buffer(b, src);
++ buffer_copy_buffer(b, src);
+ return b;
+ }
+
+-/**
+- * free the buffer
+- *
+- */
++buffer *buffer_init_string(const char *str) {
++ buffer *b = buffer_init();
++ buffer_copy_string(b, str);
++ return b;
++}
+
+ void buffer_free(buffer *b) {
+- if (!b) return;
++ if (NULL == b) return;
+
+ free(b->ptr);
+ free(b);
+ }
+
+ void buffer_reset(buffer *b) {
+- if (!b) return;
++ if (NULL == b) return;
+
+ /* limit don't reuse buffer larger than ... bytes */
+ if (b->size > BUFFER_MAX_REUSE_SIZE) {
+ free(b->ptr);
+ b->ptr = NULL;
+ b->size = 0;
+- } else if (b->size) {
++ } else if (b->size > 0) {
+ b->ptr[0] = '\0';
+ }
+
+ b->used = 0;
+ }
+
++void buffer_move(buffer *b, buffer *src) {
++ buffer tmp;
+
+-/**
+- *
+- * allocate (if neccessary) enough space for 'size' bytes and
+- * set the 'used' counter to 0
+- *
+- */
++ if (NULL == b) {
++ buffer_reset(src);
++ return;
++ }
++ buffer_reset(b);
++ if (NULL == src) return;
++
++ tmp = *src; *src = *b; *b = tmp;
++}
+
+ #define BUFFER_PIECE_SIZE 64
++static size_t buffer_align_size(size_t size) {
++ size_t align = BUFFER_PIECE_SIZE - (size % BUFFER_PIECE_SIZE);
++ /* overflow on unsinged size_t is defined to wrap around */
++ if (size + align < size) return size;
++ return size + align;
++}
+
+-int buffer_prepare_copy(buffer *b, size_t size) {
+- if (!b) return -1;
++char* buffer_prepare_copy(buffer *b, size_t size) {
++ force_assert(NULL != b);
+
+- if ((0 == b->size) ||
+- (size > b->size)) {
+- if (b->size) free(b->ptr);
++ /* also allocate space for terminating 0 */
++ /* check for overflow: unsigned overflow is defined to wrap around */
++ force_assert(1 + size > size);
++ ++size;
+
+- b->size = size;
++ if (0 == b->size || size > b->size) {
++ if (NULL != b->ptr) free(b->ptr);
++ b->ptr = NULL;
+
+- /* always allocate a multiply of BUFFER_PIECE_SIZE */
+- b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
++ b->size = buffer_align_size(size);
++ force_assert(b->size > 0);
+
+ b->ptr = malloc(b->size);
+- force_assert(b->ptr);
++ force_assert(NULL != b->ptr);
+ }
+- b->used = 0;
+- return 0;
+-}
+-
+-/**
+- *
+- * increase the internal buffer (if neccessary) to append another 'size' byte
+- * ->used isn't changed
+- *
+- */
+
+-int buffer_prepare_append(buffer *b, size_t size) {
+- if (!b) return -1;
+-
+- if (0 == b->size) {
+- b->size = size;
+-
+- /* always allocate a multiply of BUFFER_PIECE_SIZE */
+- b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
++ /* reset */
++ b->used = 0;
++ b->ptr[0] = '\0';
+
+- b->ptr = malloc(b->size);
+- b->used = 0;
+- force_assert(b->ptr);
+- } else if (b->used + size > b->size) {
+- b->size += size;
++ return b->ptr;
++}
+
+- /* always allocate a multiply of BUFFER_PIECE_SIZE */
+- b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
++char* buffer_prepare_append(buffer *b, size_t size) {
++ size_t req_size;
++ force_assert(NULL != b);
+
+- b->ptr = realloc(b->ptr, b->size);
+- force_assert(b->ptr);
++ if (buffer_string_is_empty(b)) {
++ size_t old_used = b->used; /* either 0 or 1 */
++ /* just prepare copy (free+malloc instead of realloc) */
++ buffer_prepare_copy(b, size);
++ b->used = old_used; /* buffer_prepare_append mustn't modify b->used */
++ return b->ptr;
+ }
+- return 0;
+-}
+
+-int buffer_copy_string(buffer *b, const char *s) {
+- size_t s_len;
++ /* not empty, b->used already includes a terminating 0 */
++ req_size = b->used + size;
+
+- if (!s || !b) return -1;
++ /* check for overflow: unsigned overflow is defined to wrap around */
++ force_assert(req_size >= b->used);
+
+- s_len = strlen(s) + 1;
+- buffer_prepare_copy(b, s_len);
++ if (req_size > b->size) {
++ char *ptr;
++ b->size = buffer_align_size(req_size);
+
+- memcpy(b->ptr, s, s_len);
+- b->used = s_len;
++ ptr = realloc(b->ptr, b->size);
++ force_assert(NULL != ptr);
++ b->ptr = ptr;
++ }
+
+- return 0;
++ return b->ptr + b->used - 1;
+ }
+
+-int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
+- if (!s || !b) return -1;
+-#if 0
+- /* removed optimization as we have to keep the empty string
+- * in some cases for the config handling
+- *
+- * url.access-deny = ( "" )
+- */
+- if (s_len == 0) return 0;
+-#endif
+- buffer_prepare_copy(b, s_len + 1);
+-
+- memcpy(b->ptr, s, s_len);
+- b->ptr[s_len] = '\0';
+- b->used = s_len + 1;
++void buffer_commit(buffer *b, size_t size)
++{
++ force_assert(NULL != b);
++ force_assert(b->size > 0);
+
+- return 0;
+-}
++ if (0 == b->used) b->used = 1;
+
+-int buffer_copy_string_buffer(buffer *b, const buffer *src) {
+- if (!src) return -1;
++ if (size > 0) {
++ /* check for overflow: unsigned overflow is defined to wrap around */
++ force_assert(b->used + size > b->used);
+
+- if (src->used == 0) {
+- buffer_reset(b);
+- return 0;
++ force_assert(b->used + size <= b->size);
++ b->used += size;
+ }
+- return buffer_copy_string_len(b, src->ptr, src->used - 1);
++
++ b->ptr[b->used - 1] = '\0';
+ }
+
+-int buffer_append_string(buffer *b, const char *s) {
+- size_t s_len;
++void buffer_copy_string(buffer *b, const char *s) {
++ buffer_copy_string_len(b, s, NULL != s ? strlen(s) : 0);
++}
+
+- if (!s || !b) return -1;
++void buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
++ force_assert(NULL != b);
++ force_assert(NULL != s || s_len == 0);
+
+- s_len = strlen(s);
+- buffer_prepare_append(b, s_len + 1);
+- if (b->used == 0)
+- b->used++;
++ buffer_prepare_copy(b, s_len);
+
+- memcpy(b->ptr + b->used - 1, s, s_len + 1);
+- b->used += s_len;
++ if (0 != s_len) memcpy(b->ptr, s, s_len);
+
+- return 0;
++ buffer_commit(b, s_len);
+ }
+
+-int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen) {
+- size_t s_len;
+-
+- if (!s || !b) return -1;
+-
+- s_len = strlen(s);
+- if (s_len > maxlen) s_len = maxlen;
+- buffer_prepare_append(b, maxlen + 1);
+- if (b->used == 0)
+- b->used++;
+-
+- memcpy(b->ptr + b->used - 1, s, s_len);
+- if (maxlen > s_len) {
+- memset(b->ptr + b->used - 1 + s_len, ' ', maxlen - s_len);
++void buffer_copy_buffer(buffer *b, const buffer *src) {
++ if (NULL == src || 0 == src->used) {
++ buffer_prepare_copy(b, 0);
++ } else {
++ buffer_copy_string_len(b, src->ptr, buffer_string_length(src));
+ }
++}
+
+- b->used += maxlen;
+- b->ptr[b->used - 1] = '\0';
+- return 0;
++void buffer_append_string(buffer *b, const char *s) {
++ buffer_append_string_len(b, s, NULL != s ? strlen(s) : 0);
+ }
+
+ /**
+@@ -218,176 +195,138 @@ int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen) {
+ * @param s_len size of the string (without the terminating \0)
+ */
+
+-int buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
+- if (!s || !b) return -1;
+- if (s_len == 0) return 0;
+-
+- buffer_prepare_append(b, s_len + 1);
+- if (b->used == 0)
+- b->used++;
+-
+- memcpy(b->ptr + b->used - 1, s, s_len);
+- b->used += s_len;
+- b->ptr[b->used - 1] = '\0';
+-
+- return 0;
+-}
++void buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
++ char *target_buf;
+
+-int buffer_append_string_buffer(buffer *b, const buffer *src) {
+- if (!src) return -1;
+- if (src->used == 0) return 0;
++ force_assert(NULL != b);
++ force_assert(NULL != s || s_len == 0);
+
+- return buffer_append_string_len(b, src->ptr, src->used - 1);
+-}
++ target_buf = buffer_prepare_append(b, s_len);
+
+-int buffer_append_memory(buffer *b, const char *s, size_t s_len) {
+- if (!s || !b) return -1;
+- if (s_len == 0) return 0;
++ /* only append to 0-terminated string */
++ force_assert('\0' == *target_buf);
+
+- buffer_prepare_append(b, s_len);
+- memcpy(b->ptr + b->used, s, s_len);
+- b->used += s_len;
++ if (s_len > 0) memcpy(target_buf, s, s_len);
+
+- return 0;
++ buffer_commit(b, s_len);
+ }
+
+-int buffer_copy_memory(buffer *b, const char *s, size_t s_len) {
+- if (!s || !b) return -1;
+-
+- b->used = 0;
+-
+- return buffer_append_memory(b, s, s_len);
++void buffer_append_string_buffer(buffer *b, const buffer *src) {
++ if (NULL == src) {
++ buffer_append_string_len(b, NULL, 0);
++ } else {
++ buffer_append_string_len(b, src->ptr, buffer_string_length(src));
++ }
+ }
+
+-int buffer_append_long_hex(buffer *b, unsigned long value) {
++void buffer_append_long_hex(buffer *b, unsigned long value) {
+ char *buf;
+ int shift = 0;
+- unsigned long copy = value;
+
+- while (copy) {
+- copy >>= 4;
+- shift++;
++ {
++ unsigned long copy = value;
++ do {
++ copy >>= 8;
++ shift += 2; /* counting nibbles (4 bits) */
++ } while (0 != copy);
+ }
+- if (shift == 0)
+- shift++;
+- if (shift & 0x01)
+- shift++;
+-
+- buffer_prepare_append(b, shift + 1);
+- if (b->used == 0)
+- b->used++;
+- buf = b->ptr + (b->used - 1);
+- b->used += shift;
+-
+- shift <<= 2;
++
++ buf = buffer_prepare_append(b, shift);
++ buffer_commit(b, shift); /* will fill below */
++
++ shift <<= 2; /* count bits now */
+ while (shift > 0) {
+ shift -= 4;
+ *(buf++) = hex_chars[(value >> shift) & 0x0F];
+ }
+- *buf = '\0';
+-
+- return 0;
+ }
+
+-int LI_ltostr(char *buf, long val) {
+- char swap;
+- char *end;
+- int len = 1;
+-
+- if (val < 0) {
+- len++;
+- *(buf++) = '-';
+- val = -val;
+- }
+-
+- end = buf;
+- while (val > 9) {
+- *(end++) = '0' + (val % 10);
+- val = val / 10;
+- }
+- *(end) = '0' + val;
+- *(end + 1) = '\0';
+- len += end - buf;
++static char* utostr(char * const buf_end, uintmax_t val) {
++ char *cur = buf_end;
++ do {
++ int mod = val % 10;
++ val /= 10;
++ /* prepend digit mod */
++ *(--cur) = (char) ('0' + mod);
++ } while (0 != val);
++ return cur;
++}
+
+- while (buf < end) {
+- swap = *end;
+- *end = *buf;
+- *buf = swap;
++static char* itostr(char * const buf_end, intmax_t val) {
++ char *cur = buf_end;
++ if (val >= 0) return utostr(buf_end, (uintmax_t) val);
+
+- buf++;
+- end--;
+- }
++ /* can't take absolute value, as it isn't defined for INTMAX_MIN */
++ do {
++ int mod = val % 10;
++ val /= 10;
++ /* val * 10 + mod == orig val, -10 < mod < 10 */
++ /* we want a negative mod */
++ if (mod > 0) {
++ mod -= 10;
++ val += 1;
++ }
++ /* prepend digit abs(mod) */
++ *(--cur) = (char) ('0' + (-mod));
++ } while (0 != val);
++ *(--cur) = '-';
+
+- return len;
++ return cur;
+ }
+
+-int buffer_append_long(buffer *b, long val) {
+- if (!b) return -1;
++void buffer_append_int(buffer *b, intmax_t val) {
++ char buf[LI_ITOSTRING_LENGTH];
++ char* const buf_end = buf + sizeof(buf);
++ char *str;
+
+- buffer_prepare_append(b, 32);
+- if (b->used == 0)
+- b->used++;
++ force_assert(NULL != b);
+
+- b->used += LI_ltostr(b->ptr + (b->used - 1), val);
+- return 0;
++ str = itostr(buf_end, val);
++ force_assert(buf_end > str && str >= buf);
++
++ buffer_append_string_len(b, str, buf_end - str);
+ }
+
+-int buffer_copy_long(buffer *b, long val) {
+- if (!b) return -1;
++void buffer_copy_int(buffer *b, intmax_t val) {
++ force_assert(NULL != b);
+
+ b->used = 0;
+- return buffer_append_long(b, val);
++ buffer_append_int(b, val);
+ }
+
+-#if !defined(SIZEOF_LONG) || (SIZEOF_LONG != SIZEOF_OFF_T)
+-int buffer_append_off_t(buffer *b, off_t val) {
+- char swap;
+- char *end;
+- char *start;
+- int len = 1;
+-
+- if (!b) return -1;
++void li_itostrn(char *buf, size_t buf_len, intmax_t val) {
++ char p_buf[LI_ITOSTRING_LENGTH];
++ char* const p_buf_end = p_buf + sizeof(p_buf);
++ char* str = p_buf_end - 1;
++ *str = '\0';
+
+- buffer_prepare_append(b, 32);
+- if (b->used == 0)
+- b->used++;
++ str = itostr(str, val);
++ force_assert(p_buf_end > str && str >= p_buf);
+
+- start = b->ptr + (b->used - 1);
+- if (val < 0) {
+- len++;
+- *(start++) = '-';
+- val = -val;
+- }
++ force_assert(buf_len >= (size_t) (p_buf_end - str));
++ memcpy(buf, str, p_buf_end - str);
++}
+
+- end = start;
+- while (val > 9) {
+- *(end++) = '0' + (val % 10);
+- val = val / 10;
+- }
+- *(end) = '0' + val;
+- *(end + 1) = '\0';
+- len += end - start;
++void li_itostr(char *buf, intmax_t val) {
++ li_itostrn(buf, LI_ITOSTRING_LENGTH, val);
++}
+
+- while (start < end) {
+- swap = *end;
+- *end = *start;
+- *start = swap;
++void li_utostrn(char *buf, size_t buf_len, uintmax_t val) {
++ char p_buf[LI_ITOSTRING_LENGTH];
++ char* const p_buf_end = p_buf + sizeof(p_buf);
++ char* str = p_buf_end - 1;
++ *str = '\0';
+
+- start++;
+- end--;
+- }
++ str = utostr(str, val);
++ force_assert(p_buf_end > str && str >= p_buf);
+
+- b->used += len;
+- return 0;
++ force_assert(buf_len >= (size_t) (p_buf_end - str));
++ memcpy(buf, str, p_buf_end - str);
+ }
+
+-int buffer_copy_off_t(buffer *b, off_t val) {
+- if (!b) return -1;
+-
+- b->used = 0;
+- return buffer_append_off_t(b, val);
++void li_utostr(char *buf, uintmax_t val) {
++ li_utostrn(buf, LI_ITOSTRING_LENGTH, val);
+ }
+-#endif /* !defined(SIZEOF_LONG) || (SIZEOF_LONG != SIZEOF_OFF_T) */
+
+ char int2hex(char c) {
+ return hex_chars[(c & 0x0F)];
+@@ -397,99 +336,21 @@ char int2hex(char c) {
+ * returns 0xFF on invalid input.
+ */
+ char hex2int(unsigned char hex) {
+- hex = hex - '0';
+- if (hex > 9) {
+- hex = (hex + '0' - 1) | 0x20;
+- hex = hex - 'a' + 11;
++ unsigned char value = hex - '0';
++ if (value > 9) {
++ hex |= 0x20; /* to lower case */
++ value = hex - 'a' + 10;
++ if (value < 10) value = 0xff;
+ }
+- if (hex > 15)
+- hex = 0xFF;
++ if (value > 15) value = 0xff;
+
+- return hex;
++ return value;
+ }
+
+-
+-/**
+- * init the buffer
+- *
+- */
+-
+-buffer_array* buffer_array_init(void) {
+- buffer_array *b;
+-
+- b = malloc(sizeof(*b));
+-
+- force_assert(b);
+- b->ptr = NULL;
+- b->size = 0;
+- b->used = 0;
+-
+- return b;
+-}
+-
+-void buffer_array_reset(buffer_array *b) {
+- size_t i;
+-
+- if (!b) return;
+-
+- /* if they are too large, reduce them */
+- for (i = 0; i < b->used; i++) {
+- buffer_reset(b->ptr[i]);
+- }
+-
+- b->used = 0;
+-}
+-
+-
+-/**
+- * free the buffer_array
+- *
+- */
+-
+-void buffer_array_free(buffer_array *b) {
+- size_t i;
+- if (!b) return;
+-
+- for (i = 0; i < b->size; i++) {
+- if (b->ptr[i]) buffer_free(b->ptr[i]);
+- }
+- free(b->ptr);
+- free(b);
+-}
+-
+-buffer *buffer_array_append_get_buffer(buffer_array *b) {
+- size_t i;
+-
+- if (b->size == 0) {
+- b->size = 16;
+- b->ptr = malloc(sizeof(*b->ptr) * b->size);
+- force_assert(b->ptr);
+- for (i = 0; i < b->size; i++) {
+- b->ptr[i] = NULL;
+- }
+- } else if (b->size == b->used) {
+- b->size += 16;
+- b->ptr = realloc(b->ptr, sizeof(*b->ptr) * b->size);
+- force_assert(b->ptr);
+- for (i = b->used; i < b->size; i++) {
+- b->ptr[i] = NULL;
+- }
+- }
+-
+- if (b->ptr[b->used] == NULL) {
+- b->ptr[b->used] = buffer_init();
+- }
+-
+- b->ptr[b->used]->used = 0;
+-
+- return b->ptr[b->used++];
+-}
+-
+-
+ char * buffer_search_string_len(buffer *b, const char *needle, size_t len) {
+ size_t i;
+- if (len == 0) return NULL;
+- if (needle == NULL) return NULL;
++ force_assert(NULL != b);
++ force_assert(0 != len && NULL != needle); /* empty needles not allowed */
+
+ if (b->used < len) return NULL;
+
+@@ -502,17 +363,12 @@ char * buffer_search_string_len(buffer *b, const char *needle, size_t len) {
+ return NULL;
+ }
+
+-buffer *buffer_init_string(const char *str) {
+- buffer *b = buffer_init();
+-
+- buffer_copy_string(b, str);
+-
+- return b;
++int buffer_is_empty(buffer *b) {
++ return NULL == b || 0 == b->used;
+ }
+
+-int buffer_is_empty(buffer *b) {
+- if (!b) return 1;
+- return (b->used == 0);
++int buffer_string_is_empty(buffer *b) {
++ return 0 == buffer_string_length(b);
+ }
+
+ /**
+@@ -523,24 +379,30 @@ int buffer_is_empty(buffer *b) {
+ */
+
+ int buffer_is_equal(buffer *a, buffer *b) {
++ force_assert(NULL != a && NULL != b);
++
+ if (a->used != b->used) return 0;
+ if (a->used == 0) return 1;
+
+- return (0 == strcmp(a->ptr, b->ptr));
++ return (0 == memcmp(a->ptr, b->ptr, a->used));
+ }
+
+ int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
+- buffer b;
++ force_assert(NULL != a && NULL != s);
++ force_assert(b_len + 1 > b_len);
+
+- b.ptr = (char *)s;
+- b.used = b_len + 1;
++ if (a->used != b_len + 1) return 0;
++ if (0 != memcmp(a->ptr, s, b_len)) return 0;
++ if ('\0' != a->ptr[a->used-1]) return 0;
+
+- return buffer_is_equal(a, &b);
++ return 1;
+ }
+
+ /* buffer_is_equal_caseless_string(b, CONST_STR_LEN("value")) */
+ int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len) {
++ force_assert(NULL != a);
+ if (a->used != b_len + 1) return 0;
++ force_assert('\0' == a->ptr[a->used - 1]);
+
+ return (0 == strcasecmp(a->ptr, s));
+ }
+@@ -554,30 +416,18 @@ int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b
+ if (ca == cb) continue;
+
+ /* always lowercase for transitive results */
+-#if 1
+ if (ca >= 'A' && ca <= 'Z') ca |= 32;
+ if (cb >= 'A' && cb <= 'Z') cb |= 32;
+-#else
+- /* try to produce code without branching (jumps) */
+- ca |= ((unsigned char)(ca - (unsigned char)'A') <= (unsigned char)('Z' - 'A')) ? 32 : 0;
+- cb |= ((unsigned char)(cb - (unsigned char)'A') <= (unsigned char)('Z' - 'A')) ? 32 : 0;
+-#endif
+
+ if (ca == cb) continue;
+ return ca - cb;
+ }
+ if (a_len == b_len) return 0;
+- return a_len - b_len;
++ return a_len < b_len ? -1 : 1;
+ }
+
+-/**
+- * check if the rightmost bytes of the string are equal.
+- *
+- *
+- */
+-
+ int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
+- /* no, len -> equal */
++ /* no len -> equal */
+ if (len == 0) return 1;
+
+ /* len > 0, but empty buffers -> not equal */
+@@ -586,29 +436,23 @@ int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
+ /* buffers too small -> not equal */
+ if (b1->used - 1 < len || b2->used - 1 < len) return 0;
+
+- if (0 == strncmp(b1->ptr + b1->used - 1 - len,
+- b2->ptr + b2->used - 1 - len, len)) {
+- return 1;
+- }
+-
+- return 0;
++ return 0 == memcmp(b1->ptr + b1->used - 1 - len, b2->ptr + b2->used - 1 - len, len);
+ }
+
+-int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
++void buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
+ size_t i;
+
+- /* BO protection */
+- if (in_len * 2 < in_len) return -1;
++ /* overflow protection */
++ force_assert(in_len * 2 + 1 > in_len);
+
+- buffer_prepare_copy(b, in_len * 2 + 1);
++ buffer_prepare_copy(b, in_len * 2);
+
++ b->used = 0;
+ for (i = 0; i < in_len; i++) {
+ b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
+ b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
+ }
+ b->ptr[b->used++] = '\0';
+-
+- return 0;
+ }
+
+ /* everything except: ! ( ) * - . 0-9 A-Z _ a-z */
+@@ -747,18 +591,15 @@ static const char encoded_chars_http_header[] = {
+
+
+
+-int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding) {
++void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding) {
+ unsigned char *ds, *d;
+ size_t d_len, ndx;
+ const char *map = NULL;
+
+- if (!s || !b) return -1;
+-
+- if (b->ptr[b->used - 1] != '\0') {
+- SEGFAULT();
+- }
++ force_assert(NULL != b);
++ force_assert(NULL != s || 0 == s_len);
+
+- if (s_len == 0) return 0;
++ if (0 == s_len) return;
+
+ switch(encoding) {
+ case ENCODING_REL_URI:
+@@ -779,11 +620,9 @@ int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_
+ case ENCODING_HTTP_HEADER:
+ map = encoded_chars_http_header;
+ break;
+- case ENCODING_UNSET:
+- break;
+ }
+
+- force_assert(map != NULL);
++ force_assert(NULL != map);
+
+ /* count to-be-encoded-characters */
+ for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
+@@ -801,17 +640,17 @@ int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_
+ case ENCODING_HEX:
+ d_len += 2;
+ break;
+- case ENCODING_UNSET:
+- break;
+ }
+ } else {
+- d_len ++;
++ d_len++;
+ }
+ }
+
+- buffer_prepare_append(b, d_len);
++ d = (unsigned char*) buffer_prepare_append(b, d_len);
++ buffer_commit(b, d_len); /* fill below */
++ force_assert('\0' == *d);
+
+- for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
++ for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
+ if (map[*ds]) {
+ switch(encoding) {
+ case ENCODING_REL_URI:
+@@ -837,20 +676,11 @@ int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_
+ d[d_len++] = *ds;
+ d[d_len++] = '\t';
+ break;
+- case ENCODING_UNSET:
+- break;
+ }
+ } else {
+ d[d_len++] = *ds;
+ }
+ }
+-
+- /* terminate buffer and calculate new length */
+- b->ptr[b->used + d_len - 1] = '\0';
+-
+- b->used += d_len;
+-
+- return 0;
+ }
+
+
+@@ -858,26 +688,35 @@ int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_
+ * replaces non-printable characters with '_'
+ */
+
+-static int buffer_urldecode_internal(buffer *url, int is_query) {
++static void buffer_urldecode_internal(buffer *url, int is_query) {
+ unsigned char high, low;
+- const char *src;
++ char *src;
+ char *dst;
+
+- if (!url || !url->ptr) return -1;
++ force_assert(NULL != url);
++ if (buffer_string_is_empty(url)) return;
++
++ force_assert('\0' == url->ptr[url->used-1]);
+
+- src = (const char*) url->ptr;
+- dst = (char*) url->ptr;
++ src = (char*) url->ptr;
+
+- while ((*src) != '\0') {
++ while ('\0' != *src) {
++ if ('%' == *src) break;
++ if (is_query && '+' == *src) *src = ' ';
++ src++;
++ }
++ dst = src;
++
++ while ('\0' != *src) {
+ if (is_query && *src == '+') {
+ *dst = ' ';
+ } else if (*src == '%') {
+ *dst = '%';
+
+ high = hex2int(*(src + 1));
+- if (high != 0xFF) {
++ if (0xFF != high) {
+ low = hex2int(*(src + 2));
+- if (low != 0xFF) {
++ if (0xFF != low) {
+ high = (high << 4) | low;
+
+ /* map control-characters out */
+@@ -897,19 +736,19 @@ static int buffer_urldecode_internal(buffer *url, int is_query) {
+
+ *dst = '\0';
+ url->used = (dst - url->ptr) + 1;
+-
+- return 0;
+ }
+
+-int buffer_urldecode_path(buffer *url) {
+- return buffer_urldecode_internal(url, 0);
++void buffer_urldecode_path(buffer *url) {
++ buffer_urldecode_internal(url, 0);
+ }
+
+-int buffer_urldecode_query(buffer *url) {
+- return buffer_urldecode_internal(url, 1);
++void buffer_urldecode_query(buffer *url) {
++ buffer_urldecode_internal(url, 1);
+ }
+
+-/* Remove "/../", "//", "/./" parts from path.
++/* Remove "/../", "//", "/./" parts from path,
++ * strips leading spaces,
++ * prepends "/" if not present already
+ *
+ * /blah/.. gets /
+ * /blah/../foo gets /foo
+@@ -920,20 +759,38 @@ int buffer_urldecode_query(buffer *url) {
+ * the operation is performed in-place.
+ */
+
+-int buffer_path_simplify(buffer *dest, buffer *src)
++void buffer_path_simplify(buffer *dest, buffer *src)
+ {
+ int toklen;
+ char c, pre1;
+ char *start, *slash, *walk, *out;
+ unsigned short pre;
+
+- if (src == NULL || src->ptr == NULL || dest == NULL)
+- return -1;
++ force_assert(NULL != dest && NULL != src);
+
+- if (src == dest)
++ if (buffer_string_is_empty(src)) {
++ buffer_copy_string_len(dest, NULL, 0);
++ return;
++ }
++
++ force_assert('\0' == src->ptr[src->used-1]);
++
++ /* might need one character more for the '/' prefix */
++ if (src == dest) {
+ buffer_prepare_append(dest, 1);
+- else
+- buffer_prepare_copy(dest, src->used + 1);
++ } else {
++ buffer_prepare_copy(dest, buffer_string_length(src) + 1);
++ }
++
++#if defined(__WIN32) || defined(__CYGWIN__)
++ /* cygwin is treating \ and / the same, so we have to that too */
++ {
++ char *p;
++ for (p = src->ptr; *p; p++) {
++ if (*p == '\\') *p = '/';
++ }
++ }
++#endif
+
+ walk = src->ptr;
+ start = dest->ptr;
+@@ -941,16 +798,6 @@ int buffer_path_simplify(buffer *dest, buffer *src)
+ slash = dest->ptr;
+
+
+-#if defined(__WIN32) || defined(__CYGWIN__)
+- /* cygwin is treating \ and / the same, so we have to that too
+- */
+-
+- for (walk = src->ptr; *walk; walk++) {
+- if (*walk == '\\') *walk = '/';
+- }
+- walk = src->ptr;
+-#endif
+-
+ while (*walk == ' ') {
+ walk++;
+ }
+@@ -966,34 +813,29 @@ int buffer_path_simplify(buffer *dest, buffer *src)
+
+ if (pre1 == '\0') {
+ dest->used = (out - start) + 1;
+- return 0;
++ return;
+ }
+
+- while (1) {
++ for (;;) {
+ if (c == '/' || c == '\0') {
+ toklen = out - slash;
+ if (toklen == 3 && pre == (('.' << 8) | '.')) {
+ out = slash;
+ if (out > start) {
+ out--;
+- while (out > start && *out != '/') {
+- out--;
+- }
++ while (out > start && *out != '/') out--;
+ }
+
+- if (c == '\0')
+- out++;
++ if (c == '\0') out++;
+ } else if (toklen == 1 || pre == (('/' << 8) | '.')) {
+ out = slash;
+- if (c == '\0')
+- out++;
++ if (c == '\0') out++;
+ }
+
+ slash = out;
+ }
+
+- if (c == '\0')
+- break;
++ if (c == '\0') break;
+
+ pre1 = c;
+ pre = (pre << 8) | pre1;
+@@ -1006,8 +848,6 @@ int buffer_path_simplify(buffer *dest, buffer *src)
+
+ *out = '\0';
+ dest->used = (out - start) + 1;
+-
+- return 0;
+ }
+
+ int light_isdigit(int c) {
+@@ -1030,33 +870,23 @@ int light_isalnum(int c) {
+ return light_isdigit(c) || light_isalpha(c);
+ }
+
+-int buffer_to_lower(buffer *b) {
+- char *c;
+-
+- if (b->used == 0) return 0;
++void buffer_to_lower(buffer *b) {
++ size_t i;
+
+- for (c = b->ptr; *c; c++) {
+- if (*c >= 'A' && *c <= 'Z') {
+- *c |= 32;
+- }
++ for (i = 0; i < b->used; ++i) {
++ char c = b->ptr[i];
++ if (c >= 'A' && c <= 'Z') b->ptr[i] |= 0x20;
+ }
+-
+- return 0;
+ }
+
+
+-int buffer_to_upper(buffer *b) {
+- char *c;
+-
+- if (b->used == 0) return 0;
++void buffer_to_upper(buffer *b) {
++ size_t i;
+
+- for (c = b->ptr; *c; c++) {
+- if (*c >= 'a' && *c <= 'z') {
+- *c &= ~32;
+- }
++ for (i = 0; i < b->used; ++i) {
++ char c = b->ptr[i];
++ if (c >= 'A' && c <= 'Z') b->ptr[i] &= ~0x20;
+ }
+-
+- return 0;
+ }
+
+ #ifdef HAVE_LIBUNWIND
+diff --git a/src/buffer.h b/src/buffer.h
+index d2f5985..ff57d68 100644
+--- a/src/buffer.h
++++ b/src/buffer.h
+@@ -11,74 +11,96 @@
+ #include <sys/types.h>
+ #include <stdio.h>
+
++#if defined HAVE_STDINT_H
++# include <stdint.h>
++#elif defined HAVE_INTTYPES_H
++# include <inttypes.h>
++#endif
++
++/* generic string + binary data container; contains a terminating 0 in both
++ * cases
++ *
++ * used == 0 indicates a special "empty" state (unset config values); ptr
++ * might be NULL too then. otherwise an empty string has used == 1 (and ptr[0]
++ * == 0);
++ *
++ * copy/append functions will ensure used >= 1 (i.e. never leave it in the
++ * special empty state); only buffer_copy_buffer will copy the special empty
++ * state.
++ */
+ typedef struct {
+ char *ptr;
+
++ /* "used" includes a terminating 0 */
+ size_t used;
++ /* size of allocated buffer at *ptr */
+ size_t size;
+ } buffer;
+
+-typedef struct {
+- buffer **ptr;
+-
+- size_t used;
+- size_t size;
+-} buffer_array;
+-
+-typedef struct {
+- char *ptr;
+-
+- size_t offset; /* input-pointer */
+-
+- size_t used; /* output-pointer */
+- size_t size;
+-} read_buffer;
+-
+-buffer_array* buffer_array_init(void);
+-void buffer_array_free(buffer_array *b);
+-void buffer_array_reset(buffer_array *b);
+-buffer *buffer_array_append_get_buffer(buffer_array *b);
+-
++/* create new buffer; either empty or copy given data */
+ buffer* buffer_init(void);
+-buffer* buffer_init_buffer(buffer *b);
+-buffer* buffer_init_string(const char *str);
+-void buffer_free(buffer *b);
+-void buffer_reset(buffer *b);
+-
+-int buffer_prepare_copy(buffer *b, size_t size);
+-int buffer_prepare_append(buffer *b, size_t size);
+-
+-int buffer_copy_string(buffer *b, const char *s);
+-int buffer_copy_string_len(buffer *b, const char *s, size_t s_len);
+-int buffer_copy_string_buffer(buffer *b, const buffer *src);
+-int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len);
+-
+-int buffer_copy_long(buffer *b, long val);
+-
+-int buffer_copy_memory(buffer *b, const char *s, size_t s_len);
+-
+-int buffer_append_string(buffer *b, const char *s);
+-int buffer_append_string_len(buffer *b, const char *s, size_t s_len);
+-int buffer_append_string_buffer(buffer *b, const buffer *src);
+-int buffer_append_string_lfill(buffer *b, const char *s, size_t maxlen);
+-int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen);
+-
+-int buffer_append_long_hex(buffer *b, unsigned long len);
+-int buffer_append_long(buffer *b, long val);
+-
+-#if defined(SIZEOF_LONG) && (SIZEOF_LONG == SIZEOF_OFF_T)
+-#define buffer_copy_off_t(x, y) buffer_copy_long(x, y)
+-#define buffer_append_off_t(x, y) buffer_append_long(x, y)
+-#else
+-int buffer_copy_off_t(buffer *b, off_t val);
+-int buffer_append_off_t(buffer *b, off_t val);
+-#endif
+-
+-int buffer_append_memory(buffer *b, const char *s, size_t s_len);
++buffer* buffer_init_buffer(const buffer *src); /* src can be NULL */
++buffer* buffer_init_string(const char *str); /* str can be NULL */
++
++void buffer_free(buffer *b); /* b can be NULL */
++/* truncates to used == 0; frees large buffers, might keep smaller ones for reuse */
++void buffer_reset(buffer *b); /* b can be NULL */
++
++/* reset b. if NULL != b && NULL != src, move src content to b. reset src. */
++void buffer_move(buffer *b, buffer *src);
++
++/* prepare for size bytes in the buffer (b->size > size), destroys content
++ * (sets used = 0 and ptr[0] = 0). allocates storage for terminating 0.
++ * @return b->ptr
++ */
++char* buffer_prepare_copy(buffer *b, size_t size);
++
++/* prepare for appending size bytes to the buffer
++ * allocates storage for terminating 0; if used > 0 assumes ptr[used-1] == 0,
++ * i.e. doesn't allocate another byte for terminating 0.
++ * @return (b->used > 0 ? b->ptr + b->used - 1 : b->ptr) - first new character
++ */
++char* buffer_prepare_append(buffer *b, size_t size);
++
++/* use after prepare_(copy,append) when you have written data to the buffer
++ * to increase the buffer length by size. also sets the terminating zero.
++ * requires enough space is present for the terminating zero (prepare with the
++ * same size to be sure).
++ */
++void buffer_commit(buffer *b, size_t size);
++
++void buffer_copy_string(buffer *b, const char *s);
++void buffer_copy_string_len(buffer *b, const char *s, size_t s_len);
++void buffer_copy_buffer(buffer *b, const buffer *src);
++/* convert input to hex and store in buffer */
++void buffer_copy_string_hex(buffer *b, const char *in, size_t in_len);
++
++void buffer_append_string(buffer *b, const char *s);
++void buffer_append_string_len(buffer *b, const char *s, size_t s_len);
++void buffer_append_string_buffer(buffer *b, const buffer *src);
++
++void buffer_append_long_hex(buffer *b, unsigned long len);
++void buffer_append_int(buffer *b, intmax_t val);
++void buffer_copy_int(buffer *b, intmax_t val);
++
++/* '-', log_10 (2^bits) = bits * log 2 / log 10 < bits * 0.31, terminating 0 */
++#define LI_ITOSTRING_LENGTH (2 + (8 * sizeof(intmax_t) * 31 + 99) / 100)
++
++void li_itostrn(char *buf, size_t buf_len, intmax_t val);
++void li_itostr(char *buf, intmax_t val); /* buf must have at least LI_ITOSTRING_LENGTH bytes */
++void li_utostrn(char *buf, size_t buf_len, uintmax_t val);
++void li_utostr(char *buf, uintmax_t val); /* buf must have at least LI_ITOSTRING_LENGTH bytes */
+
+ char * buffer_search_string_len(buffer *b, const char *needle, size_t len);
+
++/* NULL buffer or empty buffer (used == 0);
++ * unset "string" (buffer) config options are initialized to used == 0,
++ * while setting an empty string leads to used == 1
++ */
+ int buffer_is_empty(buffer *b);
++/* NULL buffer, empty buffer (used == 0) or empty string (used == 1) */
++int buffer_string_is_empty(buffer *b);
++
+ int buffer_is_equal(buffer *a, buffer *b);
+ int buffer_is_equal_right_len(buffer *a, buffer *b, size_t len);
+ int buffer_is_equal_string(buffer *a, const char *s, size_t b_len);
+@@ -86,7 +108,6 @@ int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len);
+ int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len);
+
+ typedef enum {
+- ENCODING_UNSET,
+ ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
+ ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */
+ ENCODING_HTML, /* & becomes &amp; and so on */
+@@ -95,17 +116,17 @@ typedef enum {
+ ENCODING_HTTP_HEADER /* encode \n with \t\n */
+ } buffer_encoding_t;
+
+-int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding);
++void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding);
++
++void buffer_urldecode_path(buffer *url);
++void buffer_urldecode_query(buffer *url);
++void buffer_path_simplify(buffer *dest, buffer *src);
+
+-int buffer_urldecode_path(buffer *url);
+-int buffer_urldecode_query(buffer *url);
+-int buffer_path_simplify(buffer *dest, buffer *src);
++void buffer_to_lower(buffer *b);
++void buffer_to_upper(buffer *b);
+
+-int buffer_to_lower(buffer *b);
+-int buffer_to_upper(buffer *b);
+
+ /** deprecated */
+-int LI_ltostr(char *buf, long val);
+ char hex2int(unsigned char c);
+ char int2hex(char i);
+
+@@ -114,17 +135,17 @@ int light_isxdigit(int c);
+ int light_isalpha(int c);
+ int light_isalnum(int c);
+
++static inline size_t buffer_string_length(const buffer *b); /* buffer string length without terminating 0 */
++static inline void buffer_append_slash(buffer *b); /* append '/' no non-empty strings not ending in '/' */
++
+ #define BUFFER_APPEND_STRING_CONST(x, y) \
+ buffer_append_string_len(x, y, sizeof(y) - 1)
+
+ #define BUFFER_COPY_STRING_CONST(x, y) \
+ buffer_copy_string_len(x, y, sizeof(y) - 1)
+
+-#define BUFFER_APPEND_SLASH(x) \
+- if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); }
+-
+-#define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
+-#define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
++#define CONST_STR_LEN(x) x, (x) ? sizeof(x) - 1 : 0
++#define CONST_BUF_LEN(x) (x)->ptr, buffer_string_length(x)
+
+
+ #define UNUSED(x) ( (void)(x) )
+@@ -134,4 +155,15 @@ void log_failed_assert(const char *filename, unsigned int line, const char *msg)
+ #define force_assert(x) do { if (!(x)) log_failed_assert(__FILE__, __LINE__, "assertion failed: " #x); } while(0)
+ #define SEGFAULT() log_failed_assert(__FILE__, __LINE__, "aborted");
+
++/* inline implementations */
++
++static inline size_t buffer_string_length(const buffer *b) {
++ return NULL != b && 0 != b->used ? b->used - 1 : 0;
++}
++
++static inline void buffer_append_slash(buffer *b) {
++ size_t len = buffer_string_length(b);
++ if (len > 0 && '/' != b->ptr[len-1]) BUFFER_APPEND_STRING_CONST(b, "/");
++}
++
+ #endif
+diff --git a/src/chunk.c b/src/chunk.c
+index 7583db6..c991b82 100644
+--- a/src/chunk.c
++++ b/src/chunk.c
+@@ -36,30 +36,28 @@ static chunk *chunk_init(void) {
+
+ c = calloc(1, sizeof(*c));
+
++ c->type = MEM_CHUNK;
+ c->mem = buffer_init();
+ c->file.name = buffer_init();
++ c->file.start = c->file.length = c->file.mmap.offset = 0;
+ c->file.fd = -1;
+ c->file.mmap.start = MAP_FAILED;
++ c->file.mmap.length = 0;
++ c->file.is_temp = 0;
++ c->offset = 0;
+ c->next = NULL;
+
+ return c;
+ }
+
+-static void chunk_free(chunk *c) {
+- if (!c) return;
+-
+- buffer_free(c->mem);
+- buffer_free(c->file.name);
+-
+- free(c);
+-}
+-
+ static void chunk_reset(chunk *c) {
+- if (!c) return;
++ if (NULL == c) return;
++
++ c->type = MEM_CHUNK;
+
+ buffer_reset(c->mem);
+
+- if (c->file.is_temp && !buffer_is_empty(c->file.name)) {
++ if (c->file.is_temp && !buffer_string_is_empty(c->file.name)) {
+ unlink(c->file.name->ptr);
+ }
+
+@@ -73,13 +71,28 @@ static void chunk_reset(chunk *c) {
+ munmap(c->file.mmap.start, c->file.mmap.length);
+ c->file.mmap.start = MAP_FAILED;
+ }
++ c->file.start = c->file.length = c->file.mmap.offset = 0;
++ c->file.mmap.length = 0;
++ c->file.is_temp = 0;
++ c->offset = 0;
++ c->next = NULL;
+ }
+
++static void chunk_free(chunk *c) {
++ if (NULL == c) return;
++
++ chunk_reset(c);
++
++ buffer_free(c->mem);
++ buffer_free(c->file.name);
++
++ free(c);
++}
+
+ void chunkqueue_free(chunkqueue *cq) {
+ chunk *c, *pc;
+
+- if (!cq) return;
++ if (NULL == cq) return;
+
+ for (c = cq->first; c; ) {
+ pc = c;
+@@ -96,11 +109,27 @@ void chunkqueue_free(chunkqueue *cq) {
+ free(cq);
+ }
+
++static void chunkqueue_push_unused_chunk(chunkqueue *cq, chunk *c) {
++ force_assert(NULL != cq && NULL != c);
++
++ /* keep at max 4 chunks in the 'unused'-cache */
++ if (cq->unused_chunks > 4) {
++ chunk_free(c);
++ } else {
++ chunk_reset(c);
++ c->next = cq->unused;
++ cq->unused = c;
++ cq->unused_chunks++;
++ }
++}
++
+ static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) {
+ chunk *c;
+
++ force_assert(NULL != cq);
++
+ /* check if we have a unused chunk */
+- if (!cq->unused) {
++ if (0 == cq->unused) {
+ c = chunk_init();
+ } else {
+ /* take the first element from the list (a stack) */
+@@ -113,130 +142,95 @@ static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) {
+ return c;
+ }
+
+-static int chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) {
++static void chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) {
+ c->next = cq->first;
+ cq->first = c;
+
+- if (cq->last == NULL) {
++ if (NULL == cq->last) {
+ cq->last = c;
+ }
+-
+- return 0;
+ }
+
+-static int chunkqueue_append_chunk(chunkqueue *cq, chunk *c) {
++static void chunkqueue_append_chunk(chunkqueue *cq, chunk *c) {
+ if (cq->last) {
+ cq->last->next = c;
+ }
+ cq->last = c;
+
+- if (cq->first == NULL) {
++ if (NULL == cq->first) {
+ cq->first = c;
+ }
+-
+- return 0;
+ }
+
+ void chunkqueue_reset(chunkqueue *cq) {
+- chunk *c;
+- /* move everything to the unused queue */
++ chunk *cur = cq->first;
+
+- /* mark all read written */
+- for (c = cq->first; c; c = c->next) {
+- switch(c->type) {
+- case MEM_CHUNK:
+- c->offset = c->mem->used - 1;
+- break;
+- case FILE_CHUNK:
+- c->offset = c->file.length;
+- break;
+- default:
+- break;
+- }
++ cq->first = cq->last = NULL;
++
++ while (NULL != cur) {
++ chunk *next = cur->next;
++ chunkqueue_push_unused_chunk(cq, cur);
++ cur = next;
+ }
+
+- chunkqueue_remove_finished_chunks(cq);
+ cq->bytes_in = 0;
+ cq->bytes_out = 0;
+ }
+
+-int chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) {
++void chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) {
+ chunk *c;
+
+- if (len == 0) return 0;
++ if (0 == len) return;
+
+ c = chunkqueue_get_unused_chunk(cq);
+
+ c->type = FILE_CHUNK;
+
+- buffer_copy_string_buffer(c->file.name, fn);
++ buffer_copy_buffer(c->file.name, fn);
+ c->file.start = offset;
+ c->file.length = len;
+ c->offset = 0;
+
+ chunkqueue_append_chunk(cq, c);
+-
+- return 0;
+ }
+
+-int chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) {
++void chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) {
+ chunk *c;
+
+- if (mem->used == 0) return 0;
+-
+- c = chunkqueue_get_unused_chunk(cq);
+- c->type = MEM_CHUNK;
+- c->offset = 0;
+- buffer_copy_string_buffer(c->mem, mem);
+-
+- chunkqueue_append_chunk(cq, c);
+-
+- return 0;
+-}
+-
+-int chunkqueue_append_buffer_weak(chunkqueue *cq, buffer *mem) {
+- chunk *c;
++ if (buffer_string_is_empty(mem)) return;
+
+ c = chunkqueue_get_unused_chunk(cq);
+ c->type = MEM_CHUNK;
+- c->offset = 0;
+- if (c->mem) buffer_free(c->mem);
+- c->mem = mem;
++ force_assert(NULL != c->mem);
++ buffer_move(c->mem, mem);
+
+ chunkqueue_append_chunk(cq, c);
+-
+- return 0;
+ }
+
+-int chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) {
++void chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) {
+ chunk *c;
+
+- if (mem->used == 0) return 0;
++ if (buffer_string_is_empty(mem)) return;
+
+ c = chunkqueue_get_unused_chunk(cq);
+ c->type = MEM_CHUNK;
+- c->offset = 0;
+- buffer_copy_string_buffer(c->mem, mem);
++ force_assert(NULL != c->mem);
++ buffer_move(c->mem, mem);
+
+ chunkqueue_prepend_chunk(cq, c);
+-
+- return 0;
+ }
+
+
+-int chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
++void chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
+ chunk *c;
+
+- if (len == 0) return 0;
++ if (0 == len) return;
+
+ c = chunkqueue_get_unused_chunk(cq);
+ c->type = MEM_CHUNK;
+- c->offset = 0;
+- buffer_copy_string_len(c->mem, mem, len - 1);
++ buffer_copy_string_len(c->mem, mem, len);
+
+ chunkqueue_append_chunk(cq, c);
+-
+- return 0;
+ }
+
+ buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) {
+@@ -245,8 +239,6 @@ buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) {
+ c = chunkqueue_get_unused_chunk(cq);
+
+ c->type = MEM_CHUNK;
+- c->offset = 0;
+- buffer_reset(c->mem);
+
+ chunkqueue_prepend_chunk(cq, c);
+
+@@ -259,20 +251,15 @@ buffer *chunkqueue_get_append_buffer(chunkqueue *cq) {
+ c = chunkqueue_get_unused_chunk(cq);
+
+ c->type = MEM_CHUNK;
+- c->offset = 0;
+- buffer_reset(c->mem);
+
+ chunkqueue_append_chunk(cq, c);
+
+ return c->mem;
+ }
+
+-int chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs) {
+- if (!cq) return -1;
+-
++void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs) {
++ force_assert(NULL != cq);
+ cq->tempdirs = tempdirs;
+-
+- return 0;
+ }
+
+ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
+@@ -282,7 +269,6 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
+ c = chunkqueue_get_unused_chunk(cq);
+
+ c->type = FILE_CHUNK;
+- c->offset = 0;
+
+ if (cq->tempdirs && cq->tempdirs->used) {
+ size_t i;
+@@ -292,8 +278,8 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
+ for (i = 0; i < cq->tempdirs->used; i++) {
+ data_string *ds = (data_string *)cq->tempdirs->data[i];
+
+- buffer_copy_string_buffer(template, ds->value);
+- BUFFER_APPEND_SLASH(template);
++ buffer_copy_buffer(template, ds->value);
++ buffer_append_slash(template);
+ buffer_append_string_len(template, CONST_STR_LEN("lighttpd-upload-XXXXXX"));
+
+ if (-1 != (c->file.fd = mkstemp(template->ptr))) {
+@@ -309,7 +295,7 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
+ }
+ }
+
+- buffer_copy_string_buffer(c->file.name, template);
++ buffer_copy_buffer(c->file.name, template);
+ c->file.length = 0;
+
+ chunkqueue_append_chunk(cq, c);
+@@ -319,82 +305,102 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
+ return c;
+ }
+
++void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) {
++ while (len > 0) {
++ chunk *c = src->first;
++ off_t clen = 0;
+
+-off_t chunkqueue_length(chunkqueue *cq) {
+- off_t len = 0;
+- chunk *c;
++ if (NULL == c) break;
+
+- for (c = cq->first; c; c = c->next) {
+ switch (c->type) {
+ case MEM_CHUNK:
+- len += c->mem->used ? c->mem->used - 1 : 0;
++ clen = buffer_string_length(c->mem);
+ break;
+ case FILE_CHUNK:
+- len += c->file.length;
++ clen = c->file.length;
+ break;
+- default:
++ }
++ force_assert(clen >= c->offset);
++ clen -= c->offset;
++
++ if (len >= clen) {
++ /* move complete chunk */
++ src->first = c->next;
++ if (c == src->last) src->last = NULL;
++
++ chunkqueue_append_chunk(dest, c);
++ src->bytes_out += clen;
++ dest->bytes_in += clen;
++ len -= clen;
++ continue;
++ }
++
++ /* partial chunk with length "len" */
++
++ switch (c->type) {
++ case MEM_CHUNK:
++ chunkqueue_append_mem(dest, c->mem->ptr + c->offset, len);
++ break;
++ case FILE_CHUNK:
++ /* tempfile flag is in "last" chunk after the split */
++ chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, len);
+ break;
+ }
+- }
+
+- return len;
++ c->offset += len;
++ src->bytes_out += len;
++ dest->bytes_in += len;
++ len = 0;
++ }
+ }
+
+-off_t chunkqueue_written(chunkqueue *cq) {
++off_t chunkqueue_length(chunkqueue *cq) {
+ off_t len = 0;
+ chunk *c;
+
+ for (c = cq->first; c; c = c->next) {
++ off_t c_len = 0;
++
+ switch (c->type) {
+ case MEM_CHUNK:
+- case FILE_CHUNK:
+- len += c->offset;
++ c_len = buffer_string_length(c->mem);
+ break;
+- default:
++ case FILE_CHUNK:
++ c_len = c->file.length;
+ break;
+ }
++ force_assert(c_len >= c->offset);
++ len += c_len - c->offset;
+ }
+
+ return len;
+ }
+
+ int chunkqueue_is_empty(chunkqueue *cq) {
+- return cq->first ? 0 : 1;
++ return NULL == cq->first;
+ }
+
+-int chunkqueue_remove_finished_chunks(chunkqueue *cq) {
++void chunkqueue_remove_finished_chunks(chunkqueue *cq) {
+ chunk *c;
+
+ for (c = cq->first; c; c = cq->first) {
+- int is_finished = 0;
++ off_t c_len = 0;
+
+ switch (c->type) {
+ case MEM_CHUNK:
+- if (c->mem->used == 0 || (c->offset == (off_t)c->mem->used - 1)) is_finished = 1;
++ c_len = buffer_string_length(c->mem);
+ break;
+ case FILE_CHUNK:
+- if (c->offset == c->file.length) is_finished = 1;
+- break;
+- default:
++ c_len = c->file.length;
+ break;
+ }
++ force_assert(c_len >= c->offset);
+
+- if (!is_finished) break;
+-
+- chunk_reset(c);
++ if (c_len > c->offset) break; /* not finished yet */
+
+ cq->first = c->next;
+ if (c == cq->last) cq->last = NULL;
+
+- /* keep at max 4 chunks in the 'unused'-cache */
+- if (cq->unused_chunks > 4) {
+- chunk_free(c);
+- } else {
+- c->next = cq->unused;
+- cq->unused = c;
+- cq->unused_chunks++;
+- }
++ chunkqueue_push_unused_chunk(cq, c);
+ }
+-
+- return 0;
+ }
+diff --git a/src/chunk.h b/src/chunk.h
+index e43d3eb..6559000 100644
+--- a/src/chunk.h
++++ b/src/chunk.h
+@@ -6,7 +6,7 @@
+ #include "sys-mmap.h"
+
+ typedef struct chunk {
+- enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type;
++ enum { MEM_CHUNK, FILE_CHUNK } type;
+
+ buffer *mem; /* either the storage of the mem-chunk or the read-ahead buffer */
+
+@@ -48,21 +48,21 @@ typedef struct {
+ } chunkqueue;
+
+ chunkqueue *chunkqueue_init(void);
+-int chunkqueue_set_tempdirs(chunkqueue *c, array *tempdirs);
+-int chunkqueue_append_file(chunkqueue *c, buffer *fn, off_t offset, off_t len);
+-int chunkqueue_append_mem(chunkqueue *c, const char *mem, size_t len);
+-int chunkqueue_append_buffer(chunkqueue *c, buffer *mem);
+-int chunkqueue_append_buffer_weak(chunkqueue *c, buffer *mem);
+-int chunkqueue_prepend_buffer(chunkqueue *c, buffer *mem);
++void chunkqueue_set_tempdirs(chunkqueue *c, array *tempdirs);
++void chunkqueue_append_file(chunkqueue *c, buffer *fn, off_t offset, off_t len); /* copies "fn" */
++void chunkqueue_append_mem(chunkqueue *c, const char *mem, size_t len); /* copies memory */
++void chunkqueue_append_buffer(chunkqueue *c, buffer *mem); /* may reset "mem" */
++void chunkqueue_prepend_buffer(chunkqueue *c, buffer *mem); /* may reset "mem" */
+
+ buffer * chunkqueue_get_append_buffer(chunkqueue *c);
+ buffer * chunkqueue_get_prepend_buffer(chunkqueue *c);
+ chunk * chunkqueue_get_append_tempfile(chunkqueue *cq);
+
+-int chunkqueue_remove_finished_chunks(chunkqueue *cq);
++void chunkqueue_remove_finished_chunks(chunkqueue *cq);
++
++void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len);
+
+ off_t chunkqueue_length(chunkqueue *c);
+-off_t chunkqueue_written(chunkqueue *c);
+ void chunkqueue_free(chunkqueue *c);
+ void chunkqueue_reset(chunkqueue *c);
+
+diff --git a/src/configfile-glue.c b/src/configfile-glue.c
+index 9f24dcb..2fb8c62 100644
+--- a/src/configfile-glue.c
++++ b/src/configfile-glue.c
+@@ -46,12 +46,12 @@ int config_insert_values_internal(server *srv, array *ca, const config_values_t
+ if (da->value->data[j]->type == TYPE_STRING) {
+ data_string *ds = data_string_init();
+
+- buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
++ buffer_copy_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
+ if (!da->is_index_key) {
+ /* the id's were generated automaticly, as we copy now we might have to renumber them
+ * this is used to prepend server.modules by mod_indexfile as it has to be loaded
+ * before mod_fastcgi and friends */
+- buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
++ buffer_copy_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
+ }
+
+ array_insert_unique(cv[i].destination, (data_unset *)ds);
+@@ -73,7 +73,7 @@ int config_insert_values_internal(server *srv, array *ca, const config_values_t
+ if (du->type == TYPE_STRING) {
+ data_string *ds = (data_string *)du;
+
+- buffer_copy_string_buffer(cv[i].destination, ds->value);
++ buffer_copy_buffer(cv[i].destination, ds->value);
+ } else {
+ log_error_write(srv, __FILE__, __LINE__, "ssss", cv[i].key, "should have been a string like ... = \"...\"");
+
+@@ -202,7 +202,7 @@ int config_insert_values_global(server *srv, array *ca, const config_values_t cv
+ touched = data_string_init();
+
+ buffer_copy_string_len(touched->value, CONST_STR_LEN(""));
+- buffer_copy_string_buffer(touched->key, du->key);
++ buffer_copy_buffer(touched->key, du->key);
+
+ array_insert_unique(srv->config_touched, (data_unset *)touched);
+ }
+@@ -285,7 +285,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
+ case COMP_HTTP_HOST: {
+ char *ck_colon = NULL, *val_colon = NULL;
+
+- if (!buffer_is_empty(con->uri.authority)) {
++ if (!buffer_string_is_empty(con->uri.authority)) {
+
+ /*
+ * append server-port to the HTTP_POST if necessary
+@@ -301,9 +301,9 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
+
+ if (NULL != ck_colon && NULL == val_colon) {
+ /* condition "host:port" but client send "host" */
+- buffer_copy_string_buffer(srv->cond_check_buf, l);
++ buffer_copy_buffer(srv->cond_check_buf, l);
+ buffer_append_string_len(srv->cond_check_buf, CONST_STR_LEN(":"));
+- buffer_append_long(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr)));
++ buffer_append_int(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr)));
+ l = srv->cond_check_buf;
+ } else if (NULL != val_colon && NULL == ck_colon) {
+ /* condition "host" but client send "host:port" */
+@@ -315,7 +315,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
+ break;
+ }
+ #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
+- } else if (!buffer_is_empty(con->tlsext_server_name)) {
++ } else if (!buffer_string_is_empty(con->tlsext_server_name)) {
+ l = con->tlsext_server_name;
+ #endif
+ } else {
+diff --git a/src/configfile.c b/src/configfile.c
+index bf9a34d..2b09d86 100644
+--- a/src/configfile.c
++++ b/src/configfile.c
+@@ -273,7 +273,7 @@ static int config_insert(server *srv) {
+ }
+ }
+
+- if (buffer_is_empty(stat_cache_string)) {
++ if (buffer_string_is_empty(stat_cache_string)) {
+ srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
+ } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {
+ srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
+@@ -323,7 +323,7 @@ int config_setup_connection(server *srv, connection *con) {
+ PATCH(global_bytes_per_second_cnt);
+
+ con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
+- buffer_copy_string_buffer(con->server_name, s->server_name);
++ buffer_copy_buffer(con->server_name, s->server_name);
+
+ PATCH(log_request_header);
+ PATCH(log_response_header);
+@@ -442,7 +442,7 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) {
+ PATCH(follow_symlink);
+ #endif
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.name"))) {
+- buffer_copy_string_buffer(con->server_name, s->server_name);
++ buffer_copy_buffer(con->server_name, s->server_name);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.tag"))) {
+ PATCH(server_tag);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("connection.kbytes-per-second"))) {
+@@ -512,7 +512,7 @@ typedef struct {
+
+ #if 0
+ static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) {
+- if (buffer_is_empty(basedir) ||
++ if (buffer_string_is_empty(basedir) ||
+ (fn[0] == '/' || fn[0] == '\\') ||
+ (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {
+ t->file = buffer_init_string(fn);
+@@ -934,7 +934,7 @@ static int config_parse(server *srv, config_t *context, tokenizer_t *t) {
+ lasttoken = buffer_init();
+ token = buffer_init();
+ while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) {
+- buffer_copy_string_buffer(lasttoken, token);
++ buffer_copy_buffer(lasttoken, token);
+ configparser(pParser, token_id, token, context);
+
+ token = buffer_init();
+@@ -986,7 +986,7 @@ int config_parse_file(server *srv, config_t *context, const char *fn) {
+ int ret;
+ buffer *filename;
+
+- if (buffer_is_empty(context->basedir) ||
++ if (buffer_string_is_empty(context->basedir) ||
+ (fn[0] == '/' || fn[0] == '\\') ||
+ (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {
+ filename = buffer_init_string(fn);
+@@ -1057,7 +1057,7 @@ int config_parse_cmd(server *srv, config_t *context, const char *cmd) {
+ source = buffer_init_string(cmd);
+ out = buffer_init();
+
+- if (!buffer_is_empty(context->basedir)) {
++ if (!buffer_string_is_empty(context->basedir)) {
+ chdir(context->basedir->ptr);
+ }
+
+@@ -1173,7 +1173,7 @@ int config_read(server *srv, const char *fn) {
+
+ prepends = (data_array *)configparser_merge_data((data_unset *)prepends, (data_unset *)modules);
+ force_assert(NULL != prepends);
+- buffer_copy_string_buffer(prepends->key, modules->key);
++ buffer_copy_buffer(prepends->key, modules->key);
+ array_replace(srv->config, (data_unset *)prepends);
+ modules->free((data_unset *)modules);
+ modules = prepends;
+@@ -1255,7 +1255,7 @@ int config_set_defaults(server *srv) {
+ { FDEVENT_HANDLER_UNSET, NULL }
+ };
+
+- if (!buffer_is_empty(srv->srvconf.changeroot)) {
++ if (!buffer_string_is_empty(srv->srvconf.changeroot)) {
+ if (-1 == stat(srv->srvconf.changeroot->ptr, &st1)) {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "server.chroot doesn't exist:", srv->srvconf.changeroot);
+@@ -1268,14 +1268,14 @@ int config_set_defaults(server *srv) {
+ }
+ }
+
+- if (buffer_is_empty(s->document_root)) {
++ if (buffer_string_is_empty(s->document_root)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "a default document-root has to be set");
+
+ return -1;
+ }
+
+- buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
++ buffer_copy_buffer(srv->tmp_buf, s->document_root);
+
+ buffer_to_lower(srv->tmp_buf);
+
+@@ -1288,7 +1288,7 @@ int config_set_defaults(server *srv) {
+ is_lower = buffer_is_equal(srv->tmp_buf, s->document_root);
+
+ /* lower-case existed, check upper-case */
+- buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
++ buffer_copy_buffer(srv->tmp_buf, s->document_root);
+
+ buffer_to_upper(srv->tmp_buf);
+
+@@ -1356,7 +1356,7 @@ int config_set_defaults(server *srv) {
+ }
+
+ if (s->ssl_enabled) {
+- if (buffer_is_empty(s->ssl_pemfile)) {
++ if (buffer_string_is_empty(s->ssl_pemfile)) {
+ /* PEM file is require */
+
+ log_error_write(srv, __FILE__, __LINE__, "s",
+diff --git a/src/configparser.y b/src/configparser.y
+index efa4afd..e4a4f51 100644
+--- a/src/configparser.y
++++ b/src/configparser.y
+@@ -61,11 +61,11 @@ data_unset *configparser_merge_data(data_unset *op1, const data_unset *op2) {
+ if (op1->type != op2->type) {
+ if (op1->type == TYPE_STRING && op2->type == TYPE_INTEGER) {
+ data_string *ds = (data_string *)op1;
+- buffer_append_long(ds->value, ((data_integer*)op2)->value);
++ buffer_append_int(ds->value, ((data_integer*)op2)->value);
+ return op1;
+ } else if (op1->type == TYPE_INTEGER && op2->type == TYPE_STRING) {
+ data_string *ds = data_string_init();
+- buffer_append_long(ds->value, ((data_integer*)op1)->value);
++ buffer_append_int(ds->value, ((data_integer*)op1)->value);
+ buffer_append_string_buffer(ds->value, ((data_string*)op2)->value);
+ op1->free(op1);
+ return (data_unset *)ds;
+@@ -145,7 +145,7 @@ metaline ::= EOL.
+
+ varline ::= key(A) ASSIGN expression(B). {
+ if (ctx->ok) {
+- buffer_copy_string_buffer(B->key, A);
++ buffer_copy_buffer(B->key, A);
+ if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
+ fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
+ ctx->current->context_ndx,
+@@ -183,7 +183,7 @@ varline ::= key(A) APPEND expression(B). {
+ ctx->ok = 0;
+ }
+ else {
+- buffer_copy_string_buffer(du->key, A);
++ buffer_copy_buffer(du->key, A);
+ array_replace(vars, du);
+ }
+ B->free(B);
+@@ -193,12 +193,12 @@ varline ::= key(A) APPEND expression(B). {
+ ctx->ok = 0;
+ }
+ else {
+- buffer_copy_string_buffer(du->key, A);
++ buffer_copy_buffer(du->key, A);
+ array_insert_unique(ctx->current->value, du);
+ }
+ B->free(B);
+ } else {
+- buffer_copy_string_buffer(B->key, A);
++ buffer_copy_buffer(B->key, A);
+ array_insert_unique(ctx->current->value, B);
+ }
+ buffer_free(A);
+@@ -262,7 +262,7 @@ value(A) ::= key(B). {
+
+ value(A) ::= STRING(B). {
+ A = (data_unset *)data_string_init();
+- buffer_copy_string_buffer(((data_string *)(A))->value, B);
++ buffer_copy_buffer(((data_string *)(A))->value, B);
+ buffer_free(B);
+ B = NULL;
+ }
+@@ -320,7 +320,7 @@ aelement(A) ::= expression(B). {
+ B = NULL;
+ }
+ aelement(A) ::= stringop(B) ARRAY_ASSIGN expression(C). {
+- buffer_copy_string_buffer(C->key, B);
++ buffer_copy_buffer(C->key, B);
+ buffer_free(B);
+ B = NULL;
+
+@@ -405,7 +405,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio
+ }
+
+ b = buffer_init();
+- buffer_copy_string_buffer(b, ctx->current->key);
++ buffer_copy_buffer(b, ctx->current->key);
+ buffer_append_string(b, "/");
+ buffer_append_string_buffer(b, B);
+ buffer_append_string_buffer(b, C);
+@@ -441,9 +441,9 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio
+
+ dc = data_config_init();
+
+- buffer_copy_string_buffer(dc->key, b);
+- buffer_copy_string_buffer(dc->op, op);
+- buffer_copy_string_buffer(dc->comp_key, B);
++ buffer_copy_buffer(dc->key, b);
++ buffer_copy_buffer(dc->op, op);
++ buffer_copy_buffer(dc->comp_key, B);
+ buffer_append_string_len(dc->comp_key, CONST_STR_LEN("[\""));
+ buffer_append_string_buffer(dc->comp_key, C);
+ buffer_append_string_len(dc->comp_key, CONST_STR_LEN("\"]"));
+@@ -546,7 +546,7 @@ stringop(A) ::= expression(B). {
+ A = buffer_init_buffer(((data_string*)B)->value);
+ } else if (B->type == TYPE_INTEGER) {
+ A = buffer_init();
+- buffer_copy_long(A, ((data_integer *)B)->value);
++ buffer_copy_int(A, ((data_integer *)B)->value);
+ } else {
+ fprintf(stderr, "operand must be string");
+ ctx->ok = 0;
+diff --git a/src/connections.c b/src/connections.c
+index fe683a2..bc770bf 100644
+--- a/src/connections.c
++++ b/src/connections.c
+@@ -212,7 +212,7 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
+ b = chunkqueue_get_append_buffer(con->read_queue);
+ len = SSL_pending(con->ssl);
+ if (len < 4*1024) len = 4*1024; /* always alloc >= 4k buffer */
+- buffer_prepare_copy(b, len + 1);
++ buffer_prepare_copy(b, len);
+
+ /* overwrite everything with 0 */
+ memset(b->ptr, 0, b->size);
+@@ -362,7 +362,7 @@ static int connection_handle_read(server *srv, connection *con) {
+ } else {
+ if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
+ b = chunkqueue_get_append_buffer(con->read_queue);
+- buffer_prepare_copy(b, toread + 1);
++ buffer_prepare_copy(b, toread);
+ }
+
+ read_offset = (b->used == 0) ? 0 : b->used - 1;
+@@ -473,11 +473,11 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
+ buffer_reset(con->physical.path);
+
+ /* try to send static errorfile */
+- if (!buffer_is_empty(con->conf.errorfile_prefix)) {
++ if (!buffer_string_is_empty(con->conf.errorfile_prefix)) {
+ stat_cache_entry *sce = NULL;
+
+- buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix);
+- buffer_append_long(con->physical.path, con->http_status);
++ buffer_copy_buffer(con->physical.path, con->conf.errorfile_prefix);
++ buffer_append_int(con->physical.path, con->http_status);
+ buffer_append_string_len(con->physical.path, CONST_STR_LEN(".html"));
+
+ if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
+@@ -504,7 +504,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
+ " <head>\n"
+ " <title>"));
+- buffer_append_long(b, con->http_status);
++ buffer_append_int(b, con->http_status);
+ buffer_append_string_len(b, CONST_STR_LEN(" - "));
+ buffer_append_string(b, get_http_status_name(con->http_status));
+
+@@ -513,7 +513,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
+ " </head>\n"
+ " <body>\n"
+ " <h1>"));
+- buffer_append_long(b, con->http_status);
++ buffer_append_int(b, con->http_status);
+ buffer_append_string_len(b, CONST_STR_LEN(" - "));
+ buffer_append_string(b, get_http_status_name(con->http_status));
+
+@@ -554,7 +554,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
+ /* qlen = 0 is important for Redirects (301, ...) as they MAY have
+ * a content. Browsers are waiting for a Content otherwise
+ */
+- buffer_copy_off_t(srv->tmp_buf, qlen);
++ buffer_copy_int(srv->tmp_buf, qlen);
+
+ response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));
+ }
+@@ -1135,7 +1135,7 @@ found_header_end:
+ } else {
+ b = chunkqueue_get_append_buffer(dst_cq);
+ /* prepare buffer size for remaining POST data; is < 64kb */
+- buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in + 1);
++ buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in);
+ }
+ buffer_append_string_len(b, c->mem->ptr + c->offset, toRead);
+ }
+@@ -1430,17 +1430,17 @@ int connection_state_machine(server *srv, connection *con) {
+ /* 404 error-handler */
+
+ if (con->in_error_handler == 0 &&
+- (!buffer_is_empty(con->conf.error_handler) ||
+- !buffer_is_empty(con->error_handler))) {
++ (!buffer_string_is_empty(con->conf.error_handler) ||
++ !buffer_string_is_empty(con->error_handler))) {
+ /* call error-handler */
+
+ con->error_handler_saved_status = con->http_status;
+ con->http_status = 0;
+
+- if (buffer_is_empty(con->error_handler)) {
+- buffer_copy_string_buffer(con->request.uri, con->conf.error_handler);
++ if (buffer_string_is_empty(con->error_handler)) {
++ buffer_copy_buffer(con->request.uri, con->conf.error_handler);
+ } else {
+- buffer_copy_string_buffer(con->request.uri, con->error_handler);
++ buffer_copy_buffer(con->request.uri, con->error_handler);
+ }
+ buffer_reset(con->physical.path);
+
+diff --git a/src/data_array.c b/src/data_array.c
+index 094d8c0..ad96207 100644
+--- a/src/data_array.c
++++ b/src/data_array.c
+@@ -8,7 +8,7 @@ static data_unset *data_array_copy(const data_unset *s) {
+ data_array *src = (data_array *)s;
+ data_array *ds = data_array_init();
+
+- buffer_copy_string_buffer(ds->key, src->key);
++ buffer_copy_buffer(ds->key, src->key);
+ array_free(ds->value);
+ ds->value = array_init_array(src->value);
+ ds->is_index_key = src->is_index_key;
+diff --git a/src/data_config.c b/src/data_config.c
+index 80e38de..b05ba20 100644
+--- a/src/data_config.c
++++ b/src/data_config.c
+@@ -8,8 +8,8 @@ static data_unset *data_config_copy(const data_unset *s) {
+ data_config *src = (data_config *)s;
+ data_config *ds = data_config_init();
+
+- buffer_copy_string_buffer(ds->key, src->key);
+- buffer_copy_string_buffer(ds->comp_key, src->comp_key);
++ buffer_copy_buffer(ds->key, src->key);
++ buffer_copy_buffer(ds->comp_key, src->comp_key);
+ array_free(ds->value);
+ ds->value = array_init_array(src->value);
+ return (data_unset *)ds;
+diff --git a/src/data_count.c b/src/data_count.c
+index 8d36c8b..0337224 100644
+--- a/src/data_count.c
++++ b/src/data_count.c
+@@ -8,7 +8,7 @@ static data_unset *data_count_copy(const data_unset *s) {
+ data_count *src = (data_count *)s;
+ data_count *ds = data_count_init();
+
+- buffer_copy_string_buffer(ds->key, src->key);
++ buffer_copy_buffer(ds->key, src->key);
+ ds->count = src->count;
+ ds->is_index_key = src->is_index_key;
+ return (data_unset *)ds;
+diff --git a/src/data_fastcgi.c b/src/data_fastcgi.c
+index e13a470..a312506 100644
+--- a/src/data_fastcgi.c
++++ b/src/data_fastcgi.c
+@@ -9,8 +9,8 @@ static data_unset *data_fastcgi_copy(const data_unset *s) {
+ data_fastcgi *src = (data_fastcgi *)s;
+ data_fastcgi *ds = data_fastcgi_init();
+
+- buffer_copy_string_buffer(ds->key, src->key);
+- buffer_copy_string_buffer(ds->host, src->host);
++ buffer_copy_buffer(ds->key, src->key);
++ buffer_copy_buffer(ds->host, src->host);
+ ds->is_index_key = src->is_index_key;
+ return (data_unset *)ds;
+ }
+diff --git a/src/data_integer.c b/src/data_integer.c
+index 63cbb10..5cfe11b 100644
+--- a/src/data_integer.c
++++ b/src/data_integer.c
+@@ -8,7 +8,7 @@ static data_unset *data_integer_copy(const data_unset *s) {
+ data_integer *src = (data_integer *)s;
+ data_integer *ds = data_integer_init();
+
+- buffer_copy_string_buffer(ds->key, src->key);
++ buffer_copy_buffer(ds->key, src->key);
+ ds->is_index_key = src->is_index_key;
+ ds->value = src->value;
+ return (data_unset *)ds;
+diff --git a/src/data_string.c b/src/data_string.c
+index 41c9ec1..fc57de2 100644
+--- a/src/data_string.c
++++ b/src/data_string.c
+@@ -9,8 +9,8 @@ static data_unset *data_string_copy(const data_unset *s) {
+ data_string *src = (data_string *)s;
+ data_string *ds = data_string_init();
+
+- buffer_copy_string_buffer(ds->key, src->key);
+- buffer_copy_string_buffer(ds->value, src->value);
++ buffer_copy_buffer(ds->key, src->key);
++ buffer_copy_buffer(ds->value, src->value);
+ ds->is_index_key = src->is_index_key;
+ return (data_unset *)ds;
+ }
+@@ -40,7 +40,7 @@ static int data_string_insert_dup(data_unset *dst, data_unset *src) {
+ buffer_append_string_len(ds_dst->value, CONST_STR_LEN(", "));
+ buffer_append_string_buffer(ds_dst->value, ds_src->value);
+ } else {
+- buffer_copy_string_buffer(ds_dst->value, ds_src->value);
++ buffer_copy_buffer(ds_dst->value, ds_src->value);
+ }
+
+ src->free(src);
+@@ -58,7 +58,7 @@ static int data_response_insert_dup(data_unset *dst, data_unset *src) {
+ buffer_append_string_len(ds_dst->value, CONST_STR_LEN(": "));
+ buffer_append_string_buffer(ds_dst->value, ds_src->value);
+ } else {
+- buffer_copy_string_buffer(ds_dst->value, ds_src->value);
++ buffer_copy_buffer(ds_dst->value, ds_src->value);
+ }
+
+ src->free(src);
+diff --git a/src/etag.c b/src/etag.c
+index e7e9e3f..bf63d94 100644
+--- a/src/etag.c
++++ b/src/etag.c
+@@ -10,7 +10,7 @@
+ #include <string.h>
+
+ int etag_is_equal(buffer *etag, const char *matches) {
+- if (etag && !buffer_is_empty(etag) && 0 == strcmp(etag->ptr, matches)) return 1;
++ if (etag && !buffer_string_is_empty(etag) && 0 == strcmp(etag->ptr, matches)) return 1;
+ return 0;
+ }
+
+@@ -20,17 +20,17 @@ int etag_create(buffer *etag, struct stat *st,etag_flags_t flags) {
+ buffer_reset(etag);
+
+ if (flags & ETAG_USE_INODE) {
+- buffer_append_off_t(etag, st->st_ino);
++ buffer_append_int(etag, st->st_ino);
+ buffer_append_string_len(etag, CONST_STR_LEN("-"));
+ }
+
+ if (flags & ETAG_USE_SIZE) {
+- buffer_append_off_t(etag, st->st_size);
++ buffer_append_int(etag, st->st_size);
+ buffer_append_string_len(etag, CONST_STR_LEN("-"));
+ }
+
+ if (flags & ETAG_USE_MTIME) {
+- buffer_append_long(etag, st->st_mtime);
++ buffer_append_int(etag, st->st_mtime);
+ }
+
+ return 0;
+@@ -44,7 +44,7 @@ int etag_mutate(buffer *mut, buffer *etag) {
+
+ buffer_reset(mut);
+ buffer_copy_string_len(mut, CONST_STR_LEN("\""));
+- buffer_append_off_t(mut, h);
++ buffer_append_int(mut, h);
+ buffer_append_string_len(mut, CONST_STR_LEN("\""));
+
+ return 0;
+diff --git a/src/http-header-glue.c b/src/http-header-glue.c
+index fe2f4fb..abffb7d 100644
+--- a/src/http-header-glue.c
++++ b/src/http-header-glue.c
+@@ -123,7 +123,7 @@ int http_response_redirect_to_directory(server *srv, connection *con) {
+
+ o = buffer_init();
+
+- buffer_copy_string_buffer(o, con->uri.scheme);
++ buffer_copy_buffer(o, con->uri.scheme);
+ buffer_append_string_len(o, CONST_STR_LEN("://"));
+ if (con->uri.authority->used) {
+ buffer_append_string_buffer(o, con->uri.authority);
+@@ -197,13 +197,13 @@ int http_response_redirect_to_directory(server *srv, connection *con) {
+ }
+ if (default_port != srv->srvconf.port) {
+ buffer_append_string_len(o, CONST_STR_LEN(":"));
+- buffer_append_long(o, srv->srvconf.port);
++ buffer_append_int(o, srv->srvconf.port);
+ }
+ }
+ }
+ buffer_append_string_buffer(o, con->uri.path);
+ buffer_append_string_len(o, CONST_STR_LEN("/"));
+- if (!buffer_is_empty(con->uri.query)) {
++ if (!buffer_string_is_empty(con->uri.query)) {
+ buffer_append_string_len(o, CONST_STR_LEN("?"));
+ buffer_append_string_buffer(o, con->uri.query);
+ }
+diff --git a/src/http_auth.c b/src/http_auth.c
+index e1d15e0..91e388c 100644
+--- a/src/http_auth.c
++++ b/src/http_auth.c
+@@ -172,7 +172,7 @@ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *
+ stream f;
+ char * f_line;
+
+- if (buffer_is_empty(p->conf.auth_htdigest_userfile)) return -1;
++ if (buffer_string_is_empty(p->conf.auth_htdigest_userfile)) return -1;
+
+ if (0 != stream_open(&f, p->conf.auth_htdigest_userfile)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbss", "opening digest-userfile", p->conf.auth_htdigest_userfile, "failed:", strerror(errno));
+@@ -253,7 +253,7 @@ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *
+
+ auth_fn = (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) ? p->conf.auth_htpasswd_userfile : p->conf.auth_plain_userfile;
+
+- if (buffer_is_empty(auth_fn)) return -1;
++ if (buffer_string_is_empty(auth_fn)) return -1;
+
+ if (0 != stream_open(&f, auth_fn)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbss",
+@@ -748,7 +748,7 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
+ return -1;
+
+ /* build filter */
+- buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
++ buffer_copy_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
+ buffer_append_string_buffer(p->ldap_filter, username);
+ buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post);
+
+@@ -903,7 +903,7 @@ int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p,
+ }
+
+ /* remember the username */
+- buffer_copy_string_buffer(p->auth_user, username);
++ buffer_copy_buffer(p->auth_user, username);
+
+ buffer_free(username);
+ buffer_free(password);
+@@ -1192,7 +1192,7 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
+ int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer *fn, char out[33]) {
+ HASH h;
+ li_MD5_CTX Md5Ctx;
+- char hh[32];
++ char hh[LI_ITOSTRING_LENGTH];
+
+ UNUSED(p);
+
+@@ -1202,10 +1202,10 @@ int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer
+ li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
+
+ /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
+- LI_ltostr(hh, srv->cur_ts);
++ li_itostr(hh, srv->cur_ts);
+ li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
+ li_MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy));
+- LI_ltostr(hh, rand());
++ li_itostr(hh, rand());
+ li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
+
+ li_MD5_Final(h, &Md5Ctx);
+diff --git a/src/http_chunk.c b/src/http_chunk.c
+index 5557edc..e3647e6 100644
+--- a/src/http_chunk.c
++++ b/src/http_chunk.c
+@@ -20,21 +20,23 @@
+ #include <errno.h>
+ #include <string.h>
+
+-static int http_chunk_append_len(server *srv, connection *con, size_t len) {
++static void http_chunk_append_len(server *srv, connection *con, size_t len) {
+ size_t i, olen = len, j;
+ buffer *b;
+
++ force_assert(NULL != srv);
++
+ b = srv->tmp_chunk_len;
+
+ if (len == 0) {
+- buffer_copy_string_len(b, CONST_STR_LEN("0"));
++ buffer_copy_string_len(b, CONST_STR_LEN("0\r\n"));
+ } else {
+ for (i = 0; i < 8 && len; i++) {
+ len >>= 4;
+ }
+
+ /* i is the number of hex digits we have */
+- buffer_prepare_copy(b, i + 1);
++ buffer_prepare_copy(b, i + 2);
+
+ for (j = i-1, len = olen; j+1 > 0; j--) {
+ b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
+@@ -42,39 +44,40 @@ static int http_chunk_append_len(server *srv, connection *con, size_t len) {
+ }
+ b->used = i;
+ b->ptr[b->used++] = '\0';
++
++ buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
+ }
+
+- buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
+ chunkqueue_append_buffer(con->write_queue, b);
+-
+- return 0;
+ }
+
+
+-int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
++void http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
+ chunkqueue *cq;
+
+- if (!con) return -1;
++ force_assert(NULL != con);
++ if (0 == len) return;
+
+ cq = con->write_queue;
+
++
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+ http_chunk_append_len(srv, con, len);
+ }
+
+ chunkqueue_append_file(cq, fn, offset, len);
+
+- if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) {
+- chunkqueue_append_mem(cq, "\r\n", 2 + 1);
++ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
++ chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n"));
+ }
+-
+- return 0;
+ }
+
+-int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
++void http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
+ chunkqueue *cq;
+
+- if (!con) return -1;
++ force_assert(NULL != con);
++
++ if (buffer_string_is_empty(mem)) return;
+
+ cq = con->write_queue;
+
+@@ -84,49 +87,37 @@ int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
+
+ chunkqueue_append_buffer(cq, mem);
+
+- if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) {
+- chunkqueue_append_mem(cq, "\r\n", 2 + 1);
++ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
++ chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n"));
+ }
+-
+- return 0;
+ }
+
+-int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
++void http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
+ chunkqueue *cq;
+
+- if (!con) return -1;
++ force_assert(NULL != con);
++ force_assert(NULL != mem || 0 == len);
+
+- cq = con->write_queue;
++ if (NULL == mem || 0 == len) return;
+
+- if (len == 0) {
+- if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+- chunkqueue_append_mem(cq, "0\r\n\r\n", 5 + 1);
+- } else {
+- chunkqueue_append_mem(cq, "", 1);
+- }
+- return 0;
+- }
++ cq = con->write_queue;
+
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+- http_chunk_append_len(srv, con, len - 1);
++ http_chunk_append_len(srv, con, len);
+ }
+
+ chunkqueue_append_mem(cq, mem, len);
+
+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
+- chunkqueue_append_mem(cq, "\r\n", 2 + 1);
++ chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n"));
+ }
+-
+- return 0;
+ }
+
++void http_chunk_close(server *srv, connection *con) {
++ UNUSED(srv);
++ force_assert(NULL != con);
+
+-off_t http_chunkqueue_length(server *srv, connection *con) {
+- if (!con) {
+- log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!");
+-
+- return 0;
++ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
++ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("0\r\n\r\n"));
+ }
+-
+- return chunkqueue_length(con->write_queue);
+ }
+diff --git a/src/http_chunk.h b/src/http_chunk.h
+index 4ba24a2..127a116 100644
+--- a/src/http_chunk.h
++++ b/src/http_chunk.h
+@@ -4,9 +4,9 @@
+ #include "server.h"
+ #include <sys/types.h>
+
+-int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len);
+-int http_chunk_append_buffer(server *srv, connection *con, buffer *mem);
+-int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len);
+-off_t http_chunkqueue_length(server *srv, connection *con);
++void http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len); /* copies memory */
++void http_chunk_append_buffer(server *srv, connection *con, buffer *mem); /* may reset "mem" */
++void http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len); /* copies "fn" */
++void http_chunk_close(server *srv, connection *con);
+
+ #endif
+diff --git a/src/log.c b/src/log.c
+index 8033d17..75decfe 100644
+--- a/src/log.c
++++ b/src/log.c
+@@ -152,7 +152,7 @@ int log_error_open(server *srv) {
+
+ if (srv->srvconf.errorlog_use_syslog) {
+ srv->errorlog_mode = ERRORLOG_SYSLOG;
+- } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
++ } else if (!buffer_string_is_empty(srv->srvconf.errorlog_file)) {
+ const char *logfile = srv->srvconf.errorlog_file->ptr;
+
+ if (-1 == (srv->errorlog_fd = open_logfile_or_pipe(srv, logfile))) {
+@@ -170,7 +170,7 @@ int log_error_open(server *srv) {
+ srv->errorlog_fd = -1;
+ }
+
+- if (!buffer_is_empty(srv->srvconf.breakagelog_file)) {
++ if (!buffer_string_is_empty(srv->srvconf.breakagelog_file)) {
+ int breakage_fd;
+ const char *logfile = srv->srvconf.breakagelog_file->ptr;
+
+@@ -277,12 +277,12 @@ static void log_buffer_append_printf(buffer *out, const char *fmt, va_list ap) {
+ break;
+ case 'd': /* int */
+ d = va_arg(ap, int);
+- buffer_append_long(out, d);
++ buffer_append_int(out, d);
+ buffer_append_string_len(out, CONST_STR_LEN(" "));
+ break;
+ case 'o': /* off_t */
+ o = va_arg(ap, off_t);
+- buffer_append_off_t(out, o);
++ buffer_append_int(out, o);
+ buffer_append_string_len(out, CONST_STR_LEN(" "));
+ break;
+ case 'x': /* int (hex) */
+@@ -301,11 +301,11 @@ static void log_buffer_append_printf(buffer *out, const char *fmt, va_list ap) {
+ break;
+ case 'D': /* int */
+ d = va_arg(ap, int);
+- buffer_append_long(out, d);
++ buffer_append_int(out, d);
+ break;
+ case 'O': /* off_t */
+ o = va_arg(ap, off_t);
+- buffer_append_off_t(out, o);
++ buffer_append_int(out, o);
+ break;
+ case 'X': /* int (hex) */
+ d = va_arg(ap, int);
+@@ -339,7 +339,7 @@ static int log_buffer_prepare(buffer *b, server *srv, const char *filename, unsi
+ srv->last_generated_debug_ts = srv->cur_ts;
+ }
+
+- buffer_copy_string_buffer(b, srv->ts_debug_str);
++ buffer_copy_buffer(b, srv->ts_debug_str);
+ buffer_append_string_len(b, CONST_STR_LEN(": ("));
+ break;
+ case ERRORLOG_SYSLOG:
+@@ -350,7 +350,7 @@ static int log_buffer_prepare(buffer *b, server *srv, const char *filename, unsi
+
+ buffer_append_string(b, filename);
+ buffer_append_string_len(b, CONST_STR_LEN("."));
+- buffer_append_long(b, line);
++ buffer_append_int(b, line);
+ buffer_append_string_len(b, CONST_STR_LEN(") "));
+
+ return 0;
+diff --git a/src/mod_access.c b/src/mod_access.c
+index c4774b8..7b88e19 100644
+--- a/src/mod_access.c
++++ b/src/mod_access.c
+@@ -132,7 +132,7 @@ URIHANDLER_FUNC(mod_access_uri_handler) {
+ s_len = con->uri.path->used - 1;
+
+ if (con->conf.log_request_handling) {
+- log_error_write(srv, __FILE__, __LINE__, "s",
++ log_error_write(srv, __FILE__, __LINE__, "s",
+ "-- mod_access_uri_handler called");
+ }
+
+diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
+index 21a7764..89fd7f5 100644
+--- a/src/mod_accesslog.c
++++ b/src/mod_accesslog.c
+@@ -494,7 +494,7 @@ SETDEFAULTS_FUNC(log_access_open) {
+ return HANDLER_ERROR;
+ }
+
+- if (i == 0 && buffer_is_empty(s->format)) {
++ if (i == 0 && buffer_string_is_empty(s->format)) {
+ /* set a default logfile string */
+
+ buffer_copy_string_len(s->format, CONST_STR_LEN("%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""));
+@@ -523,7 +523,7 @@ SETDEFAULTS_FUNC(log_access_open) {
+ for (j = 0; j < s->parsed_format->used; j++) {
+ if (FIELD_FORMAT == s->parsed_format->ptr[j]->type) {
+ if (FORMAT_TIMESTAMP == s->parsed_format->ptr[j]->field) {
+- if (!buffer_is_empty(s->parsed_format->ptr[j]->string)) {
++ if (!buffer_string_is_empty(s->parsed_format->ptr[j]->string)) {
+ buffer_copy_string(s->ts_accesslog_fmt_str, s->parsed_format->ptr[j]->string->ptr);
+ }
+
+@@ -558,7 +558,7 @@ SETDEFAULTS_FUNC(log_access_open) {
+ }
+
+ s->append_tz_offset = 0;
+- if (buffer_is_empty(s->ts_accesslog_fmt_str)) {
++ if (buffer_string_is_empty(s->ts_accesslog_fmt_str)) {
+ #if defined(HAVE_STRUCT_TM_GMTOFF)
+ BUFFER_COPY_STRING_CONST(s->ts_accesslog_fmt_str, "[%d/%b/%Y:%H:%M:%S ");
+ s->append_tz_offset = 1;
+@@ -730,10 +730,10 @@ REQUESTDONE_FUNC(log_access_write) {
+
+ /* hours */
+ if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
+- buffer_append_long(p->conf.ts_accesslog_str, hrs);
++ buffer_append_int(p->conf.ts_accesslog_str, hrs);
+
+ if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
+- buffer_append_long(p->conf.ts_accesslog_str, min);
++ buffer_append_int(p->conf.ts_accesslog_str, min);
+ buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]"));
+ }
+ #else /* HAVE_STRUCT_TM_GMTOFF */
+@@ -777,12 +777,12 @@ REQUESTDONE_FUNC(log_access_write) {
+ }
+ break;
+ case FORMAT_STATUS:
+- buffer_append_long(b, con->http_status);
++ buffer_append_int(b, con->http_status);
+ break;
+
+ case FORMAT_BYTES_OUT_NO_HEADER:
+ if (con->bytes_written > 0) {
+- buffer_append_off_t(b,
++ buffer_append_int(b,
+ con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header);
+ } else {
+ buffer_append_string_len(b, CONST_STR_LEN("-"));
+@@ -818,20 +818,20 @@ REQUESTDONE_FUNC(log_access_write) {
+ break;
+ case FORMAT_BYTES_OUT:
+ if (con->bytes_written > 0) {
+- buffer_append_off_t(b, con->bytes_written);
++ buffer_append_int(b, con->bytes_written);
+ } else {
+ buffer_append_string_len(b, CONST_STR_LEN("-"));
+ }
+ break;
+ case FORMAT_BYTES_IN:
+ if (con->bytes_read > 0) {
+- buffer_append_off_t(b, con->bytes_read);
++ buffer_append_int(b, con->bytes_read);
+ } else {
+ buffer_append_string_len(b, CONST_STR_LEN("-"));
+ }
+ break;
+ case FORMAT_TIME_USED:
+- buffer_append_long(b, srv->cur_ts - con->request_start);
++ buffer_append_int(b, srv->cur_ts - con->request_start);
+ break;
+ case FORMAT_SERVER_NAME:
+ if (con->server_name->used > 1) {
+@@ -869,7 +869,7 @@ REQUESTDONE_FUNC(log_access_write) {
+ if (colon) {
+ buffer_append_string(b, colon+1);
+ } else {
+- buffer_append_long(b, srv->srvconf.port);
++ buffer_append_int(b, srv->srvconf.port);
+ }
+ }
+ break;
+diff --git a/src/mod_alias.c b/src/mod_alias.c
+index 062c268..bf22b5f 100644
+--- a/src/mod_alias.c
++++ b/src/mod_alias.c
+@@ -173,10 +173,10 @@ PHYSICALPATH_FUNC(mod_alias_physical_handler) {
+ strncmp(uri_ptr, ds->key->ptr, alias_len))) {
+ /* matched */
+
+- buffer_copy_string_buffer(con->physical.basedir, ds->value);
+- buffer_copy_string_buffer(srv->tmp_buf, ds->value);
++ buffer_copy_buffer(con->physical.basedir, ds->value);
++ buffer_copy_buffer(srv->tmp_buf, ds->value);
+ buffer_append_string(srv->tmp_buf, uri_ptr + alias_len);
+- buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
++ buffer_copy_buffer(con->physical.path, srv->tmp_buf);
+
+ return HANDLER_GO_ON;
+ }
+diff --git a/src/mod_auth.c b/src/mod_auth.c
+index 31e1140..d5a3f1c 100644
+--- a/src/mod_auth.c
++++ b/src/mod_auth.c
+@@ -324,7 +324,7 @@ static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
+ buffer_copy_string(ds->key, "REMOTE_USER");
+ array_insert_unique(con->environment, (data_unset *)ds);
+ }
+- buffer_copy_string_buffer(ds->value, p->auth_user);
++ buffer_copy_buffer(ds->value, p->auth_user);
+
+ /* AUTH_TYPE environment */
+
+@@ -535,7 +535,7 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) {
+ data_array *a;
+
+ a = data_array_init();
+- buffer_copy_string_buffer(a->key, da_file->key);
++ buffer_copy_buffer(a->key, da_file->key);
+
+ ds = data_string_init();
+
+@@ -608,7 +608,7 @@ handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
+ if (s->auth_ldap_starttls) {
+ /* if no CA file is given, it is ok, as we will use encryption
+ * if the server requires a CAfile it will tell us */
+- if (!buffer_is_empty(s->auth_ldap_cafile)) {
++ if (!buffer_string_is_empty(s->auth_ldap_cafile)) {
+ if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
+ s->auth_ldap_cafile->ptr))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+diff --git a/src/mod_cgi.c b/src/mod_cgi.c
+index 734ecee..76882e8 100644
+--- a/src/mod_cgi.c
++++ b/src/mod_cgi.c
+@@ -235,7 +235,7 @@ static int cgi_response_parse(server *srv, connection *con, plugin_data *p, buff
+
+ UNUSED(srv);
+
+- buffer_copy_string_buffer(p->parse_response, in);
++ buffer_copy_buffer(p->parse_response, in);
+
+ for (s = p->parse_response->ptr;
+ NULL != (ns = strchr(s, '\n'));
+@@ -350,7 +350,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
+ buffer_prepare_copy(hctx->response, 4 * 1024);
+ } else {
+ if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
+- buffer_prepare_copy(hctx->response, toread + 1);
++ buffer_prepare_copy(hctx->response, toread);
+ }
+ #endif
+
+@@ -370,7 +370,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
+ con->file_finished = 1;
+
+ /* send final chunk */
+- http_chunk_append_mem(srv, con, NULL, 0);
++ http_chunk_close(srv, con);
+ joblist_append(srv, con);
+
+ return FDEVENT_HANDLED_FINISHED;
+@@ -458,7 +458,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
+ con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
+ }
+
+- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
++ http_chunk_append_buffer(srv, con, hctx->response_header);
+ joblist_append(srv, con);
+ } else {
+ const char *bstart;
+@@ -493,7 +493,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
+ }
+
+ if (blen > 0) {
+- http_chunk_append_mem(srv, con, bstart, blen + 1);
++ http_chunk_append_mem(srv, con, bstart, blen);
+ joblist_append(srv, con);
+ }
+ }
+@@ -501,7 +501,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
+ con->file_started = 1;
+ }
+ } else {
+- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
++ http_chunk_append_buffer(srv, con, hctx->response);
+ joblist_append(srv, con);
+ }
+
+@@ -668,27 +668,17 @@ static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) {
+ /* perhaps this issue is already handled */
+ if (revents & FDEVENT_HUP) {
+ /* check if we still have a unfinished header package which is a body in reality */
+- if (con->file_started == 0 &&
+- hctx->response_header->used) {
++ if (con->file_started == 0 && !buffer_string_is_empty(hctx->response_header)) {
+ con->file_started = 1;
+- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
+- joblist_append(srv, con);
++ http_chunk_append_buffer(srv, con, hctx->response_header);
+ }
+
+ if (con->file_finished == 0) {
+- http_chunk_append_mem(srv, con, NULL, 0);
+- joblist_append(srv, con);
++ http_chunk_close(srv, con);
+ }
+-
+ con->file_finished = 1;
+
+- if (chunkqueue_is_empty(con->write_queue)) {
+- /* there is nothing left to write */
+- connection_set_state(srv, con, CON_STATE_RESPONSE_END);
+- } else {
+- /* used the write-handler to finish the request on demand */
+-
+- }
++ joblist_append(srv, con);
+
+ # if 0
+ log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
+@@ -777,7 +767,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
+ char **args;
+ int argc;
+ int i = 0;
+- char buf[32];
++ char buf[LI_ITOSTRING_LENGTH];
+ size_t n;
+ char_array env;
+ char *c;
+@@ -809,7 +799,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
+ cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag));
+ }
+
+- if (!buffer_is_empty(con->server_name)) {
++ if (!buffer_string_is_empty(con->server_name)) {
+ size_t len = con->server_name->used - 1;
+
+ if (con->server_name->ptr[0] == '[') {
+@@ -839,7 +829,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
+
+ cgi_env_add(&env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
+
+- LI_ltostr(buf,
++ li_utostr(buf,
+ #ifdef HAVE_IPV6
+ ntohs(srv_sock->addr.plain.sa_family == AF_INET6 ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
+ #else
+@@ -874,14 +864,14 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
+ s = get_http_method_name(con->request.http_method);
+ cgi_env_add(&env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
+
+- if (!buffer_is_empty(con->request.pathinfo)) {
++ if (!buffer_string_is_empty(con->request.pathinfo)) {
+ cgi_env_add(&env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
+ }
+ cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200"));
+- if (!buffer_is_empty(con->uri.query)) {
++ if (!buffer_string_is_empty(con->uri.query)) {
+ cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
+ }
+- if (!buffer_is_empty(con->request.orig_uri)) {
++ if (!buffer_string_is_empty(con->request.orig_uri)) {
+ cgi_env_add(&env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
+ }
+
+@@ -909,7 +899,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
+ }
+ cgi_env_add(&env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
+
+- LI_ltostr(buf,
++ li_utostr(buf,
+ #ifdef HAVE_IPV6
+ ntohs(con->dst_addr.plain.sa_family == AF_INET6 ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
+ #else
+@@ -922,8 +912,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
+ cgi_env_add(&env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
+ }
+
+- /* request.content_length < SSIZE_MAX, see request.c */
+- LI_ltostr(buf, con->request.content_length);
++ li_itostr(buf, con->request.content_length);
+ cgi_env_add(&env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
+ cgi_env_add(&env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
+ cgi_env_add(&env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
+@@ -1134,8 +1123,6 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
+ }
+ }
+ break;
+- case UNUSED_CHUNK:
+- break;
+ }
+
+ if (r > 0) {
+diff --git a/src/mod_cml.c b/src/mod_cml.c
+index b5b5ac2..3033d42 100644
+--- a/src/mod_cml.c
++++ b/src/mod_cml.c
+@@ -184,7 +184,7 @@ static int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *
+
+ /* cleanup basedir */
+ b = p->baseurl;
+- buffer_copy_string_buffer(b, con->uri.path);
++ buffer_copy_buffer(b, con->uri.path);
+ for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
+
+ if (*c == '/') {
+@@ -193,7 +193,7 @@ static int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *
+ }
+
+ b = p->basedir;
+- buffer_copy_string_buffer(b, con->physical.path);
++ buffer_copy_buffer(b, con->physical.path);
+ for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
+
+ if (*c == '/') {
+@@ -218,7 +218,7 @@ URIHANDLER_FUNC(mod_cml_power_magnet) {
+ buffer_reset(p->baseurl);
+ buffer_reset(p->trigger_handler);
+
+- if (buffer_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON;
++ if (buffer_string_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON;
+
+ /*
+ * power-magnet:
+@@ -264,7 +264,7 @@ URIHANDLER_FUNC(mod_cml_power_magnet) {
+ URIHANDLER_FUNC(mod_cml_is_handled) {
+ plugin_data *p = p_d;
+
+- if (buffer_is_empty(con->physical.path)) return HANDLER_ERROR;
++ if (buffer_string_is_empty(con->physical.path)) return HANDLER_ERROR;
+
+ mod_cml_patch_connection(srv, con, p);
+
+@@ -272,7 +272,7 @@ URIHANDLER_FUNC(mod_cml_is_handled) {
+ buffer_reset(p->baseurl);
+ buffer_reset(p->trigger_handler);
+
+- if (buffer_is_empty(p->conf.ext)) return HANDLER_GO_ON;
++ if (buffer_string_is_empty(p->conf.ext)) return HANDLER_GO_ON;
+
+ if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, p->conf.ext->used - 1)) {
+ return HANDLER_GO_ON;
+diff --git a/src/mod_cml_lua.c b/src/mod_cml_lua.c
+index d05e854..63dd1e7 100644
+--- a/src/mod_cml_lua.c
++++ b/src/mod_cml_lua.c
+@@ -260,7 +260,7 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
+ c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
+ c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
+ c_to_lua_push(L, header_tbl, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
+- if (!buffer_is_empty(con->request.pathinfo)) {
++ if (!buffer_string_is_empty(con->request.pathinfo)) {
+ c_to_lua_push(L, header_tbl, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
+ }
+
+@@ -276,7 +276,7 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
+ header_tbl = lua_gettop(L);
+ lua_gettable(L, LUA_GLOBALSINDEX);
+
+- buffer_copy_string_buffer(b, con->uri.query);
++ buffer_copy_buffer(b, con->uri.query);
+ cache_export_get_params(L, header_tbl, b);
+ buffer_reset(b);
+
+@@ -346,7 +346,7 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
+
+ /* the file is relative, make it absolute */
+ if (s[0] != '/') {
+- buffer_copy_string_buffer(b, p->basedir);
++ buffer_copy_buffer(b, p->basedir);
+ buffer_append_string(b, lua_tostring(L, -1));
+ } else {
+ buffer_copy_string(b, lua_tostring(L, -1));
+@@ -358,7 +358,7 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
+ switch(errno) {
+ case ENOENT:
+ /* a file is missing, call the handler to generate it */
+- if (!buffer_is_empty(p->trigger_handler)) {
++ if (!buffer_string_is_empty(p->trigger_handler)) {
+ ret = 1; /* cache-miss */
+
+ log_error_write(srv, __FILE__, __LINE__, "s",
+@@ -433,12 +433,12 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
+ }
+ }
+
+- if (ret == 1 && !buffer_is_empty(p->trigger_handler)) {
++ if (ret == 1 && !buffer_string_is_empty(p->trigger_handler)) {
+ /* cache-miss */
+- buffer_copy_string_buffer(con->uri.path, p->baseurl);
++ buffer_copy_buffer(con->uri.path, p->baseurl);
+ buffer_append_string_buffer(con->uri.path, p->trigger_handler);
+
+- buffer_copy_string_buffer(con->physical.path, p->basedir);
++ buffer_copy_buffer(con->physical.path, p->basedir);
+ buffer_append_string_buffer(con->physical.path, p->trigger_handler);
+
+ chunkqueue_reset(con->write_queue);
+diff --git a/src/mod_compress.c b/src/mod_compress.c
+index c4183bb..ad6e9f2 100644
+--- a/src/mod_compress.c
++++ b/src/mod_compress.c
+@@ -222,7 +222,7 @@ SETDEFAULTS_FUNC(mod_compress_setdefaults) {
+
+ array_free(encodings_arr);
+
+- if (!buffer_is_empty(s->compress_cache_dir)) {
++ if (!buffer_string_is_empty(s->compress_cache_dir)) {
+ struct stat st;
+ mkdir_recursive(s->compress_cache_dir->ptr);
+
+@@ -351,7 +351,7 @@ static int deflate_file_to_buffer_deflate(server *srv, connection *con, plugin_d
+ }
+
+ /* trailer */
+- p->b->used += z.total_out;
++ p->b->used = z.total_out;
+
+ if (Z_OK != deflateEnd(&z)) {
+ return -1;
+@@ -429,12 +429,12 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
+ if (sce->st.st_size > 128 * 1024 * 1024) return -1;
+
+ buffer_reset(p->ofn);
+- buffer_copy_string_buffer(p->ofn, p->conf.compress_cache_dir);
+- BUFFER_APPEND_SLASH(p->ofn);
++ buffer_copy_buffer(p->ofn, p->conf.compress_cache_dir);
++ buffer_append_slash(p->ofn);
+
+ if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) {
+ buffer_append_string(p->ofn, con->physical.path->ptr + con->physical.doc_root->used - 1);
+- buffer_copy_string_buffer(p->b, p->ofn);
++ buffer_copy_buffer(p->b, p->ofn);
+ } else {
+ buffer_append_string_buffer(p->ofn, con->uri.path);
+ }
+@@ -469,7 +469,7 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
+ #if 0
+ log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit");
+ #endif
+- buffer_copy_string_buffer(con->physical.path, p->ofn);
++ buffer_copy_buffer(con->physical.path, p->ofn);
+
+ return 0;
+ }
+@@ -574,7 +574,7 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
+ return -1;
+ }
+
+- buffer_copy_string_buffer(con->physical.path, p->ofn);
++ buffer_copy_buffer(con->physical.path, p->ofn);
+
+ return 0;
+ }
+@@ -652,7 +652,7 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
+
+ chunkqueue_reset(con->write_queue);
+ b = chunkqueue_get_append_buffer(con->write_queue);
+- buffer_copy_memory(b, p->b->ptr, p->b->used + 1);
++ buffer_copy_string_len(b, p->b->ptr, p->b->used);
+
+ buffer_reset(con->physical.path);
+
+@@ -732,7 +732,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
+ return HANDLER_GO_ON;
+ }
+
+- if (buffer_is_empty(con->physical.path)) {
++ if (buffer_string_is_empty(con->physical.path)) {
+ return HANDLER_GO_ON;
+ }
+
+@@ -867,7 +867,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
+
+ if (use_etag) {
+ /* try matching etag of compressed version */
+- buffer_copy_string_buffer(srv->tmp_buf, sce->etag);
++ buffer_copy_buffer(srv->tmp_buf, sce->etag);
+ buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("-"));
+ buffer_append_string(srv->tmp_buf, compression_name);
+ etag_mutate(con->physical.etag, srv->tmp_buf);
+diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
+index 6a2b139..4b7106a 100644
+--- a/src/mod_dirlisting.c
++++ b/src/mod_dirlisting.c
+@@ -124,7 +124,7 @@ static int excludes_buffer_append(excludes_buffer *exb, buffer *string) {
+ }
+
+ exb->ptr[exb->used]->string = buffer_init();
+- buffer_copy_string_buffer(exb->ptr[exb->used]->string, string);
++ buffer_copy_buffer(exb->ptr[exb->used]->string, string);
+
+ exb->used++;
+
+@@ -469,7 +469,8 @@ static int http_list_directory_sizefmt(char *buf, off_t size) {
+ u++;
+ }
+
+- out += LI_ltostr(out, size);
++ li_itostr(out, size);
++ out += strlen(out);
+ out[0] = '.';
+ out[1] = remain + '0';
+ out[2] = *u;
+@@ -539,8 +540,8 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
+ stream s;
+ /* if we have a HEADER file, display it in <pre class="header"></pre> */
+
+- buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
+- BUFFER_APPEND_SLASH(p->tmp_buf);
++ buffer_copy_buffer(p->tmp_buf, con->physical.path);
++ buffer_append_slash(p->tmp_buf);
+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("HEADER.txt"));
+
+ if (-1 != stream_open(&s, p->tmp_buf)) {
+@@ -592,8 +593,8 @@ static void http_list_directory_footer(server *srv, connection *con, plugin_data
+ stream s;
+ /* if we have a README file, display it in <pre class="readme"></pre> */
+
+- buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
+- BUFFER_APPEND_SLASH(p->tmp_buf);
++ buffer_copy_buffer(p->tmp_buf, con->physical.path);
++ buffer_append_slash(p->tmp_buf);
+ buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("README.txt"));
+
+ if (-1 != stream_open(&s, p->tmp_buf)) {
+@@ -785,7 +786,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
+
+ out = chunkqueue_get_append_buffer(con->write_queue);
+ buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\""));
+- if (buffer_is_empty(p->conf.encoding)) {
++ if (buffer_string_is_empty(p->conf.encoding)) {
+ buffer_append_string_len(out, CONST_STR_LEN("iso-8859-1"));
+ } else {
+ buffer_append_string_buffer(out, p->conf.encoding);
+@@ -889,7 +890,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
+ http_list_directory_footer(srv, con, p, out);
+
+ /* Insert possible charset to Content-Type */
+- if (buffer_is_empty(p->conf.encoding)) {
++ if (buffer_string_is_empty(p->conf.encoding)) {
+ response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
+ } else {
+ buffer_copy_string_len(p->content_charset, CONST_STR_LEN("text/html; charset="));
+diff --git a/src/mod_evhost.c b/src/mod_evhost.c
+index a491baa..5281523 100644
+--- a/src/mod_evhost.c
++++ b/src/mod_evhost.c
+@@ -200,7 +200,7 @@ static int mod_evhost_parse_host(connection *con,array *host) {
+ /* is something between the dots */
+ ds = data_string_init();
+ buffer_copy_string_len(ds->key,CONST_STR_LEN("%"));
+- buffer_append_long(ds->key, i++);
++ buffer_append_int(ds->key, i++);
+ buffer_copy_string_len(ds->value,ptr+1,colon-ptr-1);
+
+ array_insert_unique(host,(data_unset *)ds);
+@@ -213,7 +213,7 @@ static int mod_evhost_parse_host(connection *con,array *host) {
+ if (colon != ptr) {
+ ds = data_string_init();
+ buffer_copy_string_len(ds->key,CONST_STR_LEN("%"));
+- buffer_append_long(ds->key, i /* ++ */);
++ buffer_append_int(ds->key, i /* ++ */);
+ buffer_copy_string_len(ds->value,ptr,colon-ptr);
+
+ array_insert_unique(host,(data_unset *)ds);
+@@ -311,7 +311,7 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
+ }
+ }
+
+- BUFFER_APPEND_SLASH(p->tmp_buf);
++ buffer_append_slash(p->tmp_buf);
+
+ array_free(parsed_host);
+
+@@ -324,7 +324,7 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
+ }
+
+ if (!not_good) {
+- buffer_copy_string_buffer(con->physical.doc_root, p->tmp_buf);
++ buffer_copy_buffer(con->physical.doc_root, p->tmp_buf);
+ }
+
+ return HANDLER_GO_ON;
+diff --git a/src/mod_expire.c b/src/mod_expire.c
+index 476261f..41895f9 100644
+--- a/src/mod_expire.c
++++ b/src/mod_expire.c
+@@ -346,7 +346,7 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
+
+ /* HTTP/1.1 */
+ buffer_copy_string_len(p->expire_tstmp, CONST_STR_LEN("max-age="));
+- buffer_append_long(p->expire_tstmp, expires - srv->cur_ts); /* as expires >= srv->cur_ts the difference is >= 0 */
++ buffer_append_int(p->expire_tstmp, expires - srv->cur_ts); /* as expires >= srv->cur_ts the difference is >= 0 */
+
+ response_header_append(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp));
+
+diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
+index ad1ec18..01e72e5 100644
+--- a/src/mod_fastcgi.c
++++ b/src/mod_fastcgi.c
+@@ -391,7 +391,7 @@ static void fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, f
+ buffer_append_string_buffer(b, host->id);
+ if (proc) {
+ buffer_append_string_len(b, CONST_STR_LEN("."));
+- buffer_append_long(b, proc->id);
++ buffer_append_int(b, proc->id);
+ }
+ }
+
+@@ -637,7 +637,7 @@ static int fastcgi_extension_insert(fcgi_exts *ext, buffer *key, fcgi_extension_
+ force_assert(fe);
+ fe->key = buffer_init();
+ fe->last_used_ndx = -1;
+- buffer_copy_string_buffer(fe->key, key);
++ buffer_copy_buffer(fe->key, key);
+
+ /* */
+
+@@ -724,7 +724,7 @@ FREE_FUNC(mod_fastcgi_free) {
+ }
+
+ if (proc->is_local &&
+- !buffer_is_empty(proc->unixsocket)) {
++ !buffer_string_is_empty(proc->unixsocket)) {
+ unlink(proc->unixsocket->ptr);
+ }
+ }
+@@ -734,7 +734,7 @@ FREE_FUNC(mod_fastcgi_free) {
+ kill(proc->pid, host->kill_signal);
+ }
+ if (proc->is_local &&
+- !buffer_is_empty(proc->unixsocket)) {
++ !buffer_string_is_empty(proc->unixsocket)) {
+ unlink(proc->unixsocket->ptr);
+ }
+ }
+@@ -868,7 +868,7 @@ static int fcgi_spawn_connection(server *srv,
+ "new proc, socket:", proc->port, proc->unixsocket);
+ }
+
+- if (!buffer_is_empty(proc->unixsocket)) {
++ if (!buffer_string_is_empty(proc->unixsocket)) {
+ memset(&fcgi_addr, 0, sizeof(fcgi_addr));
+
+ #ifdef HAVE_SYS_UN_H
+@@ -901,7 +901,7 @@ static int fcgi_spawn_connection(server *srv,
+ } else {
+ fcgi_addr_in.sin_family = AF_INET;
+
+- if (buffer_is_empty(host->host)) {
++ if (buffer_string_is_empty(host->host)) {
+ fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ } else {
+ struct hostent *he;
+@@ -937,13 +937,13 @@ static int fcgi_spawn_connection(server *srv,
+ fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
+
+ buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));
+- if (!buffer_is_empty(host->host)) {
++ if (!buffer_string_is_empty(host->host)) {
+ buffer_append_string_buffer(proc->connection_name, host->host);
+ } else {
+ buffer_append_string_len(proc->connection_name, CONST_STR_LEN("localhost"));
+ }
+ buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":"));
+- buffer_append_long(proc->connection_name, proc->port);
++ buffer_append_int(proc->connection_name, proc->port);
+ }
+
+ if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
+@@ -958,7 +958,7 @@ static int fcgi_spawn_connection(server *srv,
+ int val;
+
+ if (errno != ENOENT &&
+- !buffer_is_empty(proc->unixsocket)) {
++ !buffer_string_is_empty(proc->unixsocket)) {
+ unlink(proc->unixsocket->ptr);
+ }
+
+@@ -1285,7 +1285,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
+ host = fastcgi_host_init();
+ buffer_reset(fcgi_mode);
+
+- buffer_copy_string_buffer(host->id, da_host->key);
++ buffer_copy_buffer(host->id, da_host->key);
+
+ host->check_local = 1;
+ host->max_procs = 4;
+@@ -1319,8 +1319,8 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
+ goto error;
+ }
+
+- if ((!buffer_is_empty(host->host) || host->port) &&
+- !buffer_is_empty(host->unixsocket)) {
++ if ((!buffer_string_is_empty(host->host) || host->port) &&
++ !buffer_string_is_empty(host->unixsocket)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
+ "either host/port or socket have to be set in:",
+ da->key, "= (",
+@@ -1330,7 +1330,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
+ goto error;
+ }
+
+- if (!buffer_is_empty(host->unixsocket)) {
++ if (!buffer_string_is_empty(host->unixsocket)) {
+ /* unix domain socket */
+ struct sockaddr_un un;
+
+@@ -1346,8 +1346,8 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
+ } else {
+ /* tcp/ip */
+
+- if (buffer_is_empty(host->host) &&
+- buffer_is_empty(host->bin_path)) {
++ if (buffer_string_is_empty(host->host) &&
++ buffer_string_is_empty(host->bin_path)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
+ "host or binpath have to be set in:",
+ da->key, "= (",
+@@ -1366,7 +1366,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
+ }
+ }
+
+- if (!buffer_is_empty(host->bin_path)) {
++ if (!buffer_string_is_empty(host->bin_path)) {
+ /* a local socket + self spawning */
+ size_t pno;
+
+@@ -1386,12 +1386,12 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
+ proc->id = host->num_procs++;
+ host->max_id++;
+
+- if (buffer_is_empty(host->unixsocket)) {
++ if (buffer_string_is_empty(host->unixsocket)) {
+ proc->port = host->port + pno;
+ } else {
+- buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
++ buffer_copy_buffer(proc->unixsocket, host->unixsocket);
+ buffer_append_string_len(proc->unixsocket, CONST_STR_LEN("-"));
+- buffer_append_long(proc->unixsocket, pno);
++ buffer_append_int(proc->unixsocket, pno);
+ }
+
+ if (s->debug) {
+@@ -1425,10 +1425,10 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
+ host->active_procs++;
+ proc->state = PROC_STATE_RUNNING;
+
+- if (buffer_is_empty(host->unixsocket)) {
++ if (buffer_string_is_empty(host->unixsocket)) {
+ proc->port = host->port;
+ } else {
+- buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
++ buffer_copy_buffer(proc->unixsocket, host->unixsocket);
+ }
+
+ fastcgi_status_init(srv, p->statuskey, host, proc);
+@@ -1438,12 +1438,12 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
+ host->max_procs = 1;
+ }
+
+- if (!buffer_is_empty(fcgi_mode)) {
++ if (!buffer_string_is_empty(fcgi_mode)) {
+ if (strcmp(fcgi_mode->ptr, "responder") == 0) {
+ host->mode = FCGI_RESPONDER;
+ } else if (strcmp(fcgi_mode->ptr, "authorizer") == 0) {
+ host->mode = FCGI_AUTHORIZER;
+- if (buffer_is_empty(host->docroot)) {
++ if (buffer_string_is_empty(host->docroot)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "ERROR: docroot is required for authorizer mode.");
+ goto error;
+@@ -1672,7 +1672,7 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
+
+ memset(&fcgi_addr, 0, sizeof(fcgi_addr));
+
+- if (!buffer_is_empty(proc->unixsocket)) {
++ if (!buffer_string_is_empty(proc->unixsocket)) {
+ #ifdef HAVE_SYS_UN_H
+ /* use the unix domain socket */
+ fcgi_addr_un.sun_family = AF_UNIX;
+@@ -1692,7 +1692,7 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
+ #endif
+ fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
+
+- if (buffer_is_empty(proc->connection_name)) {
++ if (buffer_string_is_empty(proc->connection_name)) {
+ /* on remote spawing we have to set the connection-name now */
+ buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:"));
+ buffer_append_string_buffer(proc->connection_name, proc->unixsocket);
+@@ -1702,7 +1702,7 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
+ #endif
+ } else {
+ fcgi_addr_in.sin_family = AF_INET;
+- if (!buffer_is_empty(host->host)) {
++ if (!buffer_string_is_empty(host->host)) {
+ if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
+ log_error_write(srv, __FILE__, __LINE__, "sbs",
+ "converting IP address failed for", host->host,
+@@ -1718,16 +1718,16 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
+
+ fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
+
+- if (buffer_is_empty(proc->connection_name)) {
++ if (buffer_string_is_empty(proc->connection_name)) {
+ /* on remote spawing we have to set the connection-name now */
+ buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));
+- if (!buffer_is_empty(host->host)) {
++ if (!buffer_string_is_empty(host->host)) {
+ buffer_append_string_buffer(proc->connection_name, host->host);
+ } else {
+ buffer_append_string_len(proc->connection_name, CONST_STR_LEN("localhost"));
+ }
+ buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":"));
+- buffer_append_long(proc->connection_name, proc->port);
++ buffer_append_int(proc->connection_name, proc->port);
+ }
+ }
+
+@@ -1840,7 +1840,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+ FCGI_Header header;
+ buffer *b;
+
+- char buf[32];
++ char buf[LI_ITOSTRING_LENGTH];
+ const char *s;
+ #ifdef HAVE_IPV6
+ char b2[INET6_ADDRSTRLEN + 1];
+@@ -1865,7 +1865,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+
+ b = chunkqueue_get_append_buffer(hctx->wb);
+
+- buffer_copy_memory(b, (const char *)&beginRecord, sizeof(beginRecord));
++ buffer_copy_string_len(b, (const char *)&beginRecord, sizeof(beginRecord));
+
+ /* send FCGI_PARAMS */
+ buffer_prepare_copy(p->fcgi_env, 1024);
+@@ -1904,7 +1904,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1")),con)
+
+- LI_ltostr(buf,
++ li_utostr(buf,
+ #ifdef HAVE_IPV6
+ ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
+ #else
+@@ -1924,7 +1924,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+ }
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s)),con)
+
+- LI_ltostr(buf,
++ li_utostr(buf,
+ #ifdef HAVE_IPV6
+ ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
+ #else
+@@ -1940,8 +1940,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+ if (con->request.content_length > 0 && host->mode != FCGI_AUTHORIZER) {
+ /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
+
+- /* request.content_length < SSIZE_MAX, see request.c */
+- LI_ltostr(buf, con->request.content_length);
++ li_itostr(buf, con->request.content_length);
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)),con)
+ }
+
+@@ -1955,15 +1954,15 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path)),con)
+
+- if (!buffer_is_empty(con->request.pathinfo)) {
++ if (!buffer_string_is_empty(con->request.pathinfo)) {
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo)),con)
+
+ /* PATH_TRANSLATED is only defined if PATH_INFO is set */
+
+- if (!buffer_is_empty(host->docroot)) {
+- buffer_copy_string_buffer(p->path, host->docroot);
++ if (!buffer_string_is_empty(host->docroot)) {
++ buffer_copy_buffer(p->path, host->docroot);
+ } else {
+- buffer_copy_string_buffer(p->path, con->physical.basedir);
++ buffer_copy_buffer(p->path, con->physical.basedir);
+ }
+ buffer_append_string_buffer(p->path, con->request.pathinfo);
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_TRANSLATED"), CONST_BUF_LEN(p->path)),con)
+@@ -1980,19 +1979,19 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+ * parameter.
+ */
+
+- if (!buffer_is_empty(host->docroot)) {
++ if (!buffer_string_is_empty(host->docroot)) {
+ /*
+ * rewrite SCRIPT_FILENAME
+ *
+ */
+
+- buffer_copy_string_buffer(p->path, host->docroot);
++ buffer_copy_buffer(p->path, host->docroot);
+ buffer_append_string_buffer(p->path, con->uri.path);
+
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)),con)
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot)),con)
+ } else {
+- buffer_copy_string_buffer(p->path, con->physical.path);
++ buffer_copy_buffer(p->path, con->physical.path);
+
+ /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself
+ *
+@@ -2037,7 +2036,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+ if (!buffer_is_equal(con->request.uri, con->request.orig_uri)) {
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_URI"), CONST_BUF_LEN(con->request.uri)),con)
+ }
+- if (!buffer_is_empty(con->uri.query)) {
++ if (!buffer_string_is_empty(con->uri.query)) {
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query)),con)
+ } else {
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN("")),con)
+@@ -2056,135 +2055,43 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
+ FCGI_ENV_ADD_CHECK(fcgi_env_add_request_headers(srv, con, p), con);
+
+ fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0);
+- buffer_append_memory(b, (const char *)&header, sizeof(header));
+- buffer_append_memory(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
++ buffer_append_string_len(b, (const char *)&header, sizeof(header));
++ buffer_append_string_len(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
+
+ fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
+- buffer_append_memory(b, (const char *)&header, sizeof(header));
++ buffer_append_string_len(b, (const char *)&header, sizeof(header));
+
+- b->used++; /* add virtual \0 */
+ hctx->wb->bytes_in += b->used - 1;
+
+ if (con->request.content_length) {
+ chunkqueue *req_cq = con->request_content_queue;
+- chunk *req_c;
+ off_t offset;
+
+ /* something to send ? */
+- for (offset = 0, req_c = req_cq->first; offset != req_cq->bytes_in; ) {
++ for (offset = 0; offset != req_cq->bytes_in; ) {
+ off_t weWant = req_cq->bytes_in - offset > FCGI_MAX_LENGTH ? FCGI_MAX_LENGTH : req_cq->bytes_in - offset;
+- off_t written = 0;
+- off_t weHave = 0;
+
+ /* we announce toWrite octets
+ * now take all the request_content chunks that we need to fill this request
+ * */
+
+- b = chunkqueue_get_append_buffer(hctx->wb);
+ fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
+- buffer_copy_memory(b, (const char *)&header, sizeof(header));
++ chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header));
+ hctx->wb->bytes_in += sizeof(header);
+
+ if (p->conf.debug > 10) {
+ log_error_write(srv, __FILE__, __LINE__, "soso", "tosend:", offset, "/", req_cq->bytes_in);
+ }
+
+- for (written = 0; written != weWant; ) {
+- if (p->conf.debug > 10) {
+- log_error_write(srv, __FILE__, __LINE__, "soso", "chunk:", written, "/", weWant);
+- }
+-
+- switch (req_c->type) {
+- case FILE_CHUNK:
+- weHave = req_c->file.length - req_c->offset;
+-
+- if (weHave > weWant - written) weHave = weWant - written;
+-
+- if (p->conf.debug > 10) {
+- log_error_write(srv, __FILE__, __LINE__, "soSosOsb",
+- "sending", weHave, "bytes from (",
+- req_c->offset, "/", req_c->file.length, ")",
+- req_c->file.name);
+- }
+-
+- force_assert(weHave != 0);
+-
+- chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
+-
+- req_c->offset += weHave;
+- req_cq->bytes_out += weHave;
+- written += weHave;
+-
+- hctx->wb->bytes_in += weHave;
+-
+- /* steal the tempfile
+- *
+- * This is tricky:
+- * - we reference the tempfile from the request-content-queue several times
+- * if the req_c is larger than FCGI_MAX_LENGTH
+- * - we can't simply cleanup the request-content-queue as soon as possible
+- * as it would remove the tempfiles
+- * - the idea is to 'steal' the tempfiles and attach the is_temp flag to the last
+- * referencing chunk of the fastcgi-write-queue
+- *
+- * */
+-
+- if (req_c->offset == req_c->file.length) {
+- chunk *c;
+-
+- if (p->conf.debug > 10) {
+- log_error_write(srv, __FILE__, __LINE__, "s", "next chunk");
+- }
+- c = hctx->wb->last;
+-
+- force_assert(c->type == FILE_CHUNK);
+- force_assert(req_c->file.is_temp == 1);
+-
+- c->file.is_temp = 1;
+- req_c->file.is_temp = 0;
+-
+- chunkqueue_remove_finished_chunks(req_cq);
+-
+- req_c = req_cq->first;
+- }
+-
+- break;
+- case MEM_CHUNK:
+- /* append to the buffer */
+- weHave = req_c->mem->used - 1 - req_c->offset;
+-
+- if (weHave > weWant - written) weHave = weWant - written;
+-
+- buffer_append_memory(b, req_c->mem->ptr + req_c->offset, weHave);
++ chunkqueue_steal(hctx->wb, req_cq, weWant);
+
+- req_c->offset += weHave;
+- req_cq->bytes_out += weHave;
+- written += weHave;
+-
+- hctx->wb->bytes_in += weHave;
+-
+- if (req_c->offset == (off_t) req_c->mem->used - 1) {
+- chunkqueue_remove_finished_chunks(req_cq);
+-
+- req_c = req_cq->first;
+- }
+-
+- break;
+- default:
+- break;
+- }
+- }
+-
+- b->used++; /* add virtual \0 */
+ offset += weWant;
+ }
+ }
+
+- b = chunkqueue_get_append_buffer(hctx->wb);
+ /* terminate STDIN */
+ fcgi_header(&(header), FCGI_STDIN, request_id, 0, 0);
+- buffer_copy_memory(b, (const char *)&header, sizeof(header));
+- b->used++; /* add virtual \0 */
++ chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header));
+
+ hctx->wb->bytes_in += sizeof(header);
+
+@@ -2201,7 +2108,7 @@ static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buf
+
+ UNUSED(srv);
+
+- buffer_copy_string_buffer(p->parse_response, in);
++ buffer_copy_buffer(p->parse_response, in);
+
+ /* search for \n */
+ for (s = p->parse_response->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) {
+@@ -2381,7 +2288,7 @@ range_success: ;
+ }
+
+ buffer_copy_string_len(dcls->key, "Content-Length", sizeof("Content-Length")-1);
+- buffer_copy_off_t(dcls->value, sendfile2_content_length);
++ buffer_copy_int(dcls->value, sendfile2_content_length);
+ dcls = (data_string*) array_replace(con->response.headers, (data_unset *)dcls);
+ if (dcls) dcls->free((data_unset*)dcls);
+
+@@ -2599,17 +2506,17 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
+ */
+
+ if (hctx->response_header->used == 0) {
+- buffer_copy_string_buffer(hctx->response_header, packet.b);
++ buffer_copy_buffer(hctx->response_header, packet.b);
+ } else {
+ buffer_append_string_buffer(hctx->response_header, packet.b);
+ }
+
+ if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\r\n\r\n")))) {
+- blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4;
++ blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4 - 1;
+ hctx->response_header->used = (c - hctx->response_header->ptr) + 3;
+ c += 4; /* point the the start of the response */
+ } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) {
+- blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2;
++ blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2 - 1;
+ hctx->response_header->used = c - hctx->response_header->ptr + 2;
+ c += 2; /* point the the start of the response */
+ } else {
+@@ -2650,7 +2557,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
+ joblist_append(srv, con);
+
+ buffer_copy_string_len(dcls->key, "Content-Length", sizeof("Content-Length")-1);
+- buffer_copy_off_t(dcls->value, sce->st.st_size);
++ buffer_copy_int(dcls->value, sce->st.st_size);
+ dcls = (data_string*) array_replace(con->response.headers, (data_unset *)dcls);
+ if (dcls) dcls->free((data_unset*)dcls);
+
+@@ -2668,7 +2575,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
+ }
+
+
+- if (hctx->send_content_body && blen > 1) {
++ if (hctx->send_content_body && blen > 0) {
+ /* enable chunked-transfer-encoding */
+ if (con->request.http_version == HTTP_VERSION_1_1 &&
+ !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
+@@ -2685,7 +2592,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
+ con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
+ }
+
+- http_chunk_append_mem(srv, con, packet.b->ptr, packet.b->used);
++ http_chunk_append_buffer(srv, con, packet.b);
+ joblist_append(srv, con);
+ }
+ break;
+@@ -2703,7 +2610,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
+ !(con->http_status == 0 ||
+ con->http_status == 200)) {
+ /* send chunk-end if necessary */
+- http_chunk_append_mem(srv, con, NULL, 0);
++ http_chunk_close(srv, con);
+ joblist_append(srv, con);
+ }
+
+@@ -2820,7 +2727,7 @@ static int fcgi_restart_dead_procs(server *srv, plugin_data *p, fcgi_extension_h
+ /* local procs get restarted by us,
+ * remote ones hopefully by the admin */
+
+- if (!buffer_is_empty(host->bin_path)) {
++ if (!buffer_string_is_empty(host->bin_path)) {
+ /* we still have connections bound to this proc,
+ * let them terminate first */
+ if (proc->load != 0) break;
+@@ -3264,10 +3171,10 @@ static handler_t fcgi_handle_fdevent(server *srv, void *ctx, int revents) {
+ * now to handle authorized request.
+ */
+
+- buffer_copy_string_buffer(con->physical.doc_root, host->docroot);
+- buffer_copy_string_buffer(con->physical.basedir, host->docroot);
++ buffer_copy_buffer(con->physical.doc_root, host->docroot);
++ buffer_copy_buffer(con->physical.basedir, host->docroot);
+
+- buffer_copy_string_buffer(con->physical.path, host->docroot);
++ buffer_copy_buffer(con->physical.path, host->docroot);
+ buffer_append_string_buffer(con->physical.path, con->uri.path);
+ fcgi_connection_close(srv, hctx);
+
+@@ -3486,7 +3393,7 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
+
+ fn = uri_path_handler ? con->uri.path : con->physical.path;
+
+- if (buffer_is_empty(fn)) return HANDLER_GO_ON;
++ if (buffer_string_is_empty(fn)) return HANDLER_GO_ON;
+
+ s_len = fn->used - 1;
+
+diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c
+index 8041507..501f8e8 100644
+--- a/src/mod_flv_streaming.c
++++ b/src/mod_flv_streaming.c
+@@ -191,7 +191,7 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
+
+ if (con->mode != DIRECT) return HANDLER_GO_ON;
+
+- if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
++ if (buffer_string_is_empty(con->physical.path)) return HANDLER_GO_ON;
+
+ mod_flv_streaming_patch_connection(srv, con, p);
+
+@@ -214,7 +214,7 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
+ * otherwise send the full file */
+
+ array_reset(p->get_params);
+- buffer_copy_string_buffer(p->query_str, con->uri.query);
++ buffer_copy_buffer(p->query_str, con->uri.query);
+ split_get_params(p->get_params, p->query_str);
+
+ if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {
+diff --git a/src/mod_indexfile.c b/src/mod_indexfile.c
+index b46ead6..fe750c1 100644
+--- a/src/mod_indexfile.c
++++ b/src/mod_indexfile.c
+@@ -158,9 +158,9 @@ URIHANDLER_FUNC(mod_indexfile_subrequest) {
+ if (ds->value && ds->value->ptr[0] == '/') {
+ /* if the index-file starts with a prefix as use this file as
+ * index-generator */
+- buffer_copy_string_buffer(p->tmp_buf, con->physical.doc_root);
++ buffer_copy_buffer(p->tmp_buf, con->physical.doc_root);
+ } else {
+- buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
++ buffer_copy_buffer(p->tmp_buf, con->physical.path);
+ }
+ buffer_append_string_buffer(p->tmp_buf, ds->value);
+
+@@ -192,7 +192,7 @@ URIHANDLER_FUNC(mod_indexfile_subrequest) {
+
+ /* rewrite uri.path to the real path (/ -> /index.php) */
+ buffer_append_string_buffer(con->uri.path, ds->value);
+- buffer_copy_string_buffer(con->physical.path, p->tmp_buf);
++ buffer_copy_buffer(con->physical.path, p->tmp_buf);
+
+ /* fce is already set up a few lines above */
+
+diff --git a/src/mod_magnet.c b/src/mod_magnet.c
+index cfdc976..80cb799 100644
+--- a/src/mod_magnet.c
++++ b/src/mod_magnet.c
+@@ -319,7 +319,7 @@ static int magnet_stat(lua_State *L) {
+ lua_setfield(L, -2, "st_ino");
+
+
+- if (!buffer_is_empty(sce->etag)) {
++ if (!buffer_string_is_empty(sce->etag)) {
+ /* we have to mutate the etag */
+ buffer *b = buffer_init();
+ etag_mutate(b, sce->etag);
+@@ -331,7 +331,7 @@ static int magnet_stat(lua_State *L) {
+ }
+ lua_setfield(L, -2, "etag");
+
+- if (!buffer_is_empty(sce->content_type)) {
++ if (!buffer_string_is_empty(sce->content_type)) {
+ lua_pushlstring(L, sce->content_type->ptr, sce->content_type->used - 1);
+ } else {
+ lua_pushnil(L);
+@@ -759,7 +759,7 @@ static int magnet_attach_content(server *srv, connection *con, plugin_data *p, l
+ size_t s_len = 0;
+ const char *s = lua_tolstring(L, -1, &s_len);
+
+- chunkqueue_append_mem(con->write_queue, s, s_len + 1);
++ chunkqueue_append_mem(con->write_queue, s, s_len);
+ } else if (lua_istable(L, -1)) {
+ lua_getfield(L, -1, "filename");
+ lua_getfield(L, -2, "length");
+@@ -1066,7 +1066,7 @@ static handler_t magnet_attract_array(server *srv, connection *con, plugin_data
+ data_string *ds = (data_string *)files->data[i];
+ handler_t ret;
+
+- if (buffer_is_empty(ds->value)) continue;
++ if (buffer_string_is_empty(ds->value)) continue;
+
+ ret = magnet_attract(srv, con, p, ds->value);
+
+diff --git a/src/mod_magnet_cache.c b/src/mod_magnet_cache.c
+index 90c633e..0e9f72f 100644
+--- a/src/mod_magnet_cache.c
++++ b/src/mod_magnet_cache.c
+@@ -104,7 +104,7 @@ lua_State *script_cache_get_script(server *srv, connection *con, script_cache *c
+
+ cache->ptr[cache->used++] = sc;
+
+- buffer_copy_string_buffer(sc->name, name);
++ buffer_copy_buffer(sc->name, name);
+
+ sc->L = luaL_newstate();
+ luaL_openlibs(sc->L);
+@@ -119,7 +119,7 @@ lua_State *script_cache_get_script(server *srv, connection *con, script_cache *c
+ }
+
+ if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, sc->name, &sce)) {
+- buffer_copy_string_buffer(sc->etag, sce->etag);
++ buffer_copy_buffer(sc->etag, sce->etag);
+ }
+
+ /**
+diff --git a/src/mod_mysql_vhost.c b/src/mod_mysql_vhost.c
+index a02ed2c..8442f76 100644
+--- a/src/mod_mysql_vhost.c
++++ b/src/mod_mysql_vhost.c
+@@ -227,7 +227,7 @@ SERVER_FUNC(mod_mysql_vhost_set_defaults) {
+ buffer_copy_string(s->mysql_pre, sel->ptr);
+ buffer_copy_string(s->mysql_post, qmark+1);
+ } else {
+- buffer_copy_string_buffer(s->mysql_pre, sel);
++ buffer_copy_buffer(s->mysql_pre, sel);
+ }
+
+ /* required:
+@@ -242,8 +242,8 @@ SERVER_FUNC(mod_mysql_vhost_set_defaults) {
+ */
+
+ /* all have to be set */
+- if (!(buffer_is_empty(s->myuser) ||
+- buffer_is_empty(s->mydb))) {
++ if (!(buffer_string_is_empty(s->myuser) ||
++ buffer_string_is_empty(s->mydb))) {
+ my_bool reconnect = 1;
+
+ if (NULL == (s->mysql = mysql_init(NULL))) {
+@@ -349,7 +349,7 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
+ buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON;
+
+ /* build and run SQL query */
+- buffer_copy_string_buffer(p->tmp_buf, p->conf.mysql_pre);
++ buffer_copy_buffer(p->tmp_buf, p->conf.mysql_pre);
+ if (p->conf.mysql_post->used) {
+ /* escape the uri.authority */
+ unsigned long to_len;
+@@ -382,7 +382,7 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
+
+ /* sanity check that really is a directory */
+ buffer_copy_string(p->tmp_buf, row[0]);
+- BUFFER_APPEND_SLASH(p->tmp_buf);
++ buffer_append_slash(p->tmp_buf);
+
+ if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
+ log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
+@@ -394,8 +394,8 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
+ }
+
+ /* cache the data */
+- buffer_copy_string_buffer(c->server_name, con->uri.authority);
+- buffer_copy_string_buffer(c->document_root, p->tmp_buf);
++ buffer_copy_buffer(c->server_name, con->uri.authority);
++ buffer_copy_buffer(c->document_root, p->tmp_buf);
+
+ /* fcgi_offset and fcgi_arg are optional */
+ if (cols > 1 && row[1]) {
+@@ -416,8 +416,8 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
+
+ /* fix virtual server and docroot */
+ GO_ON:
+- buffer_copy_string_buffer(con->server_name, c->server_name);
+- buffer_copy_string_buffer(con->physical.doc_root, c->document_root);
++ buffer_copy_buffer(con->server_name, c->server_name);
++ buffer_copy_buffer(con->physical.doc_root, c->document_root);
+
+ #ifdef DEBUG
+ log_error_write(srv, __FILE__, __LINE__, "sbbdb",
+diff --git a/src/mod_proxy.c b/src/mod_proxy.c
+index 957a5a2..3bfc78f 100644
+--- a/src/mod_proxy.c
++++ b/src/mod_proxy.c
+@@ -217,7 +217,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
+ return HANDLER_ERROR;
+ }
+
+- if (buffer_is_empty(p->balance_buf)) {
++ if (buffer_string_is_empty(p->balance_buf)) {
+ s->balance = PROXY_BALANCE_FAIR;
+ } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("fair"))) {
+ s->balance = PROXY_BALANCE_FAIR;
+@@ -292,7 +292,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
+
+ df->port = 80;
+
+- buffer_copy_string_buffer(df->key, da_host->key);
++ buffer_copy_buffer(df->key, da_host->key);
+
+ pcv[0].destination = df->host;
+ pcv[1].destination = &(df->port);
+@@ -302,7 +302,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
+ return HANDLER_ERROR;
+ }
+
+- if (buffer_is_empty(df->host)) {
++ if (buffer_string_is_empty(df->host)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbbbs",
+ "missing key (string):",
+ da->key,
+@@ -319,7 +319,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
+ if (NULL == (dfa = (data_array *)array_get_element(s->extensions, da_ext->key->ptr))) {
+ dfa = data_array_init();
+
+- buffer_copy_string_buffer(dfa->key, da_ext->key);
++ buffer_copy_buffer(dfa->key, da_ext->key);
+
+ array_insert_unique(dfa->value, (data_unset *)df);
+ array_insert_unique(s->extensions, (data_unset *)dfa);
+@@ -461,8 +461,7 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
+ proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
+ /* http_host is NOT is just a pointer to a buffer
+ * which is NULL if it is not set */
+- if (con->request.http_host &&
+- !buffer_is_empty(con->request.http_host)) {
++ if (!buffer_string_is_empty(con->request.http_host)) {
+ proxy_set_header(con, "X-Host", con->request.http_host->ptr);
+ }
+ proxy_set_header(con, "X-Forwarded-Proto", con->uri.scheme->ptr);
+@@ -491,55 +490,8 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
+
+ if (con->request.content_length) {
+ chunkqueue *req_cq = con->request_content_queue;
+- chunk *req_c;
+- off_t offset;
+-
+- /* something to send ? */
+- for (offset = 0, req_c = req_cq->first; offset != req_cq->bytes_in; req_c = req_c->next) {
+- off_t weWant = req_cq->bytes_in - offset;
+- off_t weHave = 0;
+-
+- /* we announce toWrite octects
+- * now take all the request_content chunk that we need to fill this request
+- * */
+-
+- switch (req_c->type) {
+- case FILE_CHUNK:
+- weHave = req_c->file.length - req_c->offset;
+-
+- if (weHave > weWant) weHave = weWant;
+-
+- chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
+-
+- req_c->offset += weHave;
+- req_cq->bytes_out += weHave;
+-
+- hctx->wb->bytes_in += weHave;
+-
+- break;
+- case MEM_CHUNK:
+- /* append to the buffer */
+- weHave = req_c->mem->used - 1 - req_c->offset;
+-
+- if (weHave > weWant) weHave = weWant;
+-
+- b = chunkqueue_get_append_buffer(hctx->wb);
+- buffer_append_memory(b, req_c->mem->ptr + req_c->offset, weHave);
+- b->used++; /* add virtual \0 */
+-
+- req_c->offset += weHave;
+- req_cq->bytes_out += weHave;
+-
+- hctx->wb->bytes_in += weHave;
+-
+- break;
+- default:
+- break;
+- }
+-
+- offset += weHave;
+- }
+
++ chunkqueue_steal(hctx->wb, req_cq, req_cq->bytes_in);
+ }
+
+ return 0;
+@@ -561,7 +513,7 @@ static int proxy_response_parse(server *srv, connection *con, plugin_data *p, bu
+
+ /* \r\n -> \0\0 */
+
+- buffer_copy_string_buffer(p->parse_response, in);
++ buffer_copy_buffer(p->parse_response, in);
+
+ for (s = p->parse_response->ptr; NULL != (ns = strstr(s, "\r\n")); s = ns + 2) {
+ char *key, *value;
+@@ -705,12 +657,12 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
+ char *c;
+
+ /* search for the \r\n\r\n in the string */
+- if (NULL != (c = buffer_search_string_len(hctx->response, "\r\n\r\n", 4))) {
++ if (NULL != (c = buffer_search_string_len(hctx->response, CONST_STR_LEN("\r\n\r\n")))) {
+ size_t hlen = c - hctx->response->ptr + 4;
+ size_t blen = hctx->response->used - hlen - 1;
+ /* found */
+
+- buffer_append_string_len(hctx->response_header, hctx->response->ptr, c - hctx->response->ptr + 4);
++ buffer_append_string_len(hctx->response_header, hctx->response->ptr, hlen);
+ #if 0
+ log_error_write(srv, __FILE__, __LINE__, "sb", "Header:", hctx->response_header);
+ #endif
+@@ -724,14 +676,12 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
+ }
+
+ con->file_started = 1;
+- if (blen) {
+- http_chunk_append_mem(srv, con, c + 4, blen + 1);
+- }
++ if (blen > 0) http_chunk_append_mem(srv, con, c + 4, blen);
+ hctx->response->used = 0;
+ joblist_append(srv, con);
+ }
+ } else {
+- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
++ http_chunk_append_buffer(srv, con, hctx->response);
+ joblist_append(srv, con);
+ hctx->response->used = 0;
+ }
+@@ -740,7 +690,7 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
+ /* reading from upstream done */
+ con->file_finished = 1;
+
+- http_chunk_append_mem(srv, con, NULL, 0);
++ http_chunk_close(srv, con);
+ joblist_append(srv, con);
+
+ fin = 1;
+@@ -976,6 +926,7 @@ static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) {
+ case 1:
+ /* we are done */
+ proxy_connection_close(srv, hctx);
++ log_error_write(srv, __FILE__, __LINE__, "s", "proxy request finished");
+
+ joblist_append(srv, con);
+ return HANDLER_FINISHED;
+@@ -1092,7 +1043,7 @@ static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) {
+ }
+
+ if (!con->file_finished) {
+- http_chunk_append_mem(srv, con, NULL, 0);
++ http_chunk_close(srv, con);
+ }
+
+ con->file_finished = 1;
+diff --git a/src/mod_redirect.c b/src/mod_redirect.c
+index bfc00d7..93cecb7 100644
+--- a/src/mod_redirect.c
++++ b/src/mod_redirect.c
+@@ -183,7 +183,7 @@ static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_
+
+ mod_redirect_patch_connection(srv, con, p);
+
+- buffer_copy_string_buffer(p->match_buf, con->request.uri);
++ buffer_copy_buffer(p->match_buf, con->request.uri);
+
+ for (i = 0; i < p->conf.redirect->used; i++) {
+ pcre *match;
+diff --git a/src/mod_rewrite.c b/src/mod_rewrite.c
+index 381f0ed..48c0987 100644
+--- a/src/mod_rewrite.c
++++ b/src/mod_rewrite.c
+@@ -101,7 +101,7 @@ static int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buf
+ }
+
+ kvb->ptr[kvb->used]->value = buffer_init();
+- buffer_copy_string_buffer(kvb->ptr[kvb->used]->value, value);
++ buffer_copy_buffer(kvb->ptr[kvb->used]->value, value);
+ kvb->ptr[kvb->used]->once = once;
+
+ kvb->used++;
+@@ -359,7 +359,7 @@ static int process_rewrite_rules(server *srv, connection *con, plugin_data *p, r
+ if (hctx->state == REWRITE_STATE_FINISHED) return HANDLER_GO_ON;
+ }
+
+- buffer_copy_string_buffer(p->match_buf, con->request.uri);
++ buffer_copy_buffer(p->match_buf, con->request.uri);
+
+ for (i = 0; i < kvb->used; i++) {
+ pcre *match;
+diff --git a/src/mod_rrdtool.c b/src/mod_rrdtool.c
+index df2a781..4986ea3 100644
+--- a/src/mod_rrdtool.c
++++ b/src/mod_rrdtool.c
+@@ -366,7 +366,7 @@ SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
+ return HANDLER_ERROR;
+ }
+
+- if (i > 0 && !buffer_is_empty(s->path_rrdtool_bin)) {
++ if (i > 0 && !buffer_string_is_empty(s->path_rrdtool_bin)) {
+ /* path_rrdtool_bin is a global option */
+
+ log_error_write(srv, __FILE__, __LINE__, "s",
+@@ -382,7 +382,7 @@ SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
+
+ /* check for dir */
+
+- if (buffer_is_empty(p->conf.path_rrdtool_bin)) {
++ if (buffer_string_is_empty(p->conf.path_rrdtool_bin)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "rrdtool.binary has to be set");
+ return HANDLER_ERROR;
+@@ -409,7 +409,7 @@ TRIGGER_FUNC(mod_rrd_trigger) {
+ plugin_config *s = p->config_storage[i];
+ int r;
+
+- if (buffer_is_empty(s->path_rrd)) continue;
++ if (buffer_string_is_empty(s->path_rrd)) continue;
+
+ /* write the data down every minute */
+
+@@ -418,11 +418,11 @@ TRIGGER_FUNC(mod_rrd_trigger) {
+ buffer_copy_string_len(p->cmd, CONST_STR_LEN("update "));
+ buffer_append_string_buffer(p->cmd, s->path_rrd);
+ buffer_append_string_len(p->cmd, CONST_STR_LEN(" N:"));
+- buffer_append_off_t(p->cmd, s->bytes_read);
++ buffer_append_int(p->cmd, s->bytes_read);
+ buffer_append_string_len(p->cmd, CONST_STR_LEN(":"));
+- buffer_append_off_t(p->cmd, s->bytes_written);
++ buffer_append_int(p->cmd, s->bytes_written);
+ buffer_append_string_len(p->cmd, CONST_STR_LEN(":"));
+- buffer_append_long(p->cmd, s->requests);
++ buffer_append_int(p->cmd, s->requests);
+ buffer_append_string_len(p->cmd, CONST_STR_LEN("\n"));
+
+ if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
+diff --git a/src/mod_scgi.c b/src/mod_scgi.c
+index 1c16c2d..66dce5e 100644
+--- a/src/mod_scgi.c
++++ b/src/mod_scgi.c
+@@ -306,7 +306,6 @@ typedef struct {
+
+ int reconnects; /* number of reconnect attempts */
+
+- read_buffer *rb;
+ chunkqueue *wb;
+
+ buffer *response_header;
+@@ -380,11 +379,6 @@ static void handler_ctx_free(handler_ctx *hctx) {
+
+ chunkqueue_free(hctx->wb);
+
+- if (hctx->rb) {
+- if (hctx->rb->ptr) free(hctx->rb->ptr);
+- free(hctx->rb);
+- }
+-
+ free(hctx);
+ }
+
+@@ -497,7 +491,7 @@ static int scgi_extension_insert(scgi_exts *ext, buffer *key, scgi_extension_hos
+ fe = calloc(1, sizeof(*fe));
+ force_assert(fe);
+ fe->key = buffer_init();
+- buffer_copy_string_buffer(fe->key, key);
++ buffer_copy_buffer(fe->key, key);
+
+ /* */
+
+@@ -579,7 +573,7 @@ FREE_FUNC(mod_scgi_free) {
+ if (proc->pid != 0) kill(proc->pid, SIGTERM);
+
+ if (proc->is_local &&
+- !buffer_is_empty(proc->socket)) {
++ !buffer_string_is_empty(proc->socket)) {
+ unlink(proc->socket->ptr);
+ }
+ }
+@@ -588,7 +582,7 @@ FREE_FUNC(mod_scgi_free) {
+ if (proc->pid != 0) kill(proc->pid, SIGTERM);
+
+ if (proc->is_local &&
+- !buffer_is_empty(proc->socket)) {
++ !buffer_string_is_empty(proc->socket)) {
+ unlink(proc->socket->ptr);
+ }
+ }
+@@ -665,7 +659,7 @@ static int scgi_spawn_connection(server *srv,
+ "new proc, socket:", proc->port, proc->socket);
+ }
+
+- if (!buffer_is_empty(proc->socket)) {
++ if (!buffer_string_is_empty(proc->socket)) {
+ memset(&scgi_addr, 0, sizeof(scgi_addr));
+
+ #ifdef HAVE_SYS_UN_H
+@@ -694,7 +688,7 @@ static int scgi_spawn_connection(server *srv,
+ } else {
+ scgi_addr_in.sin_family = AF_INET;
+
+- if (buffer_is_empty(host->host)) {
++ if (buffer_string_is_empty(host->host)) {
+ scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
+ } else {
+ struct hostent *he;
+@@ -741,7 +735,7 @@ static int scgi_spawn_connection(server *srv,
+ pid_t child;
+ int val;
+
+- if (!buffer_is_empty(proc->socket)) {
++ if (!buffer_string_is_empty(proc->socket)) {
+ unlink(proc->socket->ptr);
+ }
+
+@@ -1066,15 +1060,15 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
+ goto error;
+ }
+
+- if ((!buffer_is_empty(df->host) || df->port) &&
+- !buffer_is_empty(df->unixsocket)) {
++ if ((!buffer_string_is_empty(df->host) || df->port) &&
++ !buffer_string_is_empty(df->unixsocket)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "either host+port or socket");
+
+ goto error;
+ }
+
+- if (!buffer_is_empty(df->unixsocket)) {
++ if (!buffer_string_is_empty(df->unixsocket)) {
+ /* unix domain socket */
+ struct sockaddr_un un;
+
+@@ -1086,8 +1080,8 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
+ } else {
+ /* tcp/ip */
+
+- if (buffer_is_empty(df->host) &&
+- buffer_is_empty(df->bin_path)) {
++ if (buffer_string_is_empty(df->host) &&
++ buffer_string_is_empty(df->bin_path)) {
+ log_error_write(srv, __FILE__, __LINE__, "sbbbs",
+ "missing key (string):",
+ da->key,
+@@ -1107,7 +1101,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
+ }
+ }
+
+- if (!buffer_is_empty(df->bin_path)) {
++ if (!buffer_string_is_empty(df->bin_path)) {
+ /* a local socket + self spawning */
+ size_t pno;
+
+@@ -1134,12 +1128,12 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
+ proc->id = df->num_procs++;
+ df->max_id++;
+
+- if (buffer_is_empty(df->unixsocket)) {
++ if (buffer_string_is_empty(df->unixsocket)) {
+ proc->port = df->port + pno;
+ } else {
+- buffer_copy_string_buffer(proc->socket, df->unixsocket);
++ buffer_copy_buffer(proc->socket, df->unixsocket);
+ buffer_append_string_len(proc->socket, CONST_STR_LEN("-"));
+- buffer_append_long(proc->socket, pno);
++ buffer_append_int(proc->socket, pno);
+ }
+
+ if (s->debug) {
+@@ -1171,10 +1165,10 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
+ df->active_procs++;
+ fp->state = PROC_STATE_RUNNING;
+
+- if (buffer_is_empty(df->unixsocket)) {
++ if (buffer_string_is_empty(df->unixsocket)) {
+ fp->port = df->port;
+ } else {
+- buffer_copy_string_buffer(fp->socket, df->unixsocket);
++ buffer_copy_buffer(fp->socket, df->unixsocket);
+ }
+
+ df->first = fp;
+@@ -1342,7 +1336,7 @@ static int scgi_establish_connection(server *srv, handler_ctx *hctx) {
+
+ memset(&scgi_addr, 0, sizeof(scgi_addr));
+
+- if (!buffer_is_empty(proc->socket)) {
++ if (!buffer_string_is_empty(proc->socket)) {
+ #ifdef HAVE_SYS_UN_H
+ /* use the unix domain socket */
+ scgi_addr_un.sun_family = AF_UNIX;
+@@ -1471,7 +1465,7 @@ static int scgi_env_add_request_headers(server *srv, connection *con, plugin_dat
+
+
+ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+- char buf[32];
++ char buf[LI_ITOSTRING_LENGTH];
+ const char *s;
+ #ifdef HAVE_IPV6
+ char b2[INET6_ADDRSTRLEN + 1];
+@@ -1491,8 +1485,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+
+ /* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */
+
+- /* request.content_length < SSIZE_MAX, see request.c */
+- LI_ltostr(buf, con->request.content_length);
++ li_itostr(buf, con->request.content_length);
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SCGI"), CONST_STR_LEN("1"));
+
+@@ -1530,7 +1523,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
+
+- LI_ltostr(buf,
++ li_utostr(buf,
+ #ifdef HAVE_IPV6
+ ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
+ #else
+@@ -1550,7 +1543,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+ }
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
+
+- LI_ltostr(buf,
++ li_utostr(buf,
+ #ifdef HAVE_IPV6
+ ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
+ #else
+@@ -1571,15 +1564,15 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
+
+- if (!buffer_is_empty(con->request.pathinfo)) {
++ if (!buffer_string_is_empty(con->request.pathinfo)) {
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
+
+ /* PATH_TRANSLATED is only defined if PATH_INFO is set */
+
+- if (!buffer_is_empty(host->docroot)) {
+- buffer_copy_string_buffer(p->path, host->docroot);
++ if (!buffer_string_is_empty(host->docroot)) {
++ buffer_copy_buffer(p->path, host->docroot);
+ } else {
+- buffer_copy_string_buffer(p->path, con->physical.basedir);
++ buffer_copy_buffer(p->path, con->physical.basedir);
+ }
+ buffer_append_string_buffer(p->path, con->request.pathinfo);
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("PATH_TRANSLATED"), CONST_BUF_LEN(p->path));
+@@ -1595,19 +1588,19 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+ * parameter.
+ */
+
+- if (!buffer_is_empty(host->docroot)) {
++ if (!buffer_string_is_empty(host->docroot)) {
+ /*
+ * rewrite SCRIPT_FILENAME
+ *
+ */
+
+- buffer_copy_string_buffer(p->path, host->docroot);
++ buffer_copy_buffer(p->path, host->docroot);
+ buffer_append_string_buffer(p->path, con->uri.path);
+
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot));
+ } else {
+- buffer_copy_string_buffer(p->path, con->physical.path);
++ buffer_copy_buffer(p->path, con->physical.path);
+
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.basedir));
+@@ -1616,7 +1609,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+ if (!buffer_is_equal(con->request.uri, con->request.orig_uri)) {
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("REDIRECT_URI"), CONST_BUF_LEN(con->request.uri));
+ }
+- if (!buffer_is_empty(con->uri.query)) {
++ if (!buffer_string_is_empty(con->uri.query)) {
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
+ } else {
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
+@@ -1638,7 +1631,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+
+ b = chunkqueue_get_append_buffer(hctx->wb);
+
+- buffer_append_long(b, p->scgi_env->used);
++ buffer_append_int(b, p->scgi_env->used);
+ buffer_append_string_len(b, CONST_STR_LEN(":"));
+ buffer_append_string_len(b, (const char *)p->scgi_env->ptr, p->scgi_env->used);
+ buffer_append_string_len(b, CONST_STR_LEN(","));
+@@ -1647,54 +1640,8 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
+
+ if (con->request.content_length) {
+ chunkqueue *req_cq = con->request_content_queue;
+- chunk *req_c;
+- off_t offset;
+-
+- /* something to send ? */
+- for (offset = 0, req_c = req_cq->first; offset != req_cq->bytes_in; req_c = req_c->next) {
+- off_t weWant = req_cq->bytes_in - offset;
+- off_t weHave = 0;
+-
+- /* we announce toWrite octects
+- * now take all the request_content chunk that we need to fill this request
+- * */
+-
+- switch (req_c->type) {
+- case FILE_CHUNK:
+- weHave = req_c->file.length - req_c->offset;
+-
+- if (weHave > weWant) weHave = weWant;
+-
+- chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
+-
+- req_c->offset += weHave;
+- req_cq->bytes_out += weHave;
+-
+- hctx->wb->bytes_in += weHave;
+-
+- break;
+- case MEM_CHUNK:
+- /* append to the buffer */
+- weHave = req_c->mem->used - 1 - req_c->offset;
+
+- if (weHave > weWant) weHave = weWant;
+-
+- b = chunkqueue_get_append_buffer(hctx->wb);
+- buffer_append_memory(b, req_c->mem->ptr + req_c->offset, weHave);
+- b->used++; /* add virtual \0 */
+-
+- req_c->offset += weHave;
+- req_cq->bytes_out += weHave;
+-
+- hctx->wb->bytes_in += weHave;
+-
+- break;
+- default:
+- break;
+- }
+-
+- offset += weHave;
+- }
++ chunkqueue_steal(hctx->wb, req_cq, req_cq->bytes_in);
+ }
+
+ return 0;
+@@ -1707,7 +1654,7 @@ static int scgi_response_parse(server *srv, connection *con, plugin_data *p, buf
+
+ UNUSED(srv);
+
+- buffer_copy_string_buffer(p->parse_response, in);
++ buffer_copy_buffer(p->parse_response, in);
+
+ for (s = p->parse_response->ptr;
+ NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
+@@ -1827,7 +1774,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
+ con->file_finished = 1;
+
+ /* send final chunk */
+- http_chunk_append_mem(srv, con, NULL, 0);
++ http_chunk_close(srv, con);
+ joblist_append(srv, con);
+
+ return 1;
+@@ -1905,7 +1852,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
+ con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
+ }
+
+- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
++ http_chunk_append_buffer(srv, con, hctx->response_header);
+ joblist_append(srv, con);
+ } else {
+ size_t blen = hctx->response_header->used - hlen - 1;
+@@ -1924,7 +1871,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
+ }
+
+ if ((hctx->response->used != hlen) && blen > 0) {
+- http_chunk_append_mem(srv, con, hctx->response_header->ptr + hlen, blen + 1);
++ http_chunk_append_mem(srv, con, hctx->response_header->ptr + hlen, blen);
+ joblist_append(srv, con);
+ }
+ }
+@@ -1932,7 +1879,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
+ con->file_started = 1;
+ }
+ } else {
+- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
++ http_chunk_append_buffer(srv, con, hctx->response);
+ joblist_append(srv, con);
+ }
+
+@@ -2727,7 +2674,7 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
+
+ fn = uri_path_handler ? con->uri.path : con->physical.path;
+
+- if (buffer_is_empty(fn)) return HANDLER_GO_ON;
++ if (buffer_string_is_empty(fn)) return HANDLER_GO_ON;
+
+ s_len = fn->used - 1;
+
+@@ -3007,12 +2954,12 @@ TRIGGER_FUNC(mod_scgi_handle_trigger) {
+
+ host->num_procs++;
+
+- if (buffer_is_empty(host->unixsocket)) {
++ if (buffer_string_is_empty(host->unixsocket)) {
+ fp->port = host->port + fp->id;
+ } else {
+- buffer_copy_string_buffer(fp->socket, host->unixsocket);
++ buffer_copy_buffer(fp->socket, host->unixsocket);
+ buffer_append_string_len(fp->socket, CONST_STR_LEN("-"));
+- buffer_append_long(fp->socket, fp->id);
++ buffer_append_int(fp->socket, fp->id);
+ }
+
+ if (scgi_spawn_connection(srv, p, host, fp)) {
+diff --git a/src/mod_secure_download.c b/src/mod_secure_download.c
+index c32a3ac..d94482e 100644
+--- a/src/mod_secure_download.c
++++ b/src/mod_secure_download.c
+@@ -204,13 +204,13 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
+
+ if (buffer_is_empty(p->conf.uri_prefix)) return HANDLER_GO_ON;
+
+- if (buffer_is_empty(p->conf.secret)) {
++ if (buffer_string_is_empty(p->conf.secret)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "secdownload.secret has to be set");
+ return HANDLER_ERROR;
+ }
+
+- if (buffer_is_empty(p->conf.doc_root)) {
++ if (buffer_string_is_empty(p->conf.doc_root)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "secdownload.document-root has to be set");
+ return HANDLER_ERROR;
+@@ -233,7 +233,7 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
+ if (*(ts_str + 8) != '/') return HANDLER_GO_ON;
+
+ for (i = 0; i < 8; i++) {
+- ts = (ts << 4) + hex2int(*(ts_str + i));
++ ts = (ts << 4) + hex2int(ts_str[i]);
+ }
+
+ /* timed-out */
+@@ -252,7 +252,7 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
+ * <secret><rel-path><timestamp-hex>
+ */
+
+- buffer_copy_string_buffer(p->md5, p->conf.secret);
++ buffer_copy_buffer(p->md5, p->conf.secret);
+ buffer_append_string(p->md5, rel_uri);
+ buffer_append_string_len(p->md5, ts_str, 8);
+ force_assert(p->md5->used > 0);
+@@ -276,10 +276,10 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
+ /* starting with the last / we should have relative-path to the docroot
+ */
+
+- buffer_copy_string_buffer(con->physical.doc_root, p->conf.doc_root);
+- buffer_copy_string_buffer(con->physical.basedir, p->conf.doc_root);
++ buffer_copy_buffer(con->physical.doc_root, p->conf.doc_root);
++ buffer_copy_buffer(con->physical.basedir, p->conf.doc_root);
+ buffer_copy_string(con->physical.rel_path, rel_uri);
+- buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
++ buffer_copy_buffer(con->physical.path, con->physical.doc_root);
+ buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
+
+ return HANDLER_GO_ON;
+diff --git a/src/mod_setenv.c b/src/mod_setenv.c
+index ad91609..60e9b55 100644
+--- a/src/mod_setenv.c
++++ b/src/mod_setenv.c
+@@ -185,8 +185,8 @@ URIHANDLER_FUNC(mod_setenv_uri_handler) {
+ ds_dst = data_string_init();
+ }
+
+- buffer_copy_string_buffer(ds_dst->key, ds->key);
+- buffer_copy_string_buffer(ds_dst->value, ds->value);
++ buffer_copy_buffer(ds_dst->key, ds->key);
++ buffer_copy_buffer(ds_dst->value, ds->value);
+
+ array_insert_unique(con->request.headers, (data_unset *)ds_dst);
+ }
+@@ -199,8 +199,8 @@ URIHANDLER_FUNC(mod_setenv_uri_handler) {
+ ds_dst = data_string_init();
+ }
+
+- buffer_copy_string_buffer(ds_dst->key, ds->key);
+- buffer_copy_string_buffer(ds_dst->value, ds->value);
++ buffer_copy_buffer(ds_dst->key, ds->key);
++ buffer_copy_buffer(ds_dst->value, ds->value);
+
+ array_insert_unique(con->environment, (data_unset *)ds_dst);
+ }
+diff --git a/src/mod_simple_vhost.c b/src/mod_simple_vhost.c
+index 1240fda..7245fd5 100644
+--- a/src/mod_simple_vhost.c
++++ b/src/mod_simple_vhost.c
+@@ -127,7 +127,7 @@ static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *
+ force_assert(p->conf.server_root->used > 1);
+
+ buffer_prepare_copy(out, 128);
+- buffer_copy_string_buffer(out, p->conf.server_root);
++ buffer_copy_buffer(out, p->conf.server_root);
+
+ if (host->used) {
+ /* a hostname has to start with a alpha-numerical character
+@@ -135,7 +135,7 @@ static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *
+ */
+ char *dp;
+
+- BUFFER_APPEND_SLASH(out);
++ buffer_append_slash(out);
+
+ if (NULL == (dp = strchr(host->ptr, ':'))) {
+ buffer_append_string_buffer(out, host);
+@@ -143,13 +143,13 @@ static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *
+ buffer_append_string_len(out, host->ptr, dp - host->ptr);
+ }
+ }
+- BUFFER_APPEND_SLASH(out);
++ buffer_append_slash(out);
+
+ if (p->conf.document_root->used > 2 && p->conf.document_root->ptr[0] == '/') {
+ buffer_append_string_len(out, p->conf.document_root->ptr + 1, p->conf.document_root->used - 2);
+ } else {
+ buffer_append_string_buffer(out, p->conf.document_root);
+- BUFFER_APPEND_SLASH(out);
++ buffer_append_slash(out);
+ }
+
+ if (HANDLER_ERROR == stat_cache_get_entry(srv, con, out, &sce)) {
+@@ -233,8 +233,8 @@ static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_
+ con->uri.authority->used &&
+ buffer_is_equal(p->conf.docroot_cache_key, con->uri.authority)) {
+ /* cache hit */
+- buffer_copy_string_buffer(con->server_name, p->conf.docroot_cache_servername);
+- buffer_copy_string_buffer(con->physical.doc_root, p->conf.docroot_cache_value);
++ buffer_copy_buffer(con->server_name, p->conf.docroot_cache_servername);
++ buffer_copy_buffer(con->physical.doc_root, p->conf.docroot_cache_value);
+ } else {
+ /* build document-root */
+ if ((con->uri.authority->used == 0) ||
+@@ -244,21 +244,21 @@ static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_
+ p->doc_root,
+ p->conf.default_host)) {
+ /* default host worked */
+- buffer_copy_string_buffer(con->server_name, p->conf.default_host);
+- buffer_copy_string_buffer(con->physical.doc_root, p->doc_root);
++ buffer_copy_buffer(con->server_name, p->conf.default_host);
++ buffer_copy_buffer(con->physical.doc_root, p->doc_root);
+ /* do not cache default host */
+ }
+ return HANDLER_GO_ON;
+ }
+
+ /* found host */
+- buffer_copy_string_buffer(con->server_name, con->uri.authority);
+- buffer_copy_string_buffer(con->physical.doc_root, p->doc_root);
++ buffer_copy_buffer(con->server_name, con->uri.authority);
++ buffer_copy_buffer(con->physical.doc_root, p->doc_root);
+
+ /* copy to cache */
+- buffer_copy_string_buffer(p->conf.docroot_cache_key, con->uri.authority);
+- buffer_copy_string_buffer(p->conf.docroot_cache_value, p->doc_root);
+- buffer_copy_string_buffer(p->conf.docroot_cache_servername, con->server_name);
++ buffer_copy_buffer(p->conf.docroot_cache_key, con->uri.authority);
++ buffer_copy_buffer(p->conf.docroot_cache_value, p->doc_root);
++ buffer_copy_buffer(p->conf.docroot_cache_servername, con->server_name);
+ }
+
+ return HANDLER_GO_ON;
+diff --git a/src/mod_ssi.c b/src/mod_ssi.c
+index 0c1cdba..38eeac5 100644
+--- a/src/mod_ssi.c
++++ b/src/mod_ssi.c
+@@ -236,7 +236,7 @@ static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data
+ }
+
+ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
+- char buf[32];
++ char buf[LI_ITOSTRING_LENGTH];
+
+ server_socket *srv_sock = con->srv_socket;
+
+@@ -263,7 +263,7 @@ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
+ );
+ ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1");
+
+- LI_ltostr(buf,
++ li_utostr(buf,
+ #ifdef HAVE_IPV6
+ ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
+ #else
+@@ -279,8 +279,7 @@ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
+ if (con->request.content_length > 0) {
+ /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
+
+- /* request.content_length < SSIZE_MAX, see request.c */
+- LI_ltostr(buf, con->request.content_length);
++ li_itostr(buf, con->request.content_length);
+ ssi_env_add(p->ssi_cgi_env, CONST_STRING("CONTENT_LENGTH"), buf);
+ }
+
+@@ -434,12 +433,12 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
+ b = chunkqueue_get_append_buffer(con->write_queue);
+ #ifdef HAVE_PWD_H
+ if (NULL == (pw = getpwuid(sce->st.st_uid))) {
+- buffer_copy_long(b, sce->st.st_uid);
++ buffer_copy_int(b, sce->st.st_uid);
+ } else {
+ buffer_copy_string(b, pw->pw_name);
+ }
+ #else
+- buffer_copy_long(b, sce->st.st_uid);
++ buffer_copy_int(b, sce->st.st_uid);
+ #endif
+ break;
+ }
+@@ -481,7 +480,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
+
+ b = chunkqueue_get_append_buffer(con->write_queue);
+ if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
+- buffer_copy_string_buffer(b, con->physical.path);
++ buffer_copy_buffer(b, con->physical.path);
+ } else {
+ buffer_copy_string(b, sl + 1);
+ }
+@@ -489,7 +488,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
+ }
+ case SSI_ECHO_DOCUMENT_URI: {
+ b = chunkqueue_get_append_buffer(con->write_queue);
+- buffer_copy_string_buffer(b, con->uri.path);
++ buffer_copy_buffer(b, con->uri.path);
+ break;
+ }
+ default: {
+@@ -499,7 +498,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
+ b = chunkqueue_get_append_buffer(con->write_queue);
+
+ if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) {
+- buffer_copy_string_buffer(b, ds->value);
++ buffer_copy_buffer(b, ds->value);
+ } else {
+ buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
+ }
+@@ -575,7 +574,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
+
+ /* we have an uri */
+
+- buffer_copy_string_buffer(p->stat_fn, con->physical.doc_root);
++ buffer_copy_buffer(p->stat_fn, con->physical.doc_root);
+ buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
+ }
+
+@@ -593,10 +592,10 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
+
+ for (j = 0; s > 1024 && abr[j+1]; s /= 1024, j++);
+
+- buffer_copy_off_t(b, s);
++ buffer_copy_int(b, s);
+ buffer_append_string(b, abr[j]);
+ } else {
+- buffer_copy_off_t(b, st.st_size);
++ buffer_copy_int(b, st.st_size);
+ }
+ break;
+ case SSI_FLASTMOD:
+@@ -783,19 +782,19 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
+ int toread;
+ /* read everything from client and paste it into the output */
+ was_interrupted = 0;
+-
++
+ while(1) {
+ if (ioctl(from_exec_fds[0], FIONREAD, &toread)) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "unexpected end-of-file (perhaps the ssi-exec process died)");
+ return -1;
+ }
+-
++
+ if (toread > 0) {
+ b = chunkqueue_get_append_buffer(con->write_queue);
+-
+- buffer_prepare_copy(b, toread + 1);
+-
++
++ buffer_prepare_copy(b, toread);
++
+ if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) {
+ /* read failed */
+ break;
+diff --git a/src/mod_ssi_expr.c b/src/mod_ssi_expr.c
+index f839987..140d086 100644
+--- a/src/mod_ssi_expr.c
++++ b/src/mod_ssi_expr.c
+@@ -215,9 +215,9 @@ static int ssi_expr_tokenizer(server *srv, connection *con, plugin_data *p,
+ tid = TK_VALUE;
+
+ if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, token->ptr))) {
+- buffer_copy_string_buffer(token, ds->value);
++ buffer_copy_buffer(token, ds->value);
+ } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) {
+- buffer_copy_string_buffer(token, ds->value);
++ buffer_copy_buffer(token, ds->value);
+ } else {
+ buffer_copy_string_len(token, CONST_STR_LEN(""));
+ }
+diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c
+index af0718e..931bc57 100644
+--- a/src/mod_staticfile.c
++++ b/src/mod_staticfile.c
+@@ -294,11 +294,11 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
+
+ /* write Content-Range */
+ buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Range: bytes "));
+- buffer_append_off_t(b, start);
++ buffer_append_int(b, start);
+ buffer_append_string_len(b, CONST_STR_LEN("-"));
+- buffer_append_off_t(b, end);
++ buffer_append_int(b, end);
+ buffer_append_string_len(b, CONST_STR_LEN("/"));
+- buffer_append_off_t(b, sce->st.st_size);
++ buffer_append_int(b, sce->st.st_size);
+
+ buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Type: "));
+ buffer_append_string_buffer(b, content_type);
+@@ -341,11 +341,11 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
+ /* add Content-Range-header */
+
+ buffer_copy_string_len(p->range_buf, CONST_STR_LEN("bytes "));
+- buffer_append_off_t(p->range_buf, start);
++ buffer_append_int(p->range_buf, start);
+ buffer_append_string_len(p->range_buf, CONST_STR_LEN("-"));
+- buffer_append_off_t(p->range_buf, end);
++ buffer_append_int(p->range_buf, end);
+ buffer_append_string_len(p->range_buf, CONST_STR_LEN("/"));
+- buffer_append_off_t(p->range_buf, sce->st.st_size);
++ buffer_append_int(p->range_buf, sce->st.st_size);
+
+ response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(p->range_buf));
+ }
+@@ -449,7 +449,7 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
+ /* set response content-type, if not set already */
+
+ if (NULL == array_get_element(con->response.headers, "Content-Type")) {
+- if (buffer_is_empty(sce->content_type)) {
++ if (buffer_string_is_empty(sce->content_type)) {
+ /* we are setting application/octet-stream, but also announce that
+ * this header field might change in the seconds few requests
+ *
+@@ -469,7 +469,7 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
+ }
+
+ if (allow_caching) {
+- if (p->conf.etags_used && con->etag_flags != 0 && !buffer_is_empty(sce->etag)) {
++ if (p->conf.etags_used && con->etag_flags != 0 && !buffer_string_is_empty(sce->etag)) {
+ if (NULL == array_get_element(con->response.headers, "ETag")) {
+ /* generate e-tag */
+ etag_mutate(con->physical.etag, sce->etag);
+diff --git a/src/mod_status.c b/src/mod_status.c
+index f0d753b..e8da0a8 100644
+--- a/src/mod_status.c
++++ b/src/mod_status.c
+@@ -323,21 +323,21 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
+ seconds = ts;
+
+ if (days) {
+- buffer_append_long(b, days);
++ buffer_append_int(b, days);
+ buffer_append_string_len(b, CONST_STR_LEN(" days "));
+ }
+
+ if (hours) {
+- buffer_append_long(b, hours);
++ buffer_append_int(b, hours);
+ buffer_append_string_len(b, CONST_STR_LEN(" hours "));
+ }
+
+ if (mins) {
+- buffer_append_long(b, mins);
++ buffer_append_int(b, mins);
+ buffer_append_string_len(b, CONST_STR_LEN(" min "));
+ }
+
+- buffer_append_long(b, seconds);
++ buffer_append_int(b, seconds);
+ buffer_append_string_len(b, CONST_STR_LEN(" s"));
+
+ buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n"));
+@@ -357,7 +357,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
+
+ mod_status_get_multiplier(&avg, &multiplier, 1000);
+
+- buffer_append_long(b, avg);
++ buffer_append_int(b, avg);
+ buffer_append_string_len(b, CONST_STR_LEN(" "));
+ if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+ buffer_append_string_len(b, CONST_STR_LEN("req</td></tr>\n"));
+@@ -382,7 +382,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
+
+ mod_status_get_multiplier(&avg, &multiplier, 1000);
+
+- buffer_append_long(b, avg);
++ buffer_append_int(b, avg);
+ buffer_append_string_len(b, CONST_STR_LEN(" "));
+ if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+ buffer_append_string_len(b, CONST_STR_LEN("req/s</td></tr>\n"));
+@@ -411,7 +411,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
+
+ mod_status_get_multiplier(&avg, &multiplier, 1000);
+
+- buffer_append_long(b, avg);
++ buffer_append_int(b, avg);
+ buffer_append_string_len(b, CONST_STR_LEN(" "));
+ if (multiplier) buffer_append_string_len(b, &multiplier, 1);
+
+@@ -444,7 +444,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
+ "s = response-start, S = response-end\n"));
+
+ buffer_append_string_len(b, CONST_STR_LEN("<b>"));
+- buffer_append_long(b, srv->conns->used);
++ buffer_append_int(b, srv->conns->used);
+ buffer_append_string_len(b, CONST_STR_LEN(" connections</b>\n"));
+
+ for (j = 0; j < srv->conns->used; j++) {
+@@ -488,18 +488,18 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
+ buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
+
+ if (c->request.content_length) {
+- buffer_append_long(b, c->request_content_queue->bytes_in);
++ buffer_append_int(b, c->request_content_queue->bytes_in);
+ buffer_append_string_len(b, CONST_STR_LEN("/"));
+- buffer_append_long(b, c->request.content_length);
++ buffer_append_int(b, c->request.content_length);
+ } else {
+ buffer_append_string_len(b, CONST_STR_LEN("0/0"));
+ }
+
+ buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
+
+- buffer_append_off_t(b, chunkqueue_written(c->write_queue));
++ buffer_append_int(b, c->write_queue->bytes_out);
+ buffer_append_string_len(b, CONST_STR_LEN("/"));
+- buffer_append_off_t(b, chunkqueue_length(c->write_queue));
++ buffer_append_int(b, c->write_queue->bytes_out + chunkqueue_length(c->write_queue));
+
+ buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
+
+@@ -511,11 +511,11 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
+
+ buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
+
+- buffer_append_long(b, srv->cur_ts - c->request_start);
++ buffer_append_int(b, srv->cur_ts - c->request_start);
+
+ buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
+
+- if (buffer_is_empty(c->server_name)) {
++ if (buffer_string_is_empty(c->server_name)) {
+ buffer_append_string_buffer(b, c->uri.authority);
+ }
+ else {
+@@ -524,16 +524,16 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
+
+ buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
+
+- if (!buffer_is_empty(c->uri.path)) {
++ if (!buffer_string_is_empty(c->uri.path)) {
+ buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
+ }
+
+- if (!buffer_is_empty(c->uri.query)) {
++ if (!buffer_string_is_empty(c->uri.query)) {
+ buffer_append_string_len(b, CONST_STR_LEN("?"));
+ buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML);
+ }
+
+- if (!buffer_is_empty(c->request.orig_uri)) {
++ if (!buffer_string_is_empty(c->request.orig_uri)) {
+ buffer_append_string_len(b, CONST_STR_LEN(" ("));
+ buffer_append_string_encoded(b, CONST_BUF_LEN(c->request.orig_uri), ENCODING_HTML);
+ buffer_append_string_len(b, CONST_STR_LEN(")"));
+@@ -589,16 +589,16 @@ static handler_t mod_status_handle_server_status_text(server *srv, connection *c
+ /* output uptime */
+ buffer_append_string_len(b, CONST_STR_LEN("Uptime: "));
+ ts = srv->cur_ts - srv->startup_ts;
+- buffer_append_long(b, ts);
++ buffer_append_int(b, ts);
+ buffer_append_string_len(b, CONST_STR_LEN("\n"));
+
+ /* output busy servers */
+ buffer_append_string_len(b, CONST_STR_LEN("BusyServers: "));
+- buffer_append_long(b, srv->conns->used);
++ buffer_append_int(b, srv->conns->used);
+ buffer_append_string_len(b, CONST_STR_LEN("\n"));
+
+ buffer_append_string_len(b, CONST_STR_LEN("IdleServers: "));
+- buffer_append_long(b, srv->conns->size - srv->conns->used);
++ buffer_append_int(b, srv->conns->size - srv->conns->used);
+ buffer_append_string_len(b, CONST_STR_LEN("\n"));
+
+ /* output scoreboard */
+@@ -641,7 +641,7 @@ static handler_t mod_status_handle_server_statistics(server *srv, connection *co
+
+ buffer_append_string_buffer(b, st->data[ndx]->key);
+ buffer_append_string_len(b, CONST_STR_LEN(": "));
+- buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value);
++ buffer_append_int(b, ((data_integer *)(st->data[ndx]))->value);
+ buffer_append_string_len(b, CONST_STR_LEN("\n"));
+ }
+
+@@ -740,7 +740,7 @@ static handler_t mod_status_handle_server_config(server *srv, connection *con, v
+ plugin *pl = ps[i];
+
+ if (i == 0) {
+- buffer_copy_string_buffer(m, pl->name);
++ buffer_copy_buffer(m, pl->name);
+ } else {
+ buffer_append_string_len(m, CONST_STR_LEN("<br />"));
+ buffer_append_string_buffer(m, pl->name);
+@@ -809,13 +809,13 @@ static handler_t mod_status_handler(server *srv, connection *con, void *p_d) {
+
+ mod_status_patch_connection(srv, con, p);
+
+- if (!buffer_is_empty(p->conf.status_url) &&
++ if (!buffer_string_is_empty(p->conf.status_url) &&
+ buffer_is_equal(p->conf.status_url, con->uri.path)) {
+ return mod_status_handle_server_status(srv, con, p_d);
+- } else if (!buffer_is_empty(p->conf.config_url) &&
++ } else if (!buffer_string_is_empty(p->conf.config_url) &&
+ buffer_is_equal(p->conf.config_url, con->uri.path)) {
+ return mod_status_handle_server_config(srv, con, p_d);
+- } else if (!buffer_is_empty(p->conf.statistics_url) &&
++ } else if (!buffer_string_is_empty(p->conf.statistics_url) &&
+ buffer_is_equal(p->conf.statistics_url, con->uri.path)) {
+ return mod_status_handle_server_statistics(srv, con, p_d);
+ }
+diff --git a/src/mod_trigger_b4_dl.c b/src/mod_trigger_b4_dl.c
+index 6d9010d..cff125c 100644
+--- a/src/mod_trigger_b4_dl.c
++++ b/src/mod_trigger_b4_dl.c
+@@ -175,7 +175,7 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
+ return HANDLER_ERROR;
+ }
+ #if defined(HAVE_GDBM_H)
+- if (!buffer_is_empty(s->db_filename)) {
++ if (!buffer_string_is_empty(s->db_filename)) {
+ if (NULL == (s->db = gdbm_open(s->db_filename->ptr, 4096, GDBM_WRCREAT | GDBM_NOLOCK, S_IRUSR | S_IWUSR, 0))) {
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "gdbm-open failed");
+@@ -185,7 +185,7 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
+ }
+ #endif
+ #if defined(HAVE_PCRE_H)
+- if (!buffer_is_empty(s->download_url)) {
++ if (!buffer_string_is_empty(s->download_url)) {
+ if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr,
+ 0, &errptr, &erroff, NULL))) {
+
+@@ -196,7 +196,7 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
+ }
+ }
+
+- if (!buffer_is_empty(s->trigger_url)) {
++ if (!buffer_string_is_empty(s->trigger_url)) {
+ if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr,
+ 0, &errptr, &erroff, NULL))) {
+
+@@ -384,7 +384,7 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
+ # if defined(HAVE_MEMCACHE_H)
+ if (p->conf.mc) {
+ size_t i;
+- buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
++ buffer_copy_buffer(p->tmp_buf, p->conf.mc_namespace);
+ buffer_append_string(p->tmp_buf, remote_ip);
+
+ for (i = 0; i < p->tmp_buf->used - 1; i++) {
+@@ -471,7 +471,7 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
+ void *r;
+ size_t i;
+
+- buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
++ buffer_copy_buffer(p->tmp_buf, p->conf.mc_namespace);
+ buffer_append_string(p->tmp_buf, remote_ip);
+
+ for (i = 0; i < p->tmp_buf->used - 1; i++) {
+diff --git a/src/mod_userdir.c b/src/mod_userdir.c
+index 572b5e7..392f4b2 100644
+--- a/src/mod_userdir.c
++++ b/src/mod_userdir.c
+@@ -209,7 +209,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
+
+ buffer_copy_string_len(p->username, con->uri.path->ptr + 2, rel_url - (con->uri.path->ptr + 2));
+
+- if (buffer_is_empty(p->conf.basepath)
++ if (buffer_string_is_empty(p->conf.basepath)
+ #ifdef HAVE_PWD_H
+ && NULL == (pwd = getpwnam(p->username->ptr))
+ #endif
+@@ -245,7 +245,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
+
+ /* we build the physical path */
+
+- if (buffer_is_empty(p->conf.basepath)) {
++ if (buffer_string_is_empty(p->conf.basepath)) {
+ #ifdef HAVE_PWD_H
+ buffer_copy_string(p->temp_path, pwd->pw_dir);
+ #endif
+@@ -272,18 +272,18 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
+ buffer_to_lower(p->username);
+ }
+
+- buffer_copy_string_buffer(p->temp_path, p->conf.basepath);
+- BUFFER_APPEND_SLASH(p->temp_path);
++ buffer_copy_buffer(p->temp_path, p->conf.basepath);
++ buffer_append_slash(p->temp_path);
+ if (p->conf.letterhomes) {
+ buffer_append_string_len(p->temp_path, p->username->ptr, 1);
+- BUFFER_APPEND_SLASH(p->temp_path);
++ buffer_append_slash(p->temp_path);
+ }
+ buffer_append_string_buffer(p->temp_path, p->username);
+ }
+- BUFFER_APPEND_SLASH(p->temp_path);
++ buffer_append_slash(p->temp_path);
+ buffer_append_string_buffer(p->temp_path, p->conf.path);
+
+- if (buffer_is_empty(p->conf.basepath)) {
++ if (buffer_string_is_empty(p->conf.basepath)) {
+ struct stat st;
+ int ret;
+
+@@ -293,7 +293,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
+ }
+ }
+
+- buffer_copy_string_buffer(con->physical.basedir, p->temp_path);
++ buffer_copy_buffer(con->physical.basedir, p->temp_path);
+
+ /* the physical rel_path is basically the same as uri.path;
+ * but it is converted to lowercase in case of force_lowercase_filenames and some special handling
+@@ -302,7 +302,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
+ * (docroot should only set the docroot/server name, phyiscal should only change the phyiscal.path;
+ * the exception mod_secure_download doesn't work with userdir anyway)
+ */
+- BUFFER_APPEND_SLASH(p->temp_path);
++ buffer_append_slash(p->temp_path);
+ /* if no second '/' is found, we assume that it was stripped from the uri.path for the special handling
+ * on windows.
+ * we do not care about the trailing slash here on windows, as we already ensured it is a directory
+@@ -313,7 +313,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
+ if (NULL != (rel_url = strchr(con->physical.rel_path->ptr + 2, '/'))) {
+ buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */
+ }
+- buffer_copy_string_buffer(con->physical.path, p->temp_path);
++ buffer_copy_buffer(con->physical.path, p->temp_path);
+
+ buffer_reset(p->temp_path);
+
+diff --git a/src/mod_usertrack.c b/src/mod_usertrack.c
+index 4f4f264..29e9fdf 100644
+--- a/src/mod_usertrack.c
++++ b/src/mod_usertrack.c
+@@ -98,7 +98,7 @@ SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
+ return HANDLER_ERROR;
+ }
+
+- if (buffer_is_empty(s->cookie_name)) {
++ if (buffer_string_is_empty(s->cookie_name)) {
+ buffer_copy_string_len(s->cookie_name, CONST_STR_LEN("TRACKID"));
+ } else {
+ size_t j;
+@@ -114,7 +114,7 @@ SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
+ }
+ }
+
+- if (!buffer_is_empty(s->cookie_domain)) {
++ if (!buffer_string_is_empty(s->cookie_domain)) {
+ size_t j;
+ for (j = 0; j < s->cookie_domain->used - 1; j++) {
+ char c = s->cookie_domain->ptr[j];
+@@ -173,7 +173,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
+ data_string *ds;
+ unsigned char h[16];
+ li_MD5_CTX Md5Ctx;
+- char hh[32];
++ char hh[LI_ITOSTRING_LENGTH];
+
+ if (con->uri.path->used == 0) return HANDLER_GO_ON;
+
+@@ -211,7 +211,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
+ ds = data_response_init();
+ }
+ buffer_copy_string_len(ds->key, CONST_STR_LEN("Set-Cookie"));
+- buffer_copy_string_buffer(ds->value, p->conf.cookie_name);
++ buffer_copy_buffer(ds->value, p->conf.cookie_name);
+ buffer_append_string_len(ds->value, CONST_STR_LEN("="));
+
+
+@@ -223,10 +223,10 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
+ li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
+
+ /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
+- LI_ltostr(hh, srv->cur_ts);
++ li_itostr(hh, srv->cur_ts);
+ li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
+ li_MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy));
+- LI_ltostr(hh, rand());
++ li_itostr(hh, rand());
+ li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
+
+ li_MD5_Final(h, &Md5Ctx);
+@@ -235,14 +235,14 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
+ buffer_append_string_len(ds->value, CONST_STR_LEN("; Path=/"));
+ buffer_append_string_len(ds->value, CONST_STR_LEN("; Version=1"));
+
+- if (!buffer_is_empty(p->conf.cookie_domain)) {
++ if (!buffer_string_is_empty(p->conf.cookie_domain)) {
+ buffer_append_string_len(ds->value, CONST_STR_LEN("; Domain="));
+ buffer_append_string_encoded(ds->value, CONST_BUF_LEN(p->conf.cookie_domain), ENCODING_REL_URI);
+ }
+
+ if (p->conf.cookie_max_age) {
+ buffer_append_string_len(ds->value, CONST_STR_LEN("; max-age="));
+- buffer_append_long(ds->value, p->conf.cookie_max_age);
++ buffer_append_int(ds->value, p->conf.cookie_max_age);
+ }
+
+ array_insert_unique(con->response.headers, (data_unset *)ds);
+diff --git a/src/mod_webdav.c b/src/mod_webdav.c
+index 04b2161..a3807c0 100644
+--- a/src/mod_webdav.c
++++ b/src/mod_webdav.c
+@@ -198,7 +198,7 @@ SETDEFAULTS_FUNC(mod_webdav_set_defaults) {
+ return HANDLER_ERROR;
+ }
+
+- if (!buffer_is_empty(s->sqlite_db_name)) {
++ if (!buffer_string_is_empty(s->sqlite_db_name)) {
+ #ifdef USE_PROPPATCH
+ const char *next_stmt;
+ char *err;
+@@ -519,7 +519,7 @@ static int webdav_gen_response_status_tag(server *srv, connection *con, physical
+ } else {
+ buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
+ }
+- buffer_append_long(b, status);
++ buffer_append_int(b, status);
+ buffer_append_string_len(b, CONST_STR_LEN(" "));
+ buffer_append_string(b, get_http_status_name(status));
+
+@@ -595,12 +595,12 @@ static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physi
+ /* ignore the parent dir */
+ }
+
+- buffer_copy_string_buffer(d.path, dst->path);
+- BUFFER_APPEND_SLASH(d.path);
++ buffer_copy_buffer(d.path, dst->path);
++ buffer_append_slash(d.path);
+ buffer_append_string(d.path, de->d_name);
+
+- buffer_copy_string_buffer(d.rel_path, dst->rel_path);
+- BUFFER_APPEND_SLASH(d.rel_path);
++ buffer_copy_buffer(d.rel_path, dst->rel_path);
++ buffer_append_slash(d.rel_path);
+ buffer_append_string(d.rel_path, de->d_name);
+
+ /* stat and unlink afterwards */
+@@ -756,20 +756,20 @@ static int webdav_copy_dir(server *srv, connection *con, plugin_data *p, physica
+ continue;
+ }
+
+- buffer_copy_string_buffer(s.path, src->path);
+- BUFFER_APPEND_SLASH(s.path);
++ buffer_copy_buffer(s.path, src->path);
++ buffer_append_slash(s.path);
+ buffer_append_string(s.path, de->d_name);
+
+- buffer_copy_string_buffer(d.path, dst->path);
+- BUFFER_APPEND_SLASH(d.path);
++ buffer_copy_buffer(d.path, dst->path);
++ buffer_append_slash(d.path);
+ buffer_append_string(d.path, de->d_name);
+
+- buffer_copy_string_buffer(s.rel_path, src->rel_path);
+- BUFFER_APPEND_SLASH(s.rel_path);
++ buffer_copy_buffer(s.rel_path, src->rel_path);
++ buffer_append_slash(s.rel_path);
+ buffer_append_string(s.rel_path, de->d_name);
+
+- buffer_copy_string_buffer(d.rel_path, dst->rel_path);
+- BUFFER_APPEND_SLASH(d.rel_path);
++ buffer_copy_buffer(d.rel_path, dst->rel_path);
++ buffer_append_slash(d.rel_path);
+ buffer_append_string(d.rel_path, de->d_name);
+
+ if (-1 == stat(s.path->ptr, &st)) {
+@@ -877,7 +877,7 @@ static int webdav_get_live_property(server *srv, connection *con, plugin_data *p
+ found = 1;
+ } else if (0 == strcmp(prop_name, "getcontentlength")) {
+ buffer_append_string_len(b,CONST_STR_LEN("<D:getcontentlength>"));
+- buffer_append_off_t(b, sce->st.st_size);
++ buffer_append_int(b, sce->st.st_size);
+ buffer_append_string_len(b, CONST_STR_LEN("</D:getcontentlength>"));
+ found = 1;
+ } else if (0 == strcmp(prop_name, "getcontentlanguage")) {
+@@ -1062,8 +1062,6 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
+ cq->bytes_out += weHave;
+
+ break;
+- case UNUSED_CHUNK:
+- break;
+ }
+ chunkqueue_remove_finished_chunks(cq);
+ }
+@@ -1367,7 +1365,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
+ buffer_append_string_encoded(b, CONST_BUF_LEN(con->uri.path), ENCODING_REL_URI);
+ buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
+
+- if (!buffer_is_empty(prop_200)) {
++ if (!buffer_string_is_empty(prop_200)) {
+ buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
+ buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
+
+@@ -1379,7 +1377,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
+
+ buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
+ }
+- if (!buffer_is_empty(prop_404)) {
++ if (!buffer_string_is_empty(prop_404)) {
+ buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
+ buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
+
+@@ -1410,11 +1408,11 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
+ /* ignore the parent dir */
+ }
+
+- buffer_copy_string_buffer(d.path, dst->path);
+- BUFFER_APPEND_SLASH(d.path);
++ buffer_copy_buffer(d.path, dst->path);
++ buffer_append_slash(d.path);
+
+- buffer_copy_string_buffer(d.rel_path, dst->rel_path);
+- BUFFER_APPEND_SLASH(d.rel_path);
++ buffer_copy_buffer(d.rel_path, dst->rel_path);
++ buffer_append_slash(d.rel_path);
+
+ if (de->d_name[0] == '.' && de->d_name[1] == '\0') {
+ /* don't append the . */
+@@ -1436,7 +1434,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
+ buffer_append_string_encoded(b, CONST_BUF_LEN(d.rel_path), ENCODING_REL_URI);
+ buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
+
+- if (!buffer_is_empty(prop_200)) {
++ if (!buffer_string_is_empty(prop_200)) {
+ buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
+ buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
+
+@@ -1448,7 +1446,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
+
+ buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
+ }
+- if (!buffer_is_empty(prop_404)) {
++ if (!buffer_string_is_empty(prop_404)) {
+ buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
+ buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
+
+@@ -1763,8 +1761,6 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
+ }
+ }
+ break;
+- case UNUSED_CHUNK:
+- break;
+ }
+
+ if (r > 0) {
+@@ -1862,21 +1858,21 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
+ return HANDLER_FINISHED;
+ }
+
+- buffer_copy_string_buffer(p->tmp_buf, p->uri.path_raw);
++ buffer_copy_buffer(p->tmp_buf, p->uri.path_raw);
+ buffer_urldecode_path(p->tmp_buf);
+ buffer_path_simplify(p->uri.path, p->tmp_buf);
+
+ /* we now have a URI which is clean. transform it into a physical path */
+- buffer_copy_string_buffer(p->physical.doc_root, con->physical.doc_root);
+- buffer_copy_string_buffer(p->physical.rel_path, p->uri.path);
++ buffer_copy_buffer(p->physical.doc_root, con->physical.doc_root);
++ buffer_copy_buffer(p->physical.rel_path, p->uri.path);
+
+ if (con->conf.force_lowercase_filenames) {
+ buffer_to_lower(p->physical.rel_path);
+ }
+
+- buffer_copy_string_buffer(p->physical.path, p->physical.doc_root);
+- BUFFER_APPEND_SLASH(p->physical.path);
+- buffer_copy_string_buffer(p->physical.basedir, p->physical.path);
++ buffer_copy_buffer(p->physical.path, p->physical.doc_root);
++ buffer_append_slash(p->physical.path);
++ buffer_copy_buffer(p->physical.basedir, p->physical.path);
+
+ /* don't add a second / */
+ if (p->physical.rel_path->ptr[0] == '/') {
+diff --git a/src/network.c b/src/network.c
+index 776a86c..f1c9489 100644
+--- a/src/network.c
++++ b/src/network.c
+@@ -187,10 +187,10 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
+ srv_socket->fde_ndx = -1;
+
+ srv_socket->srv_token = buffer_init();
+- buffer_copy_string_buffer(srv_socket->srv_token, host_token);
++ buffer_copy_buffer(srv_socket->srv_token, host_token);
+
+ b = buffer_init();
+- buffer_copy_string_buffer(b, host_token);
++ buffer_copy_buffer(b, host_token);
+
+ /* ipv4:port
+ * [ipv6]:port
+@@ -701,7 +701,7 @@ int network_init(server *srv) {
+ long ssloptions =
+ SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_COMPRESSION;
+
+- if (buffer_is_empty(s->ssl_pemfile) && buffer_is_empty(s->ssl_ca_file)) continue;
++ if (buffer_string_is_empty(s->ssl_pemfile) && buffer_string_is_empty(s->ssl_ca_file)) continue;
+
+ if (srv->ssl_is_init == 0) {
+ SSL_load_error_strings();
+@@ -716,7 +716,7 @@ int network_init(server *srv) {
+ }
+ }
+
+- if (!buffer_is_empty(s->ssl_pemfile)) {
++ if (!buffer_string_is_empty(s->ssl_pemfile)) {
+ #ifdef OPENSSL_NO_TLSEXT
+ data_config *dc = (data_config *)srv->config_context->data[i];
+ if (COMP_HTTP_HOST == dc->comp) {
+@@ -729,7 +729,7 @@ int network_init(server *srv) {
+ }
+
+
+- if (!buffer_is_empty(s->ssl_ca_file)) {
++ if (!buffer_string_is_empty(s->ssl_ca_file)) {
+ s->ssl_ca_file_cert_names = SSL_load_client_CA_file(s->ssl_ca_file->ptr);
+ if (NULL == s->ssl_ca_file_cert_names) {
+ log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
+@@ -737,7 +737,7 @@ int network_init(server *srv) {
+ }
+ }
+
+- if (buffer_is_empty(s->ssl_pemfile) || !s->ssl_enabled) continue;
++ if (buffer_string_is_empty(s->ssl_pemfile) || !s->ssl_enabled) continue;
+
+ if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
+@@ -784,7 +784,7 @@ int network_init(server *srv) {
+ }
+ }
+
+- if (!buffer_is_empty(s->ssl_cipher_list)) {
++ if (!buffer_string_is_empty(s->ssl_cipher_list)) {
+ /* Disable support for low encryption ciphers */
+ if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
+@@ -799,7 +799,7 @@ int network_init(server *srv) {
+
+ #ifndef OPENSSL_NO_DH
+ /* Support for Diffie-Hellman key exchange */
+- if (!buffer_is_empty(s->ssl_dh_file)) {
++ if (!buffer_string_is_empty(s->ssl_dh_file)) {
+ /* DH parameters from file */
+ bio = BIO_new_file((char *) s->ssl_dh_file->ptr, "r");
+ if (bio == NULL) {
+@@ -832,7 +832,7 @@ int network_init(server *srv) {
+ SSL_CTX_set_options(s->ssl_ctx,SSL_OP_SINGLE_DH_USE);
+ DH_free(dh);
+ #else
+- if (!buffer_is_empty(s->ssl_dh_file)) {
++ if (!buffer_string_is_empty(s->ssl_dh_file)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: openssl compiled without DH support, can't load parameters from", s->ssl_dh_file->ptr);
+ }
+ #endif
+@@ -840,7 +840,7 @@ int network_init(server *srv) {
+ #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+ #ifndef OPENSSL_NO_ECDH
+ /* Support for Elliptic-Curve Diffie-Hellman key exchange */
+- if (!buffer_is_empty(s->ssl_ec_curve)) {
++ if (!buffer_string_is_empty(s->ssl_ec_curve)) {
+ /* OpenSSL only supports the "named curves" from RFC 4492, section 5.1.1. */
+ nid = OBJ_sn2nid((char *) s->ssl_ec_curve->ptr);
+ if (nid == 0) {
+@@ -866,7 +866,7 @@ int network_init(server *srv) {
+ for (j = 0; j < srv->config_context->used; j++) {
+ specific_config *s1 = srv->config_storage[j];
+
+- if (!buffer_is_empty(s1->ssl_ca_file)) {
++ if (!buffer_string_is_empty(s1->ssl_ca_file)) {
+ if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s1->ssl_ca_file->ptr, NULL)) {
+ log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
+ ERR_error_string(ERR_get_error(), NULL), s1->ssl_ca_file);
+@@ -926,9 +926,9 @@ int network_init(server *srv) {
+
+ b = buffer_init();
+
+- buffer_copy_string_buffer(b, srv->srvconf.bindhost);
++ buffer_copy_buffer(b, srv->srvconf.bindhost);
+ buffer_append_string_len(b, CONST_STR_LEN(":"));
+- buffer_append_long(b, srv->srvconf.port);
++ buffer_append_int(b, srv->srvconf.port);
+
+ if (0 != network_server_init(srv, b, srv->config_storage[0])) {
+ buffer_free(b);
+@@ -944,7 +944,7 @@ int network_init(server *srv) {
+ backend = network_backends[0].nb;
+
+ /* match name against known types */
+- if (!buffer_is_empty(srv->srvconf.network_backend)) {
++ if (!buffer_string_is_empty(srv->srvconf.network_backend)) {
+ for (i = 0; network_backends[i].name; i++) {
+ /**/
+ if (buffer_is_equal_string(srv->srvconf.network_backend, network_backends[i].name, strlen(network_backends[i].name))) {
+diff --git a/src/plugin.c b/src/plugin.c
+index 55f8b03..d587308 100644
+--- a/src/plugin.c
++++ b/src/plugin.c
+@@ -133,7 +133,7 @@ int plugins_load(server *srv) {
+ }
+ }
+
+- buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir);
++ buffer_copy_buffer(srv->tmp_buf, srv->srvconf.modules_dir);
+
+ buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("/"));
+ buffer_append_string(srv->tmp_buf, modules);
+diff --git a/src/request.c b/src/request.c
+index 2eb0b0e..65d0a0e 100644
+--- a/src/request.c
++++ b/src/request.c
+@@ -322,7 +322,7 @@ int http_request_parse(server *srv, connection *con) {
+ buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, con->request.request->used - 1 - 2);
+ } else {
+ /* fill the local request buffer */
+- buffer_copy_string_buffer(con->parse_request, con->request.request);
++ buffer_copy_buffer(con->parse_request, con->request.request);
+ }
+
+ keep_alive_set = 0;
+@@ -508,7 +508,7 @@ int http_request_parse(server *srv, connection *con) {
+ }
+ }
+
+- buffer_copy_string_buffer(con->request.orig_uri, con->request.uri);
++ buffer_copy_buffer(con->request.orig_uri, con->request.uri);
+
+ con->http_status = 0;
+
+@@ -1061,7 +1061,7 @@ int http_request_parse(server *srv, connection *con) {
+
+ /* RFC 2616, 14.23 */
+ if (con->request.http_host == NULL ||
+- buffer_is_empty(con->request.http_host)) {
++ buffer_string_is_empty(con->request.http_host)) {
+ con->http_status = 400;
+ con->response.keep_alive = 0;
+ con->keep_alive = 0;
+diff --git a/src/response.c b/src/response.c
+index eb5c2f2..bde381f 100644
+--- a/src/response.c
++++ b/src/response.c
+@@ -40,7 +40,7 @@ int http_response_write_header(server *srv, connection *con) {
+ } else {
+ buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
+ }
+- buffer_append_long(b, con->http_status);
++ buffer_append_int(b, con->http_status);
+ buffer_append_string_len(b, CONST_STR_LEN(" "));
+ buffer_append_string(b, get_http_status_name(con->http_status));
+
+@@ -181,7 +181,7 @@ static void https_add_ssl_entries(connection *con) {
+ buffer_copy_string(ds->key, "REMOTE_USER");
+ array_insert_unique(con->environment, (data_unset *)ds);
+ }
+- buffer_copy_string_buffer(ds->value, envds->value);
++ buffer_copy_buffer(ds->value, envds->value);
+ }
+ array_insert_unique(con->environment, (data_unset *)envds);
+ }
+@@ -199,7 +199,7 @@ static void https_add_ssl_entries(connection *con) {
+ }
+
+ buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT"));
+- buffer_prepare_copy(envds->value, n+1);
++ buffer_prepare_copy(envds->value, n);
+ BIO_read(bio, envds->value->ptr, n);
+ BIO_free(bio);
+ envds->value->ptr[n] = '\0';
+@@ -278,7 +278,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
+ } else {
+ buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http"));
+ }
+- buffer_copy_string_buffer(con->uri.authority, con->request.http_host);
++ buffer_copy_buffer(con->uri.authority, con->request.http_host);
+ buffer_to_lower(con->uri.authority);
+
+ config_patch_connection(srv, con, COMP_HTTP_SCHEME); /* Scheme: */
+@@ -302,7 +302,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
+ buffer_copy_string_len(con->uri.path_raw, con->request.uri->ptr, qstr - con->request.uri->ptr);
+ } else {
+ buffer_reset (con->uri.query);
+- buffer_copy_string_buffer(con->uri.path_raw, con->request.uri);
++ buffer_copy_buffer(con->uri.path_raw, con->request.uri);
+ }
+
+ /* decode url to path
+@@ -314,9 +314,9 @@ handler_t http_response_prepare(server *srv, connection *con) {
+ if (con->request.http_method == HTTP_METHOD_OPTIONS &&
+ con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
+ /* OPTIONS * ... */
+- buffer_copy_string_buffer(con->uri.path, con->uri.path_raw);
++ buffer_copy_buffer(con->uri.path, con->uri.path_raw);
+ } else {
+- buffer_copy_string_buffer(srv->tmp_buf, con->uri.path_raw);
++ buffer_copy_buffer(srv->tmp_buf, con->uri.path_raw);
+ buffer_urldecode_path(srv->tmp_buf);
+ buffer_path_simplify(con->uri.path, srv->tmp_buf);
+ }
+@@ -430,8 +430,8 @@ handler_t http_response_prepare(server *srv, connection *con) {
+
+ /* set a default */
+
+- buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root);
+- buffer_copy_string_buffer(con->physical.rel_path, con->uri.path);
++ buffer_copy_buffer(con->physical.doc_root, con->conf.document_root);
++ buffer_copy_buffer(con->physical.rel_path, con->uri.path);
+
+ #if defined(__WIN32) || defined(__CYGWIN__)
+ /* strip dots from the end and spaces
+@@ -500,8 +500,8 @@ handler_t http_response_prepare(server *srv, connection *con) {
+ }
+
+ /* the docroot plugins might set the servername, if they don't we take http-host */
+- if (buffer_is_empty(con->server_name)) {
+- buffer_copy_string_buffer(con->server_name, con->uri.authority);
++ if (buffer_string_is_empty(con->server_name)) {
++ buffer_copy_buffer(con->server_name, con->uri.authority);
+ }
+
+ /**
+@@ -510,9 +510,9 @@ handler_t http_response_prepare(server *srv, connection *con) {
+ *
+ */
+
+- buffer_copy_string_buffer(con->physical.basedir, con->physical.doc_root);
+- buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
+- BUFFER_APPEND_SLASH(con->physical.path);
++ buffer_copy_buffer(con->physical.basedir, con->physical.doc_root);
++ buffer_copy_buffer(con->physical.path, con->physical.doc_root);
++ buffer_append_slash(con->physical.path);
+ if (con->physical.rel_path->used &&
+ con->physical.rel_path->ptr[0] == '/') {
+ buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
+@@ -645,13 +645,13 @@ handler_t http_response_prepare(server *srv, connection *con) {
+
+ /* not found, perhaps PATHINFO */
+
+- buffer_copy_string_buffer(srv->tmp_buf, con->physical.path);
++ buffer_copy_buffer(srv->tmp_buf, con->physical.path);
+
+ do {
+ if (slash) {
+ buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
+ } else {
+- buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
++ buffer_copy_buffer(con->physical.path, srv->tmp_buf);
+ }
+
+ if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
+diff --git a/src/server.c b/src/server.c
+index d47fd62..71d3538 100644
+--- a/src/server.c
++++ b/src/server.c
+@@ -999,7 +999,7 @@ int main (int argc, char **argv) {
+
+ /* write pid file */
+ if (pid_fd != -1) {
+- buffer_copy_long(srv->tmp_buf, getpid());
++ buffer_copy_int(srv->tmp_buf, getpid());
+ buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
+ force_assert(srv->tmp_buf->used > 0);
+ write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
+diff --git a/src/stat_cache.c b/src/stat_cache.c
+index 9007325..b5aa9ce 100644
+--- a/src/stat_cache.c
++++ b/src/stat_cache.c
+@@ -221,7 +221,7 @@ static int stat_cache_attr_get(buffer *buf, char *name) {
+
+ attrlen = 1024;
+ buffer_prepare_copy(buf, attrlen);
+- attrlen--;
++ attrlen = buf->size - 1;
+ if(0 == (ret = attr_get(name, "Content-Type", buf->ptr, &attrlen, 0))) {
+ buf->used = attrlen + 1;
+ buf->ptr[attrlen] = '\0';
+@@ -234,7 +234,7 @@ static int stat_cache_attr_get(buffer *buf, char *name) {
+
+ buffer_prepare_copy(buf, attrlen);
+
+- if (-1 != (attrlen = extattr_get_file(name, EXTATTR_NAMESPACE_USER, "Content-Type", buf->ptr, attrlen-1))) {
++ if (-1 != (attrlen = extattr_get_file(name, EXTATTR_NAMESPACE_USER, "Content-Type", buf->ptr, buf->size - 1))) {
+ buf->used = attrlen + 1;
+ buf->ptr[attrlen] = '\0';
+ return 0;
+@@ -294,7 +294,7 @@ handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent) {
+
+ for (j = 0; j < 2; j++) {
+ buffer_copy_string(sc->hash_key, fe.filename);
+- buffer_append_long(sc->hash_key, j);
++ buffer_append_int(sc->hash_key, j);
+
+ ndx = hashme(sc->hash_key);
+
+@@ -331,7 +331,7 @@ handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent) {
+ static int buffer_copy_dirname(buffer *dst, buffer *file) {
+ size_t i;
+
+- if (buffer_is_empty(file)) return -1;
++ if (buffer_string_is_empty(file)) return -1;
+
+ for (i = file->used - 1; i+1 > 0; i--) {
+ if (file->ptr[i] == '/') {
+@@ -394,8 +394,8 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
+
+ sc = srv->stat_cache;
+
+- buffer_copy_string_buffer(sc->hash_key, name);
+- buffer_append_long(sc->hash_key, con->conf.follow_symlink);
++ buffer_copy_buffer(sc->hash_key, name);
++ buffer_append_int(sc->hash_key, con->conf.follow_symlink);
+
+ file_ndx = hashme(sc->hash_key);
+ sc->files = splaytree_splay(sc->files, file_ndx);
+@@ -460,8 +460,8 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
+ return HANDLER_ERROR;
+ }
+
+- buffer_copy_string_buffer(sc->hash_key, sc->dir_name);
+- buffer_append_long(sc->hash_key, con->conf.follow_symlink);
++ buffer_copy_buffer(sc->hash_key, sc->dir_name);
++ buffer_append_int(sc->hash_key, con->conf.follow_symlink);
+
+ dir_ndx = hashme(sc->hash_key);
+
+@@ -518,7 +518,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
+ #endif
+
+ sce = stat_cache_entry_init();
+- buffer_copy_string_buffer(sce->name, name);
++ buffer_copy_buffer(sce->name, name);
+
+ sc->files = splaytree_insert(sc->files, file_ndx, sce);
+ #ifdef DEBUG_STAT_CACHE
+@@ -577,7 +577,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
+ char *s_cur;
+
+ dname = buffer_init();
+- buffer_copy_string_buffer(dname, name);
++ buffer_copy_buffer(dname, name);
+
+ while ((s_cur = strrchr(dname->ptr,'/'))) {
+ *s_cur = '\0';
+@@ -615,7 +615,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
+ }
+ #endif
+ /* xattr did not set a content-type. ask the config */
+- if (buffer_is_empty(sce->content_type)) {
++ if (buffer_string_is_empty(sce->content_type)) {
+ for (k = 0; k < con->conf.mimetypes->used; k++) {
+ data_string *ds = (data_string *)con->conf.mimetypes->data[k];
+ buffer *type = ds->key;
+@@ -626,7 +626,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
+ if (type->used > name->used) continue;
+
+ if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
+- buffer_copy_string_buffer(sce->content_type, ds->value);
++ buffer_copy_buffer(sce->content_type, ds->value);
+ break;
+ }
+ }
+@@ -642,7 +642,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
+ if (!dir_node) {
+ fam_dir = fam_dir_entry_init();
+
+- buffer_copy_string_buffer(fam_dir->name, sc->dir_name);
++ buffer_copy_buffer(fam_dir->name, sc->dir_name);
+
+ fam_dir->version = 1;
+
+--
+2.4.5
+