aboutsummaryrefslogtreecommitdiffstats
path: root/main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch
diff options
context:
space:
mode:
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.patch1537
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
-