diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2015-07-27 08:08:54 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2015-07-27 11:13:28 +0000 |
commit | e6c1f4a663bf13c35e0a92ce7243d282a4a29c8c (patch) | |
tree | 0d6a91e95cc690d058f478f4543141ac060866e2 /main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch | |
parent | aa12abff47161235a3c11ec5c92465e98674234b (diff) | |
download | aports-e6c1f4a663bf13c35e0a92ce7243d282a4a29c8c.tar.bz2 aports-e6c1f4a663bf13c35e0a92ce7243d282a4a29c8c.tar.xz |
main/lighttpd: upgrade to 1.4.36
Diffstat (limited to 'main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch')
-rw-r--r-- | main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch | 1537 |
1 files changed, 0 insertions, 1537 deletions
diff --git a/main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch b/main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch deleted file mode 100644 index 6f265d155b..0000000000 --- a/main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch +++ /dev/null @@ -1,1537 +0,0 @@ -From 1be163b44a53eebb0a7b0ed562d12e3f252794e1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de> -Date: Sun, 8 Feb 2015 19:10:36 +0000 -Subject: [PATCH 16/29] Remove chunkqueue_get_{append,prepend}* API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - - Although those were "easy" to use, they violated the abstraction: - content of the chunkqueue should only be modified via the API. - Replace with chunkqueue_get_memory() and chunkqueue_use_memory() for - functions that read data from network (reusing large buffers), - chunkqueue_steal_with_tempfiles() to store request bodies on disk - temporarily. - Modules that were generating content and need a buffer maintain the - buffer manually (have to be careful to free the buffer on errors, as - it isn't part of the chunkqueue yet). - -From: Stefan Bühler <stbuehler@web.de> - -git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2976 152afb58-edef-0310-8abb-c4023f1b3aa9 ---- - src/buffer.c | 23 +++- - src/buffer.h | 12 ++ - src/chunk.c | 295 +++++++++++++++++++++++++++++++++++++++-------- - src/chunk.h | 39 ++++--- - src/connections.c | 195 +++++-------------------------- - src/mod_compress.c | 4 +- - src/mod_dirlisting.c | 4 +- - src/mod_fastcgi.c | 76 +++++------- - src/mod_flv_streaming.c | 6 +- - src/mod_proxy.c | 5 +- - src/mod_scgi.c | 4 +- - src/mod_ssi.c | 63 +++++----- - src/mod_staticfile.c | 13 +-- - src/mod_status.c | 42 ++++--- - src/mod_uploadprogress.c | 11 +- - src/mod_webdav.c | 18 ++- - src/response.c | 6 +- - 17 files changed, 465 insertions(+), 351 deletions(-) - -diff --git a/src/buffer.c b/src/buffer.c -index caaa5bb..019abb7 100644 ---- a/src/buffer.c -+++ b/src/buffer.c -@@ -139,6 +139,27 @@ char* buffer_prepare_append(buffer *b, size_t size) { - return b->ptr + b->used - 1; - } - -+char* buffer_string_prepare_copy(buffer *b, size_t size) { -+ force_assert(NULL != b); -+ -+ buffer_prepare_copy(b, size); -+ b->used = 1; -+ -+ return b->ptr; -+} -+ -+char* buffer_string_prepare_append(buffer *b, size_t size) { -+ force_assert(NULL != b); -+ -+ if (0 == b->used) { -+ return buffer_string_prepare_copy(b, size); -+ } else { -+ force_assert('\0' == b->ptr[b->used - 1]); -+ return buffer_prepare_append(b, size); -+ } -+} -+ -+ - void buffer_commit(buffer *b, size_t size) - { - force_assert(NULL != b); -@@ -231,7 +252,7 @@ void buffer_append_long_hex(buffer *b, unsigned long value) { - } while (0 != copy); - } - -- buf = buffer_prepare_append(b, shift); -+ buf = buffer_string_prepare_append(b, shift); - buffer_commit(b, shift); /* will fill below */ - - shift <<= 2; /* count bits now */ -diff --git a/src/buffer.h b/src/buffer.h -index ff57d68..5d540a4 100644 ---- a/src/buffer.h -+++ b/src/buffer.h -@@ -62,6 +62,11 @@ char* buffer_prepare_copy(buffer *b, size_t size); - */ - char* buffer_prepare_append(buffer *b, size_t size); - -+/* similar to buffer_prepare_copy(b, size), but sets b->used = 1 */ -+char* buffer_string_prepare_copy(buffer *b, size_t size); -+/* similar to buffer_prepare_append(b, size), but sets b->used = 1 if used was b->0 before */ -+char* buffer_string_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 -@@ -136,6 +141,7 @@ 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 size_t buffer_string_space(const buffer *b); /* maximum length of string that can be stored without reallocating */ - static inline void buffer_append_slash(buffer *b); /* append '/' no non-empty strings not ending in '/' */ - - #define BUFFER_APPEND_STRING_CONST(x, y) \ -@@ -161,6 +167,12 @@ static inline size_t buffer_string_length(const buffer *b) { - return NULL != b && 0 != b->used ? b->used - 1 : 0; - } - -+static inline size_t buffer_string_space(const buffer *b) { -+ if (NULL == b || b->size == 0) return 0; -+ if (0 == b->used) return b->size - 1; -+ return b->size - b->used; -+} -+ - 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, "/"); -diff --git a/src/chunk.c b/src/chunk.c -index c991b82..83adc15 100644 ---- a/src/chunk.c -+++ b/src/chunk.c -@@ -5,6 +5,8 @@ - */ - - #include "chunk.h" -+#include "base.h" -+#include "log.h" - - #include <sys/types.h> - #include <sys/stat.h> -@@ -233,28 +235,84 @@ void chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) { - chunkqueue_append_chunk(cq, c); - } - --buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) { -+void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_size, size_t alloc_size) { -+ static const size_t REALLOC_MAX_SIZE = 256; - chunk *c; -+ buffer *b; -+ char *dummy_mem; -+ size_t dummy_len; - -- c = chunkqueue_get_unused_chunk(cq); -+ force_assert(NULL != cq); -+ if (NULL == mem) mem = &dummy_mem; -+ if (NULL == len) len = &dummy_len; - -- c->type = MEM_CHUNK; -+ /* default values: */ -+ if (0 == min_size) min_size = 1024; -+ if (0 == alloc_size) alloc_size = 4096; -+ if (alloc_size < min_size) alloc_size = min_size; - -- chunkqueue_prepend_chunk(cq, c); -+ if (NULL != cq->last && MEM_CHUNK == cq->last->type) { -+ size_t have; - -- return c->mem; --} -+ b = cq->last->mem; -+ have = buffer_string_space(b); - --buffer *chunkqueue_get_append_buffer(chunkqueue *cq) { -- chunk *c; -+ /* unused buffer: allocate space */ -+ if (buffer_string_is_empty(b)) { -+ buffer_string_prepare_copy(b, alloc_size); -+ have = buffer_string_space(b); -+ } -+ /* if buffer is really small just make it bigger */ -+ else if (have < min_size && b->size <= REALLOC_MAX_SIZE) { -+ size_t new_size = b->used + min_size, append; -+ if (new_size < alloc_size) new_size = alloc_size; -+ -+ append = new_size - b->used; -+ if (append >= min_size) { -+ buffer_string_prepare_append(b, append); -+ have = buffer_string_space(b); -+ } -+ } - -- c = chunkqueue_get_unused_chunk(cq); -+ /* return pointer into existing buffer if large enough */ -+ if (have >= min_size) { -+ *mem = b->ptr + buffer_string_length(b); -+ *len = have; -+ return; -+ } -+ } - -+ /* allocate new chunk */ -+ c = chunkqueue_get_unused_chunk(cq); - c->type = MEM_CHUNK; -- - chunkqueue_append_chunk(cq, c); - -- return c->mem; -+ b = c->mem; -+ buffer_string_prepare_append(b, alloc_size); -+ -+ *mem = b->ptr + buffer_string_length(b); -+ *len = buffer_string_space(b); -+} -+ -+void chunkqueue_use_memory(chunkqueue *cq, size_t len) { -+ buffer *b; -+ -+ force_assert(NULL != cq); -+ force_assert(NULL != cq->last && MEM_CHUNK == cq->last->type); -+ b = cq->last->mem; -+ -+ force_assert(b->used > 0); -+ force_assert(len <= buffer_string_space(b)); -+ -+ if (len > 0) { -+ b->used += len; -+ b->ptr[b->used - 1] = '\0'; -+ } else if (buffer_string_is_empty(b)) { -+ /* unused buffer: can't remove chunk easily from -+ * end of list, so just reset the buffer -+ */ -+ buffer_reset(b); -+ } - } - - void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs) { -@@ -262,13 +320,67 @@ void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs) { - cq->tempdirs = tempdirs; - } - --chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) { -- chunk *c; -- buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX"); -+void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) { -+ while (len > 0) { -+ chunk *c = src->first; -+ off_t clen = 0, use; - -- c = chunkqueue_get_unused_chunk(cq); -+ if (NULL == c) break; - -- c->type = FILE_CHUNK; -+ switch (c->type) { -+ case MEM_CHUNK: -+ clen = buffer_string_length(c->mem); -+ break; -+ case FILE_CHUNK: -+ clen = c->file.length; -+ break; -+ } -+ force_assert(clen >= c->offset); -+ clen -= c->offset; -+ use = len >= clen ? clen : len; -+ -+ src->bytes_out += use; -+ dest->bytes_in += use; -+ len -= use; -+ -+ if (0 == clen) { -+ /* drop empty chunk */ -+ src->first = c->next; -+ if (c == src->last) src->last = NULL; -+ chunkqueue_push_unused_chunk(src, c); -+ continue; -+ } -+ -+ if (use == clen) { -+ /* move complete chunk */ -+ src->first = c->next; -+ if (c == src->last) src->last = NULL; -+ -+ chunkqueue_append_chunk(dest, c); -+ continue; -+ } -+ -+ /* partial chunk with length "use" */ -+ -+ switch (c->type) { -+ case MEM_CHUNK: -+ chunkqueue_append_mem(dest, c->mem->ptr + c->offset, use); -+ 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, use); -+ break; -+ } -+ -+ c->offset += use; -+ force_assert(0 == len); -+ } -+} -+ -+static chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) { -+ chunk *c; -+ buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX"); -+ int fd; - - if (cq->tempdirs && cq->tempdirs->used) { - size_t i; -@@ -282,19 +394,21 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) { - buffer_append_slash(template); - buffer_append_string_len(template, CONST_STR_LEN("lighttpd-upload-XXXXXX")); - -- if (-1 != (c->file.fd = mkstemp(template->ptr))) { -- /* only trigger the unlink if we created the temp-file successfully */ -- c->file.is_temp = 1; -- break; -- } -+ if (-1 != (fd = mkstemp(template->ptr))) break; - } - } else { -- if (-1 != (c->file.fd = mkstemp(template->ptr))) { -- /* only trigger the unlink if we created the temp-file successfully */ -- c->file.is_temp = 1; -- } -+ fd = mkstemp(template->ptr); - } - -+ if (-1 == fd) { -+ buffer_free(template); -+ return NULL; -+ } -+ -+ c = chunkqueue_get_unused_chunk(cq); -+ c->type = FILE_CHUNK; -+ c->file.fd = fd; -+ c->file.is_temp = 1; - buffer_copy_buffer(c->file.name, template); - c->file.length = 0; - -@@ -305,10 +419,76 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) { - return c; - } - --void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) { -+static int chunkqueue_append_to_tempfile(server *srv, chunkqueue *dest, const char *mem, size_t len) { -+ chunk *dst_c = NULL; -+ ssize_t written; -+ /* copy everything to max 1Mb sized tempfiles */ -+ -+ /* -+ * if the last chunk is -+ * - smaller than 1Mb (size < 1Mb) -+ * - not read yet (offset == 0) -+ * -> append to it -+ * otherwise -+ * -> create a new chunk -+ * -+ * */ -+ -+ if (NULL != dest->last -+ && FILE_CHUNK != dest->last->type -+ && dest->last->file.is_temp -+ && -1 != dest->last->file.fd -+ && 0 == dest->last->offset) { -+ /* ok, take the last chunk for our job */ -+ dst_c = dest->last; -+ -+ if (dest->last->file.length >= 1 * 1024 * 1024) { -+ /* the chunk is too large now, close it */ -+ if (-1 != dst_c->file.fd) { -+ close(dst_c->file.fd); -+ dst_c->file.fd = -1; -+ } -+ dst_c = chunkqueue_get_append_tempfile(dest); -+ } -+ } else { -+ dst_c = chunkqueue_get_append_tempfile(dest); -+ } -+ -+ if (NULL == dst_c) { -+ /* we don't have file to write to, -+ * EACCES might be one reason. -+ * -+ * Instead of sending 500 we send 413 and say the request is too large -+ */ -+ -+ log_error_write(srv, __FILE__, __LINE__, "sbs", -+ "denying upload as opening temp-file for upload failed:", -+ dst_c->file.name, strerror(errno)); -+ -+ return -1; -+ } -+ -+ if (0 > (written = write(dst_c->file.fd, mem, len)) || (size_t) written != len) { -+ /* write failed for some reason ... disk full ? */ -+ log_error_write(srv, __FILE__, __LINE__, "sbs", -+ "denying upload as writing to file failed:", -+ dst_c->file.name, strerror(errno)); -+ -+ close(dst_c->file.fd); -+ dst_c->file.fd = -1; -+ -+ return -1; -+ } -+ -+ dst_c->file.length += len; -+ -+ return 0; -+} -+ -+int chunkqueue_steal_with_tempfiles(server *srv, chunkqueue *dest, chunkqueue *src, off_t len) { - while (len > 0) { - chunk *c = src->first; -- off_t clen = 0; -+ off_t clen = 0, use; - - if (NULL == c) break; - -@@ -322,36 +502,57 @@ void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) { - } - force_assert(clen >= c->offset); - clen -= c->offset; -+ use = len >= clen ? clen : len; - -- if (len >= clen) { -- /* move complete chunk */ -+ src->bytes_out += use; -+ dest->bytes_in += use; -+ len -= use; -+ -+ if (0 == clen) { -+ /* drop empty 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; -+ chunkqueue_push_unused_chunk(src, c); - continue; - } - -- /* partial chunk with length "len" */ -+ if (FILE_CHUNK == c->type) { -+ if (use == clen) { -+ /* move complete chunk */ -+ src->first = c->next; -+ if (c == src->last) src->last = NULL; - -- 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; -+ chunkqueue_append_chunk(dest, c); -+ } else { -+ /* partial chunk with length "use" */ -+ /* tempfile flag is in "last" chunk after the split */ -+ chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, use); -+ -+ c->offset += use; -+ force_assert(0 == len); -+ } -+ continue; - } - -- c->offset += len; -- src->bytes_out += len; -- dest->bytes_in += len; -- len = 0; -+ /* store "use" bytes from memory chunk in tempfile */ -+ if (0 != chunkqueue_append_to_tempfile(srv, dest, c->mem->ptr + c->offset, use)) { -+ /* undo counters */ -+ src->bytes_out -= use; -+ dest->bytes_in -= use; -+ return -1; -+ } -+ -+ -+ c->offset += use; -+ if (use == clen) { -+ /* finished chunk */ -+ src->first = c->next; -+ if (c == src->last) src->last = NULL; -+ chunkqueue_push_unused_chunk(src, c); -+ } - } -+ -+ return 0; - } - - off_t chunkqueue_length(chunkqueue *cq) { -diff --git a/src/chunk.h b/src/chunk.h -index 6559000..33b7e27 100644 ---- a/src/chunk.h -+++ b/src/chunk.h -@@ -48,24 +48,37 @@ typedef struct { - } chunkqueue; - - chunkqueue *chunkqueue_init(void); --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); -+void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs); -+void chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len); /* copies "fn" */ -+void chunkqueue_append_mem(chunkqueue *cq, const char *mem, size_t len); /* copies memory */ -+void chunkqueue_append_buffer(chunkqueue *cq, buffer *mem); /* may reset "mem" */ -+void chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem); /* may reset "mem" */ -+ -+/* functions to handle buffers to read into: */ -+/* return a pointer to a buffer in *mem with size *len; -+ * it should be at least min_size big, and use alloc_size if -+ * new memory is allocated. -+ * modifying the chunkqueue invalidates the memory area. -+ * should always be followed by chunkqueue_get_memory(), -+ * even if nothing was read. -+ * pass 0 for min_size/alloc_size for default values -+ */ -+void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_size, size_t alloc_size); -+/* append first len bytes of the memory queried with -+ * chunkqueue_get_memory to the chunkqueue -+ */ -+void chunkqueue_use_memory(chunkqueue *cq, size_t len); - - void chunkqueue_remove_finished_chunks(chunkqueue *cq); - - void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len); -+struct server; -+int chunkqueue_steal_with_tempfiles(struct server *srv, chunkqueue *dest, chunkqueue *src, off_t len); - --off_t chunkqueue_length(chunkqueue *c); --void chunkqueue_free(chunkqueue *c); --void chunkqueue_reset(chunkqueue *c); -+off_t chunkqueue_length(chunkqueue *cq); -+void chunkqueue_free(chunkqueue *cq); -+void chunkqueue_reset(chunkqueue *cq); - --int chunkqueue_is_empty(chunkqueue *c); -+int chunkqueue_is_empty(chunkqueue *cq); - - #endif -diff --git a/src/connections.c b/src/connections.c -index bc770bf..3fab768 100644 ---- a/src/connections.c -+++ b/src/connections.c -@@ -197,31 +197,22 @@ static void dump_packet(const unsigned char *data, size_t len) { - - static int connection_handle_read_ssl(server *srv, connection *con) { - #ifdef USE_OPENSSL -- int r, ssl_err, len, count = 0, read_offset, toread; -- buffer *b = NULL; -+ int r, ssl_err, len, count = 0; -+ char *mem = NULL; -+ size_t mem_len = 0; - - if (!con->srv_socket->is_ssl) return -1; - - ERR_clear_error(); - do { -- if (NULL != con->read_queue->last) { -- b = con->read_queue->last->mem; -- } -- -- if (NULL == b || b->size - b->used < 1024) { -- 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); -- -- /* overwrite everything with 0 */ -- memset(b->ptr, 0, b->size); -- } -- -- read_offset = (b->used > 0) ? b->used - 1 : 0; -- toread = b->size - 1 - read_offset; -+ chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, SSL_pending(con->ssl)); -+#if 0 -+ /* overwrite everything with 0 */ -+ memset(mem, 0, mem_len); -+#endif - -- len = SSL_read(con->ssl, b->ptr + read_offset, toread); -+ len = SSL_read(con->ssl, mem, mem_len); -+ chunkqueue_use_memory(con->read_queue, len > 0 ? len : 0); - - if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) { - log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client, killing connection"); -@@ -230,15 +221,10 @@ static int connection_handle_read_ssl(server *srv, connection *con) { - } - - if (len > 0) { -- if (b->used > 0) b->used--; -- b->used += len; -- b->ptr[b->used++] = '\0'; -- - con->bytes_read += len; -- - count += len; - } -- } while (len == toread && count < MAX_READ_LIMIT); -+ } while (len == (ssize_t) mem_len && count < MAX_READ_LIMIT); - - - if (len < 0) { -@@ -331,44 +317,36 @@ static int connection_handle_read_ssl(server *srv, connection *con) { - /* 0: everything ok, -1: error, -2: con closed */ - static int connection_handle_read(server *srv, connection *con) { - int len; -- buffer *b; -- int toread, read_offset; -+ char *mem = NULL; -+ size_t mem_len = 0; -+ int toread; - - if (con->srv_socket->is_ssl) { - return connection_handle_read_ssl(srv, con); - } - -- b = (NULL != con->read_queue->last) ? con->read_queue->last->mem : NULL; -- - /* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells - * us more than 4kb is available - * if FIONREAD doesn't signal a big chunk we fill the previous buffer - * if it has >= 1kb free - */ - #if defined(__WIN32) -- if (NULL == b || b->size - b->used < 1024) { -- b = chunkqueue_get_append_buffer(con->read_queue); -- buffer_prepare_copy(b, 4 * 1024); -- } -+ chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, 4096); - -- read_offset = (b->used == 0) ? 0 : b->used - 1; -- len = recv(con->fd, b->ptr + read_offset, b->size - 1 - read_offset, 0); -+ len = recv(con->fd, mem, mem_len, 0); - #else - if (ioctl(con->fd, FIONREAD, &toread) || toread == 0 || toread <= 4*1024) { -- if (NULL == b || b->size - b->used < 1024) { -- b = chunkqueue_get_append_buffer(con->read_queue); -- buffer_prepare_copy(b, 4 * 1024); -- } -- } else { - if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT; -- b = chunkqueue_get_append_buffer(con->read_queue); -- buffer_prepare_copy(b, toread); -+ } else { -+ toread = 4096; - } -+ chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, toread); - -- read_offset = (b->used == 0) ? 0 : b->used - 1; -- len = read(con->fd, b->ptr + read_offset, b->size - 1 - read_offset); -+ len = read(con->fd, mem, mem_len); - #endif - -+ chunkqueue_use_memory(con->read_queue, len > 0 ? len : 0); -+ - if (len < 0) { - con->is_readable = 0; - -@@ -394,16 +372,12 @@ static int connection_handle_read(server *srv, connection *con) { - /* pipelining */ - - return -2; -- } else if ((size_t)len < b->size - 1) { -+ } else if (len != (ssize_t) mem_len) { - /* we got less then expected, wait for the next fd-event */ - - con->is_readable = 0; - } - -- if (b->used > 0) b->used--; -- b->used += len; -- b->ptr[b->used++] = '\0'; -- - con->bytes_read += len; - #if 0 - dump_packet(b->ptr, len); -@@ -494,7 +468,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) { - buffer_reset(con->physical.path); - - con->file_finished = 1; -- b = chunkqueue_get_append_buffer(con->write_queue); -+ b = buffer_init(); - - /* build default error-page */ - buffer_copy_string_len(b, CONST_STR_LEN( -@@ -522,6 +496,10 @@ static int connection_handle_write_prepare(server *srv, connection *con) { - "</html>\n" - )); - -+ http_chunk_append_buffer(srv, con, b); -+ buffer_free(b); -+ http_chunk_close(srv, con); -+ - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - } - break; -@@ -1029,119 +1007,10 @@ found_header_end: - } - break; - case CON_STATE_READ_POST: -- for (c = cq->first; c && (dst_cq->bytes_in != (off_t)con->request.content_length); c = c->next) { -- off_t weWant, weHave, toRead; -- -- weWant = con->request.content_length - dst_cq->bytes_in; -- -- force_assert(c->mem->used); -- -- weHave = c->mem->used - c->offset - 1; -- -- toRead = weHave > weWant ? weWant : weHave; -- -- /* the new way, copy everything into a chunkqueue whcih might use tempfiles */ -- if (con->request.content_length > 64 * 1024) { -- chunk *dst_c = NULL; -- /* copy everything to max 1Mb sized tempfiles */ -- -- /* -- * if the last chunk is -- * - smaller than 1Mb (size < 1Mb) -- * - not read yet (offset == 0) -- * -> append to it -- * otherwise -- * -> create a new chunk -- * -- * */ -- -- if (dst_cq->last && -- dst_cq->last->type == FILE_CHUNK && -- dst_cq->last->file.is_temp && -- dst_cq->last->offset == 0) { -- /* ok, take the last chunk for our job */ -- -- if (dst_cq->last->file.length < 1 * 1024 * 1024) { -- dst_c = dst_cq->last; -- -- if (dst_c->file.fd == -1) { -- /* this should not happen as we cache the fd, but you never know */ -- dst_c->file.fd = open(dst_c->file.name->ptr, O_WRONLY | O_APPEND); -- fd_close_on_exec(dst_c->file.fd); -- } -- } else { -- /* the chunk is too large now, close it */ -- dst_c = dst_cq->last; -- -- if (dst_c->file.fd != -1) { -- close(dst_c->file.fd); -- dst_c->file.fd = -1; -- } -- dst_c = chunkqueue_get_append_tempfile(dst_cq); -- } -- } else { -- dst_c = chunkqueue_get_append_tempfile(dst_cq); -- } -- -- /* we have a chunk, let's write to it */ -- -- if (dst_c->file.fd == -1) { -- /* we don't have file to write to, -- * EACCES might be one reason. -- * -- * Instead of sending 500 we send 413 and say the request is too large -- * */ -- -- log_error_write(srv, __FILE__, __LINE__, "sbs", -- "denying upload as opening to temp-file for upload failed:", -- dst_c->file.name, strerror(errno)); -- -- con->http_status = 413; /* Request-Entity too large */ -- con->keep_alive = 0; -- connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); -- -- break; -- } -- -- if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) { -- /* write failed for some reason ... disk full ? */ -- log_error_write(srv, __FILE__, __LINE__, "sbs", -- "denying upload as writing to file failed:", -- dst_c->file.name, strerror(errno)); -- -- con->http_status = 413; /* Request-Entity too large */ -- con->keep_alive = 0; -- connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); -- -- close(dst_c->file.fd); -- dst_c->file.fd = -1; -- -- break; -- } -- -- dst_c->file.length += toRead; -- -- if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) { -- /* we read everything, close the chunk */ -- close(dst_c->file.fd); -- dst_c->file.fd = -1; -- } -- } else { -- buffer *b; -- -- if (dst_cq->last && -- dst_cq->last->type == MEM_CHUNK) { -- b = dst_cq->last->mem; -- } 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); -- } -- buffer_append_string_len(b, c->mem->ptr + c->offset, toRead); -- } -- -- c->offset += toRead; -- dst_cq->bytes_in += toRead; -+ if (0 != chunkqueue_steal_with_tempfiles(srv, dst_cq, cq, con->request.content_length - dst_cq->bytes_in )) { -+ con->http_status = 413; /* Request-Entity too large */ -+ con->keep_alive = 0; -+ connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST); - } - - /* Content is ready */ -diff --git a/src/mod_compress.c b/src/mod_compress.c -index ad6e9f2..b428cd0 100644 ---- a/src/mod_compress.c -+++ b/src/mod_compress.c -@@ -583,7 +583,6 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p, - int ifd; - int ret = -1; - void *start; -- buffer *b; - - /* overflow */ - if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1; -@@ -651,8 +650,7 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p, - if (ret != 0) return -1; - - chunkqueue_reset(con->write_queue); -- b = chunkqueue_get_append_buffer(con->write_queue); -- buffer_copy_string_len(b, p->b->ptr, p->b->used); -+ chunkqueue_append_mem(con->write_queue, p->b->ptr, p->b->used); - - buffer_reset(con->physical.path); - -diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c -index 4b7106a..e2e0bfa 100644 ---- a/src/mod_dirlisting.c -+++ b/src/mod_dirlisting.c -@@ -784,7 +784,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf - - if (files.used) http_dirls_sort(files.ent, files.used); - -- out = chunkqueue_get_append_buffer(con->write_queue); -+ out = buffer_init(); - buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"")); - if (buffer_string_is_empty(p->conf.encoding)) { - buffer_append_string_len(out, CONST_STR_LEN("iso-8859-1")); -@@ -899,6 +899,8 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf - } - - con->file_finished = 1; -+ chunkqueue_append_buffer(con->write_queue, out); -+ buffer_free(out); - - return 0; - } -diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c -index 01e72e5..e7b62f6 100644 ---- a/src/mod_fastcgi.c -+++ b/src/mod_fastcgi.c -@@ -52,13 +52,6 @@ - - #include "version.h" - --#define FCGI_ENV_ADD_CHECK(ret, con) \ -- if (ret == -1) { \ -- con->http_status = 400; \ -- con->file_finished = 1; \ -- return -1; \ -- }; -- - /* - * - * TODO: -@@ -1769,6 +1762,12 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h - return CONNECTION_OK; - } - -+#define FCGI_ENV_ADD_CHECK(ret, con) \ -+ if (ret == -1) { \ -+ con->http_status = 400; \ -+ con->file_finished = 1; \ -+ return -1; \ -+ }; - static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) { - size_t i; - -@@ -1834,11 +1833,9 @@ static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_dat - return 0; - } - -- - static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { - FCGI_BeginRequestRecord beginRecord; - FCGI_Header header; -- buffer *b; - - char buf[LI_ITOSTRING_LENGTH]; - const char *s; -@@ -1863,10 +1860,6 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { - beginRecord.body.flags = 0; - memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved)); - -- b = chunkqueue_get_append_buffer(hctx->wb); -- -- buffer_copy_string_len(b, (const char *)&beginRecord, sizeof(beginRecord)); -- - /* send FCGI_PARAMS */ - buffer_prepare_copy(p->fcgi_env, 1024); - -@@ -2054,14 +2047,22 @@ 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_string_len(b, (const char *)&header, sizeof(header)); -- buffer_append_string_len(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used); -+ { -+ buffer *b = buffer_init(); - -- fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0); -- buffer_append_string_len(b, (const char *)&header, sizeof(header)); -+ buffer_copy_string_len(b, (const char *)&beginRecord, sizeof(beginRecord)); - -- hctx->wb->bytes_in += b->used - 1; -+ fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0); -+ 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_string_len(b, (const char *)&header, sizeof(header)); -+ -+ hctx->wb->bytes_in += b->used - 1; -+ chunkqueue_append_buffer(hctx->wb, b); -+ buffer_free(b); -+ } - - if (con->request.content_length) { - chunkqueue *req_cq = con->request_content_queue; -@@ -2433,38 +2434,21 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) { - return -1; - } - -- /* init read-buffer */ -- - if (toread > 0) { -- buffer *b; -- chunk *cq_first = hctx->rb->first; -- chunk *cq_last = hctx->rb->last; -- -- b = chunkqueue_get_append_buffer(hctx->rb); -- buffer_prepare_copy(b, toread + 1); -- -- /* append to read-buffer */ -- if (-1 == (r = read(hctx->fd, b->ptr, toread))) { -- if (errno == EAGAIN) { -- /* roll back the last chunk allocation, -- and continue on next iteration */ -- buffer_free(hctx->rb->last->mem); -- free(hctx->rb->last); -- hctx->rb->first = cq_first; -- hctx->rb->last = cq_last; -- return 0; -- } -+ char *mem; -+ size_t mem_len; -+ -+ chunkqueue_get_memory(hctx->rb, &mem, &mem_len, 0, toread); -+ r = read(hctx->fd, mem, mem_len); -+ chunkqueue_use_memory(hctx->rb, r > 0 ? r : 0); -+ -+ if (-1 == r) { -+ if (errno == EAGAIN) return 0; - log_error_write(srv, __FILE__, __LINE__, "sds", - "unexpected end-of-file (perhaps the fastcgi process died):", - fcgi_fd, strerror(errno)); - return -1; - } -- -- /* this should be catched by the b > 0 above */ -- force_assert(r); -- -- b->used = r + 1; /* one extra for the fake \0 */ -- b->ptr[b->used - 1] = '\0'; - } else { - log_error_write(srv, __FILE__, __LINE__, "ssdsb", - "unexpected end-of-file (perhaps the fastcgi process died):", -@@ -2973,8 +2957,8 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) { - "fcgi-request is already in use:", hctx->request_id); - } - -- /* fall through */ - if (-1 == fcgi_create_env(srv, hctx, hctx->request_id)) return HANDLER_ERROR; -+ - fcgi_set_state(srv, hctx, FCGI_STATE_WRITE); - /* fall through */ - case FCGI_STATE_WRITE: -diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c -index 501f8e8..1c1a356 100644 ---- a/src/mod_flv_streaming.c -+++ b/src/mod_flv_streaming.c -@@ -207,7 +207,6 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) { - if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { - data_string *get_param; - stat_cache_entry *sce = NULL; -- buffer *b; - int start; - char *err = NULL; - /* if there is a start=[0-9]+ in the header use it as start, -@@ -242,10 +241,9 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) { - } - - /* we are safe now, let's build a flv header */ -- b = chunkqueue_get_append_buffer(con->write_queue); -- buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9")); -- -+ http_chunk_append_mem(srv, con, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9")); - http_chunk_append_file(srv, con, con->physical.path, start, sce->st.st_size - start); -+ http_chunk_close(srv, con); - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv")); - -diff --git a/src/mod_proxy.c b/src/mod_proxy.c -index 3bfc78f..2b5a740 100644 ---- a/src/mod_proxy.c -+++ b/src/mod_proxy.c -@@ -449,7 +449,7 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) { - - /* build header */ - -- b = chunkqueue_get_append_buffer(hctx->wb); -+ b = buffer_init(); - - /* request line */ - buffer_copy_string(b, get_http_method_name(con->request.http_method)); -@@ -486,6 +486,9 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) { - buffer_append_string_len(b, CONST_STR_LEN("\r\n")); - - hctx->wb->bytes_in += b->used - 1; -+ chunkqueue_append_buffer(hctx->wb, b); -+ buffer_free(b); -+ - /* body */ - - if (con->request.content_length) { -diff --git a/src/mod_scgi.c b/src/mod_scgi.c -index 66dce5e..2fa265d 100644 ---- a/src/mod_scgi.c -+++ b/src/mod_scgi.c -@@ -1629,7 +1629,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) { - - scgi_env_add_request_headers(srv, con, p); - -- b = chunkqueue_get_append_buffer(hctx->wb); -+ b = buffer_init(); - - buffer_append_int(b, p->scgi_env->used); - buffer_append_string_len(b, CONST_STR_LEN(":")); -@@ -1637,6 +1637,8 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) { - buffer_append_string_len(b, CONST_STR_LEN(",")); - - hctx->wb->bytes_in += b->used - 1; -+ chunkqueue_append_buffer(hctx->wb, b); -+ buffer_free(b); - - if (con->request.content_length) { - chunkqueue *req_cq = con->request_content_queue; -diff --git a/src/mod_ssi.c b/src/mod_ssi.c -index 38eeac5..ecdfb99 100644 ---- a/src/mod_ssi.c -+++ b/src/mod_ssi.c -@@ -430,7 +430,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const - case SSI_ECHO_USER_NAME: { - struct passwd *pw; - -- b = chunkqueue_get_append_buffer(con->write_queue); -+ b = buffer_init(); - #ifdef HAVE_PWD_H - if (NULL == (pw = getpwuid(sce->st.st_uid))) { - buffer_copy_int(b, sce->st.st_uid); -@@ -440,67 +440,62 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const - #else - buffer_copy_int(b, sce->st.st_uid); - #endif -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); - break; - } - case SSI_ECHO_LAST_MODIFIED: { - time_t t = sce->st.st_mtime; - -- b = chunkqueue_get_append_buffer(con->write_queue); - if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) { -- buffer_copy_string_len(b, CONST_STR_LEN("(none)")); -+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)")); - } else { -- buffer_copy_string(b, buf); -+ chunkqueue_append_mem(con->write_queue, buf, strlen(buf)); - } - break; - } - case SSI_ECHO_DATE_LOCAL: { - time_t t = time(NULL); - -- b = chunkqueue_get_append_buffer(con->write_queue); - if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) { -- buffer_copy_string_len(b, CONST_STR_LEN("(none)")); -+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)")); - } else { -- buffer_copy_string(b, buf); -+ chunkqueue_append_mem(con->write_queue, buf, strlen(buf)); - } - break; - } - case SSI_ECHO_DATE_GMT: { - time_t t = time(NULL); - -- b = chunkqueue_get_append_buffer(con->write_queue); - if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) { -- buffer_copy_string_len(b, CONST_STR_LEN("(none)")); -+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)")); - } else { -- buffer_copy_string(b, buf); -+ chunkqueue_append_mem(con->write_queue, buf, strlen(buf)); - } - break; - } - case SSI_ECHO_DOCUMENT_NAME: { - char *sl; - -- b = chunkqueue_get_append_buffer(con->write_queue); - if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) { -- buffer_copy_buffer(b, con->physical.path); -+ chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->physical.path)); - } else { -- buffer_copy_string(b, sl + 1); -+ chunkqueue_append_mem(con->write_queue, sl + 1, strlen(sl + 1)); - } - break; - } - case SSI_ECHO_DOCUMENT_URI: { -- b = chunkqueue_get_append_buffer(con->write_queue); -- buffer_copy_buffer(b, con->uri.path); -+ chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->uri.path)); - break; - } - default: { - data_string *ds; - /* check if it is a cgi-var */ - -- b = chunkqueue_get_append_buffer(con->write_queue); -- - if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) { -- buffer_copy_buffer(b, ds->value); -+ chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(ds->value)); - } else { -- buffer_copy_string_len(b, CONST_STR_LEN("(none)")); -+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)")); - } - - break; -@@ -583,7 +578,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const - - switch (ssicmd) { - case SSI_FSIZE: -- b = chunkqueue_get_append_buffer(con->write_queue); -+ b = buffer_init(); - if (p->sizefmt) { - int j = 0; - const char *abr[] = { " B", " kB", " MB", " GB", " TB", NULL }; -@@ -597,13 +592,14 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const - } else { - buffer_copy_int(b, st.st_size); - } -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); - break; - case SSI_FLASTMOD: -- b = chunkqueue_get_append_buffer(con->write_queue); - if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) { -- buffer_copy_string_len(b, CONST_STR_LEN("(none)")); -+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)")); - } else { -- buffer_copy_string(b, buf); -+ chunkqueue_append_mem(con->write_queue, buf, strlen(buf)); - } - break; - case SSI_INCLUDE: -@@ -611,7 +607,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const - - /* Keep the newest mtime of included files */ - if (st.st_mtime > include_file_last_mtime) -- include_file_last_mtime = st.st_mtime; -+ include_file_last_mtime = st.st_mtime; - - break; - } -@@ -683,7 +679,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const - case SSI_PRINTENV: - if (p->if_is_false) break; - -- b = chunkqueue_get_append_buffer(con->write_queue); -+ b = buffer_init(); - for (i = 0; i < p->ssi_vars->used; i++) { - data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]]; - -@@ -700,6 +696,8 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const - buffer_append_string_encoded(b, CONST_BUF_LEN(ds->value), ENCODING_MINIMAL_XML); - buffer_append_string_len(b, CONST_STR_LEN("\n")); - } -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); - - break; - case SSI_EXEC: { -@@ -791,17 +789,14 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const - } - - if (toread > 0) { -- b = chunkqueue_get_append_buffer(con->write_queue); -+ char *mem; -+ size_t mem_len; - -- buffer_prepare_copy(b, toread); -+ chunkqueue_get_memory(con->write_queue, &mem, &mem_len, 0, toread); -+ r = read(from_exec_fds[0], mem, mem_len); -+ chunkqueue_use_memory(con->write_queue, r > 0 ? r : 0); - -- if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) { -- /* read failed */ -- break; -- } else { -- b->used = r; -- b->ptr[b->used++] = '\0'; -- } -+ if (r < 0) break; /* read failed */ - } else { - break; - } -diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c -index 931bc57..e36c697 100644 ---- a/src/mod_staticfile.c -+++ b/src/mod_staticfile.c -@@ -285,9 +285,7 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data * - if (!error) { - if (multipart) { - /* write boundary-header */ -- buffer *b; -- -- b = chunkqueue_get_append_buffer(con->write_queue); -+ buffer *b = buffer_init(); - - buffer_copy_string_len(b, CONST_STR_LEN("\r\n--")); - buffer_append_string(b, boundary); -@@ -307,7 +305,8 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data * - buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n")); - - con->response.content_length += b->used - 1; -- -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); - } - - chunkqueue_append_file(con->write_queue, con->physical.path, start, end - start + 1); -@@ -320,15 +319,15 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data * - - if (multipart) { - /* add boundary end */ -- buffer *b; -- -- b = chunkqueue_get_append_buffer(con->write_queue); -+ buffer *b = buffer_init(); - - buffer_copy_string_len(b, "\r\n--", 4); - buffer_append_string(b, boundary); - buffer_append_string_len(b, "--\r\n", 4); - - con->response.content_length += b->used - 1; -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); - - /* set header-fields */ - -diff --git a/src/mod_status.c b/src/mod_status.c -index e8da0a8..99b332a 100644 ---- a/src/mod_status.c -+++ b/src/mod_status.c -@@ -199,7 +199,7 @@ static int mod_status_get_multiplier(double *avg, char *multiplier, int size) { - - static handler_t mod_status_handle_server_status_html(server *srv, connection *con, void *p_d) { - plugin_data *p = p_d; -- buffer *b; -+ buffer *b = buffer_init(); - size_t j; - double avg; - char multiplier = '\0'; -@@ -208,8 +208,6 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c - - int days, hours, mins, seconds; - -- b = chunkqueue_get_append_buffer(con->write_queue); -- - buffer_copy_string_len(b, CONST_STR_LEN( - "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" -@@ -555,6 +553,9 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c - "</html>\n" - )); - -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); -+ - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - - return 0; -@@ -563,15 +564,13 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c - - static handler_t mod_status_handle_server_status_text(server *srv, connection *con, void *p_d) { - plugin_data *p = p_d; -- buffer *b; -+ buffer *b = buffer_init(); - double avg; - time_t ts; - char buf[32]; - unsigned int k; - unsigned int l; - -- b = chunkqueue_get_append_buffer(con->write_queue); -- - /* output total number of requests */ - buffer_append_string_len(b, CONST_STR_LEN("Total Accesses: ")); - avg = p->abs_requests; -@@ -598,13 +597,13 @@ static handler_t mod_status_handle_server_status_text(server *srv, connection *c - buffer_append_string_len(b, CONST_STR_LEN("\n")); - - buffer_append_string_len(b, CONST_STR_LEN("IdleServers: ")); -- buffer_append_int(b, srv->conns->size - srv->conns->used); -- buffer_append_string_len(b, CONST_STR_LEN("\n")); -+ buffer_append_int(b, srv->conns->size - srv->conns->used); -+ buffer_append_string_len(b, CONST_STR_LEN("\n")); - -- /* output scoreboard */ -- buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: ")); -- for (k = 0; k < srv->conns->used; k++) { -- connection *c = srv->conns->ptr[k]; -+ /* output scoreboard */ -+ buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: ")); -+ for (k = 0; k < srv->conns->used; k++) { -+ connection *c = srv->conns->ptr[k]; - const char *state = connection_get_short_state(c->state); - buffer_append_string_len(b, state, 1); - } -@@ -613,15 +612,17 @@ static handler_t mod_status_handle_server_status_text(server *srv, connection *c - } - buffer_append_string_len(b, CONST_STR_LEN("\n")); - -- /* set text/plain output */ -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); - -+ /* set text/plain output */ - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); - - return 0; - } - - static handler_t mod_status_handle_server_statistics(server *srv, connection *con, void *p_d) { -- buffer *b; -+ buffer *b = buffer_init(); - size_t i; - array *st = srv->status; - UNUSED(p_d); -@@ -634,8 +635,6 @@ static handler_t mod_status_handle_server_statistics(server *srv, connection *co - return HANDLER_FINISHED; - } - -- b = chunkqueue_get_append_buffer(con->write_queue); -- - for (i = 0; i < st->used; i++) { - size_t ndx = st->sorted[i]; - -@@ -645,6 +644,9 @@ static handler_t mod_status_handle_server_statistics(server *srv, connection *co - buffer_append_string_len(b, CONST_STR_LEN("\n")); - } - -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); -+ - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain")); - - con->http_status = 200; -@@ -671,7 +673,8 @@ static handler_t mod_status_handle_server_status(server *srv, connection *con, v - - static handler_t mod_status_handle_server_config(server *srv, connection *con, void *p_d) { - plugin_data *p = p_d; -- buffer *b, *m = p->module_list; -+ buffer *b = buffer_init(); -+ buffer *m = p->module_list; - size_t i; - - struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = -@@ -703,8 +706,6 @@ static handler_t mod_status_handle_server_config(server *srv, connection *con, v - { FDEVENT_HANDLER_UNSET, NULL } - }; - -- b = chunkqueue_get_append_buffer(con->write_queue); -- - buffer_copy_string_len(b, CONST_STR_LEN( - "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" -@@ -756,6 +757,9 @@ static handler_t mod_status_handle_server_config(server *srv, connection *con, v - "</html>\n" - )); - -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); -+ - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html")); - - con->http_status = 200; -diff --git a/src/mod_webdav.c b/src/mod_webdav.c -index a3807c0..433b904 100644 ---- a/src/mod_webdav.c -+++ b/src/mod_webdav.c -@@ -1094,7 +1094,7 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p, - static int webdav_lockdiscovery(server *srv, connection *con, - buffer *locktoken, const char *lockscope, const char *locktype, int depth) { - -- buffer *b; -+ buffer *b = buffer_init(); - - response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken)); - -@@ -1102,8 +1102,6 @@ static int webdav_lockdiscovery(server *srv, connection *con, - CONST_STR_LEN("Content-Type"), - CONST_STR_LEN("text/xml; charset=\"utf-8\"")); - -- b = chunkqueue_get_append_buffer(con->write_queue); -- - buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")); - - buffer_append_string_len(b,CONST_STR_LEN("<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n")); -@@ -1143,6 +1141,9 @@ static int webdav_lockdiscovery(server *srv, connection *con, - buffer_append_string_len(b,CONST_STR_LEN("</D:lockdiscovery>\n")); - buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n")); - -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); -+ - return 0; - } - #endif -@@ -1341,7 +1342,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) { - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\"")); - -- b = chunkqueue_get_append_buffer(con->write_queue); -+ b = buffer_init(); - - buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")); - -@@ -1487,6 +1488,10 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) { - if (p->conf.log_xml) { - log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b); - } -+ -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); -+ - con->file_finished = 1; - - return HANDLER_FINISHED; -@@ -1555,7 +1560,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) { - /* we got an error somewhere in between, build a 207 */ - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\"")); - -- b = chunkqueue_get_append_buffer(con->write_queue); -+ b = buffer_init(); - - buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")); - -@@ -1569,6 +1574,9 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) { - log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b); - } - -+ chunkqueue_append_buffer(con->write_queue, b); -+ buffer_free(b); -+ - con->http_status = 207; - con->file_finished = 1; - } else { -diff --git a/src/response.c b/src/response.c -index bde381f..31bcd69 100644 ---- a/src/response.c -+++ b/src/response.c -@@ -33,7 +33,7 @@ int http_response_write_header(server *srv, connection *con) { - int have_date = 0; - int have_server = 0; - -- b = chunkqueue_get_prepend_buffer(con->write_queue); -+ b = buffer_init(); - - if (con->request.http_version == HTTP_VERSION_1_1) { - buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 ")); -@@ -121,13 +121,15 @@ int http_response_write_header(server *srv, connection *con) { - - buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n")); - -- - con->bytes_header = b->used - 1; - - if (con->conf.log_response_header) { - log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b); - } - -+ chunkqueue_prepend_buffer(con->write_queue, b); -+ buffer_free(b); -+ - return 0; - } - --- -2.4.5 - |