diff options
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.patch | 6095 |
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 & 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 + |