aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-07-07 14:20:33 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2015-07-07 14:23:40 +0000
commita7cd05c24e19250420da81b72e89a4abf367b785 (patch)
tree4c968d88315a158ee5db1e1ffdb8b4045053e9fc
parent7b8bccb263940f61ac2c4fe2fd8710a9e5267811 (diff)
downloadalpine_aports-a7cd05c24e19250420da81b72e89a4abf367b785.tar.bz2
alpine_aports-a7cd05c24e19250420da81b72e89a4abf367b785.tar.xz
alpine_aports-a7cd05c24e19250420da81b72e89a4abf367b785.zip
main/lighttpd: security fix for CVE-2015-3200
The upstream patch does not apply without applying lot other stuff so we simply apply all since 1.4.35 release. fixes #4330 (cherry picked from commit c1ee7a6e6d21447788c7512e7197d49ebfbc3096)
-rw-r--r--main/lighttpd/0001-next-is-1.4.36.patch72
-rw-r--r--main/lighttpd/0002-use-keep-alive-timeout-while-waiting-for-HTTP-header.patch72
-rw-r--r--main/lighttpd/0003-fix-bad-shift-in-conditional-netmask-.-0-handling.patch61
-rw-r--r--main/lighttpd/0004-add-more-mime-types-and-a-script-to-generate-mime.co.patch857
-rw-r--r--main/lighttpd/0005-fix-typo-in-NEWS-entry-for-2579.patch31
-rw-r--r--main/lighttpd/0006-add-support-for-Free-BSD-extended-attributes.patch175
-rw-r--r--main/lighttpd/0007-build-use-fortify-flags-with-extra-warnings.patch88
-rw-r--r--main/lighttpd/0008-mod_dirlisting-mod_redirect-mod_rewrite-abort-config.patch163
-rw-r--r--main/lighttpd/0009-ssl-disable-SSL3.0-by-default.patch44
-rw-r--r--main/lighttpd/0010-Fixed-typo-found-by-openSUSE-user-boo-907709.patch38
-rw-r--r--main/lighttpd/0011-add-NEWS-entry-for-previous-commit.patch30
-rw-r--r--main/lighttpd/0012-network-fix-compile-break-in-calculation-of-sockaddr.patch66
-rw-r--r--main/lighttpd/0013-connections-fix-bug-in-connection-state-handling.patch69
-rw-r--r--main/lighttpd/0014-print-backtrace-in-assert-logging-with-libunwind.patch187
-rw-r--r--main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch6095
-rw-r--r--main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch1537
-rw-r--r--main/lighttpd/0017-Remove-buffer_prepare_copy-and-buffer_prepare_append.patch1182
-rw-r--r--main/lighttpd/0018-tests-improve-valgrind-and-strace-TRACEME-disable-co.patch79
-rw-r--r--main/lighttpd/0019-Use-buffer-API-to-read-and-modify-used-member.patch4346
-rw-r--r--main/lighttpd/0020-rename-buffer_append_long_hex-to-buffer_append_uint_.patch117
-rw-r--r--main/lighttpd/0021-buffer-constify-some-parameters.patch98
-rw-r--r--main/lighttpd/0022-bitset-unused-remove.patch170
-rw-r--r--main/lighttpd/0023-remove-unused-stuff-from-server.h.patch38
-rw-r--r--main/lighttpd/0024-crc32-fix-method-signature-const-pointer.patch44
-rw-r--r--main/lighttpd/0025-tests-fix-undefined-index-warning-in-sendfile.php.patch31
-rw-r--r--main/lighttpd/0026-mod_auth-use-crypt_r-instead-of-crypt-if-available.patch102
-rw-r--r--main/lighttpd/0027-fix-error-message-for-T_CONFIG_ARRAY-config-values-i.patch49
-rw-r--r--main/lighttpd/0028-fix-segfaults-in-many-plugins-if-they-failed-configu.patch447
-rw-r--r--main/lighttpd/0029-escape-all-strings-for-logging-fixes-2646-log-file-i.patch174
-rw-r--r--main/lighttpd/APKBUILD119
30 files changed, 16580 insertions, 1 deletions
diff --git a/main/lighttpd/0001-next-is-1.4.36.patch b/main/lighttpd/0001-next-is-1.4.36.patch
new file mode 100644
index 0000000000..88512bbf3e
--- /dev/null
+++ b/main/lighttpd/0001-next-is-1.4.36.patch
@@ -0,0 +1,72 @@
1From e1b1c52028b446fdef837d26341dd1431780e0f6 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Wed, 2 Apr 2014 10:04:09 +0000
4Subject: [PATCH 01/29] - next is 1.4.36
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2961 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 CMakeLists.txt | 2 +-
14 NEWS | 7 +++++--
15 SConstruct | 2 +-
16 configure.ac | 2 +-
17 4 files changed, 8 insertions(+), 5 deletions(-)
18
19diff --git a/NEWS b/NEWS
20index 9f4c04a..b9bd48f 100644
21--- a/NEWS
22+++ b/NEWS
23@@ -3,7 +3,10 @@
24 NEWS
25 ====
26
27-- 1.4.35
28+- 1.4.36
29+ *
30+
31+- 1.4.35 - 2014-03-12
32 * [network/ssl] fix build error if TLSEXT is disabled
33 * [mod_fastcgi] fix use after free (only triggered if fastcgi debug is active)
34 * [mod_rrdtool] fix invalid read (string not null terminated)
35@@ -23,7 +26,7 @@ NEWS
36 * check length of unix domain socket filenames
37 * fix SQL injection / host name validation (thx Jann Horn)
38
39-- 1.4.34
40+- 1.4.34 - 2014-01-20
41 * [mod_auth] explicitly link ssl for SHA1 (fixes #2517)
42 * [mod_extforward] fix compilation without IPv6, (not) using undefined var (fixes #2515, thx mm)
43 * [ssl] fix SNI handling; only use key+cert from SNI specific config (fixes #2525, CVE-2013-4508)
44diff --git a/SConstruct b/SConstruct
45index cb2a58f..d8bd98a 100644
46--- a/SConstruct
47+++ b/SConstruct
48@@ -5,7 +5,7 @@ import string
49 from stat import *
50
51 package = 'lighttpd'
52-version = '1.4.35'
53+version = '1.4.36'
54
55 def checkCHeaders(autoconf, hdrs):
56 p = re.compile('[^A-Z0-9]')
57diff --git a/configure.ac b/configure.ac
58index 682023b..ae35234 100644
59--- a/configure.ac
60+++ b/configure.ac
61@@ -1,7 +1,7 @@
62 dnl -*- Autoconf -*-
63 dnl Process this file with autoconf to produce a configure script.
64 AC_PREREQ(2.57)
65-AC_INIT([lighttpd], [1.4.35], [contact@lighttpd.net])
66+AC_INIT([lighttpd], [1.4.36], [contact@lighttpd.net])
67 AC_CONFIG_SRCDIR([src/server.c])
68 AC_CONFIG_HEADER([config.h])
69 AC_CONFIG_MACRO_DIR([m4])
70--
712.4.5
72
diff --git a/main/lighttpd/0002-use-keep-alive-timeout-while-waiting-for-HTTP-header.patch b/main/lighttpd/0002-use-keep-alive-timeout-while-waiting-for-HTTP-header.patch
new file mode 100644
index 0000000000..13774eb4e6
--- /dev/null
+++ b/main/lighttpd/0002-use-keep-alive-timeout-while-waiting-for-HTTP-header.patch
@@ -0,0 +1,72 @@
1From 3605a3bec31f5e1bc79fdfb830b84e188f060982 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Wed, 2 Apr 2014 10:04:11 +0000
4Subject: [PATCH 02/29] use keep-alive timeout while waiting for HTTP headers;
5 use always the read timeout while waiting for the HTTP body
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10From: Stefan Bühler <stbuehler@web.de>
11
12git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2962 152afb58-edef-0310-8abb-c4023f1b3aa9
13---
14 NEWS | 2 +-
15 src/server.c | 20 +++++++++++---------
16 2 files changed, 12 insertions(+), 10 deletions(-)
17
18diff --git a/NEWS b/NEWS
19index b9bd48f..e82b90b 100644
20--- a/NEWS
21+++ b/NEWS
22@@ -4,7 +4,7 @@ NEWS
23 ====
24
25 - 1.4.36
26- *
27+ * use keep-alive timeout while waiting for HTTP headers; use always the read timeout while waiting for the HTTP body
28
29 - 1.4.35 - 2014-03-12
30 * [network/ssl] fix build error if TLSEXT is disabled
31diff --git a/src/server.c b/src/server.c
32index 5691921..d47fd62 100644
33--- a/src/server.c
34+++ b/src/server.c
35@@ -1296,23 +1296,25 @@ int main (int argc, char **argv) {
36
37 if (con->state == CON_STATE_READ ||
38 con->state == CON_STATE_READ_POST) {
39- if (con->request_count == 1) {
40+ if (con->request_count == 1 || con->state == CON_STATE_READ_POST) {
41 if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
42 /* time - out */
43-#if 0
44- log_error_write(srv, __FILE__, __LINE__, "sd",
45- "connection closed - read-timeout:", con->fd);
46-#endif
47+ if (con->conf.log_request_handling) {
48+ log_error_write(srv, __FILE__, __LINE__, "sd",
49+ "connection closed - read timeout:", con->fd);
50+ }
51+
52 connection_set_state(srv, con, CON_STATE_ERROR);
53 changed = 1;
54 }
55 } else {
56 if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
57 /* time - out */
58-#if 0
59- log_error_write(srv, __FILE__, __LINE__, "sd",
60- "connection closed - read-timeout:", con->fd);
61-#endif
62+ if (con->conf.log_request_handling) {
63+ log_error_write(srv, __FILE__, __LINE__, "sd",
64+ "connection closed - keep-alive timeout:", con->fd);
65+ }
66+
67 connection_set_state(srv, con, CON_STATE_ERROR);
68 changed = 1;
69 }
70--
712.4.5
72
diff --git a/main/lighttpd/0003-fix-bad-shift-in-conditional-netmask-.-0-handling.patch b/main/lighttpd/0003-fix-bad-shift-in-conditional-netmask-.-0-handling.patch
new file mode 100644
index 0000000000..0a3b51f342
--- /dev/null
+++ b/main/lighttpd/0003-fix-bad-shift-in-conditional-netmask-.-0-handling.patch
@@ -0,0 +1,61 @@
1From f8f335150675ed8f5d1cf3edadf74f7f6685f606 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Mon, 14 Apr 2014 16:12:11 +0000
4Subject: [PATCH 03/29] fix bad shift in conditional netmask ".../0" handling
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9config conditionals like $HTTP["remoteip"] == "a.b.c.d/0" (or completely
10broken netmasks) triggered bad shifts. Matching against "/0" is not very
11useful though - it is always true.
12
13From: Stefan Bühler <stbuehler@web.de>
14
15git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2963 152afb58-edef-0310-8abb-c4023f1b3aa9
16---
17 NEWS | 1 +
18 src/configfile-glue.c | 8 +++++++-
19 2 files changed, 8 insertions(+), 1 deletion(-)
20
21diff --git a/NEWS b/NEWS
22index e82b90b..780f4c6 100644
23--- a/NEWS
24+++ b/NEWS
25@@ -5,6 +5,7 @@ NEWS
26
27 - 1.4.36
28 * use keep-alive timeout while waiting for HTTP headers; use always the read timeout while waiting for the HTTP body
29+ * fix bad shift in conditional netmask ".../0" handling
30
31 - 1.4.35 - 2014-03-12
32 * [network/ssl] fix build error if TLSEXT is disabled
33diff --git a/src/configfile-glue.c b/src/configfile-glue.c
34index 3efa46a..9f24dcb 100644
35--- a/src/configfile-glue.c
36+++ b/src/configfile-glue.c
37@@ -357,6 +357,12 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
38 return COND_RESULT_FALSE;
39 }
40
41+ if (nm_bits > 32 || nm_bits < 0) {
42+ log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: invalid netmask:", dc->string, err);
43+
44+ return COND_RESULT_FALSE;
45+ }
46+
47 /* take IP convert to the native */
48 buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr);
49 #ifdef __WIN32
50@@ -375,7 +381,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
51 #endif
52
53 /* build netmask */
54- nm = htonl(~((1 << (32 - nm_bits)) - 1));
55+ nm = nm_bits ? htonl(~((1 << (32 - nm_bits)) - 1)) : 0;
56
57 if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) {
58 return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
59--
602.4.5
61
diff --git a/main/lighttpd/0004-add-more-mime-types-and-a-script-to-generate-mime.co.patch b/main/lighttpd/0004-add-more-mime-types-and-a-script-to-generate-mime.co.patch
new file mode 100644
index 0000000000..7803f68370
--- /dev/null
+++ b/main/lighttpd/0004-add-more-mime-types-and-a-script-to-generate-mime.co.patch
@@ -0,0 +1,857 @@
1From 3b23130ea2c1dff470da0970ee8a75c7dafc90fe Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Tue, 13 May 2014 10:34:46 +0000
4Subject: [PATCH 04/29] add more mime types and a script to generate mime.conf
5 (fxies #2579)
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10From: Stefan Bühler <stbuehler@web.de>
11
12git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2964 152afb58-edef-0310-8abb-c4023f1b3aa9
13---
14 NEWS | 1 +
15 doc/config/conf.d/mime.conf | 603 +++++++++++++++++++++++++++++++++++-----
16 doc/scripts/create-mime.conf.pl | 197 +++++++++++++
17 3 files changed, 735 insertions(+), 66 deletions(-)
18 create mode 100755 doc/scripts/create-mime.conf.pl
19
20diff --git a/NEWS b/NEWS
21index 780f4c6..8c34545 100644
22--- a/NEWS
23+++ b/NEWS
24@@ -6,6 +6,7 @@ NEWS
25 - 1.4.36
26 * use keep-alive timeout while waiting for HTTP headers; use always the read timeout while waiting for the HTTP body
27 * fix bad shift in conditional netmask ".../0" handling
28+ * add more mime types and a script to generate mime.conf (fxies #2579)
29
30 - 1.4.35 - 2014-03-12
31 * [network/ssl] fix build error if TLSEXT is disabled
32diff --git a/doc/config/conf.d/mime.conf b/doc/config/conf.d/mime.conf
33index 8cfdfe7..f65a02c 100644
34--- a/doc/config/conf.d/mime.conf
35+++ b/doc/config/conf.d/mime.conf
36@@ -1,78 +1,549 @@
37+# created by create-mime.conf.pl
38+
39 #######################################################################
40 ##
41 ## MimeType handling
42 ## -------------------
43 ##
44-## http://www.lighttpd.net/documentation/configuration.html#mimetypes
45+## https://redmine.lighttpd.net/projects/lighttpd/wiki/Mimetype_assignDetails
46+
47 ##
48-## Use the "Content-Type" extended attribute to obtain mime type if
49+## Use the "Content-Type" extended file attribute to obtain mime type if
50 ## possible
51 ##
52-mimetype.use-xattr = "disable"
53+## Disabled by default
54+##
55+#mimetype.use-xattr = "enable"
56
57 ##
58-## mimetype mapping
59+## mimetype ("Content-Type" HTTP header) mapping for static file handling
60 ##
61-mimetype.assign = (
62- ".pdf" => "application/pdf",
63- ".sig" => "application/pgp-signature",
64- ".spl" => "application/futuresplash",
65- ".class" => "application/octet-stream",
66- ".ps" => "application/postscript",
67- ".torrent" => "application/x-bittorrent",
68- ".dvi" => "application/x-dvi",
69- ".gz" => "application/x-gzip",
70- ".pac" => "application/x-ns-proxy-autoconfig",
71- ".swf" => "application/x-shockwave-flash",
72- ".tar.gz" => "application/x-tgz",
73- ".tgz" => "application/x-tgz",
74- ".tar" => "application/x-tar",
75- ".zip" => "application/zip",
76- ".mp3" => "audio/mpeg",
77- ".m3u" => "audio/x-mpegurl",
78- ".wma" => "audio/x-ms-wma",
79- ".wax" => "audio/x-ms-wax",
80- ".ogg" => "application/ogg",
81- ".wav" => "audio/x-wav",
82- ".gif" => "image/gif",
83- ".jpg" => "image/jpeg",
84- ".jpeg" => "image/jpeg",
85- ".png" => "image/png",
86- ".xbm" => "image/x-xbitmap",
87- ".xpm" => "image/x-xpixmap",
88- ".xwd" => "image/x-xwindowdump",
89- ".css" => "text/css",
90- ".html" => "text/html",
91- ".htm" => "text/html",
92- ".js" => "text/javascript",
93- ".asc" => "text/plain",
94- ".c" => "text/plain",
95- ".cpp" => "text/plain",
96- ".log" => "text/plain",
97- ".conf" => "text/plain",
98- ".text" => "text/plain",
99- ".txt" => "text/plain",
100- ".spec" => "text/plain",
101- ".dtd" => "text/xml",
102- ".xml" => "text/xml",
103- ".mpeg" => "video/mpeg",
104- ".mpg" => "video/mpeg",
105- ".mov" => "video/quicktime",
106- ".qt" => "video/quicktime",
107- ".avi" => "video/x-msvideo",
108- ".asf" => "video/x-ms-asf",
109- ".asx" => "video/x-ms-asf",
110- ".wmv" => "video/x-ms-wmv",
111- ".bz2" => "application/x-bzip",
112- ".tbz" => "application/x-bzip-compressed-tar",
113- ".tar.bz2" => "application/x-bzip-compressed-tar",
114- ".rpm" => "application/x-rpm",
115- ".json" => "application/json",
116- # make the default mime type application/octet-stream.
117- "" => "application/octet-stream",
118- )
119-
120-
121-#
122-#######################################################################
123+## The first matching suffix is used. If no mapping is found
124+## 'application/octet-stream' is used, and caching (etag/last-modified handling)
125+## is disabled to prevent clients from caching "unknown" mime types.
126+##
127+## Therefore the last mapping is:
128+## "" => "application/octet-stream"
129+## This matches all extensions and acts as default mime type, and enables
130+## caching for those.
131+mimetype.assign = (
132+ ".tar.bz2" => "application/x-gtar-compressed",
133+ ".tar.gz" => "application/x-gtar-compressed",
134+ ".ez" => "application/andrew-inset",
135+ ".anx" => "application/annodex",
136+ ".atom" => "application/atom+xml",
137+ ".atomcat" => "application/atomcat+xml",
138+ ".atomsrv" => "application/atomserv+xml",
139+ ".lin" => "application/bbolin",
140+ ".cu" => "application/cu-seeme",
141+ ".davmount" => "application/davmount+xml",
142+ ".dcm" => "application/dicom",
143+ ".tsp" => "application/dsptype",
144+ ".es" => "application/ecmascript",
145+ ".spl" => "application/futuresplash",
146+ ".hta" => "application/hta",
147+ ".jar" => "application/java-archive",
148+ ".ser" => "application/java-serialized-object",
149+ ".class" => "application/java-vm",
150+ ".js" => "application/javascript",
151+ ".json" => "application/json",
152+ ".m3g" => "application/m3g",
153+ ".hqx" => "application/mac-binhex40",
154+ ".cpt" => "application/mac-compactpro",
155+ ".nb" => "application/mathematica",
156+ ".nbp" => "application/mathematica",
157+ ".mbox" => "application/mbox",
158+ ".mdb" => "application/msaccess",
159+ ".doc" => "application/msword",
160+ ".dot" => "application/msword",
161+ ".mxf" => "application/mxf",
162+ ".asn" => "application/octet-stream",
163+ ".bin" => "application/octet-stream",
164+ ".ent" => "application/octet-stream",
165+ ".oda" => "application/oda",
166+ ".ogx" => "application/ogg",
167+ ".one" => "application/onenote",
168+ ".onepkg" => "application/onenote",
169+ ".onetmp" => "application/onenote",
170+ ".onetoc2" => "application/onenote",
171+ ".pdf" => "application/pdf",
172+ ".pgp" => "application/pgp-encrypted",
173+ ".key" => "application/pgp-keys",
174+ ".sig" => "application/pgp-signature",
175+ ".prf" => "application/pics-rules",
176+ ".ai" => "application/postscript",
177+ ".eps" => "application/postscript",
178+ ".eps2" => "application/postscript",
179+ ".eps3" => "application/postscript",
180+ ".epsf" => "application/postscript",
181+ ".epsi" => "application/postscript",
182+ ".ps" => "application/postscript",
183+ ".rar" => "application/rar",
184+ ".rdf" => "application/rdf+xml",
185+ ".rtf" => "application/rtf",
186+ ".stl" => "application/sla",
187+ ".smi" => "application/smil+xml",
188+ ".smil" => "application/smil+xml",
189+ ".xht" => "application/xhtml+xml",
190+ ".xhtml" => "application/xhtml+xml",
191+ ".xml" => "application/xml",
192+ ".xsd" => "application/xml",
193+ ".dtd" => "application/xml-dtd",
194+ ".xsl" => "application/xslt+xml",
195+ ".xslt" => "application/xslt+xml",
196+ ".xspf" => "application/xspf+xml",
197+ ".zip" => "application/zip",
198+ ".apk" => "application/vnd.android.package-archive",
199+ ".cdy" => "application/vnd.cinderella",
200+ ".kml" => "application/vnd.google-earth.kml+xml",
201+ ".kmz" => "application/vnd.google-earth.kmz",
202+ ".xul" => "application/vnd.mozilla.xul+xml",
203+ ".xlb" => "application/vnd.ms-excel",
204+ ".xls" => "application/vnd.ms-excel",
205+ ".xlt" => "application/vnd.ms-excel",
206+ ".eot" => "application/vnd.ms-fontobject",
207+ ".thmx" => "application/vnd.ms-officetheme",
208+ ".cat" => "application/vnd.ms-pki.seccat",
209+ ".pps" => "application/vnd.ms-powerpoint",
210+ ".ppt" => "application/vnd.ms-powerpoint",
211+ ".odc" => "application/vnd.oasis.opendocument.chart",
212+ ".odb" => "application/vnd.oasis.opendocument.database",
213+ ".odf" => "application/vnd.oasis.opendocument.formula",
214+ ".odg" => "application/vnd.oasis.opendocument.graphics",
215+ ".otg" => "application/vnd.oasis.opendocument.graphics-template",
216+ ".odi" => "application/vnd.oasis.opendocument.image",
217+ ".odp" => "application/vnd.oasis.opendocument.presentation",
218+ ".otp" => "application/vnd.oasis.opendocument.presentation-template",
219+ ".ods" => "application/vnd.oasis.opendocument.spreadsheet",
220+ ".ots" => "application/vnd.oasis.opendocument.spreadsheet-template",
221+ ".odt" => "application/vnd.oasis.opendocument.text",
222+ ".odm" => "application/vnd.oasis.opendocument.text-master",
223+ ".ott" => "application/vnd.oasis.opendocument.text-template",
224+ ".oth" => "application/vnd.oasis.opendocument.text-web",
225+ ".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
226+ ".sldx" => "application/vnd.openxmlformats-officedocument.presentationml.slide",
227+ ".ppsx" => "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
228+ ".potx" => "application/vnd.openxmlformats-officedocument.presentationml.template",
229+ ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
230+ ".xltx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
231+ ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
232+ ".dotx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
233+ ".cod" => "application/vnd.rim.cod",
234+ ".mmf" => "application/vnd.smaf",
235+ ".sdc" => "application/vnd.stardivision.calc",
236+ ".sds" => "application/vnd.stardivision.chart",
237+ ".sda" => "application/vnd.stardivision.draw",
238+ ".sdd" => "application/vnd.stardivision.impress",
239+ ".sdf" => "application/vnd.stardivision.math",
240+ ".sdw" => "application/vnd.stardivision.writer",
241+ ".sgl" => "application/vnd.stardivision.writer-global",
242+ ".sxc" => "application/vnd.sun.xml.calc",
243+ ".stc" => "application/vnd.sun.xml.calc.template",
244+ ".sxd" => "application/vnd.sun.xml.draw",
245+ ".std" => "application/vnd.sun.xml.draw.template",
246+ ".sxi" => "application/vnd.sun.xml.impress",
247+ ".sti" => "application/vnd.sun.xml.impress.template",
248+ ".sxm" => "application/vnd.sun.xml.math",
249+ ".sxw" => "application/vnd.sun.xml.writer",
250+ ".sxg" => "application/vnd.sun.xml.writer.global",
251+ ".stw" => "application/vnd.sun.xml.writer.template",
252+ ".sis" => "application/vnd.symbian.install",
253+ ".cap" => "application/vnd.tcpdump.pcap",
254+ ".pcap" => "application/vnd.tcpdump.pcap",
255+ ".vsd" => "application/vnd.visio",
256+ ".wbxml" => "application/vnd.wap.wbxml",
257+ ".wmlc" => "application/vnd.wap.wmlc",
258+ ".wmlsc" => "application/vnd.wap.wmlscriptc",
259+ ".wpd" => "application/vnd.wordperfect",
260+ ".wp5" => "application/vnd.wordperfect5.1",
261+ ".wk" => "application/x-123",
262+ ".7z" => "application/x-7z-compressed",
263+ ".abw" => "application/x-abiword",
264+ ".dmg" => "application/x-apple-diskimage",
265+ ".bcpio" => "application/x-bcpio",
266+ ".torrent" => "application/x-bittorrent",
267+ ".bz2" => "application/x-bzip",
268+ ".cab" => "application/x-cab",
269+ ".cbr" => "application/x-cbr",
270+ ".cbz" => "application/x-cbz",
271+ ".cda" => "application/x-cdf",
272+ ".cdf" => "application/x-cdf",
273+ ".vcd" => "application/x-cdlink",
274+ ".pgn" => "application/x-chess-pgn",
275+ ".mph" => "application/x-comsol",
276+ ".cpio" => "application/x-cpio",
277+ ".deb" => "application/x-debian-package",
278+ ".udeb" => "application/x-debian-package",
279+ ".dcr" => "application/x-director",
280+ ".dir" => "application/x-director",
281+ ".dxr" => "application/x-director",
282+ ".dms" => "application/x-dms",
283+ ".wad" => "application/x-doom",
284+ ".dvi" => "application/x-dvi",
285+ ".woff" => "application/x-font-woff",
286+ ".mm" => "application/x-freemind",
287+ ".gan" => "application/x-ganttproject",
288+ ".gnumeric" => "application/x-gnumeric",
289+ ".sgf" => "application/x-go-sgf",
290+ ".gcf" => "application/x-graphing-calculator",
291+ ".gtar" => "application/x-gtar",
292+ ".taz" => "application/x-gtar-compressed",
293+ ".tbz" => "application/x-gtar-compressed",
294+ ".tgz" => "application/x-gtar-compressed",
295+ ".gz" => "application/x-gzip",
296+ ".hdf" => "application/x-hdf",
297+ ".hwp" => "application/x-hwp",
298+ ".ica" => "application/x-ica",
299+ ".info" => "application/x-info",
300+ ".ins" => "application/x-internet-signup",
301+ ".isp" => "application/x-internet-signup",
302+ ".iii" => "application/x-iphone",
303+ ".iso" => "application/x-iso9660-image",
304+ ".jam" => "application/x-jam",
305+ ".jnlp" => "application/x-java-jnlp-file",
306+ ".jmz" => "application/x-jmol",
307+ ".chrt" => "application/x-kchart",
308+ ".kil" => "application/x-killustrator",
309+ ".skd" => "application/x-koan",
310+ ".skm" => "application/x-koan",
311+ ".skp" => "application/x-koan",
312+ ".skt" => "application/x-koan",
313+ ".kpr" => "application/x-kpresenter",
314+ ".kpt" => "application/x-kpresenter",
315+ ".ksp" => "application/x-kspread",
316+ ".kwd" => "application/x-kword",
317+ ".kwt" => "application/x-kword",
318+ ".latex" => "application/x-latex",
319+ ".lha" => "application/x-lha",
320+ ".lyx" => "application/x-lyx",
321+ ".lzh" => "application/x-lzh",
322+ ".lzx" => "application/x-lzx",
323+ ".book" => "application/x-maker",
324+ ".fb" => "application/x-maker",
325+ ".fbdoc" => "application/x-maker",
326+ ".fm" => "application/x-maker",
327+ ".frame" => "application/x-maker",
328+ ".frm" => "application/x-maker",
329+ ".maker" => "application/x-maker",
330+ ".md5" => "application/x-md5",
331+ ".mif" => "application/x-mif",
332+ ".wmd" => "application/x-ms-wmd",
333+ ".wmz" => "application/x-ms-wmz",
334+ ".bat" => "application/x-msdos-program",
335+ ".com" => "application/x-msdos-program",
336+ ".dll" => "application/x-msdos-program",
337+ ".exe" => "application/x-msdos-program",
338+ ".msi" => "application/x-msi",
339+ ".nc" => "application/x-netcdf",
340+ ".dat" => "application/x-ns-proxy-autoconfig",
341+ ".pac" => "application/x-ns-proxy-autoconfig",
342+ ".nwc" => "application/x-nwc",
343+ ".o" => "application/x-object",
344+ ".oza" => "application/x-oz-application",
345+ ".p7r" => "application/x-pkcs7-certreqresp",
346+ ".crl" => "application/x-pkcs7-crl",
347+ ".pyc" => "application/x-python-code",
348+ ".pyo" => "application/x-python-code",
349+ ".qgs" => "application/x-qgis",
350+ ".shp" => "application/x-qgis",
351+ ".shx" => "application/x-qgis",
352+ ".qtl" => "application/x-quicktimeplayer",
353+ ".rdp" => "application/x-rdp",
354+ ".rpm" => "application/x-redhat-package-manager",
355+ ".rss" => "application/x-rss+xml",
356+ ".rb" => "application/x-ruby",
357+ ".sce" => "application/x-scilab",
358+ ".sci" => "application/x-scilab",
359+ ".xcos" => "application/x-scilab-xcos",
360+ ".sha1" => "application/x-sha1",
361+ ".shar" => "application/x-shar",
362+ ".swf" => "application/x-shockwave-flash",
363+ ".swfl" => "application/x-shockwave-flash",
364+ ".scr" => "application/x-silverlight",
365+ ".sql" => "application/x-sql",
366+ ".sit" => "application/x-stuffit",
367+ ".sitx" => "application/x-stuffit",
368+ ".sv4cpio" => "application/x-sv4cpio",
369+ ".sv4crc" => "application/x-sv4crc",
370+ ".tar" => "application/x-tar",
371+ ".gf" => "application/x-tex-gf",
372+ ".pk" => "application/x-tex-pk",
373+ ".texi" => "application/x-texinfo",
374+ ".texinfo" => "application/x-texinfo",
375+ ".roff" => "application/x-troff",
376+ ".t" => "application/x-troff",
377+ ".tr" => "application/x-troff",
378+ ".man" => "application/x-troff-man",
379+ ".me" => "application/x-troff-me",
380+ ".ms" => "application/x-troff-ms",
381+ ".ustar" => "application/x-ustar",
382+ ".src" => "application/x-wais-source",
383+ ".wz" => "application/x-wingz",
384+ ".crt" => "application/x-x509-ca-cert",
385+ ".xcf" => "application/x-xcf",
386+ ".fig" => "application/x-xfig",
387+ ".xpi" => "application/x-xpinstall",
388+ ".amr" => "audio/amr",
389+ ".awb" => "audio/amr-wb",
390+ ".axa" => "audio/annodex",
391+ ".au" => "audio/basic",
392+ ".snd" => "audio/basic",
393+ ".csd" => "audio/csound",
394+ ".orc" => "audio/csound",
395+ ".sco" => "audio/csound",
396+ ".flac" => "audio/flac",
397+ ".kar" => "audio/midi",
398+ ".mid" => "audio/midi",
399+ ".midi" => "audio/midi",
400+ ".m4a" => "audio/mpeg",
401+ ".mp2" => "audio/mpeg",
402+ ".mp3" => "audio/mpeg",
403+ ".mpega" => "audio/mpeg",
404+ ".mpga" => "audio/mpeg",
405+ ".m3u" => "audio/mpegurl",
406+ ".oga" => "audio/ogg",
407+ ".ogg" => "audio/ogg",
408+ ".opus" => "audio/ogg",
409+ ".spx" => "audio/ogg",
410+ ".sid" => "audio/prs.sid",
411+ ".aif" => "audio/x-aiff",
412+ ".aifc" => "audio/x-aiff",
413+ ".aiff" => "audio/x-aiff",
414+ ".gsm" => "audio/x-gsm",
415+ ".wax" => "audio/x-ms-wax",
416+ ".wma" => "audio/x-ms-wma",
417+ ".ra" => "audio/x-realaudio",
418+ ".ram" => "audio/x-realaudio",
419+ ".rm" => "audio/x-realaudio",
420+ ".pls" => "audio/x-scpls",
421+ ".sd2" => "audio/x-sd2",
422+ ".wav" => "audio/x-wav",
423+ ".alc" => "chemical/x-alchemy",
424+ ".cac" => "chemical/x-cache",
425+ ".cache" => "chemical/x-cache",
426+ ".csf" => "chemical/x-cache-csf",
427+ ".cascii" => "chemical/x-cactvs-binary",
428+ ".cbin" => "chemical/x-cactvs-binary",
429+ ".ctab" => "chemical/x-cactvs-binary",
430+ ".cdx" => "chemical/x-cdx",
431+ ".cer" => "chemical/x-cerius",
432+ ".c3d" => "chemical/x-chem3d",
433+ ".chm" => "chemical/x-chemdraw",
434+ ".cif" => "chemical/x-cif",
435+ ".cmdf" => "chemical/x-cmdf",
436+ ".cml" => "chemical/x-cml",
437+ ".cpa" => "chemical/x-compass",
438+ ".bsd" => "chemical/x-crossfire",
439+ ".csm" => "chemical/x-csml",
440+ ".csml" => "chemical/x-csml",
441+ ".ctx" => "chemical/x-ctx",
442+ ".cef" => "chemical/x-cxf",
443+ ".cxf" => "chemical/x-cxf",
444+ ".emb" => "chemical/x-embl-dl-nucleotide",
445+ ".embl" => "chemical/x-embl-dl-nucleotide",
446+ ".spc" => "chemical/x-galactic-spc",
447+ ".gam" => "chemical/x-gamess-input",
448+ ".gamin" => "chemical/x-gamess-input",
449+ ".inp" => "chemical/x-gamess-input",
450+ ".fch" => "chemical/x-gaussian-checkpoint",
451+ ".fchk" => "chemical/x-gaussian-checkpoint",
452+ ".cub" => "chemical/x-gaussian-cube",
453+ ".gau" => "chemical/x-gaussian-input",
454+ ".gjc" => "chemical/x-gaussian-input",
455+ ".gjf" => "chemical/x-gaussian-input",
456+ ".gal" => "chemical/x-gaussian-log",
457+ ".gcg" => "chemical/x-gcg8-sequence",
458+ ".gen" => "chemical/x-genbank",
459+ ".hin" => "chemical/x-hin",
460+ ".ist" => "chemical/x-isostar",
461+ ".istr" => "chemical/x-isostar",
462+ ".dx" => "chemical/x-jcamp-dx",
463+ ".jdx" => "chemical/x-jcamp-dx",
464+ ".kin" => "chemical/x-kinemage",
465+ ".mcm" => "chemical/x-macmolecule",
466+ ".mmd" => "chemical/x-macromodel-input",
467+ ".mmod" => "chemical/x-macromodel-input",
468+ ".mol" => "chemical/x-mdl-molfile",
469+ ".rd" => "chemical/x-mdl-rdfile",
470+ ".rxn" => "chemical/x-mdl-rxnfile",
471+ ".sd" => "chemical/x-mdl-sdfile",
472+ ".tgf" => "chemical/x-mdl-tgf",
473+ ".mcif" => "chemical/x-mmcif",
474+ ".mol2" => "chemical/x-mol2",
475+ ".gpt" => "chemical/x-mopac-graph",
476+ ".mop" => "chemical/x-mopac-input",
477+ ".mopcrt" => "chemical/x-mopac-input",
478+ ".mpc" => "chemical/x-mopac-input",
479+ ".zmt" => "chemical/x-mopac-input",
480+ ".moo" => "chemical/x-mopac-out",
481+ ".mvb" => "chemical/x-mopac-vib",
482+ ".prt" => "chemical/x-ncbi-asn1-ascii",
483+ ".aso" => "chemical/x-ncbi-asn1-binary",
484+ ".val" => "chemical/x-ncbi-asn1-binary",
485+ ".pdb" => "chemical/x-pdb",
486+ ".ros" => "chemical/x-rosdal",
487+ ".sw" => "chemical/x-swissprot",
488+ ".vms" => "chemical/x-vamas-iso14976",
489+ ".vmd" => "chemical/x-vmd",
490+ ".xtel" => "chemical/x-xtel",
491+ ".xyz" => "chemical/x-xyz",
492+ ".gif" => "image/gif",
493+ ".ief" => "image/ief",
494+ ".jp2" => "image/jp2",
495+ ".jpg2" => "image/jp2",
496+ ".jpe" => "image/jpeg",
497+ ".jpeg" => "image/jpeg",
498+ ".jpg" => "image/jpeg",
499+ ".jpm" => "image/jpm",
500+ ".jpf" => "image/jpx",
501+ ".jpx" => "image/jpx",
502+ ".pcx" => "image/pcx",
503+ ".png" => "image/png",
504+ ".svg" => "image/svg+xml",
505+ ".svgz" => "image/svg+xml",
506+ ".tif" => "image/tiff",
507+ ".tiff" => "image/tiff",
508+ ".djv" => "image/vnd.djvu",
509+ ".djvu" => "image/vnd.djvu",
510+ ".ico" => "image/vnd.microsoft.icon",
511+ ".wbmp" => "image/vnd.wap.wbmp",
512+ ".cr2" => "image/x-canon-cr2",
513+ ".crw" => "image/x-canon-crw",
514+ ".ras" => "image/x-cmu-raster",
515+ ".cdr" => "image/x-coreldraw",
516+ ".pat" => "image/x-coreldrawpattern",
517+ ".cdt" => "image/x-coreldrawtemplate",
518+ ".erf" => "image/x-epson-erf",
519+ ".art" => "image/x-jg",
520+ ".jng" => "image/x-jng",
521+ ".bmp" => "image/x-ms-bmp",
522+ ".nef" => "image/x-nikon-nef",
523+ ".orf" => "image/x-olympus-orf",
524+ ".psd" => "image/x-photoshop",
525+ ".pnm" => "image/x-portable-anymap",
526+ ".pbm" => "image/x-portable-bitmap",
527+ ".pgm" => "image/x-portable-graymap",
528+ ".ppm" => "image/x-portable-pixmap",
529+ ".rgb" => "image/x-rgb",
530+ ".xbm" => "image/x-xbitmap",
531+ ".xpm" => "image/x-xpixmap",
532+ ".xwd" => "image/x-xwindowdump",
533+ ".eml" => "message/rfc822",
534+ ".iges" => "model/iges",
535+ ".igs" => "model/iges",
536+ ".mesh" => "model/mesh",
537+ ".msh" => "model/mesh",
538+ ".silo" => "model/mesh",
539+ ".vrml" => "model/vrml",
540+ ".wrl" => "model/vrml",
541+ ".x3db" => "model/x3d+binary",
542+ ".x3dv" => "model/x3d+vrml",
543+ ".x3d" => "model/x3d+xml",
544+ ".appcache" => "text/cache-manifest",
545+ ".ics" => "text/calendar",
546+ ".icz" => "text/calendar",
547+ ".css" => "text/css; charset=utf-8",
548+ ".csv" => "text/csv; charset=utf-8",
549+ ".323" => "text/h323",
550+ ".htm" => "text/html",
551+ ".html" => "text/html",
552+ ".shtml" => "text/html",
553+ ".uls" => "text/iuls",
554+ ".mml" => "text/mathml",
555+ ".asc" => "text/plain; charset=utf-8",
556+ ".brf" => "text/plain; charset=utf-8",
557+ ".conf" => "text/plain; charset=utf-8",
558+ ".log" => "text/plain; charset=utf-8",
559+ ".pot" => "text/plain; charset=utf-8",
560+ ".spec" => "text/plain; charset=utf-8",
561+ ".srt" => "text/plain; charset=utf-8",
562+ ".text" => "text/plain; charset=utf-8",
563+ ".txt" => "text/plain; charset=utf-8",
564+ ".rtx" => "text/richtext",
565+ ".sct" => "text/scriptlet",
566+ ".wsc" => "text/scriptlet",
567+ ".tsv" => "text/tab-separated-values",
568+ ".tm" => "text/texmacs",
569+ ".ttl" => "text/turtle",
570+ ".jad" => "text/vnd.sun.j2me.app-descriptor",
571+ ".wml" => "text/vnd.wap.wml",
572+ ".wmls" => "text/vnd.wap.wmlscript",
573+ ".bib" => "text/x-bibtex; charset=utf-8",
574+ ".boo" => "text/x-boo; charset=utf-8",
575+ ".h++" => "text/x-c++hdr; charset=utf-8",
576+ ".hh" => "text/x-c++hdr; charset=utf-8",
577+ ".hpp" => "text/x-c++hdr; charset=utf-8",
578+ ".hxx" => "text/x-c++hdr; charset=utf-8",
579+ ".c++" => "text/x-c++src; charset=utf-8",
580+ ".cc" => "text/x-c++src; charset=utf-8",
581+ ".cpp" => "text/x-c++src; charset=utf-8",
582+ ".cxx" => "text/x-c++src; charset=utf-8",
583+ ".h" => "text/x-chdr; charset=utf-8",
584+ ".htc" => "text/x-component",
585+ ".csh" => "text/x-csh; charset=utf-8",
586+ ".c" => "text/x-csrc; charset=utf-8",
587+ ".diff" => "text/x-diff; charset=utf-8",
588+ ".patch" => "text/x-diff; charset=utf-8",
589+ ".d" => "text/x-dsrc; charset=utf-8",
590+ ".hs" => "text/x-haskell; charset=utf-8",
591+ ".java" => "text/x-java; charset=utf-8",
592+ ".ly" => "text/x-lilypond; charset=utf-8",
593+ ".lhs" => "text/x-literate-haskell; charset=utf-8",
594+ ".moc" => "text/x-moc; charset=utf-8",
595+ ".p" => "text/x-pascal; charset=utf-8",
596+ ".pas" => "text/x-pascal; charset=utf-8",
597+ ".gcd" => "text/x-pcs-gcd",
598+ ".pl" => "text/x-perl; charset=utf-8",
599+ ".pm" => "text/x-perl; charset=utf-8",
600+ ".py" => "text/x-python; charset=utf-8",
601+ ".scala" => "text/x-scala; charset=utf-8",
602+ ".etx" => "text/x-setext",
603+ ".sfv" => "text/x-sfv",
604+ ".sh" => "text/x-sh; charset=utf-8",
605+ ".tcl" => "text/x-tcl; charset=utf-8",
606+ ".tk" => "text/x-tcl; charset=utf-8",
607+ ".cls" => "text/x-tex; charset=utf-8",
608+ ".ltx" => "text/x-tex; charset=utf-8",
609+ ".sty" => "text/x-tex; charset=utf-8",
610+ ".tex" => "text/x-tex; charset=utf-8",
611+ ".vcs" => "text/x-vcalendar",
612+ ".vcf" => "text/x-vcard",
613+ ".3gp" => "video/3gpp",
614+ ".axv" => "video/annodex",
615+ ".dl" => "video/dl",
616+ ".dif" => "video/dv",
617+ ".dv" => "video/dv",
618+ ".fli" => "video/fli",
619+ ".gl" => "video/gl",
620+ ".mp4" => "video/mp4",
621+ ".mpe" => "video/mpeg",
622+ ".mpeg" => "video/mpeg",
623+ ".mpg" => "video/mpeg",
624+ ".ogv" => "video/ogg",
625+ ".mov" => "video/quicktime",
626+ ".qt" => "video/quicktime",
627+ ".webm" => "video/webm",
628+ ".mxu" => "video/vnd.mpegurl",
629+ ".flv" => "video/x-flv",
630+ ".lsf" => "video/x-la-asf",
631+ ".lsx" => "video/x-la-asf",
632+ ".mkv" => "video/x-matroska",
633+ ".mpv" => "video/x-matroska",
634+ ".mng" => "video/x-mng",
635+ ".asf" => "video/x-ms-asf",
636+ ".asx" => "video/x-ms-asf",
637+ ".wm" => "video/x-ms-wm",
638+ ".wmv" => "video/x-ms-wmv",
639+ ".wmx" => "video/x-ms-wmx",
640+ ".wvx" => "video/x-ms-wvx",
641+ ".avi" => "video/x-msvideo",
642+ ".movie" => "video/x-sgi-movie",
643+ ".ice" => "x-conference/x-cooltalk",
644+ ".sisx" => "x-epoc/x-sisx-app",
645+ ".vrm" => "x-world/x-vrml",
646+ "README" => "text/plain; charset=utf-8",
647+ "Makefile" => "text/x-makefile; charset=utf-8",
648
649+ # enable caching for unknown mime types:
650+ "" => "application/octet-stream"
651+)
652diff --git a/doc/scripts/create-mime.conf.pl b/doc/scripts/create-mime.conf.pl
653new file mode 100755
654index 0000000..7c9e378
655--- /dev/null
656+++ b/doc/scripts/create-mime.conf.pl
657@@ -0,0 +1,197 @@
658+#!/usr/bin/perl -w
659+
660+# Based on create-mime.assign.pl in debian lighttpd (1.4.x) package
661+# Creates an example mime.conf from /etc/mime.types
662+
663+use strict;
664+
665+# text/* subtypes to serve as "text/...; charset=utf-8"
666+# text/html IS NOT INCLUDED: html has its own method for defining charset
667+# (<meta>), but the standards specify that content-type in HTTP wins over
668+# the setting in the html document.
669+my %text_utf8 = map { $_ => 1 } qw(
670+ css
671+ csv
672+ plain
673+ x-bibtex
674+ x-boo
675+ x-c++hdr
676+ x-c++src
677+ x-chdr
678+ x-csh
679+ x-csrc
680+ x-dsrc
681+ x-diff
682+ x-haskell
683+ x-java
684+ x-lilypond
685+ x-literate-haskell
686+ x-makefile
687+ x-moc
688+ x-pascal
689+ x-perl
690+ x-python
691+ x-scala
692+ x-sh
693+ x-tcl
694+ x-tex
695+);
696+
697+# map extension to hash which maps types to the type they should be replaced with
698+my %manual_conflicts_resolve = (
699+ '.ra' => {
700+ 'audio/x-pn-realaudio' => 'audio/x-realaudio',
701+ },
702+);
703+
704+open MIMETYPES, "/etc/mime.types" or die "Can't open /etc/mime.types: $!";
705+
706+my %extensions;
707+sub set {
708+ my ($extension, $mimetype) = @_;
709+ $extensions{$extension} = $mimetype;
710+}
711+sub add {
712+ my ($extension, $mimetype) = @_;
713+ my $have = $extensions{$extension};
714+
715+ my $r = $manual_conflicts_resolve{$extension};
716+ # update @_ too for calls to set
717+ $_[1] = $mimetype = $r->{$mimetype} if $r && $r->{$mimetype};
718+
719+ # mime.types can have same extension for different mime types
720+ if ($have) {
721+ # application/octet-stream means we couldn't resolve another conflict
722+ return if $have eq $mimetype || $have eq 'application/octet-stream';
723+
724+ my ($have_type, $have_subtype) = split /\//, $have, 2;
725+ my ($type, $subtype) = split /\//, $mimetype, 2;
726+
727+ my $have_x = ($have_type =~ /^x-/ || $have_subtype =~ /^x-/);
728+ my $x = ($type =~ /^x-/ || $subtype =~ /^x-/);
729+
730+ # entries without x- prefix in type/subtype win:
731+ if ($have_x && !$x) {
732+ return set @_; # overwrite
733+ } elsif ($x && !$have_x) {
734+ return; # ignore
735+ }
736+
737+ # text/ wins over application/ for same subtype
738+ if ($subtype eq $have_subtype) {
739+ if ($type eq "text" && $have_type eq "application") {
740+ return set @_; # overwrite
741+ } elsif ($have_type eq "text" && $type eq "application") {
742+ return; # ignore
743+ }
744+ }
745+
746+ print STDERR "Duplicate mimetype: '${extension}' => '${mimetype}' (already have '${have}'), merging to 'application/octet-stream'\n";
747+ set ($extension, 'application/octet-stream');
748+ } else {
749+ set @_;
750+ }
751+}
752+
753+sub print_type {
754+ my ($extension, $mimetype) = @_;
755+ if ($mimetype =~ /^text\/(.*)$/) {
756+ $mimetype .= "; charset=utf-8" if $text_utf8{$1};
757+ }
758+
759+ print "\t\"${extension}\" => \"${mimetype}\",\n";
760+}
761+
762+while (<MIMETYPES>) {
763+ chomp;
764+ s/\#.*//;
765+ next if /^\w*$/;
766+ if (/^([a-z0-9\/+-.]+)\s+((?:[a-z0-9.+-]+[ ]?)+)$/) {
767+ my $mimetype = $1;
768+ my @extensions = split / /, $2;
769+
770+ foreach my $ext (@extensions) {
771+ add(".${ext}", $mimetype);
772+ }
773+ }
774+}
775+
776+# missing in /etc/mime.types;
777+# from http://www.iana.org/assignments/media-types/media-types.xhtml
778+add(".dtd", "application/xml-dtd");
779+
780+# other useful mappings
781+my %useful = (
782+ ".tar.gz" => "application/x-gtar-compressed",
783+ ".gz" => "application/x-gzip",
784+ ".tbz" => "application/x-gtar-compressed",
785+ ".tar.bz2" => "application/x-gtar-compressed",
786+ ".bz2" => "application/x-bzip",
787+ ".log" => "text/plain",
788+ ".conf" => "text/plain",
789+ ".spec" => "text/plain",
790+ "README" => "text/plain",
791+ "Makefile" => "text/x-makefile",
792+);
793+
794+while (my ($ext, $mimetype) = each %useful) {
795+ add($ext, $mimetype) unless $extensions{$ext};
796+}
797+
798+
799+print <<EOF;
800+# created by create-mime.conf.pl
801+
802+#######################################################################
803+##
804+## MimeType handling
805+## -------------------
806+##
807+## https://redmine.lighttpd.net/projects/lighttpd/wiki/Mimetype_assignDetails
808+
809+##
810+## Use the "Content-Type" extended file attribute to obtain mime type if
811+## possible
812+##
813+## Disabled by default
814+##
815+#mimetype.use-xattr = "enable"
816+
817+##
818+## mimetype ("Content-Type" HTTP header) mapping for static file handling
819+##
820+## The first matching suffix is used. If no mapping is found
821+## 'application/octet-stream' is used, and caching (etag/last-modified handling)
822+## is disabled to prevent clients from caching "unknown" mime types.
823+##
824+## Therefore the last mapping is:
825+## "" => "application/octet-stream"
826+## This matches all extensions and acts as default mime type, and enables
827+## caching for those.
828+mimetype.assign = (
829+EOF
830+
831+# sort "x-" and "vnd." prefixed names after everything else
832+sub mimecmpvalue {
833+ my ($mimetype) = @_;
834+ $mimetype =~ s/(^|\/)(x-|vnd\.)/~$1$2/g;
835+ return $mimetype;
836+}
837+sub countdots {
838+ my ($s) = @_;
839+ return scalar(() = $s =~ /\./g);
840+}
841+# the first matching suffix wins, so we have to sort by "length"
842+# as all extensions start with "." we use the number of "."s as length
843+# the exceptions are "README" and "Makefile" which are assumed not to conflict
844+# (i.e. are not a suffix of any other extension)
845+for my $ext (sort { countdots($b) <=> countdots($a) || mimecmpvalue($extensions{$a}) cmp mimecmpvalue($extensions{$b}) || $a cmp $b } keys(%extensions)) {
846+ print_type($ext, $extensions{$ext});
847+}
848+
849+print <<EOF;
850+
851+ # enable caching for unknown mime types:
852+ "" => "application/octet-stream"
853+)
854+EOF
855--
8562.4.5
857
diff --git a/main/lighttpd/0005-fix-typo-in-NEWS-entry-for-2579.patch b/main/lighttpd/0005-fix-typo-in-NEWS-entry-for-2579.patch
new file mode 100644
index 0000000000..9f252e5306
--- /dev/null
+++ b/main/lighttpd/0005-fix-typo-in-NEWS-entry-for-2579.patch
@@ -0,0 +1,31 @@
1From 059a5a67ddff848385773162f90d6477b450d391 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Tue, 13 May 2014 13:04:35 +0000
4Subject: [PATCH 05/29] fix typo in NEWS entry for #2579
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2965 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 NEWS | 2 +-
14 1 file changed, 1 insertion(+), 1 deletion(-)
15
16diff --git a/NEWS b/NEWS
17index 8c34545..0bf0313 100644
18--- a/NEWS
19+++ b/NEWS
20@@ -6,7 +6,7 @@ NEWS
21 - 1.4.36
22 * use keep-alive timeout while waiting for HTTP headers; use always the read timeout while waiting for the HTTP body
23 * fix bad shift in conditional netmask ".../0" handling
24- * add more mime types and a script to generate mime.conf (fxies #2579)
25+ * add more mime types and a script to generate mime.conf (fixes #2579)
26
27 - 1.4.35 - 2014-03-12
28 * [network/ssl] fix build error if TLSEXT is disabled
29--
302.4.5
31
diff --git a/main/lighttpd/0006-add-support-for-Free-BSD-extended-attributes.patch b/main/lighttpd/0006-add-support-for-Free-BSD-extended-attributes.patch
new file mode 100644
index 0000000000..f3affb9119
--- /dev/null
+++ b/main/lighttpd/0006-add-support-for-Free-BSD-extended-attributes.patch
@@ -0,0 +1,175 @@
1From 4d55d4ada3ebbdd6b99855fe0767d26490955a22 Mon Sep 17 00:00:00 2001
2From: Moritz Wilhelmy <mw@barfooze.de>
3Date: Thu, 22 May 2014 08:30:13 +0000
4Subject: [PATCH 06/29] add support for (Free)BSD extended attributes
5
6enable with `./configure --with-attr` and `mimetype.use-xattr =
7"enable"` in the config.
8
9set attribute with:
10
11 setextattr user Content-Type text/plain path/to/www/file
12
13From: Moritz Wilhelmy <mw@barfooze.de>
14
15git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2966 152afb58-edef-0310-8abb-c4023f1b3aa9
16---
17 NEWS | 1 +
18 configure.ac | 25 +++++++++++++++++--------
19 src/mod_dirlisting.c | 17 ++++++++++++++---
20 src/stat_cache.c | 21 +++++++++++++++++++--
21 4 files changed, 51 insertions(+), 13 deletions(-)
22
23diff --git a/NEWS b/NEWS
24index 0bf0313..84a1c80 100644
25--- a/NEWS
26+++ b/NEWS
27@@ -7,6 +7,7 @@ NEWS
28 * use keep-alive timeout while waiting for HTTP headers; use always the read timeout while waiting for the HTTP body
29 * fix bad shift in conditional netmask ".../0" handling
30 * add more mime types and a script to generate mime.conf (fixes #2579)
31+ * add support for (Free)BSD extended attributes
32
33 - 1.4.35 - 2014-03-12
34 * [network/ssl] fix build error if TLSEXT is disabled
35diff --git a/configure.ac b/configure.ac
36index ae35234..48e6b52 100644
37--- a/configure.ac
38+++ b/configure.ac
39@@ -218,14 +218,23 @@ AC_ARG_WITH(attr, AC_HELP_STRING([--with-attr],[enable extended attribute suppor
40 [WITH_ATTR=$withval],[WITH_ATTR=no])
41 AC_MSG_RESULT($withval)
42 if test "$WITH_ATTR" != "no"; then
43- AC_CHECK_LIB(attr, attr_get, [
44- AC_CHECK_HEADERS([attr/attributes.h],[
45- ATTR_LIB=-lattr
46- AC_DEFINE([HAVE_XATTR], [1], [libattr])
47- AC_DEFINE([HAVE_ATTR_ATTRIBUTES_H], [1])
48- ])
49- ])
50- AC_SUBST(ATTR_LIB)
51+ # libattr (linux only?)
52+ AC_CHECK_LIB(attr, attr_get, [
53+ AC_CHECK_HEADERS([attr/attributes.h],[
54+ ATTR_LIB=-lattr
55+ AC_DEFINE([HAVE_XATTR], [1], [libattr])
56+ AC_DEFINE([HAVE_ATTR_ATTRIBUTES_H], [1])
57+ ])
58+ ])
59+ AC_SUBST(ATTR_LIB)
60+
61+ # (Free)BSD extattr
62+ AC_CHECK_FUNC([extattr_get_file], [
63+ AC_CHECK_HEADERS([sys/extattr.h],[
64+ AC_DEFINE([HAVE_EXTATTR], [1], [BSD extended attributes])
65+ AC_DEFINE([HAVE_SYS_EXTATTR_H], [1])
66+ ])
67+ ])
68 fi
69
70 dnl openssl on solaris needs -lsocket -lnsl
71diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
72index cd5809e..6aba403 100644
73--- a/src/mod_dirlisting.c
74+++ b/src/mod_dirlisting.c
75@@ -31,6 +31,10 @@
76 #include <attr/attributes.h>
77 #endif
78
79+#ifdef HAVE_SYS_EXTATTR_H
80+#include <sys/extattr.h>
81+#endif
82+
83 #include "version.h"
84
85 /* plugin config for all request/connections */
86@@ -644,7 +648,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
87 size_t k;
88 const char *content_type;
89 long name_max;
90-#ifdef HAVE_XATTR
91+#if defined(HAVE_XATTR) || defined(HAVE_EXTATTR)
92 char attrval[128];
93 int attrlen;
94 #endif
95@@ -820,8 +824,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
96 tmp = files.ent[i];
97
98 content_type = NULL;
99-#ifdef HAVE_XATTR
100-
101+#if defined(HAVE_XATTR)
102 if (con->conf.use_xattr) {
103 memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
104 attrlen = sizeof(attrval) - 1;
105@@ -830,6 +833,14 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
106 content_type = attrval;
107 }
108 }
109+#elif defined(HAVE_EXTATTR)
110+ if (con->conf.use_xattr) {
111+ memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
112+ if(-1 != (attrlen = extattr_get_file(path, EXTATTR_NAMESPACE_USER, "Content-Type", attrval, sizeof(attrval)-1))) {
113+ attrval[attrlen] = '\0';
114+ content_type = attrval;
115+ }
116+ }
117 #endif
118
119 if (content_type == NULL) {
120diff --git a/src/stat_cache.c b/src/stat_cache.c
121index 480aae4..9007325 100644
122--- a/src/stat_cache.c
123+++ b/src/stat_cache.c
124@@ -18,6 +18,10 @@
125 # include <attr/attributes.h>
126 #endif
127
128+#ifdef HAVE_SYS_EXTATTR_H
129+# include <sys/extattr.h>
130+#endif
131+
132 #ifdef HAVE_FAM_H
133 # include <fam.h>
134 #endif
135@@ -210,7 +214,7 @@ void stat_cache_free(stat_cache *sc) {
136 free(sc);
137 }
138
139-#ifdef HAVE_XATTR
140+#if defined(HAVE_XATTR)
141 static int stat_cache_attr_get(buffer *buf, char *name) {
142 int attrlen;
143 int ret;
144@@ -224,6 +228,19 @@ static int stat_cache_attr_get(buffer *buf, char *name) {
145 }
146 return ret;
147 }
148+#elif defined(HAVE_EXTATTR)
149+static int stat_cache_attr_get(buffer *buf, char *name) {
150+ ssize_t attrlen = 1024;
151+
152+ buffer_prepare_copy(buf, attrlen);
153+
154+ if (-1 != (attrlen = extattr_get_file(name, EXTATTR_NAMESPACE_USER, "Content-Type", buf->ptr, attrlen-1))) {
155+ buf->used = attrlen + 1;
156+ buf->ptr[attrlen] = '\0';
157+ return 0;
158+ }
159+ return -1;
160+}
161 #endif
162
163 /* the famous DJB hash function for strings */
164@@ -592,7 +609,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
165 if (S_ISREG(st.st_mode)) {
166 /* determine mimetype */
167 buffer_reset(sce->content_type);
168-#ifdef HAVE_XATTR
169+#if defined(HAVE_XATTR) || defined(HAVE_EXTATTR)
170 if (con->conf.use_xattr) {
171 stat_cache_attr_get(sce->content_type, name->ptr);
172 }
173--
1742.4.5
175
diff --git a/main/lighttpd/0007-build-use-fortify-flags-with-extra-warnings.patch b/main/lighttpd/0007-build-use-fortify-flags-with-extra-warnings.patch
new file mode 100644
index 0000000000..13db16ac19
--- /dev/null
+++ b/main/lighttpd/0007-build-use-fortify-flags-with-extra-warnings.patch
@@ -0,0 +1,88 @@
1From c4f214584aeaa30214d5364ef8bc2171dbd7bb3c Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Thu, 16 Oct 2014 17:52:10 +0000
4Subject: [PATCH 07/29] [build] use fortify flags with "extra-warnings"
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2967 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 NEWS | 1 +
14 configure.ac | 27 ++++++++++++++++++++++++---
15 src/CMakeLists.txt | 2 +-
16 3 files changed, 26 insertions(+), 4 deletions(-)
17
18diff --git a/NEWS b/NEWS
19index 84a1c80..115e638 100644
20--- a/NEWS
21+++ b/NEWS
22@@ -8,6 +8,7 @@ NEWS
23 * fix bad shift in conditional netmask ".../0" handling
24 * add more mime types and a script to generate mime.conf (fixes #2579)
25 * add support for (Free)BSD extended attributes
26+ * [build] use fortify flags with "extra-warnings"
27
28 - 1.4.35 - 2014-03-12
29 * [network/ssl] fix build error if TLSEXT is disabled
30diff --git a/configure.ac b/configure.ac
31index 48e6b52..e804030 100644
32--- a/configure.ac
33+++ b/configure.ac
34@@ -23,6 +23,26 @@ AM_INIT_AUTOMAKE([-Wall -Wno-portability -Wno-override foreign dist-bzip2 tar-us
35 dnl enable with --enable-silent-rules or make V=0 (needs automake >= 1.11)
36 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
37
38+
39+dnl @synopsis TRY_CFLAGS [compiler flags]
40+dnl @summary check whether compiler supports given C flags and adds them to CFLAGS
41+AC_DEFUN([TRY_CFLAGS],
42+[dnl
43+ AC_MSG_CHECKING([if $CC supports $1])
44+ AC_LANG_PUSH([C])
45+ ac_try_cflags_saved_cflags="${CFLAGS}"
46+ CFLAGS="${CFLAGS} $1"
47+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
48+ [AC_MSG_RESULT([yes])],
49+ [
50+ AC_MSG_ERROR([no])
51+ CFLAGS="${ac_try_cflags_saved_cflags}"
52+ ]
53+ )
54+ AC_LANG_POP([C])
55+])
56+
57+
58 dnl Checks for programs.
59 AC_PROG_CC
60 AM_PROG_CC_C_O
61@@ -394,7 +414,7 @@ if test "$WITH_FAM" != "no"; then
62 LIBS=$FAM_LIBS
63 AC_CHECK_FUNCS([FAMNoExists])
64 LIBS=$OLD_LIBS
65-
66+
67 if test x$FAM_LIBS = x; then
68 AC_MSG_ERROR([fam/gamin-headers and/or libs where not found, install them or build with --without-fam])
69 fi
70@@ -622,7 +642,8 @@ AM_CONDITIONAL(CHECK_WITH_FASTCGI, test "x$fastcgi_found" = xyes)
71
72 dnl check for extra compiler options (warning options)
73 if test "${GCC}" = "yes"; then
74- CFLAGS="${CFLAGS} -Wall -W -Wshadow -pedantic -std=gnu99"
75+ TRY_CFLAGS([-Wall -W -Wshadow -pedantic])
76+ TRY_CFLAGS([-std=gnu99])
77 fi
78
79 AC_ARG_ENABLE(extra-warnings,
80@@ -634,7 +655,7 @@ AC_ARG_ENABLE(extra-warnings,
81 esac],[extrawarnings=false])
82
83 if test x$extrawarnings = xtrue; then
84- CFLAGS="${CFLAGS} -g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wno-pointer-sign -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -Wformat-security"
85+ TRY_CFLAGS([-g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security])
86 fi
87
88 dnl build version-id
diff --git a/main/lighttpd/0008-mod_dirlisting-mod_redirect-mod_rewrite-abort-config.patch b/main/lighttpd/0008-mod_dirlisting-mod_redirect-mod_rewrite-abort-config.patch
new file mode 100644
index 0000000000..637f1721d0
--- /dev/null
+++ b/main/lighttpd/0008-mod_dirlisting-mod_redirect-mod_rewrite-abort-config.patch
@@ -0,0 +1,163 @@
1From 4a6838103d8a6de025dcce1adfa6f508f17b3c16 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Thu, 16 Oct 2014 17:52:12 +0000
4Subject: [PATCH 08/29] [mod_dirlisting,mod_redirect,mod_rewrite] abort config
5 parsing if pcre-compile fails or isn't available
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10From: Stefan Bühler <stbuehler@web.de>
11
12git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2968 152afb58-edef-0310-8abb-c4023f1b3aa9
13---
14 NEWS | 1 +
15 src/mod_dirlisting.c | 80 +++++++++++++++++++++++++---------------------------
16 src/mod_redirect.c | 1 +
17 src/mod_rewrite.c | 1 +
18 4 files changed, 41 insertions(+), 42 deletions(-)
19
20diff --git a/NEWS b/NEWS
21index 115e638..7260fc5 100644
22--- a/NEWS
23+++ b/NEWS
24@@ -9,6 +9,7 @@ NEWS
25 * add more mime types and a script to generate mime.conf (fixes #2579)
26 * add support for (Free)BSD extended attributes
27 * [build] use fortify flags with "extra-warnings"
28+ * [mod_dirlisting,mod_redirect,mod_rewrite] abort config parsing if pcre-compile fails or isn't available
29
30 - 1.4.35 - 2014-03-12
31 * [network/ssl] fix build error if TLSEXT is disabled
32diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
33index 6aba403..6a2b139 100644
34--- a/src/mod_dirlisting.c
35+++ b/src/mod_dirlisting.c
36@@ -198,47 +198,6 @@ FREE_FUNC(mod_dirlisting_free) {
37 return HANDLER_GO_ON;
38 }
39
40-static int parse_config_entry(server *srv, plugin_config *s, array *ca, const char *option) {
41- data_unset *du;
42-
43- if (NULL != (du = array_get_element(ca, option))) {
44- data_array *da;
45- size_t j;
46-
47- if (du->type != TYPE_ARRAY) {
48- log_error_write(srv, __FILE__, __LINE__, "sss",
49- "unexpected type for key: ", option, "array of strings");
50-
51- return HANDLER_ERROR;
52- }
53-
54- da = (data_array *)du;
55-
56- for (j = 0; j < da->value->used; j++) {
57- if (da->value->data[j]->type != TYPE_STRING) {
58- log_error_write(srv, __FILE__, __LINE__, "sssbs",
59- "unexpected type for key: ", option, "[",
60- da->value->data[j]->key, "](string)");
61-
62- return HANDLER_ERROR;
63- }
64-
65- if (0 != excludes_buffer_append(s->excludes,
66- ((data_string *)(da->value->data[j]))->value)) {
67-#ifdef HAVE_PCRE_H
68- log_error_write(srv, __FILE__, __LINE__, "sb",
69- "pcre-compile failed for", ((data_string *)(da->value->data[j]))->value);
70-#else
71- log_error_write(srv, __FILE__, __LINE__, "s",
72- "pcre support is missing, please install libpcre and the headers");
73-#endif
74- }
75- }
76- }
77-
78- return 0;
79-}
80-
81 /* handle plugin config and check values */
82
83 #define CONFIG_EXCLUDE "dir-listing.exclude"
84@@ -287,6 +246,7 @@ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
85 for (i = 0; i < srv->config_context->used; i++) {
86 plugin_config *s;
87 array *ca;
88+ data_unset *du_excludes;
89
90 s = calloc(1, sizeof(plugin_config));
91 s->excludes = excludes_buffer_init();
92@@ -326,7 +286,43 @@ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
93 return HANDLER_ERROR;
94 }
95
96- parse_config_entry(srv, s, ca, CONFIG_EXCLUDE);
97+ if (NULL != (du_excludes = array_get_element(ca, CONFIG_EXCLUDE))) {
98+ array *excludes_list;
99+ size_t j;
100+
101+ if (du_excludes->type != TYPE_ARRAY) {
102+ log_error_write(srv, __FILE__, __LINE__, "sss",
103+ "unexpected type for key: ", CONFIG_EXCLUDE, "array of strings");
104+ return HANDLER_ERROR;
105+ }
106+
107+ excludes_list = ((data_array*)du_excludes)->value;
108+
109+#ifndef HAVE_PCRE_H
110+ if (excludes_list->used > 0) {
111+ log_error_write(srv, __FILE__, __LINE__, "sss",
112+ "pcre support is missing for: ", CONFIG_EXCLUDE, ", please install libpcre and the headers");
113+ return HANDLER_ERROR;
114+ }
115+#else
116+ for (j = 0; j < excludes_list->used; j++) {
117+ data_unset *du_exclude = excludes_list->data[j];
118+
119+ if (du_exclude->type != TYPE_STRING) {
120+ log_error_write(srv, __FILE__, __LINE__, "sssbs",
121+ "unexpected type for key: ", CONFIG_EXCLUDE, "[",
122+ du_exclude->key, "](string)");
123+ return HANDLER_ERROR;
124+ }
125+
126+ if (0 != excludes_buffer_append(s->excludes, ((data_string*)(du_exclude))->value)) {
127+ log_error_write(srv, __FILE__, __LINE__, "sb",
128+ "pcre-compile failed for", ((data_string*)(du_exclude))->value);
129+ return HANDLER_ERROR;
130+ }
131+ }
132+#endif
133+ }
134 }
135
136 return HANDLER_GO_ON;
137diff --git a/src/mod_redirect.c b/src/mod_redirect.c
138index 3fdb4e3..bfc00d7 100644
139--- a/src/mod_redirect.c
140+++ b/src/mod_redirect.c
141@@ -129,6 +129,7 @@ SETDEFAULTS_FUNC(mod_redirect_set_defaults) {
142
143 log_error_write(srv, __FILE__, __LINE__, "sb",
144 "pcre-compile failed for", da->value->data[j]->key);
145+ return HANDLER_ERROR;
146 }
147 }
148 }
149diff --git a/src/mod_rewrite.c b/src/mod_rewrite.c
150index 988dfd7..381f0ed 100644
151--- a/src/mod_rewrite.c
152+++ b/src/mod_rewrite.c
153@@ -191,6 +191,7 @@ static int parse_config_entry(server *srv, array *ca, rewrite_rule_buffer *kvb,
154 once)) {
155 log_error_write(srv, __FILE__, __LINE__, "sb",
156 "pcre-compile failed for", da->value->data[j]->key);
157+ return HANDLER_ERROR;
158 }
159 }
160 }
161--
1622.4.5
163
diff --git a/main/lighttpd/0009-ssl-disable-SSL3.0-by-default.patch b/main/lighttpd/0009-ssl-disable-SSL3.0-by-default.patch
new file mode 100644
index 0000000000..6980a19497
--- /dev/null
+++ b/main/lighttpd/0009-ssl-disable-SSL3.0-by-default.patch
@@ -0,0 +1,44 @@
1From 084df7e99a8738be79f83e330415a8963280dc4a Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Thu, 16 Oct 2014 17:52:14 +0000
4Subject: [PATCH 09/29] [ssl] disable SSL3.0 by default
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2969 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 NEWS | 1 +
14 src/configfile.c | 2 +-
15 2 files changed, 2 insertions(+), 1 deletion(-)
16
17diff --git a/NEWS b/NEWS
18index 7260fc5..a702941 100644
19--- a/NEWS
20+++ b/NEWS
21@@ -10,6 +10,7 @@ NEWS
22 * add support for (Free)BSD extended attributes
23 * [build] use fortify flags with "extra-warnings"
24 * [mod_dirlisting,mod_redirect,mod_rewrite] abort config parsing if pcre-compile fails or isn't available
25+ * [ssl] disable SSL3.0 by default
26
27 - 1.4.35 - 2014-03-12
28 * [network/ssl] fix build error if TLSEXT is disabled
29diff --git a/src/configfile.c b/src/configfile.c
30index 1e96ce0..bf9a34d 100644
31--- a/src/configfile.c
32+++ b/src/configfile.c
33@@ -182,7 +182,7 @@ static int config_insert(server *srv) {
34 s->ssl_honor_cipher_order = 1;
35 s->ssl_empty_fragments = 0;
36 s->ssl_use_sslv2 = 0;
37- s->ssl_use_sslv3 = 1;
38+ s->ssl_use_sslv3 = 0;
39 s->use_ipv6 = 0;
40 s->set_v6only = 1;
41 s->defer_accept = 0;
42--
432.4.5
44
diff --git a/main/lighttpd/0010-Fixed-typo-found-by-openSUSE-user-boo-907709.patch b/main/lighttpd/0010-Fixed-typo-found-by-openSUSE-user-boo-907709.patch
new file mode 100644
index 0000000000..9f95d3ee41
--- /dev/null
+++ b/main/lighttpd/0010-Fixed-typo-found-by-openSUSE-user-boo-907709.patch
@@ -0,0 +1,38 @@
1From e1aab1c420e8d291299d1024e1c3450d85bec772 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Marcus=20R=C3=BCckert?= <darix@opensu.se>
3Date: Thu, 5 Feb 2015 15:29:01 +0000
4Subject: [PATCH 10/29] Fixed typo found by openSUSE user (boo# 907709)
5
6git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2970 152afb58-edef-0310-8abb-c4023f1b3aa9
7---
8 doc/config/vhosts.d/vhosts.template | 6 +++---
9 1 file changed, 3 insertions(+), 3 deletions(-)
10
11diff --git a/doc/config/vhosts.d/vhosts.template b/doc/config/vhosts.d/vhosts.template
12index 2c443aa..efd441f 100644
13--- a/doc/config/vhosts.d/vhosts.template
14+++ b/doc/config/vhosts.d/vhosts.template
15@@ -8,17 +8,17 @@ $HTTP["host"] == "download.example.com" {
16 var.server_name = "download.example.com"
17
18 server.name = server_name
19- ##
20+ ## example how to include another config:
21 ## use trigger before download
22 ##
23- include "conf.d/trigger_b4_dl.conf"
24+ # include "conf.d/trigger_b4_dl.conf"
25
26 server.document-root = vhosts_dir + "/example.com/download/htdocs"
27 ##
28 ## use a seperate access log file
29 ## At the moment you cant have different error log files.
30 ##
31- accesslog.filename = log_root + "/" + server_name "/access.log"
32+ accesslog.filename = log_root + "/" + server_name + "/access.log"
33 }
34
35 $SERVER["socket"] == "127.0.0.1:443" {
36--
372.4.5
38
diff --git a/main/lighttpd/0011-add-NEWS-entry-for-previous-commit.patch b/main/lighttpd/0011-add-NEWS-entry-for-previous-commit.patch
new file mode 100644
index 0000000000..791eafaf90
--- /dev/null
+++ b/main/lighttpd/0011-add-NEWS-entry-for-previous-commit.patch
@@ -0,0 +1,30 @@
1From 76870cfef1ae3a39c792ce9839e6191e0696c1cb Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sat, 7 Feb 2015 11:33:28 +0000
4Subject: [PATCH 11/29] add NEWS entry for previous commit
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2971 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 NEWS | 1 +
14 1 file changed, 1 insertion(+)
15
16diff --git a/NEWS b/NEWS
17index a702941..7347012 100644
18--- a/NEWS
19+++ b/NEWS
20@@ -11,6 +11,7 @@ NEWS
21 * [build] use fortify flags with "extra-warnings"
22 * [mod_dirlisting,mod_redirect,mod_rewrite] abort config parsing if pcre-compile fails or isn't available
23 * [ssl] disable SSL3.0 by default
24+ * fixed typo in example config found by openSUSE user (boo# 907709)
25
26 - 1.4.35 - 2014-03-12
27 * [network/ssl] fix build error if TLSEXT is disabled
28--
292.4.5
30
diff --git a/main/lighttpd/0012-network-fix-compile-break-in-calculation-of-sockaddr.patch b/main/lighttpd/0012-network-fix-compile-break-in-calculation-of-sockaddr.patch
new file mode 100644
index 0000000000..9aa38e537d
--- /dev/null
+++ b/main/lighttpd/0012-network-fix-compile-break-in-calculation-of-sockaddr.patch
@@ -0,0 +1,66 @@
1From b0a632f253737463138c182a3fb9c8be04caef5d Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sat, 7 Feb 2015 11:33:30 +0000
4Subject: [PATCH 12/29] [network] fix compile break in calculation of
5 sockaddr_un size if SUN_LEN is not defined (fixes #2609)
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10From: Stefan Bühler <stbuehler@web.de>
11
12git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2972 152afb58-edef-0310-8abb-c4023f1b3aa9
13---
14 NEWS | 1 +
15 src/network.c | 13 +++++++------
16 2 files changed, 8 insertions(+), 6 deletions(-)
17
18diff --git a/NEWS b/NEWS
19index 7347012..bf8984f 100644
20--- a/NEWS
21+++ b/NEWS
22@@ -12,6 +12,7 @@ NEWS
23 * [mod_dirlisting,mod_redirect,mod_rewrite] abort config parsing if pcre-compile fails or isn't available
24 * [ssl] disable SSL3.0 by default
25 * fixed typo in example config found by openSUSE user (boo# 907709)
26+ * [network] fix compile break in calculation of sockaddr_un size if SUN_LEN is not defined (fixes #2609)
27
28 - 1.4.35 - 2014-03-12
29 * [network/ssl] fix build error if TLSEXT is disabled
30diff --git a/src/network.c b/src/network.c
31index ebde43b..776a86c 100644
32--- a/src/network.c
33+++ b/src/network.c
34@@ -349,6 +349,8 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
35
36 break;
37 case AF_UNIX:
38+ memset(&srv_socket->addr, 0, sizeof(struct sockaddr_un));
39+ srv_socket->addr.un.sun_family = AF_UNIX;
40 {
41 size_t hostlen = strlen(host) + 1;
42 if (hostlen > sizeof(srv_socket->addr.un.sun_path)) {
43@@ -356,15 +358,14 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
44 goto error_free_socket;
45 }
46 memcpy(srv_socket->addr.un.sun_path, host, hostlen);
47- }
48- srv_socket->addr.un.sun_family = AF_UNIX;
49
50-#ifdef SUN_LEN
51- addr_len = SUN_LEN(&srv_socket->addr.un);
52+#if defined(SUN_LEN)
53+ addr_len = SUN_LEN(&srv_socket->addr.un);
54 #else
55- /* stevens says: */
56- addr_len = hostlen + sizeof(srv_socket->addr.un.sun_family);
57+ /* stevens says: */
58+ addr_len = hostlen + sizeof(srv_socket->addr.un.sun_family);
59 #endif
60+ }
61
62 /* check if the socket exists and try to connect to it. */
63 if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
64--
652.4.5
66
diff --git a/main/lighttpd/0013-connections-fix-bug-in-connection-state-handling.patch b/main/lighttpd/0013-connections-fix-bug-in-connection-state-handling.patch
new file mode 100644
index 0000000000..1567759899
--- /dev/null
+++ b/main/lighttpd/0013-connections-fix-bug-in-connection-state-handling.patch
@@ -0,0 +1,69 @@
1From d00e1e79b94e0f4da35292d2293595dac02993c7 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sat, 7 Feb 2015 13:32:54 +0000
4Subject: [PATCH 13/29] [connections] fix bug in connection state handling
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9 if a request was finished (con->file_finished = 1) and the state
10 machine was triggered, but the write queue was empty, it didn't
11 actually finish the request.
12
13From: Stefan Bühler <stbuehler@web.de>
14
15git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2973 152afb58-edef-0310-8abb-c4023f1b3aa9
16---
17 NEWS | 1 +
18 src/connections.c | 22 +++++++++-------------
19 2 files changed, 10 insertions(+), 13 deletions(-)
20
21diff --git a/NEWS b/NEWS
22index bf8984f..9c579de 100644
23--- a/NEWS
24+++ b/NEWS
25@@ -13,6 +13,7 @@ NEWS
26 * [ssl] disable SSL3.0 by default
27 * fixed typo in example config found by openSUSE user (boo# 907709)
28 * [network] fix compile break in calculation of sockaddr_un size if SUN_LEN is not defined (fixes #2609)
29+ * [connections] fix bug in connection state handling
30
31 - 1.4.35 - 2014-03-12
32 * [network/ssl] fix build error if TLSEXT is disabled
33diff --git a/src/connections.c b/src/connections.c
34index bbaa632..fe683a2 100644
35--- a/src/connections.c
36+++ b/src/connections.c
37@@ -1632,20 +1632,16 @@ int connection_state_machine(server *srv, connection *con) {
38
39 /* only try to write if we have something in the queue */
40 if (!chunkqueue_is_empty(con->write_queue)) {
41-#if 0
42- log_error_write(srv, __FILE__, __LINE__, "dsd",
43- con->fd,
44- "packets to write:",
45- con->write_queue->used);
46-#endif
47- }
48- if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) {
49- if (-1 == connection_handle_write(srv, con)) {
50- log_error_write(srv, __FILE__, __LINE__, "ds",
51- con->fd,
52- "handle write failed.");
53- connection_set_state(srv, con, CON_STATE_ERROR);
54+ if (con->is_writable) {
55+ if (-1 == connection_handle_write(srv, con)) {
56+ log_error_write(srv, __FILE__, __LINE__, "ds",
57+ con->fd,
58+ "handle write failed.");
59+ connection_set_state(srv, con, CON_STATE_ERROR);
60+ }
61 }
62+ } else if (con->file_finished) {
63+ connection_set_state(srv, con, CON_STATE_RESPONSE_END);
64 }
65
66 break;
67--
682.4.5
69
diff --git a/main/lighttpd/0014-print-backtrace-in-assert-logging-with-libunwind.patch b/main/lighttpd/0014-print-backtrace-in-assert-logging-with-libunwind.patch
new file mode 100644
index 0000000000..ff6ef06902
--- /dev/null
+++ b/main/lighttpd/0014-print-backtrace-in-assert-logging-with-libunwind.patch
@@ -0,0 +1,187 @@
1From 3521be8b8599ae2cc12361c8f600fc58a473de91 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sat, 7 Feb 2015 13:32:56 +0000
4Subject: [PATCH 14/29] print backtrace in assert logging with libunwind
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2974 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 NEWS | 1 +
14 configure.ac | 11 +++++++++
15 src/CMakeLists.txt | 11 +++++++++
16 src/Makefile.am | 5 ++--
17 src/buffer.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
18 src/buffer.h | 2 ++
19 src/config.h.cmake | 3 +++
20 7 files changed, 102 insertions(+), 2 deletions(-)
21
22diff --git a/NEWS b/NEWS
23index 9c579de..fd537e8 100644
24--- a/NEWS
25+++ b/NEWS
26@@ -14,6 +14,7 @@ NEWS
27 * fixed typo in example config found by openSUSE user (boo# 907709)
28 * [network] fix compile break in calculation of sockaddr_un size if SUN_LEN is not defined (fixes #2609)
29 * [connections] fix bug in connection state handling
30+ * print backtrace in assert logging with libunwind
31
32 - 1.4.35 - 2014-03-12
33 * [network/ssl] fix build error if TLSEXT is disabled
34diff --git a/configure.ac b/configure.ac
35index e804030..63261ca 100644
36--- a/configure.ac
37+++ b/configure.ac
38@@ -285,6 +285,17 @@ if test "$WITH_VALGRIND" != "no"; then
39 AC_CHECK_HEADERS([valgrind/valgrind.h])
40 fi
41
42+dnl Checking for libunwind
43+AC_MSG_CHECKING(for libunwind)
44+AC_ARG_WITH(libunwind,
45+ AC_HELP_STRING([--with-libunwind],[Include libunwind support for backtraces on assert failures]),
46+ [WITH_LIBUNWIND=$withval],[WITH_LIBUNWIND=no])
47+
48+if test "$WITH_LIBUNWIND" != "no"; then
49+ PKG_CHECK_MODULES(LIBUNWIND, libunwind)
50+ AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support])
51+fi
52+
53 dnl Check for openssl
54 AC_MSG_CHECKING(for OpenSSL)
55 AC_ARG_WITH(openssl,
56diff --git a/src/Makefile.am b/src/Makefile.am
57index 4afdcc6..a5471ff 100644
58--- a/src/Makefile.am
59+++ b/src/Makefile.am
60@@ -1,4 +1,4 @@
61-AM_CFLAGS = $(FAM_CFLAGS)
62+AM_CFLAGS = $(FAM_CFLAGS) $(LIBUNWIND_CFLAGS)
63
64 noinst_PROGRAMS=proc_open lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license
65 sbin_PROGRAMS=lighttpd lighttpd-angel
66@@ -284,11 +284,12 @@ hdr = server.h buffer.h network.h log.h keyvalue.h \
67 DEFS= @DEFS@ -DHAVE_VERSION_H -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\""
68
69 lighttpd_SOURCES = $(src)
70-lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) $(ATTR_LIB) $(common_libadd) $(SSL_LIB) $(FAM_LIBS) $(LIBEV_LIBS)
71+lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) $(ATTR_LIB) $(common_libadd) $(SSL_LIB) $(FAM_LIBS) $(LIBEV_LIBS) $(LIBUNWIND_LIBS)
72 lighttpd_LDFLAGS = -export-dynamic
73 lighttpd_CCPFLAGS = $(FAM_CFLAGS) $(LIBEV_CFLAGS)
74
75 proc_open_SOURCES = proc_open.c buffer.c
76+proc_open_LDADD = $(LIBUNWIND_LIBS)
77 proc_open_CPPFLAGS= -DDEBUG_PROC_OPEN
78
79 #gen_license_SOURCES = license.c md5.c buffer.c gen_license.c
80diff --git a/src/buffer.c b/src/buffer.c
81index 1199164..b4bd415 100644
82--- a/src/buffer.c
83+++ b/src/buffer.c
84@@ -1059,9 +1059,80 @@ int buffer_to_upper(buffer *b) {
85 return 0;
86 }
87
88+#ifdef HAVE_LIBUNWIND
89+# define UNW_LOCAL_ONLY
90+# include <libunwind.h>
91+
92+void print_backtrace(FILE *file) {
93+ unw_cursor_t cursor;
94+ unw_context_t context;
95+ int ret;
96+ unsigned int frame = 0;
97+
98+ if (0 != (ret = unw_getcontext(&context))) goto error;
99+ if (0 != (ret = unw_init_local(&cursor, &context))) goto error;
100+
101+ fprintf(file, "Backtrace:\n");
102+
103+ while (0 < (ret = unw_step(&cursor))) {
104+ unw_word_t proc_ip = 0;
105+ unw_proc_info_t procinfo;
106+ char procname[256];
107+ unw_word_t proc_offset = 0;
108+
109+ if (0 != (ret = unw_get_reg(&cursor, UNW_REG_IP, &proc_ip))) goto error;
110+
111+ if (0 == proc_ip) {
112+ /* without an IP the other functions are useless; unw_get_proc_name would return UNW_EUNSPEC */
113+ ++frame;
114+ fprintf(file, "%u: (nil)\n", frame);
115+ continue;
116+ }
117+
118+ if (0 != (ret = unw_get_proc_info(&cursor, &procinfo))) goto error;
119+
120+ if (0 != (ret = unw_get_proc_name(&cursor, procname, sizeof(procname), &proc_offset))) {
121+ switch (-ret) {
122+ case UNW_ENOMEM:
123+ memset(procname + sizeof(procname) - 4, '.', 3);
124+ procname[sizeof(procname) - 1] = '\0';
125+ break;
126+ case UNW_ENOINFO:
127+ procname[0] = '?';
128+ procname[1] = '\0';
129+ proc_offset = 0;
130+ break;
131+ default:
132+ snprintf(procname, sizeof(procname), "?? (unw_get_proc_name error %d)", -ret);
133+ break;
134+ }
135+ }
136+
137+ ++frame;
138+ fprintf(file, "%u: %s (+0x%x) [%p]\n",
139+ frame,
140+ procname,
141+ (unsigned int) proc_offset,
142+ (void*)(uintptr_t)proc_ip);
143+ }
144+
145+ if (0 != ret) goto error;
146+
147+ return;
148+
149+error:
150+ fprintf(file, "Error while generating backtrace: unwind error %i\n", (int) -ret);
151+}
152+#else
153+void print_backtrace(FILE *file) {
154+ UNUSED(file);
155+}
156+#endif
157+
158 void log_failed_assert(const char *filename, unsigned int line, const char *msg) {
159 /* can't use buffer here; could lead to recursive assertions */
160 fprintf(stderr, "%s.%d: %s\n", filename, line, msg);
161+ print_backtrace(stderr);
162 fflush(stderr);
163 abort();
164 }
165diff --git a/src/buffer.h b/src/buffer.h
166index 20635e2..d2f5985 100644
167--- a/src/buffer.h
168+++ b/src/buffer.h
169@@ -9,6 +9,7 @@
170
171 #include <stdlib.h>
172 #include <sys/types.h>
173+#include <stdio.h>
174
175 typedef struct {
176 char *ptr;
177@@ -128,6 +129,7 @@ int light_isalnum(int c);
178
179 #define UNUSED(x) ( (void)(x) )
180
181+void print_backtrace(FILE *file);
182 void log_failed_assert(const char *filename, unsigned int line, const char *msg) LI_NORETURN;
183 #define force_assert(x) do { if (!(x)) log_failed_assert(__FILE__, __LINE__, "assertion failed: " #x); } while(0)
184 #define SEGFAULT() log_failed_assert(__FILE__, __LINE__, "aborted");
185--
1862.4.5
187
diff --git a/main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch b/main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch
new file mode 100644
index 0000000000..7380ce5ce8
--- /dev/null
+++ b/main/lighttpd/0015-fix-buffer-chunk-and-http_chunk-API.patch
@@ -0,0 +1,6095 @@
1From 6afad87d2ed66a48cda2a7c01dbcc59023774b73 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 12:37:10 +0000
4Subject: [PATCH 15/29] fix buffer, chunk and http_chunk API
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9 * remove unused structs and functions
10 (buffer_array, read_buffer)
11 * change return type from int to void for many functions,
12 as the return value (indicating error/success) was never checked,
13 and the function would only fail on programming errors and not on
14 invalid input; changed functions to use force_assert instead of
15 returning an error.
16 * all "len" parameters now are the real size of the memory to be read.
17 the length of strings is given always without the terminating 0.
18 * the "buffer" struct still counts the terminating 0 in ->used,
19 provide buffer_string_length() to get the length of a string in a
20 buffer.
21 unset config "strings" have used == 0, which is used in some places
22 to distinguish unset values from "" (empty string) values.
23 * most buffer usages should now use it as string container.
24 * optimise some buffer copying by "moving" data to other buffers
25 * use (u)intmax_t for generic int-to-string functions
26 * remove unused enum values: UNUSED_CHUNK, ENCODING_UNSET
27 * converted BUFFER_APPEND_SLASH to inline function (no macro feature
28 needed)
29 * refactor: create chunkqueue_steal: moving (partial) chunks into another
30 queue
31 * http_chunk: added separate function to terminate chunked body instead of
32 magic handling in http_chunk_append_mem().
33 http_chunk_append_* now handle empty chunks, and never terminate the
34 chunked body.
35
36From: Stefan Bühler <stbuehler@web.de>
37
38git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2975 152afb58-edef-0310-8abb-c4023f1b3aa9
39---
40 NEWS | 1 +
41 src/array.c | 2 +-
42 src/buffer.c | 752 ++++++++++++++++++----------------------------
43 src/buffer.h | 170 ++++++-----
44 src/chunk.c | 244 +++++++--------
45 src/chunk.h | 18 +-
46 src/configfile-glue.c | 16 +-
47 src/configfile.c | 26 +-
48 src/configparser.y | 26 +-
49 src/connections.c | 28 +-
50 src/data_array.c | 2 +-
51 src/data_config.c | 4 +-
52 src/data_count.c | 2 +-
53 src/data_fastcgi.c | 4 +-
54 src/data_integer.c | 2 +-
55 src/data_string.c | 8 +-
56 src/etag.c | 10 +-
57 src/http-header-glue.c | 6 +-
58 src/http_auth.c | 14 +-
59 src/http_chunk.c | 71 ++---
60 src/http_chunk.h | 8 +-
61 src/log.c | 16 +-
62 src/mod_access.c | 2 +-
63 src/mod_accesslog.c | 22 +-
64 src/mod_alias.c | 6 +-
65 src/mod_auth.c | 6 +-
66 src/mod_cgi.c | 49 ++-
67 src/mod_cml.c | 10 +-
68 src/mod_cml_lua.c | 14 +-
69 src/mod_compress.c | 20 +-
70 src/mod_dirlisting.c | 17 +-
71 src/mod_evhost.c | 8 +-
72 src/mod_expire.c | 2 +-
73 src/mod_fastcgi.c | 219 ++++----------
74 src/mod_flv_streaming.c | 4 +-
75 src/mod_indexfile.c | 6 +-
76 src/mod_magnet.c | 8 +-
77 src/mod_magnet_cache.c | 4 +-
78 src/mod_mysql_vhost.c | 18 +-
79 src/mod_proxy.c | 77 +----
80 src/mod_redirect.c | 2 +-
81 src/mod_rewrite.c | 4 +-
82 src/mod_rrdtool.c | 12 +-
83 src/mod_scgi.c | 135 +++------
84 src/mod_secure_download.c | 14 +-
85 src/mod_setenv.c | 8 +-
86 src/mod_simple_vhost.c | 26 +-
87 src/mod_ssi.c | 33 +-
88 src/mod_ssi_expr.c | 4 +-
89 src/mod_staticfile.c | 16 +-
90 src/mod_status.c | 50 +--
91 src/mod_trigger_b4_dl.c | 10 +-
92 src/mod_uploadprogress.c | 10 +-
93 src/mod_userdir.c | 20 +-
94 src/mod_usertrack.c | 16 +-
95 src/mod_webdav.c | 62 ++--
96 src/network.c | 28 +-
97 src/plugin.c | 2 +-
98 src/request.c | 6 +-
99 src/response.c | 32 +-
100 src/server.c | 2 +-
101 src/stat_cache.c | 26 +-
102 62 files changed, 1044 insertions(+), 1396 deletions(-)
103
104diff --git a/NEWS b/NEWS
105index fd537e8..ddb370d 100644
106--- a/NEWS
107+++ b/NEWS
108@@ -15,6 +15,7 @@ NEWS
109 * [network] fix compile break in calculation of sockaddr_un size if SUN_LEN is not defined (fixes #2609)
110 * [connections] fix bug in connection state handling
111 * print backtrace in assert logging with libunwind
112+ * major refactoring of internal buffer/chunk handling
113
114 - 1.4.35 - 2014-03-12
115 * [network/ssl] fix build error if TLSEXT is disabled
116diff --git a/src/array.c b/src/array.c
117index c9af995..9a15abd 100644
118--- a/src/array.c
119+++ b/src/array.c
120@@ -188,7 +188,7 @@ int array_insert_unique(array *a, data_unset *str) {
121
122 /* generate unique index if neccesary */
123 if (str->key->used == 0 || str->is_index_key) {
124- buffer_copy_long(str->key, a->unique_ndx++);
125+ buffer_copy_int(str->key, a->unique_ndx++);
126 str->is_index_key = 1;
127 }
128
129diff --git a/src/buffer.c b/src/buffer.c
130index b4bd415..caaa5bb 100644
131--- a/src/buffer.c
132+++ b/src/buffer.c
133@@ -7,12 +7,6 @@
134 #include <assert.h>
135 #include <ctype.h>
136
137-#if defined HAVE_STDINT_H
138-# include <stdint.h>
139-#elif defined HAVE_INTTYPES_H
140-# include <inttypes.h>
141-#endif
142-
143 static const char hex_chars[] = "0123456789abcdef";
144
145
146@@ -34,177 +28,160 @@ buffer* buffer_init(void) {
147 return b;
148 }
149
150-buffer *buffer_init_buffer(buffer *src) {
151+buffer *buffer_init_buffer(const buffer *src) {
152 buffer *b = buffer_init();
153- buffer_copy_string_buffer(b, src);
154+ buffer_copy_buffer(b, src);
155 return b;
156 }
157
158-/**
159- * free the buffer
160- *
161- */
162+buffer *buffer_init_string(const char *str) {
163+ buffer *b = buffer_init();
164+ buffer_copy_string(b, str);
165+ return b;
166+}
167
168 void buffer_free(buffer *b) {
169- if (!b) return;
170+ if (NULL == b) return;
171
172 free(b->ptr);
173 free(b);
174 }
175
176 void buffer_reset(buffer *b) {
177- if (!b) return;
178+ if (NULL == b) return;
179
180 /* limit don't reuse buffer larger than ... bytes */
181 if (b->size > BUFFER_MAX_REUSE_SIZE) {
182 free(b->ptr);
183 b->ptr = NULL;
184 b->size = 0;
185- } else if (b->size) {
186+ } else if (b->size > 0) {
187 b->ptr[0] = '\0';
188 }
189
190 b->used = 0;
191 }
192
193+void buffer_move(buffer *b, buffer *src) {
194+ buffer tmp;
195
196-/**
197- *
198- * allocate (if neccessary) enough space for 'size' bytes and
199- * set the 'used' counter to 0
200- *
201- */
202+ if (NULL == b) {
203+ buffer_reset(src);
204+ return;
205+ }
206+ buffer_reset(b);
207+ if (NULL == src) return;
208+
209+ tmp = *src; *src = *b; *b = tmp;
210+}
211
212 #define BUFFER_PIECE_SIZE 64
213+static size_t buffer_align_size(size_t size) {
214+ size_t align = BUFFER_PIECE_SIZE - (size % BUFFER_PIECE_SIZE);
215+ /* overflow on unsinged size_t is defined to wrap around */
216+ if (size + align < size) return size;
217+ return size + align;
218+}
219
220-int buffer_prepare_copy(buffer *b, size_t size) {
221- if (!b) return -1;
222+char* buffer_prepare_copy(buffer *b, size_t size) {
223+ force_assert(NULL != b);
224
225- if ((0 == b->size) ||
226- (size > b->size)) {
227- if (b->size) free(b->ptr);
228+ /* also allocate space for terminating 0 */
229+ /* check for overflow: unsigned overflow is defined to wrap around */
230+ force_assert(1 + size > size);
231+ ++size;
232
233- b->size = size;
234+ if (0 == b->size || size > b->size) {
235+ if (NULL != b->ptr) free(b->ptr);
236+ b->ptr = NULL;
237
238- /* always allocate a multiply of BUFFER_PIECE_SIZE */
239- b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
240+ b->size = buffer_align_size(size);
241+ force_assert(b->size > 0);
242
243 b->ptr = malloc(b->size);
244- force_assert(b->ptr);
245+ force_assert(NULL != b->ptr);
246 }
247- b->used = 0;
248- return 0;
249-}
250-
251-/**
252- *
253- * increase the internal buffer (if neccessary) to append another 'size' byte
254- * ->used isn't changed
255- *
256- */
257
258-int buffer_prepare_append(buffer *b, size_t size) {
259- if (!b) return -1;
260-
261- if (0 == b->size) {
262- b->size = size;
263-
264- /* always allocate a multiply of BUFFER_PIECE_SIZE */
265- b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
266+ /* reset */
267+ b->used = 0;
268+ b->ptr[0] = '\0';
269
270- b->ptr = malloc(b->size);
271- b->used = 0;
272- force_assert(b->ptr);
273- } else if (b->used + size > b->size) {
274- b->size += size;
275+ return b->ptr;
276+}
277
278- /* always allocate a multiply of BUFFER_PIECE_SIZE */
279- b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
280+char* buffer_prepare_append(buffer *b, size_t size) {
281+ size_t req_size;
282+ force_assert(NULL != b);
283
284- b->ptr = realloc(b->ptr, b->size);
285- force_assert(b->ptr);
286+ if (buffer_string_is_empty(b)) {
287+ size_t old_used = b->used; /* either 0 or 1 */
288+ /* just prepare copy (free+malloc instead of realloc) */
289+ buffer_prepare_copy(b, size);
290+ b->used = old_used; /* buffer_prepare_append mustn't modify b->used */
291+ return b->ptr;
292 }
293- return 0;
294-}
295
296-int buffer_copy_string(buffer *b, const char *s) {
297- size_t s_len;
298+ /* not empty, b->used already includes a terminating 0 */
299+ req_size = b->used + size;
300
301- if (!s || !b) return -1;
302+ /* check for overflow: unsigned overflow is defined to wrap around */
303+ force_assert(req_size >= b->used);
304
305- s_len = strlen(s) + 1;
306- buffer_prepare_copy(b, s_len);
307+ if (req_size > b->size) {
308+ char *ptr;
309+ b->size = buffer_align_size(req_size);
310
311- memcpy(b->ptr, s, s_len);
312- b->used = s_len;
313+ ptr = realloc(b->ptr, b->size);
314+ force_assert(NULL != ptr);
315+ b->ptr = ptr;
316+ }
317
318- return 0;
319+ return b->ptr + b->used - 1;
320 }
321
322-int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
323- if (!s || !b) return -1;
324-#if 0
325- /* removed optimization as we have to keep the empty string
326- * in some cases for the config handling
327- *
328- * url.access-deny = ( "" )
329- */
330- if (s_len == 0) return 0;
331-#endif
332- buffer_prepare_copy(b, s_len + 1);
333-
334- memcpy(b->ptr, s, s_len);
335- b->ptr[s_len] = '\0';
336- b->used = s_len + 1;
337+void buffer_commit(buffer *b, size_t size)
338+{
339+ force_assert(NULL != b);
340+ force_assert(b->size > 0);
341
342- return 0;
343-}
344+ if (0 == b->used) b->used = 1;
345
346-int buffer_copy_string_buffer(buffer *b, const buffer *src) {
347- if (!src) return -1;
348+ if (size > 0) {
349+ /* check for overflow: unsigned overflow is defined to wrap around */
350+ force_assert(b->used + size > b->used);
351
352- if (src->used == 0) {
353- buffer_reset(b);
354- return 0;
355+ force_assert(b->used + size <= b->size);
356+ b->used += size;
357 }
358- return buffer_copy_string_len(b, src->ptr, src->used - 1);
359+
360+ b->ptr[b->used - 1] = '\0';
361 }
362
363-int buffer_append_string(buffer *b, const char *s) {
364- size_t s_len;
365+void buffer_copy_string(buffer *b, const char *s) {
366+ buffer_copy_string_len(b, s, NULL != s ? strlen(s) : 0);
367+}
368
369- if (!s || !b) return -1;
370+void buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
371+ force_assert(NULL != b);
372+ force_assert(NULL != s || s_len == 0);
373
374- s_len = strlen(s);
375- buffer_prepare_append(b, s_len + 1);
376- if (b->used == 0)
377- b->used++;
378+ buffer_prepare_copy(b, s_len);
379
380- memcpy(b->ptr + b->used - 1, s, s_len + 1);
381- b->used += s_len;
382+ if (0 != s_len) memcpy(b->ptr, s, s_len);
383
384- return 0;
385+ buffer_commit(b, s_len);
386 }
387
388-int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen) {
389- size_t s_len;
390-
391- if (!s || !b) return -1;
392-
393- s_len = strlen(s);
394- if (s_len > maxlen) s_len = maxlen;
395- buffer_prepare_append(b, maxlen + 1);
396- if (b->used == 0)
397- b->used++;
398-
399- memcpy(b->ptr + b->used - 1, s, s_len);
400- if (maxlen > s_len) {
401- memset(b->ptr + b->used - 1 + s_len, ' ', maxlen - s_len);
402+void buffer_copy_buffer(buffer *b, const buffer *src) {
403+ if (NULL == src || 0 == src->used) {
404+ buffer_prepare_copy(b, 0);
405+ } else {
406+ buffer_copy_string_len(b, src->ptr, buffer_string_length(src));
407 }
408+}
409
410- b->used += maxlen;
411- b->ptr[b->used - 1] = '\0';
412- return 0;
413+void buffer_append_string(buffer *b, const char *s) {
414+ buffer_append_string_len(b, s, NULL != s ? strlen(s) : 0);
415 }
416
417 /**
418@@ -218,176 +195,138 @@ int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen) {
419 * @param s_len size of the string (without the terminating \0)
420 */
421
422-int buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
423- if (!s || !b) return -1;
424- if (s_len == 0) return 0;
425-
426- buffer_prepare_append(b, s_len + 1);
427- if (b->used == 0)
428- b->used++;
429-
430- memcpy(b->ptr + b->used - 1, s, s_len);
431- b->used += s_len;
432- b->ptr[b->used - 1] = '\0';
433-
434- return 0;
435-}
436+void buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
437+ char *target_buf;
438
439-int buffer_append_string_buffer(buffer *b, const buffer *src) {
440- if (!src) return -1;
441- if (src->used == 0) return 0;
442+ force_assert(NULL != b);
443+ force_assert(NULL != s || s_len == 0);
444
445- return buffer_append_string_len(b, src->ptr, src->used - 1);
446-}
447+ target_buf = buffer_prepare_append(b, s_len);
448
449-int buffer_append_memory(buffer *b, const char *s, size_t s_len) {
450- if (!s || !b) return -1;
451- if (s_len == 0) return 0;
452+ /* only append to 0-terminated string */
453+ force_assert('\0' == *target_buf);
454
455- buffer_prepare_append(b, s_len);
456- memcpy(b->ptr + b->used, s, s_len);
457- b->used += s_len;
458+ if (s_len > 0) memcpy(target_buf, s, s_len);
459
460- return 0;
461+ buffer_commit(b, s_len);
462 }
463
464-int buffer_copy_memory(buffer *b, const char *s, size_t s_len) {
465- if (!s || !b) return -1;
466-
467- b->used = 0;
468-
469- return buffer_append_memory(b, s, s_len);
470+void buffer_append_string_buffer(buffer *b, const buffer *src) {
471+ if (NULL == src) {
472+ buffer_append_string_len(b, NULL, 0);
473+ } else {
474+ buffer_append_string_len(b, src->ptr, buffer_string_length(src));
475+ }
476 }
477
478-int buffer_append_long_hex(buffer *b, unsigned long value) {
479+void buffer_append_long_hex(buffer *b, unsigned long value) {
480 char *buf;
481 int shift = 0;
482- unsigned long copy = value;
483
484- while (copy) {
485- copy >>= 4;
486- shift++;
487+ {
488+ unsigned long copy = value;
489+ do {
490+ copy >>= 8;
491+ shift += 2; /* counting nibbles (4 bits) */
492+ } while (0 != copy);
493 }
494- if (shift == 0)
495- shift++;
496- if (shift & 0x01)
497- shift++;
498-
499- buffer_prepare_append(b, shift + 1);
500- if (b->used == 0)
501- b->used++;
502- buf = b->ptr + (b->used - 1);
503- b->used += shift;
504-
505- shift <<= 2;
506+
507+ buf = buffer_prepare_append(b, shift);
508+ buffer_commit(b, shift); /* will fill below */
509+
510+ shift <<= 2; /* count bits now */
511 while (shift > 0) {
512 shift -= 4;
513 *(buf++) = hex_chars[(value >> shift) & 0x0F];
514 }
515- *buf = '\0';
516-
517- return 0;
518 }
519
520-int LI_ltostr(char *buf, long val) {
521- char swap;
522- char *end;
523- int len = 1;
524-
525- if (val < 0) {
526- len++;
527- *(buf++) = '-';
528- val = -val;
529- }
530-
531- end = buf;
532- while (val > 9) {
533- *(end++) = '0' + (val % 10);
534- val = val / 10;
535- }
536- *(end) = '0' + val;
537- *(end + 1) = '\0';
538- len += end - buf;
539+static char* utostr(char * const buf_end, uintmax_t val) {
540+ char *cur = buf_end;
541+ do {
542+ int mod = val % 10;
543+ val /= 10;
544+ /* prepend digit mod */
545+ *(--cur) = (char) ('0' + mod);
546+ } while (0 != val);
547+ return cur;
548+}
549
550- while (buf < end) {
551- swap = *end;
552- *end = *buf;
553- *buf = swap;
554+static char* itostr(char * const buf_end, intmax_t val) {
555+ char *cur = buf_end;
556+ if (val >= 0) return utostr(buf_end, (uintmax_t) val);
557
558- buf++;
559- end--;
560- }
561+ /* can't take absolute value, as it isn't defined for INTMAX_MIN */
562+ do {
563+ int mod = val % 10;
564+ val /= 10;
565+ /* val * 10 + mod == orig val, -10 < mod < 10 */
566+ /* we want a negative mod */
567+ if (mod > 0) {
568+ mod -= 10;
569+ val += 1;
570+ }
571+ /* prepend digit abs(mod) */
572+ *(--cur) = (char) ('0' + (-mod));
573+ } while (0 != val);
574+ *(--cur) = '-';
575
576- return len;
577+ return cur;
578 }
579
580-int buffer_append_long(buffer *b, long val) {
581- if (!b) return -1;
582+void buffer_append_int(buffer *b, intmax_t val) {
583+ char buf[LI_ITOSTRING_LENGTH];
584+ char* const buf_end = buf + sizeof(buf);
585+ char *str;
586
587- buffer_prepare_append(b, 32);
588- if (b->used == 0)
589- b->used++;
590+ force_assert(NULL != b);
591
592- b->used += LI_ltostr(b->ptr + (b->used - 1), val);
593- return 0;
594+ str = itostr(buf_end, val);
595+ force_assert(buf_end > str && str >= buf);
596+
597+ buffer_append_string_len(b, str, buf_end - str);
598 }
599
600-int buffer_copy_long(buffer *b, long val) {
601- if (!b) return -1;
602+void buffer_copy_int(buffer *b, intmax_t val) {
603+ force_assert(NULL != b);
604
605 b->used = 0;
606- return buffer_append_long(b, val);
607+ buffer_append_int(b, val);
608 }
609
610-#if !defined(SIZEOF_LONG) || (SIZEOF_LONG != SIZEOF_OFF_T)
611-int buffer_append_off_t(buffer *b, off_t val) {
612- char swap;
613- char *end;
614- char *start;
615- int len = 1;
616-
617- if (!b) return -1;
618+void li_itostrn(char *buf, size_t buf_len, intmax_t val) {
619+ char p_buf[LI_ITOSTRING_LENGTH];
620+ char* const p_buf_end = p_buf + sizeof(p_buf);
621+ char* str = p_buf_end - 1;
622+ *str = '\0';
623
624- buffer_prepare_append(b, 32);
625- if (b->used == 0)
626- b->used++;
627+ str = itostr(str, val);
628+ force_assert(p_buf_end > str && str >= p_buf);
629
630- start = b->ptr + (b->used - 1);
631- if (val < 0) {
632- len++;
633- *(start++) = '-';
634- val = -val;
635- }
636+ force_assert(buf_len >= (size_t) (p_buf_end - str));
637+ memcpy(buf, str, p_buf_end - str);
638+}
639
640- end = start;
641- while (val > 9) {
642- *(end++) = '0' + (val % 10);
643- val = val / 10;
644- }
645- *(end) = '0' + val;
646- *(end + 1) = '\0';
647- len += end - start;
648+void li_itostr(char *buf, intmax_t val) {
649+ li_itostrn(buf, LI_ITOSTRING_LENGTH, val);
650+}
651
652- while (start < end) {
653- swap = *end;
654- *end = *start;
655- *start = swap;
656+void li_utostrn(char *buf, size_t buf_len, uintmax_t val) {
657+ char p_buf[LI_ITOSTRING_LENGTH];
658+ char* const p_buf_end = p_buf + sizeof(p_buf);
659+ char* str = p_buf_end - 1;
660+ *str = '\0';
661
662- start++;
663- end--;
664- }
665+ str = utostr(str, val);
666+ force_assert(p_buf_end > str && str >= p_buf);
667
668- b->used += len;
669- return 0;
670+ force_assert(buf_len >= (size_t) (p_buf_end - str));
671+ memcpy(buf, str, p_buf_end - str);
672 }
673
674-int buffer_copy_off_t(buffer *b, off_t val) {
675- if (!b) return -1;
676-
677- b->used = 0;
678- return buffer_append_off_t(b, val);
679+void li_utostr(char *buf, uintmax_t val) {
680+ li_utostrn(buf, LI_ITOSTRING_LENGTH, val);
681 }
682-#endif /* !defined(SIZEOF_LONG) || (SIZEOF_LONG != SIZEOF_OFF_T) */
683
684 char int2hex(char c) {
685 return hex_chars[(c & 0x0F)];
686@@ -397,99 +336,21 @@ char int2hex(char c) {
687 * returns 0xFF on invalid input.
688 */
689 char hex2int(unsigned char hex) {
690- hex = hex - '0';
691- if (hex > 9) {
692- hex = (hex + '0' - 1) | 0x20;
693- hex = hex - 'a' + 11;
694+ unsigned char value = hex - '0';
695+ if (value > 9) {
696+ hex |= 0x20; /* to lower case */
697+ value = hex - 'a' + 10;
698+ if (value < 10) value = 0xff;
699 }
700- if (hex > 15)
701- hex = 0xFF;
702+ if (value > 15) value = 0xff;
703
704- return hex;
705+ return value;
706 }
707
708-
709-/**
710- * init the buffer
711- *
712- */
713-
714-buffer_array* buffer_array_init(void) {
715- buffer_array *b;
716-
717- b = malloc(sizeof(*b));
718-
719- force_assert(b);
720- b->ptr = NULL;
721- b->size = 0;
722- b->used = 0;
723-
724- return b;
725-}
726-
727-void buffer_array_reset(buffer_array *b) {
728- size_t i;
729-
730- if (!b) return;
731-
732- /* if they are too large, reduce them */
733- for (i = 0; i < b->used; i++) {
734- buffer_reset(b->ptr[i]);
735- }
736-
737- b->used = 0;
738-}
739-
740-
741-/**
742- * free the buffer_array
743- *
744- */
745-
746-void buffer_array_free(buffer_array *b) {
747- size_t i;
748- if (!b) return;
749-
750- for (i = 0; i < b->size; i++) {
751- if (b->ptr[i]) buffer_free(b->ptr[i]);
752- }
753- free(b->ptr);
754- free(b);
755-}
756-
757-buffer *buffer_array_append_get_buffer(buffer_array *b) {
758- size_t i;
759-
760- if (b->size == 0) {
761- b->size = 16;
762- b->ptr = malloc(sizeof(*b->ptr) * b->size);
763- force_assert(b->ptr);
764- for (i = 0; i < b->size; i++) {
765- b->ptr[i] = NULL;
766- }
767- } else if (b->size == b->used) {
768- b->size += 16;
769- b->ptr = realloc(b->ptr, sizeof(*b->ptr) * b->size);
770- force_assert(b->ptr);
771- for (i = b->used; i < b->size; i++) {
772- b->ptr[i] = NULL;
773- }
774- }
775-
776- if (b->ptr[b->used] == NULL) {
777- b->ptr[b->used] = buffer_init();
778- }
779-
780- b->ptr[b->used]->used = 0;
781-
782- return b->ptr[b->used++];
783-}
784-
785-
786 char * buffer_search_string_len(buffer *b, const char *needle, size_t len) {
787 size_t i;
788- if (len == 0) return NULL;
789- if (needle == NULL) return NULL;
790+ force_assert(NULL != b);
791+ force_assert(0 != len && NULL != needle); /* empty needles not allowed */
792
793 if (b->used < len) return NULL;
794
795@@ -502,17 +363,12 @@ char * buffer_search_string_len(buffer *b, const char *needle, size_t len) {
796 return NULL;
797 }
798
799-buffer *buffer_init_string(const char *str) {
800- buffer *b = buffer_init();
801-
802- buffer_copy_string(b, str);
803-
804- return b;
805+int buffer_is_empty(buffer *b) {
806+ return NULL == b || 0 == b->used;
807 }
808
809-int buffer_is_empty(buffer *b) {
810- if (!b) return 1;
811- return (b->used == 0);
812+int buffer_string_is_empty(buffer *b) {
813+ return 0 == buffer_string_length(b);
814 }
815
816 /**
817@@ -523,24 +379,30 @@ int buffer_is_empty(buffer *b) {
818 */
819
820 int buffer_is_equal(buffer *a, buffer *b) {
821+ force_assert(NULL != a && NULL != b);
822+
823 if (a->used != b->used) return 0;
824 if (a->used == 0) return 1;
825
826- return (0 == strcmp(a->ptr, b->ptr));
827+ return (0 == memcmp(a->ptr, b->ptr, a->used));
828 }
829
830 int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
831- buffer b;
832+ force_assert(NULL != a && NULL != s);
833+ force_assert(b_len + 1 > b_len);
834
835- b.ptr = (char *)s;
836- b.used = b_len + 1;
837+ if (a->used != b_len + 1) return 0;
838+ if (0 != memcmp(a->ptr, s, b_len)) return 0;
839+ if ('\0' != a->ptr[a->used-1]) return 0;
840
841- return buffer_is_equal(a, &b);
842+ return 1;
843 }
844
845 /* buffer_is_equal_caseless_string(b, CONST_STR_LEN("value")) */
846 int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len) {
847+ force_assert(NULL != a);
848 if (a->used != b_len + 1) return 0;
849+ force_assert('\0' == a->ptr[a->used - 1]);
850
851 return (0 == strcasecmp(a->ptr, s));
852 }
853@@ -554,30 +416,18 @@ int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b
854 if (ca == cb) continue;
855
856 /* always lowercase for transitive results */
857-#if 1
858 if (ca >= 'A' && ca <= 'Z') ca |= 32;
859 if (cb >= 'A' && cb <= 'Z') cb |= 32;
860-#else
861- /* try to produce code without branching (jumps) */
862- ca |= ((unsigned char)(ca - (unsigned char)'A') <= (unsigned char)('Z' - 'A')) ? 32 : 0;
863- cb |= ((unsigned char)(cb - (unsigned char)'A') <= (unsigned char)('Z' - 'A')) ? 32 : 0;
864-#endif
865
866 if (ca == cb) continue;
867 return ca - cb;
868 }
869 if (a_len == b_len) return 0;
870- return a_len - b_len;
871+ return a_len < b_len ? -1 : 1;
872 }
873
874-/**
875- * check if the rightmost bytes of the string are equal.
876- *
877- *
878- */
879-
880 int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
881- /* no, len -> equal */
882+ /* no len -> equal */
883 if (len == 0) return 1;
884
885 /* len > 0, but empty buffers -> not equal */
886@@ -586,29 +436,23 @@ int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
887 /* buffers too small -> not equal */
888 if (b1->used - 1 < len || b2->used - 1 < len) return 0;
889
890- if (0 == strncmp(b1->ptr + b1->used - 1 - len,
891- b2->ptr + b2->used - 1 - len, len)) {
892- return 1;
893- }
894-
895- return 0;
896+ return 0 == memcmp(b1->ptr + b1->used - 1 - len, b2->ptr + b2->used - 1 - len, len);
897 }
898
899-int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
900+void buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
901 size_t i;
902
903- /* BO protection */
904- if (in_len * 2 < in_len) return -1;
905+ /* overflow protection */
906+ force_assert(in_len * 2 + 1 > in_len);
907
908- buffer_prepare_copy(b, in_len * 2 + 1);
909+ buffer_prepare_copy(b, in_len * 2);
910
911+ b->used = 0;
912 for (i = 0; i < in_len; i++) {
913 b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
914 b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
915 }
916 b->ptr[b->used++] = '\0';
917-
918- return 0;
919 }
920
921 /* everything except: ! ( ) * - . 0-9 A-Z _ a-z */
922@@ -747,18 +591,15 @@ static const char encoded_chars_http_header[] = {
923
924
925
926-int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding) {
927+void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding) {
928 unsigned char *ds, *d;
929 size_t d_len, ndx;
930 const char *map = NULL;
931
932- if (!s || !b) return -1;
933-
934- if (b->ptr[b->used - 1] != '\0') {
935- SEGFAULT();
936- }
937+ force_assert(NULL != b);
938+ force_assert(NULL != s || 0 == s_len);
939
940- if (s_len == 0) return 0;
941+ if (0 == s_len) return;
942
943 switch(encoding) {
944 case ENCODING_REL_URI:
945@@ -779,11 +620,9 @@ int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_
946 case ENCODING_HTTP_HEADER:
947 map = encoded_chars_http_header;
948 break;
949- case ENCODING_UNSET:
950- break;
951 }
952
953- force_assert(map != NULL);
954+ force_assert(NULL != map);
955
956 /* count to-be-encoded-characters */
957 for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
958@@ -801,17 +640,17 @@ int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_
959 case ENCODING_HEX:
960 d_len += 2;
961 break;
962- case ENCODING_UNSET:
963- break;
964 }
965 } else {
966- d_len ++;
967+ d_len++;
968 }
969 }
970
971- buffer_prepare_append(b, d_len);
972+ d = (unsigned char*) buffer_prepare_append(b, d_len);
973+ buffer_commit(b, d_len); /* fill below */
974+ force_assert('\0' == *d);
975
976- for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
977+ for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
978 if (map[*ds]) {
979 switch(encoding) {
980 case ENCODING_REL_URI:
981@@ -837,20 +676,11 @@ int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_
982 d[d_len++] = *ds;
983 d[d_len++] = '\t';
984 break;
985- case ENCODING_UNSET:
986- break;
987 }
988 } else {
989 d[d_len++] = *ds;
990 }
991 }
992-
993- /* terminate buffer and calculate new length */
994- b->ptr[b->used + d_len - 1] = '\0';
995-
996- b->used += d_len;
997-
998- return 0;
999 }
1000
1001
1002@@ -858,26 +688,35 @@ int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_
1003 * replaces non-printable characters with '_'
1004 */
1005
1006-static int buffer_urldecode_internal(buffer *url, int is_query) {
1007+static void buffer_urldecode_internal(buffer *url, int is_query) {
1008 unsigned char high, low;
1009- const char *src;
1010+ char *src;
1011 char *dst;
1012
1013- if (!url || !url->ptr) return -1;
1014+ force_assert(NULL != url);
1015+ if (buffer_string_is_empty(url)) return;
1016+
1017+ force_assert('\0' == url->ptr[url->used-1]);
1018
1019- src = (const char*) url->ptr;
1020- dst = (char*) url->ptr;
1021+ src = (char*) url->ptr;
1022
1023- while ((*src) != '\0') {
1024+ while ('\0' != *src) {
1025+ if ('%' == *src) break;
1026+ if (is_query && '+' == *src) *src = ' ';
1027+ src++;
1028+ }
1029+ dst = src;
1030+
1031+ while ('\0' != *src) {
1032 if (is_query && *src == '+') {
1033 *dst = ' ';
1034 } else if (*src == '%') {
1035 *dst = '%';
1036
1037 high = hex2int(*(src + 1));
1038- if (high != 0xFF) {
1039+ if (0xFF != high) {
1040 low = hex2int(*(src + 2));
1041- if (low != 0xFF) {
1042+ if (0xFF != low) {
1043 high = (high << 4) | low;
1044
1045 /* map control-characters out */
1046@@ -897,19 +736,19 @@ static int buffer_urldecode_internal(buffer *url, int is_query) {
1047
1048 *dst = '\0';
1049 url->used = (dst - url->ptr) + 1;
1050-
1051- return 0;
1052 }
1053
1054-int buffer_urldecode_path(buffer *url) {
1055- return buffer_urldecode_internal(url, 0);
1056+void buffer_urldecode_path(buffer *url) {
1057+ buffer_urldecode_internal(url, 0);
1058 }
1059
1060-int buffer_urldecode_query(buffer *url) {
1061- return buffer_urldecode_internal(url, 1);
1062+void buffer_urldecode_query(buffer *url) {
1063+ buffer_urldecode_internal(url, 1);
1064 }
1065
1066-/* Remove "/../", "//", "/./" parts from path.
1067+/* Remove "/../", "//", "/./" parts from path,
1068+ * strips leading spaces,
1069+ * prepends "/" if not present already
1070 *
1071 * /blah/.. gets /
1072 * /blah/../foo gets /foo
1073@@ -920,20 +759,38 @@ int buffer_urldecode_query(buffer *url) {
1074 * the operation is performed in-place.
1075 */
1076
1077-int buffer_path_simplify(buffer *dest, buffer *src)
1078+void buffer_path_simplify(buffer *dest, buffer *src)
1079 {
1080 int toklen;
1081 char c, pre1;
1082 char *start, *slash, *walk, *out;
1083 unsigned short pre;
1084
1085- if (src == NULL || src->ptr == NULL || dest == NULL)
1086- return -1;
1087+ force_assert(NULL != dest && NULL != src);
1088
1089- if (src == dest)
1090+ if (buffer_string_is_empty(src)) {
1091+ buffer_copy_string_len(dest, NULL, 0);
1092+ return;
1093+ }
1094+
1095+ force_assert('\0' == src->ptr[src->used-1]);
1096+
1097+ /* might need one character more for the '/' prefix */
1098+ if (src == dest) {
1099 buffer_prepare_append(dest, 1);
1100- else
1101- buffer_prepare_copy(dest, src->used + 1);
1102+ } else {
1103+ buffer_prepare_copy(dest, buffer_string_length(src) + 1);
1104+ }
1105+
1106+#if defined(__WIN32) || defined(__CYGWIN__)
1107+ /* cygwin is treating \ and / the same, so we have to that too */
1108+ {
1109+ char *p;
1110+ for (p = src->ptr; *p; p++) {
1111+ if (*p == '\\') *p = '/';
1112+ }
1113+ }
1114+#endif
1115
1116 walk = src->ptr;
1117 start = dest->ptr;
1118@@ -941,16 +798,6 @@ int buffer_path_simplify(buffer *dest, buffer *src)
1119 slash = dest->ptr;
1120
1121
1122-#if defined(__WIN32) || defined(__CYGWIN__)
1123- /* cygwin is treating \ and / the same, so we have to that too
1124- */
1125-
1126- for (walk = src->ptr; *walk; walk++) {
1127- if (*walk == '\\') *walk = '/';
1128- }
1129- walk = src->ptr;
1130-#endif
1131-
1132 while (*walk == ' ') {
1133 walk++;
1134 }
1135@@ -966,34 +813,29 @@ int buffer_path_simplify(buffer *dest, buffer *src)
1136
1137 if (pre1 == '\0') {
1138 dest->used = (out - start) + 1;
1139- return 0;
1140+ return;
1141 }
1142
1143- while (1) {
1144+ for (;;) {
1145 if (c == '/' || c == '\0') {
1146 toklen = out - slash;
1147 if (toklen == 3 && pre == (('.' << 8) | '.')) {
1148 out = slash;
1149 if (out > start) {
1150 out--;
1151- while (out > start && *out != '/') {
1152- out--;
1153- }
1154+ while (out > start && *out != '/') out--;
1155 }
1156
1157- if (c == '\0')
1158- out++;
1159+ if (c == '\0') out++;
1160 } else if (toklen == 1 || pre == (('/' << 8) | '.')) {
1161 out = slash;
1162- if (c == '\0')
1163- out++;
1164+ if (c == '\0') out++;
1165 }
1166
1167 slash = out;
1168 }
1169
1170- if (c == '\0')
1171- break;
1172+ if (c == '\0') break;
1173
1174 pre1 = c;
1175 pre = (pre << 8) | pre1;
1176@@ -1006,8 +848,6 @@ int buffer_path_simplify(buffer *dest, buffer *src)
1177
1178 *out = '\0';
1179 dest->used = (out - start) + 1;
1180-
1181- return 0;
1182 }
1183
1184 int light_isdigit(int c) {
1185@@ -1030,33 +870,23 @@ int light_isalnum(int c) {
1186 return light_isdigit(c) || light_isalpha(c);
1187 }
1188
1189-int buffer_to_lower(buffer *b) {
1190- char *c;
1191-
1192- if (b->used == 0) return 0;
1193+void buffer_to_lower(buffer *b) {
1194+ size_t i;
1195
1196- for (c = b->ptr; *c; c++) {
1197- if (*c >= 'A' && *c <= 'Z') {
1198- *c |= 32;
1199- }
1200+ for (i = 0; i < b->used; ++i) {
1201+ char c = b->ptr[i];
1202+ if (c >= 'A' && c <= 'Z') b->ptr[i] |= 0x20;
1203 }
1204-
1205- return 0;
1206 }
1207
1208
1209-int buffer_to_upper(buffer *b) {
1210- char *c;
1211-
1212- if (b->used == 0) return 0;
1213+void buffer_to_upper(buffer *b) {
1214+ size_t i;
1215
1216- for (c = b->ptr; *c; c++) {
1217- if (*c >= 'a' && *c <= 'z') {
1218- *c &= ~32;
1219- }
1220+ for (i = 0; i < b->used; ++i) {
1221+ char c = b->ptr[i];
1222+ if (c >= 'A' && c <= 'Z') b->ptr[i] &= ~0x20;
1223 }
1224-
1225- return 0;
1226 }
1227
1228 #ifdef HAVE_LIBUNWIND
1229diff --git a/src/buffer.h b/src/buffer.h
1230index d2f5985..ff57d68 100644
1231--- a/src/buffer.h
1232+++ b/src/buffer.h
1233@@ -11,74 +11,96 @@
1234 #include <sys/types.h>
1235 #include <stdio.h>
1236
1237+#if defined HAVE_STDINT_H
1238+# include <stdint.h>
1239+#elif defined HAVE_INTTYPES_H
1240+# include <inttypes.h>
1241+#endif
1242+
1243+/* generic string + binary data container; contains a terminating 0 in both
1244+ * cases
1245+ *
1246+ * used == 0 indicates a special "empty" state (unset config values); ptr
1247+ * might be NULL too then. otherwise an empty string has used == 1 (and ptr[0]
1248+ * == 0);
1249+ *
1250+ * copy/append functions will ensure used >= 1 (i.e. never leave it in the
1251+ * special empty state); only buffer_copy_buffer will copy the special empty
1252+ * state.
1253+ */
1254 typedef struct {
1255 char *ptr;
1256
1257+ /* "used" includes a terminating 0 */
1258 size_t used;
1259+ /* size of allocated buffer at *ptr */
1260 size_t size;
1261 } buffer;
1262
1263-typedef struct {
1264- buffer **ptr;
1265-
1266- size_t used;
1267- size_t size;
1268-} buffer_array;
1269-
1270-typedef struct {
1271- char *ptr;
1272-
1273- size_t offset; /* input-pointer */
1274-
1275- size_t used; /* output-pointer */
1276- size_t size;
1277-} read_buffer;
1278-
1279-buffer_array* buffer_array_init(void);
1280-void buffer_array_free(buffer_array *b);
1281-void buffer_array_reset(buffer_array *b);
1282-buffer *buffer_array_append_get_buffer(buffer_array *b);
1283-
1284+/* create new buffer; either empty or copy given data */
1285 buffer* buffer_init(void);
1286-buffer* buffer_init_buffer(buffer *b);
1287-buffer* buffer_init_string(const char *str);
1288-void buffer_free(buffer *b);
1289-void buffer_reset(buffer *b);
1290-
1291-int buffer_prepare_copy(buffer *b, size_t size);
1292-int buffer_prepare_append(buffer *b, size_t size);
1293-
1294-int buffer_copy_string(buffer *b, const char *s);
1295-int buffer_copy_string_len(buffer *b, const char *s, size_t s_len);
1296-int buffer_copy_string_buffer(buffer *b, const buffer *src);
1297-int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len);
1298-
1299-int buffer_copy_long(buffer *b, long val);
1300-
1301-int buffer_copy_memory(buffer *b, const char *s, size_t s_len);
1302-
1303-int buffer_append_string(buffer *b, const char *s);
1304-int buffer_append_string_len(buffer *b, const char *s, size_t s_len);
1305-int buffer_append_string_buffer(buffer *b, const buffer *src);
1306-int buffer_append_string_lfill(buffer *b, const char *s, size_t maxlen);
1307-int buffer_append_string_rfill(buffer *b, const char *s, size_t maxlen);
1308-
1309-int buffer_append_long_hex(buffer *b, unsigned long len);
1310-int buffer_append_long(buffer *b, long val);
1311-
1312-#if defined(SIZEOF_LONG) && (SIZEOF_LONG == SIZEOF_OFF_T)
1313-#define buffer_copy_off_t(x, y) buffer_copy_long(x, y)
1314-#define buffer_append_off_t(x, y) buffer_append_long(x, y)
1315-#else
1316-int buffer_copy_off_t(buffer *b, off_t val);
1317-int buffer_append_off_t(buffer *b, off_t val);
1318-#endif
1319-
1320-int buffer_append_memory(buffer *b, const char *s, size_t s_len);
1321+buffer* buffer_init_buffer(const buffer *src); /* src can be NULL */
1322+buffer* buffer_init_string(const char *str); /* str can be NULL */
1323+
1324+void buffer_free(buffer *b); /* b can be NULL */
1325+/* truncates to used == 0; frees large buffers, might keep smaller ones for reuse */
1326+void buffer_reset(buffer *b); /* b can be NULL */
1327+
1328+/* reset b. if NULL != b && NULL != src, move src content to b. reset src. */
1329+void buffer_move(buffer *b, buffer *src);
1330+
1331+/* prepare for size bytes in the buffer (b->size > size), destroys content
1332+ * (sets used = 0 and ptr[0] = 0). allocates storage for terminating 0.
1333+ * @return b->ptr
1334+ */
1335+char* buffer_prepare_copy(buffer *b, size_t size);
1336+
1337+/* prepare for appending size bytes to the buffer
1338+ * allocates storage for terminating 0; if used > 0 assumes ptr[used-1] == 0,
1339+ * i.e. doesn't allocate another byte for terminating 0.
1340+ * @return (b->used > 0 ? b->ptr + b->used - 1 : b->ptr) - first new character
1341+ */
1342+char* buffer_prepare_append(buffer *b, size_t size);
1343+
1344+/* use after prepare_(copy,append) when you have written data to the buffer
1345+ * to increase the buffer length by size. also sets the terminating zero.
1346+ * requires enough space is present for the terminating zero (prepare with the
1347+ * same size to be sure).
1348+ */
1349+void buffer_commit(buffer *b, size_t size);
1350+
1351+void buffer_copy_string(buffer *b, const char *s);
1352+void buffer_copy_string_len(buffer *b, const char *s, size_t s_len);
1353+void buffer_copy_buffer(buffer *b, const buffer *src);
1354+/* convert input to hex and store in buffer */
1355+void buffer_copy_string_hex(buffer *b, const char *in, size_t in_len);
1356+
1357+void buffer_append_string(buffer *b, const char *s);
1358+void buffer_append_string_len(buffer *b, const char *s, size_t s_len);
1359+void buffer_append_string_buffer(buffer *b, const buffer *src);
1360+
1361+void buffer_append_long_hex(buffer *b, unsigned long len);
1362+void buffer_append_int(buffer *b, intmax_t val);
1363+void buffer_copy_int(buffer *b, intmax_t val);
1364+
1365+/* '-', log_10 (2^bits) = bits * log 2 / log 10 < bits * 0.31, terminating 0 */
1366+#define LI_ITOSTRING_LENGTH (2 + (8 * sizeof(intmax_t) * 31 + 99) / 100)
1367+
1368+void li_itostrn(char *buf, size_t buf_len, intmax_t val);
1369+void li_itostr(char *buf, intmax_t val); /* buf must have at least LI_ITOSTRING_LENGTH bytes */
1370+void li_utostrn(char *buf, size_t buf_len, uintmax_t val);
1371+void li_utostr(char *buf, uintmax_t val); /* buf must have at least LI_ITOSTRING_LENGTH bytes */
1372
1373 char * buffer_search_string_len(buffer *b, const char *needle, size_t len);
1374
1375+/* NULL buffer or empty buffer (used == 0);
1376+ * unset "string" (buffer) config options are initialized to used == 0,
1377+ * while setting an empty string leads to used == 1
1378+ */
1379 int buffer_is_empty(buffer *b);
1380+/* NULL buffer, empty buffer (used == 0) or empty string (used == 1) */
1381+int buffer_string_is_empty(buffer *b);
1382+
1383 int buffer_is_equal(buffer *a, buffer *b);
1384 int buffer_is_equal_right_len(buffer *a, buffer *b, size_t len);
1385 int buffer_is_equal_string(buffer *a, const char *s, size_t b_len);
1386@@ -86,7 +108,6 @@ int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len);
1387 int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len);
1388
1389 typedef enum {
1390- ENCODING_UNSET,
1391 ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
1392 ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */
1393 ENCODING_HTML, /* & becomes &amp; and so on */
1394@@ -95,17 +116,17 @@ typedef enum {
1395 ENCODING_HTTP_HEADER /* encode \n with \t\n */
1396 } buffer_encoding_t;
1397
1398-int buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding);
1399+void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding);
1400+
1401+void buffer_urldecode_path(buffer *url);
1402+void buffer_urldecode_query(buffer *url);
1403+void buffer_path_simplify(buffer *dest, buffer *src);
1404
1405-int buffer_urldecode_path(buffer *url);
1406-int buffer_urldecode_query(buffer *url);
1407-int buffer_path_simplify(buffer *dest, buffer *src);
1408+void buffer_to_lower(buffer *b);
1409+void buffer_to_upper(buffer *b);
1410
1411-int buffer_to_lower(buffer *b);
1412-int buffer_to_upper(buffer *b);
1413
1414 /** deprecated */
1415-int LI_ltostr(char *buf, long val);
1416 char hex2int(unsigned char c);
1417 char int2hex(char i);
1418
1419@@ -114,17 +135,17 @@ int light_isxdigit(int c);
1420 int light_isalpha(int c);
1421 int light_isalnum(int c);
1422
1423+static inline size_t buffer_string_length(const buffer *b); /* buffer string length without terminating 0 */
1424+static inline void buffer_append_slash(buffer *b); /* append '/' no non-empty strings not ending in '/' */
1425+
1426 #define BUFFER_APPEND_STRING_CONST(x, y) \
1427 buffer_append_string_len(x, y, sizeof(y) - 1)
1428
1429 #define BUFFER_COPY_STRING_CONST(x, y) \
1430 buffer_copy_string_len(x, y, sizeof(y) - 1)
1431
1432-#define BUFFER_APPEND_SLASH(x) \
1433- if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); }
1434-
1435-#define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
1436-#define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
1437+#define CONST_STR_LEN(x) x, (x) ? sizeof(x) - 1 : 0
1438+#define CONST_BUF_LEN(x) (x)->ptr, buffer_string_length(x)
1439
1440
1441 #define UNUSED(x) ( (void)(x) )
1442@@ -134,4 +155,15 @@ void log_failed_assert(const char *filename, unsigned int line, const char *msg)
1443 #define force_assert(x) do { if (!(x)) log_failed_assert(__FILE__, __LINE__, "assertion failed: " #x); } while(0)
1444 #define SEGFAULT() log_failed_assert(__FILE__, __LINE__, "aborted");
1445
1446+/* inline implementations */
1447+
1448+static inline size_t buffer_string_length(const buffer *b) {
1449+ return NULL != b && 0 != b->used ? b->used - 1 : 0;
1450+}
1451+
1452+static inline void buffer_append_slash(buffer *b) {
1453+ size_t len = buffer_string_length(b);
1454+ if (len > 0 && '/' != b->ptr[len-1]) BUFFER_APPEND_STRING_CONST(b, "/");
1455+}
1456+
1457 #endif
1458diff --git a/src/chunk.c b/src/chunk.c
1459index 7583db6..c991b82 100644
1460--- a/src/chunk.c
1461+++ b/src/chunk.c
1462@@ -36,30 +36,28 @@ static chunk *chunk_init(void) {
1463
1464 c = calloc(1, sizeof(*c));
1465
1466+ c->type = MEM_CHUNK;
1467 c->mem = buffer_init();
1468 c->file.name = buffer_init();
1469+ c->file.start = c->file.length = c->file.mmap.offset = 0;
1470 c->file.fd = -1;
1471 c->file.mmap.start = MAP_FAILED;
1472+ c->file.mmap.length = 0;
1473+ c->file.is_temp = 0;
1474+ c->offset = 0;
1475 c->next = NULL;
1476
1477 return c;
1478 }
1479
1480-static void chunk_free(chunk *c) {
1481- if (!c) return;
1482-
1483- buffer_free(c->mem);
1484- buffer_free(c->file.name);
1485-
1486- free(c);
1487-}
1488-
1489 static void chunk_reset(chunk *c) {
1490- if (!c) return;
1491+ if (NULL == c) return;
1492+
1493+ c->type = MEM_CHUNK;
1494
1495 buffer_reset(c->mem);
1496
1497- if (c->file.is_temp && !buffer_is_empty(c->file.name)) {
1498+ if (c->file.is_temp && !buffer_string_is_empty(c->file.name)) {
1499 unlink(c->file.name->ptr);
1500 }
1501
1502@@ -73,13 +71,28 @@ static void chunk_reset(chunk *c) {
1503 munmap(c->file.mmap.start, c->file.mmap.length);
1504 c->file.mmap.start = MAP_FAILED;
1505 }
1506+ c->file.start = c->file.length = c->file.mmap.offset = 0;
1507+ c->file.mmap.length = 0;
1508+ c->file.is_temp = 0;
1509+ c->offset = 0;
1510+ c->next = NULL;
1511 }
1512
1513+static void chunk_free(chunk *c) {
1514+ if (NULL == c) return;
1515+
1516+ chunk_reset(c);
1517+
1518+ buffer_free(c->mem);
1519+ buffer_free(c->file.name);
1520+
1521+ free(c);
1522+}
1523
1524 void chunkqueue_free(chunkqueue *cq) {
1525 chunk *c, *pc;
1526
1527- if (!cq) return;
1528+ if (NULL == cq) return;
1529
1530 for (c = cq->first; c; ) {
1531 pc = c;
1532@@ -96,11 +109,27 @@ void chunkqueue_free(chunkqueue *cq) {
1533 free(cq);
1534 }
1535
1536+static void chunkqueue_push_unused_chunk(chunkqueue *cq, chunk *c) {
1537+ force_assert(NULL != cq && NULL != c);
1538+
1539+ /* keep at max 4 chunks in the 'unused'-cache */
1540+ if (cq->unused_chunks > 4) {
1541+ chunk_free(c);
1542+ } else {
1543+ chunk_reset(c);
1544+ c->next = cq->unused;
1545+ cq->unused = c;
1546+ cq->unused_chunks++;
1547+ }
1548+}
1549+
1550 static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) {
1551 chunk *c;
1552
1553+ force_assert(NULL != cq);
1554+
1555 /* check if we have a unused chunk */
1556- if (!cq->unused) {
1557+ if (0 == cq->unused) {
1558 c = chunk_init();
1559 } else {
1560 /* take the first element from the list (a stack) */
1561@@ -113,130 +142,95 @@ static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) {
1562 return c;
1563 }
1564
1565-static int chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) {
1566+static void chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) {
1567 c->next = cq->first;
1568 cq->first = c;
1569
1570- if (cq->last == NULL) {
1571+ if (NULL == cq->last) {
1572 cq->last = c;
1573 }
1574-
1575- return 0;
1576 }
1577
1578-static int chunkqueue_append_chunk(chunkqueue *cq, chunk *c) {
1579+static void chunkqueue_append_chunk(chunkqueue *cq, chunk *c) {
1580 if (cq->last) {
1581 cq->last->next = c;
1582 }
1583 cq->last = c;
1584
1585- if (cq->first == NULL) {
1586+ if (NULL == cq->first) {
1587 cq->first = c;
1588 }
1589-
1590- return 0;
1591 }
1592
1593 void chunkqueue_reset(chunkqueue *cq) {
1594- chunk *c;
1595- /* move everything to the unused queue */
1596+ chunk *cur = cq->first;
1597
1598- /* mark all read written */
1599- for (c = cq->first; c; c = c->next) {
1600- switch(c->type) {
1601- case MEM_CHUNK:
1602- c->offset = c->mem->used - 1;
1603- break;
1604- case FILE_CHUNK:
1605- c->offset = c->file.length;
1606- break;
1607- default:
1608- break;
1609- }
1610+ cq->first = cq->last = NULL;
1611+
1612+ while (NULL != cur) {
1613+ chunk *next = cur->next;
1614+ chunkqueue_push_unused_chunk(cq, cur);
1615+ cur = next;
1616 }
1617
1618- chunkqueue_remove_finished_chunks(cq);
1619 cq->bytes_in = 0;
1620 cq->bytes_out = 0;
1621 }
1622
1623-int chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) {
1624+void chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) {
1625 chunk *c;
1626
1627- if (len == 0) return 0;
1628+ if (0 == len) return;
1629
1630 c = chunkqueue_get_unused_chunk(cq);
1631
1632 c->type = FILE_CHUNK;
1633
1634- buffer_copy_string_buffer(c->file.name, fn);
1635+ buffer_copy_buffer(c->file.name, fn);
1636 c->file.start = offset;
1637 c->file.length = len;
1638 c->offset = 0;
1639
1640 chunkqueue_append_chunk(cq, c);
1641-
1642- return 0;
1643 }
1644
1645-int chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) {
1646+void chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) {
1647 chunk *c;
1648
1649- if (mem->used == 0) return 0;
1650-
1651- c = chunkqueue_get_unused_chunk(cq);
1652- c->type = MEM_CHUNK;
1653- c->offset = 0;
1654- buffer_copy_string_buffer(c->mem, mem);
1655-
1656- chunkqueue_append_chunk(cq, c);
1657-
1658- return 0;
1659-}
1660-
1661-int chunkqueue_append_buffer_weak(chunkqueue *cq, buffer *mem) {
1662- chunk *c;
1663+ if (buffer_string_is_empty(mem)) return;
1664
1665 c = chunkqueue_get_unused_chunk(cq);
1666 c->type = MEM_CHUNK;
1667- c->offset = 0;
1668- if (c->mem) buffer_free(c->mem);
1669- c->mem = mem;
1670+ force_assert(NULL != c->mem);
1671+ buffer_move(c->mem, mem);
1672
1673 chunkqueue_append_chunk(cq, c);
1674-
1675- return 0;
1676 }
1677
1678-int chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) {
1679+void chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) {
1680 chunk *c;
1681
1682- if (mem->used == 0) return 0;
1683+ if (buffer_string_is_empty(mem)) return;
1684
1685 c = chunkqueue_get_unused_chunk(cq);
1686 c->type = MEM_CHUNK;
1687- c->offset = 0;
1688- buffer_copy_string_buffer(c->mem, mem);
1689+ force_assert(NULL != c->mem);
1690+ buffer_move(c->mem, mem);
1691
1692 chunkqueue_prepend_chunk(cq, c);
1693-
1694- return 0;
1695 }
1696
1697
1698-int chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
1699+void chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
1700 chunk *c;
1701
1702- if (len == 0) return 0;
1703+ if (0 == len) return;
1704
1705 c = chunkqueue_get_unused_chunk(cq);
1706 c->type = MEM_CHUNK;
1707- c->offset = 0;
1708- buffer_copy_string_len(c->mem, mem, len - 1);
1709+ buffer_copy_string_len(c->mem, mem, len);
1710
1711 chunkqueue_append_chunk(cq, c);
1712-
1713- return 0;
1714 }
1715
1716 buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) {
1717@@ -245,8 +239,6 @@ buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) {
1718 c = chunkqueue_get_unused_chunk(cq);
1719
1720 c->type = MEM_CHUNK;
1721- c->offset = 0;
1722- buffer_reset(c->mem);
1723
1724 chunkqueue_prepend_chunk(cq, c);
1725
1726@@ -259,20 +251,15 @@ buffer *chunkqueue_get_append_buffer(chunkqueue *cq) {
1727 c = chunkqueue_get_unused_chunk(cq);
1728
1729 c->type = MEM_CHUNK;
1730- c->offset = 0;
1731- buffer_reset(c->mem);
1732
1733 chunkqueue_append_chunk(cq, c);
1734
1735 return c->mem;
1736 }
1737
1738-int chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs) {
1739- if (!cq) return -1;
1740-
1741+void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs) {
1742+ force_assert(NULL != cq);
1743 cq->tempdirs = tempdirs;
1744-
1745- return 0;
1746 }
1747
1748 chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
1749@@ -282,7 +269,6 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
1750 c = chunkqueue_get_unused_chunk(cq);
1751
1752 c->type = FILE_CHUNK;
1753- c->offset = 0;
1754
1755 if (cq->tempdirs && cq->tempdirs->used) {
1756 size_t i;
1757@@ -292,8 +278,8 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
1758 for (i = 0; i < cq->tempdirs->used; i++) {
1759 data_string *ds = (data_string *)cq->tempdirs->data[i];
1760
1761- buffer_copy_string_buffer(template, ds->value);
1762- BUFFER_APPEND_SLASH(template);
1763+ buffer_copy_buffer(template, ds->value);
1764+ buffer_append_slash(template);
1765 buffer_append_string_len(template, CONST_STR_LEN("lighttpd-upload-XXXXXX"));
1766
1767 if (-1 != (c->file.fd = mkstemp(template->ptr))) {
1768@@ -309,7 +295,7 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
1769 }
1770 }
1771
1772- buffer_copy_string_buffer(c->file.name, template);
1773+ buffer_copy_buffer(c->file.name, template);
1774 c->file.length = 0;
1775
1776 chunkqueue_append_chunk(cq, c);
1777@@ -319,82 +305,102 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
1778 return c;
1779 }
1780
1781+void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) {
1782+ while (len > 0) {
1783+ chunk *c = src->first;
1784+ off_t clen = 0;
1785
1786-off_t chunkqueue_length(chunkqueue *cq) {
1787- off_t len = 0;
1788- chunk *c;
1789+ if (NULL == c) break;
1790
1791- for (c = cq->first; c; c = c->next) {
1792 switch (c->type) {
1793 case MEM_CHUNK:
1794- len += c->mem->used ? c->mem->used - 1 : 0;
1795+ clen = buffer_string_length(c->mem);
1796 break;
1797 case FILE_CHUNK:
1798- len += c->file.length;
1799+ clen = c->file.length;
1800 break;
1801- default:
1802+ }
1803+ force_assert(clen >= c->offset);
1804+ clen -= c->offset;
1805+
1806+ if (len >= clen) {
1807+ /* move complete chunk */
1808+ src->first = c->next;
1809+ if (c == src->last) src->last = NULL;
1810+
1811+ chunkqueue_append_chunk(dest, c);
1812+ src->bytes_out += clen;
1813+ dest->bytes_in += clen;
1814+ len -= clen;
1815+ continue;
1816+ }
1817+
1818+ /* partial chunk with length "len" */
1819+
1820+ switch (c->type) {
1821+ case MEM_CHUNK:
1822+ chunkqueue_append_mem(dest, c->mem->ptr + c->offset, len);
1823+ break;
1824+ case FILE_CHUNK:
1825+ /* tempfile flag is in "last" chunk after the split */
1826+ chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, len);
1827 break;
1828 }
1829- }
1830
1831- return len;
1832+ c->offset += len;
1833+ src->bytes_out += len;
1834+ dest->bytes_in += len;
1835+ len = 0;
1836+ }
1837 }
1838
1839-off_t chunkqueue_written(chunkqueue *cq) {
1840+off_t chunkqueue_length(chunkqueue *cq) {
1841 off_t len = 0;
1842 chunk *c;
1843
1844 for (c = cq->first; c; c = c->next) {
1845+ off_t c_len = 0;
1846+
1847 switch (c->type) {
1848 case MEM_CHUNK:
1849- case FILE_CHUNK:
1850- len += c->offset;
1851+ c_len = buffer_string_length(c->mem);
1852 break;
1853- default:
1854+ case FILE_CHUNK:
1855+ c_len = c->file.length;
1856 break;
1857 }
1858+ force_assert(c_len >= c->offset);
1859+ len += c_len - c->offset;
1860 }
1861
1862 return len;
1863 }
1864
1865 int chunkqueue_is_empty(chunkqueue *cq) {
1866- return cq->first ? 0 : 1;
1867+ return NULL == cq->first;
1868 }
1869
1870-int chunkqueue_remove_finished_chunks(chunkqueue *cq) {
1871+void chunkqueue_remove_finished_chunks(chunkqueue *cq) {
1872 chunk *c;
1873
1874 for (c = cq->first; c; c = cq->first) {
1875- int is_finished = 0;
1876+ off_t c_len = 0;
1877
1878 switch (c->type) {
1879 case MEM_CHUNK:
1880- if (c->mem->used == 0 || (c->offset == (off_t)c->mem->used - 1)) is_finished = 1;
1881+ c_len = buffer_string_length(c->mem);
1882 break;
1883 case FILE_CHUNK:
1884- if (c->offset == c->file.length) is_finished = 1;
1885- break;
1886- default:
1887+ c_len = c->file.length;
1888 break;
1889 }
1890+ force_assert(c_len >= c->offset);
1891
1892- if (!is_finished) break;
1893-
1894- chunk_reset(c);
1895+ if (c_len > c->offset) break; /* not finished yet */
1896
1897 cq->first = c->next;
1898 if (c == cq->last) cq->last = NULL;
1899
1900- /* keep at max 4 chunks in the 'unused'-cache */
1901- if (cq->unused_chunks > 4) {
1902- chunk_free(c);
1903- } else {
1904- c->next = cq->unused;
1905- cq->unused = c;
1906- cq->unused_chunks++;
1907- }
1908+ chunkqueue_push_unused_chunk(cq, c);
1909 }
1910-
1911- return 0;
1912 }
1913diff --git a/src/chunk.h b/src/chunk.h
1914index e43d3eb..6559000 100644
1915--- a/src/chunk.h
1916+++ b/src/chunk.h
1917@@ -6,7 +6,7 @@
1918 #include "sys-mmap.h"
1919
1920 typedef struct chunk {
1921- enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type;
1922+ enum { MEM_CHUNK, FILE_CHUNK } type;
1923
1924 buffer *mem; /* either the storage of the mem-chunk or the read-ahead buffer */
1925
1926@@ -48,21 +48,21 @@ typedef struct {
1927 } chunkqueue;
1928
1929 chunkqueue *chunkqueue_init(void);
1930-int chunkqueue_set_tempdirs(chunkqueue *c, array *tempdirs);
1931-int chunkqueue_append_file(chunkqueue *c, buffer *fn, off_t offset, off_t len);
1932-int chunkqueue_append_mem(chunkqueue *c, const char *mem, size_t len);
1933-int chunkqueue_append_buffer(chunkqueue *c, buffer *mem);
1934-int chunkqueue_append_buffer_weak(chunkqueue *c, buffer *mem);
1935-int chunkqueue_prepend_buffer(chunkqueue *c, buffer *mem);
1936+void chunkqueue_set_tempdirs(chunkqueue *c, array *tempdirs);
1937+void chunkqueue_append_file(chunkqueue *c, buffer *fn, off_t offset, off_t len); /* copies "fn" */
1938+void chunkqueue_append_mem(chunkqueue *c, const char *mem, size_t len); /* copies memory */
1939+void chunkqueue_append_buffer(chunkqueue *c, buffer *mem); /* may reset "mem" */
1940+void chunkqueue_prepend_buffer(chunkqueue *c, buffer *mem); /* may reset "mem" */
1941
1942 buffer * chunkqueue_get_append_buffer(chunkqueue *c);
1943 buffer * chunkqueue_get_prepend_buffer(chunkqueue *c);
1944 chunk * chunkqueue_get_append_tempfile(chunkqueue *cq);
1945
1946-int chunkqueue_remove_finished_chunks(chunkqueue *cq);
1947+void chunkqueue_remove_finished_chunks(chunkqueue *cq);
1948+
1949+void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len);
1950
1951 off_t chunkqueue_length(chunkqueue *c);
1952-off_t chunkqueue_written(chunkqueue *c);
1953 void chunkqueue_free(chunkqueue *c);
1954 void chunkqueue_reset(chunkqueue *c);
1955
1956diff --git a/src/configfile-glue.c b/src/configfile-glue.c
1957index 9f24dcb..2fb8c62 100644
1958--- a/src/configfile-glue.c
1959+++ b/src/configfile-glue.c
1960@@ -46,12 +46,12 @@ int config_insert_values_internal(server *srv, array *ca, const config_values_t
1961 if (da->value->data[j]->type == TYPE_STRING) {
1962 data_string *ds = data_string_init();
1963
1964- buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
1965+ buffer_copy_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
1966 if (!da->is_index_key) {
1967 /* the id's were generated automaticly, as we copy now we might have to renumber them
1968 * this is used to prepend server.modules by mod_indexfile as it has to be loaded
1969 * before mod_fastcgi and friends */
1970- buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
1971+ buffer_copy_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
1972 }
1973
1974 array_insert_unique(cv[i].destination, (data_unset *)ds);
1975@@ -73,7 +73,7 @@ int config_insert_values_internal(server *srv, array *ca, const config_values_t
1976 if (du->type == TYPE_STRING) {
1977 data_string *ds = (data_string *)du;
1978
1979- buffer_copy_string_buffer(cv[i].destination, ds->value);
1980+ buffer_copy_buffer(cv[i].destination, ds->value);
1981 } else {
1982 log_error_write(srv, __FILE__, __LINE__, "ssss", cv[i].key, "should have been a string like ... = \"...\"");
1983
1984@@ -202,7 +202,7 @@ int config_insert_values_global(server *srv, array *ca, const config_values_t cv
1985 touched = data_string_init();
1986
1987 buffer_copy_string_len(touched->value, CONST_STR_LEN(""));
1988- buffer_copy_string_buffer(touched->key, du->key);
1989+ buffer_copy_buffer(touched->key, du->key);
1990
1991 array_insert_unique(srv->config_touched, (data_unset *)touched);
1992 }
1993@@ -285,7 +285,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
1994 case COMP_HTTP_HOST: {
1995 char *ck_colon = NULL, *val_colon = NULL;
1996
1997- if (!buffer_is_empty(con->uri.authority)) {
1998+ if (!buffer_string_is_empty(con->uri.authority)) {
1999
2000 /*
2001 * append server-port to the HTTP_POST if necessary
2002@@ -301,9 +301,9 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
2003
2004 if (NULL != ck_colon && NULL == val_colon) {
2005 /* condition "host:port" but client send "host" */
2006- buffer_copy_string_buffer(srv->cond_check_buf, l);
2007+ buffer_copy_buffer(srv->cond_check_buf, l);
2008 buffer_append_string_len(srv->cond_check_buf, CONST_STR_LEN(":"));
2009- buffer_append_long(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr)));
2010+ buffer_append_int(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr)));
2011 l = srv->cond_check_buf;
2012 } else if (NULL != val_colon && NULL == ck_colon) {
2013 /* condition "host" but client send "host:port" */
2014@@ -315,7 +315,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
2015 break;
2016 }
2017 #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
2018- } else if (!buffer_is_empty(con->tlsext_server_name)) {
2019+ } else if (!buffer_string_is_empty(con->tlsext_server_name)) {
2020 l = con->tlsext_server_name;
2021 #endif
2022 } else {
2023diff --git a/src/configfile.c b/src/configfile.c
2024index bf9a34d..2b09d86 100644
2025--- a/src/configfile.c
2026+++ b/src/configfile.c
2027@@ -273,7 +273,7 @@ static int config_insert(server *srv) {
2028 }
2029 }
2030
2031- if (buffer_is_empty(stat_cache_string)) {
2032+ if (buffer_string_is_empty(stat_cache_string)) {
2033 srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
2034 } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {
2035 srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
2036@@ -323,7 +323,7 @@ int config_setup_connection(server *srv, connection *con) {
2037 PATCH(global_bytes_per_second_cnt);
2038
2039 con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
2040- buffer_copy_string_buffer(con->server_name, s->server_name);
2041+ buffer_copy_buffer(con->server_name, s->server_name);
2042
2043 PATCH(log_request_header);
2044 PATCH(log_response_header);
2045@@ -442,7 +442,7 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) {
2046 PATCH(follow_symlink);
2047 #endif
2048 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.name"))) {
2049- buffer_copy_string_buffer(con->server_name, s->server_name);
2050+ buffer_copy_buffer(con->server_name, s->server_name);
2051 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.tag"))) {
2052 PATCH(server_tag);
2053 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("connection.kbytes-per-second"))) {
2054@@ -512,7 +512,7 @@ typedef struct {
2055
2056 #if 0
2057 static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) {
2058- if (buffer_is_empty(basedir) ||
2059+ if (buffer_string_is_empty(basedir) ||
2060 (fn[0] == '/' || fn[0] == '\\') ||
2061 (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {
2062 t->file = buffer_init_string(fn);
2063@@ -934,7 +934,7 @@ static int config_parse(server *srv, config_t *context, tokenizer_t *t) {
2064 lasttoken = buffer_init();
2065 token = buffer_init();
2066 while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) {
2067- buffer_copy_string_buffer(lasttoken, token);
2068+ buffer_copy_buffer(lasttoken, token);
2069 configparser(pParser, token_id, token, context);
2070
2071 token = buffer_init();
2072@@ -986,7 +986,7 @@ int config_parse_file(server *srv, config_t *context, const char *fn) {
2073 int ret;
2074 buffer *filename;
2075
2076- if (buffer_is_empty(context->basedir) ||
2077+ if (buffer_string_is_empty(context->basedir) ||
2078 (fn[0] == '/' || fn[0] == '\\') ||
2079 (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {
2080 filename = buffer_init_string(fn);
2081@@ -1057,7 +1057,7 @@ int config_parse_cmd(server *srv, config_t *context, const char *cmd) {
2082 source = buffer_init_string(cmd);
2083 out = buffer_init();
2084
2085- if (!buffer_is_empty(context->basedir)) {
2086+ if (!buffer_string_is_empty(context->basedir)) {
2087 chdir(context->basedir->ptr);
2088 }
2089
2090@@ -1173,7 +1173,7 @@ int config_read(server *srv, const char *fn) {
2091
2092 prepends = (data_array *)configparser_merge_data((data_unset *)prepends, (data_unset *)modules);
2093 force_assert(NULL != prepends);
2094- buffer_copy_string_buffer(prepends->key, modules->key);
2095+ buffer_copy_buffer(prepends->key, modules->key);
2096 array_replace(srv->config, (data_unset *)prepends);
2097 modules->free((data_unset *)modules);
2098 modules = prepends;
2099@@ -1255,7 +1255,7 @@ int config_set_defaults(server *srv) {
2100 { FDEVENT_HANDLER_UNSET, NULL }
2101 };
2102
2103- if (!buffer_is_empty(srv->srvconf.changeroot)) {
2104+ if (!buffer_string_is_empty(srv->srvconf.changeroot)) {
2105 if (-1 == stat(srv->srvconf.changeroot->ptr, &st1)) {
2106 log_error_write(srv, __FILE__, __LINE__, "sb",
2107 "server.chroot doesn't exist:", srv->srvconf.changeroot);
2108@@ -1268,14 +1268,14 @@ int config_set_defaults(server *srv) {
2109 }
2110 }
2111
2112- if (buffer_is_empty(s->document_root)) {
2113+ if (buffer_string_is_empty(s->document_root)) {
2114 log_error_write(srv, __FILE__, __LINE__, "s",
2115 "a default document-root has to be set");
2116
2117 return -1;
2118 }
2119
2120- buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
2121+ buffer_copy_buffer(srv->tmp_buf, s->document_root);
2122
2123 buffer_to_lower(srv->tmp_buf);
2124
2125@@ -1288,7 +1288,7 @@ int config_set_defaults(server *srv) {
2126 is_lower = buffer_is_equal(srv->tmp_buf, s->document_root);
2127
2128 /* lower-case existed, check upper-case */
2129- buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
2130+ buffer_copy_buffer(srv->tmp_buf, s->document_root);
2131
2132 buffer_to_upper(srv->tmp_buf);
2133
2134@@ -1356,7 +1356,7 @@ int config_set_defaults(server *srv) {
2135 }
2136
2137 if (s->ssl_enabled) {
2138- if (buffer_is_empty(s->ssl_pemfile)) {
2139+ if (buffer_string_is_empty(s->ssl_pemfile)) {
2140 /* PEM file is require */
2141
2142 log_error_write(srv, __FILE__, __LINE__, "s",
2143diff --git a/src/configparser.y b/src/configparser.y
2144index efa4afd..e4a4f51 100644
2145--- a/src/configparser.y
2146+++ b/src/configparser.y
2147@@ -61,11 +61,11 @@ data_unset *configparser_merge_data(data_unset *op1, const data_unset *op2) {
2148 if (op1->type != op2->type) {
2149 if (op1->type == TYPE_STRING && op2->type == TYPE_INTEGER) {
2150 data_string *ds = (data_string *)op1;
2151- buffer_append_long(ds->value, ((data_integer*)op2)->value);
2152+ buffer_append_int(ds->value, ((data_integer*)op2)->value);
2153 return op1;
2154 } else if (op1->type == TYPE_INTEGER && op2->type == TYPE_STRING) {
2155 data_string *ds = data_string_init();
2156- buffer_append_long(ds->value, ((data_integer*)op1)->value);
2157+ buffer_append_int(ds->value, ((data_integer*)op1)->value);
2158 buffer_append_string_buffer(ds->value, ((data_string*)op2)->value);
2159 op1->free(op1);
2160 return (data_unset *)ds;
2161@@ -145,7 +145,7 @@ metaline ::= EOL.
2162
2163 varline ::= key(A) ASSIGN expression(B). {
2164 if (ctx->ok) {
2165- buffer_copy_string_buffer(B->key, A);
2166+ buffer_copy_buffer(B->key, A);
2167 if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
2168 fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
2169 ctx->current->context_ndx,
2170@@ -183,7 +183,7 @@ varline ::= key(A) APPEND expression(B). {
2171 ctx->ok = 0;
2172 }
2173 else {
2174- buffer_copy_string_buffer(du->key, A);
2175+ buffer_copy_buffer(du->key, A);
2176 array_replace(vars, du);
2177 }
2178 B->free(B);
2179@@ -193,12 +193,12 @@ varline ::= key(A) APPEND expression(B). {
2180 ctx->ok = 0;
2181 }
2182 else {
2183- buffer_copy_string_buffer(du->key, A);
2184+ buffer_copy_buffer(du->key, A);
2185 array_insert_unique(ctx->current->value, du);
2186 }
2187 B->free(B);
2188 } else {
2189- buffer_copy_string_buffer(B->key, A);
2190+ buffer_copy_buffer(B->key, A);
2191 array_insert_unique(ctx->current->value, B);
2192 }
2193 buffer_free(A);
2194@@ -262,7 +262,7 @@ value(A) ::= key(B). {
2195
2196 value(A) ::= STRING(B). {
2197 A = (data_unset *)data_string_init();
2198- buffer_copy_string_buffer(((data_string *)(A))->value, B);
2199+ buffer_copy_buffer(((data_string *)(A))->value, B);
2200 buffer_free(B);
2201 B = NULL;
2202 }
2203@@ -320,7 +320,7 @@ aelement(A) ::= expression(B). {
2204 B = NULL;
2205 }
2206 aelement(A) ::= stringop(B) ARRAY_ASSIGN expression(C). {
2207- buffer_copy_string_buffer(C->key, B);
2208+ buffer_copy_buffer(C->key, B);
2209 buffer_free(B);
2210 B = NULL;
2211
2212@@ -405,7 +405,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio
2213 }
2214
2215 b = buffer_init();
2216- buffer_copy_string_buffer(b, ctx->current->key);
2217+ buffer_copy_buffer(b, ctx->current->key);
2218 buffer_append_string(b, "/");
2219 buffer_append_string_buffer(b, B);
2220 buffer_append_string_buffer(b, C);
2221@@ -441,9 +441,9 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio
2222
2223 dc = data_config_init();
2224
2225- buffer_copy_string_buffer(dc->key, b);
2226- buffer_copy_string_buffer(dc->op, op);
2227- buffer_copy_string_buffer(dc->comp_key, B);
2228+ buffer_copy_buffer(dc->key, b);
2229+ buffer_copy_buffer(dc->op, op);
2230+ buffer_copy_buffer(dc->comp_key, B);
2231 buffer_append_string_len(dc->comp_key, CONST_STR_LEN("[\""));
2232 buffer_append_string_buffer(dc->comp_key, C);
2233 buffer_append_string_len(dc->comp_key, CONST_STR_LEN("\"]"));
2234@@ -546,7 +546,7 @@ stringop(A) ::= expression(B). {
2235 A = buffer_init_buffer(((data_string*)B)->value);
2236 } else if (B->type == TYPE_INTEGER) {
2237 A = buffer_init();
2238- buffer_copy_long(A, ((data_integer *)B)->value);
2239+ buffer_copy_int(A, ((data_integer *)B)->value);
2240 } else {
2241 fprintf(stderr, "operand must be string");
2242 ctx->ok = 0;
2243diff --git a/src/connections.c b/src/connections.c
2244index fe683a2..bc770bf 100644
2245--- a/src/connections.c
2246+++ b/src/connections.c
2247@@ -212,7 +212,7 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
2248 b = chunkqueue_get_append_buffer(con->read_queue);
2249 len = SSL_pending(con->ssl);
2250 if (len < 4*1024) len = 4*1024; /* always alloc >= 4k buffer */
2251- buffer_prepare_copy(b, len + 1);
2252+ buffer_prepare_copy(b, len);
2253
2254 /* overwrite everything with 0 */
2255 memset(b->ptr, 0, b->size);
2256@@ -362,7 +362,7 @@ static int connection_handle_read(server *srv, connection *con) {
2257 } else {
2258 if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
2259 b = chunkqueue_get_append_buffer(con->read_queue);
2260- buffer_prepare_copy(b, toread + 1);
2261+ buffer_prepare_copy(b, toread);
2262 }
2263
2264 read_offset = (b->used == 0) ? 0 : b->used - 1;
2265@@ -473,11 +473,11 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
2266 buffer_reset(con->physical.path);
2267
2268 /* try to send static errorfile */
2269- if (!buffer_is_empty(con->conf.errorfile_prefix)) {
2270+ if (!buffer_string_is_empty(con->conf.errorfile_prefix)) {
2271 stat_cache_entry *sce = NULL;
2272
2273- buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix);
2274- buffer_append_long(con->physical.path, con->http_status);
2275+ buffer_copy_buffer(con->physical.path, con->conf.errorfile_prefix);
2276+ buffer_append_int(con->physical.path, con->http_status);
2277 buffer_append_string_len(con->physical.path, CONST_STR_LEN(".html"));
2278
2279 if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
2280@@ -504,7 +504,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
2281 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
2282 " <head>\n"
2283 " <title>"));
2284- buffer_append_long(b, con->http_status);
2285+ buffer_append_int(b, con->http_status);
2286 buffer_append_string_len(b, CONST_STR_LEN(" - "));
2287 buffer_append_string(b, get_http_status_name(con->http_status));
2288
2289@@ -513,7 +513,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
2290 " </head>\n"
2291 " <body>\n"
2292 " <h1>"));
2293- buffer_append_long(b, con->http_status);
2294+ buffer_append_int(b, con->http_status);
2295 buffer_append_string_len(b, CONST_STR_LEN(" - "));
2296 buffer_append_string(b, get_http_status_name(con->http_status));
2297
2298@@ -554,7 +554,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
2299 /* qlen = 0 is important for Redirects (301, ...) as they MAY have
2300 * a content. Browsers are waiting for a Content otherwise
2301 */
2302- buffer_copy_off_t(srv->tmp_buf, qlen);
2303+ buffer_copy_int(srv->tmp_buf, qlen);
2304
2305 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));
2306 }
2307@@ -1135,7 +1135,7 @@ found_header_end:
2308 } else {
2309 b = chunkqueue_get_append_buffer(dst_cq);
2310 /* prepare buffer size for remaining POST data; is < 64kb */
2311- buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in + 1);
2312+ buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in);
2313 }
2314 buffer_append_string_len(b, c->mem->ptr + c->offset, toRead);
2315 }
2316@@ -1430,17 +1430,17 @@ int connection_state_machine(server *srv, connection *con) {
2317 /* 404 error-handler */
2318
2319 if (con->in_error_handler == 0 &&
2320- (!buffer_is_empty(con->conf.error_handler) ||
2321- !buffer_is_empty(con->error_handler))) {
2322+ (!buffer_string_is_empty(con->conf.error_handler) ||
2323+ !buffer_string_is_empty(con->error_handler))) {
2324 /* call error-handler */
2325
2326 con->error_handler_saved_status = con->http_status;
2327 con->http_status = 0;
2328
2329- if (buffer_is_empty(con->error_handler)) {
2330- buffer_copy_string_buffer(con->request.uri, con->conf.error_handler);
2331+ if (buffer_string_is_empty(con->error_handler)) {
2332+ buffer_copy_buffer(con->request.uri, con->conf.error_handler);
2333 } else {
2334- buffer_copy_string_buffer(con->request.uri, con->error_handler);
2335+ buffer_copy_buffer(con->request.uri, con->error_handler);
2336 }
2337 buffer_reset(con->physical.path);
2338
2339diff --git a/src/data_array.c b/src/data_array.c
2340index 094d8c0..ad96207 100644
2341--- a/src/data_array.c
2342+++ b/src/data_array.c
2343@@ -8,7 +8,7 @@ static data_unset *data_array_copy(const data_unset *s) {
2344 data_array *src = (data_array *)s;
2345 data_array *ds = data_array_init();
2346
2347- buffer_copy_string_buffer(ds->key, src->key);
2348+ buffer_copy_buffer(ds->key, src->key);
2349 array_free(ds->value);
2350 ds->value = array_init_array(src->value);
2351 ds->is_index_key = src->is_index_key;
2352diff --git a/src/data_config.c b/src/data_config.c
2353index 80e38de..b05ba20 100644
2354--- a/src/data_config.c
2355+++ b/src/data_config.c
2356@@ -8,8 +8,8 @@ static data_unset *data_config_copy(const data_unset *s) {
2357 data_config *src = (data_config *)s;
2358 data_config *ds = data_config_init();
2359
2360- buffer_copy_string_buffer(ds->key, src->key);
2361- buffer_copy_string_buffer(ds->comp_key, src->comp_key);
2362+ buffer_copy_buffer(ds->key, src->key);
2363+ buffer_copy_buffer(ds->comp_key, src->comp_key);
2364 array_free(ds->value);
2365 ds->value = array_init_array(src->value);
2366 return (data_unset *)ds;
2367diff --git a/src/data_count.c b/src/data_count.c
2368index 8d36c8b..0337224 100644
2369--- a/src/data_count.c
2370+++ b/src/data_count.c
2371@@ -8,7 +8,7 @@ static data_unset *data_count_copy(const data_unset *s) {
2372 data_count *src = (data_count *)s;
2373 data_count *ds = data_count_init();
2374
2375- buffer_copy_string_buffer(ds->key, src->key);
2376+ buffer_copy_buffer(ds->key, src->key);
2377 ds->count = src->count;
2378 ds->is_index_key = src->is_index_key;
2379 return (data_unset *)ds;
2380diff --git a/src/data_fastcgi.c b/src/data_fastcgi.c
2381index e13a470..a312506 100644
2382--- a/src/data_fastcgi.c
2383+++ b/src/data_fastcgi.c
2384@@ -9,8 +9,8 @@ static data_unset *data_fastcgi_copy(const data_unset *s) {
2385 data_fastcgi *src = (data_fastcgi *)s;
2386 data_fastcgi *ds = data_fastcgi_init();
2387
2388- buffer_copy_string_buffer(ds->key, src->key);
2389- buffer_copy_string_buffer(ds->host, src->host);
2390+ buffer_copy_buffer(ds->key, src->key);
2391+ buffer_copy_buffer(ds->host, src->host);
2392 ds->is_index_key = src->is_index_key;
2393 return (data_unset *)ds;
2394 }
2395diff --git a/src/data_integer.c b/src/data_integer.c
2396index 63cbb10..5cfe11b 100644
2397--- a/src/data_integer.c
2398+++ b/src/data_integer.c
2399@@ -8,7 +8,7 @@ static data_unset *data_integer_copy(const data_unset *s) {
2400 data_integer *src = (data_integer *)s;
2401 data_integer *ds = data_integer_init();
2402
2403- buffer_copy_string_buffer(ds->key, src->key);
2404+ buffer_copy_buffer(ds->key, src->key);
2405 ds->is_index_key = src->is_index_key;
2406 ds->value = src->value;
2407 return (data_unset *)ds;
2408diff --git a/src/data_string.c b/src/data_string.c
2409index 41c9ec1..fc57de2 100644
2410--- a/src/data_string.c
2411+++ b/src/data_string.c
2412@@ -9,8 +9,8 @@ static data_unset *data_string_copy(const data_unset *s) {
2413 data_string *src = (data_string *)s;
2414 data_string *ds = data_string_init();
2415
2416- buffer_copy_string_buffer(ds->key, src->key);
2417- buffer_copy_string_buffer(ds->value, src->value);
2418+ buffer_copy_buffer(ds->key, src->key);
2419+ buffer_copy_buffer(ds->value, src->value);
2420 ds->is_index_key = src->is_index_key;
2421 return (data_unset *)ds;
2422 }
2423@@ -40,7 +40,7 @@ static int data_string_insert_dup(data_unset *dst, data_unset *src) {
2424 buffer_append_string_len(ds_dst->value, CONST_STR_LEN(", "));
2425 buffer_append_string_buffer(ds_dst->value, ds_src->value);
2426 } else {
2427- buffer_copy_string_buffer(ds_dst->value, ds_src->value);
2428+ buffer_copy_buffer(ds_dst->value, ds_src->value);
2429 }
2430
2431 src->free(src);
2432@@ -58,7 +58,7 @@ static int data_response_insert_dup(data_unset *dst, data_unset *src) {
2433 buffer_append_string_len(ds_dst->value, CONST_STR_LEN(": "));
2434 buffer_append_string_buffer(ds_dst->value, ds_src->value);
2435 } else {
2436- buffer_copy_string_buffer(ds_dst->value, ds_src->value);
2437+ buffer_copy_buffer(ds_dst->value, ds_src->value);
2438 }
2439
2440 src->free(src);
2441diff --git a/src/etag.c b/src/etag.c
2442index e7e9e3f..bf63d94 100644
2443--- a/src/etag.c
2444+++ b/src/etag.c
2445@@ -10,7 +10,7 @@
2446 #include <string.h>
2447
2448 int etag_is_equal(buffer *etag, const char *matches) {
2449- if (etag && !buffer_is_empty(etag) && 0 == strcmp(etag->ptr, matches)) return 1;
2450+ if (etag && !buffer_string_is_empty(etag) && 0 == strcmp(etag->ptr, matches)) return 1;
2451 return 0;
2452 }
2453
2454@@ -20,17 +20,17 @@ int etag_create(buffer *etag, struct stat *st,etag_flags_t flags) {
2455 buffer_reset(etag);
2456
2457 if (flags & ETAG_USE_INODE) {
2458- buffer_append_off_t(etag, st->st_ino);
2459+ buffer_append_int(etag, st->st_ino);
2460 buffer_append_string_len(etag, CONST_STR_LEN("-"));
2461 }
2462
2463 if (flags & ETAG_USE_SIZE) {
2464- buffer_append_off_t(etag, st->st_size);
2465+ buffer_append_int(etag, st->st_size);
2466 buffer_append_string_len(etag, CONST_STR_LEN("-"));
2467 }
2468
2469 if (flags & ETAG_USE_MTIME) {
2470- buffer_append_long(etag, st->st_mtime);
2471+ buffer_append_int(etag, st->st_mtime);
2472 }
2473
2474 return 0;
2475@@ -44,7 +44,7 @@ int etag_mutate(buffer *mut, buffer *etag) {
2476
2477 buffer_reset(mut);
2478 buffer_copy_string_len(mut, CONST_STR_LEN("\""));
2479- buffer_append_off_t(mut, h);
2480+ buffer_append_int(mut, h);
2481 buffer_append_string_len(mut, CONST_STR_LEN("\""));
2482
2483 return 0;
2484diff --git a/src/http-header-glue.c b/src/http-header-glue.c
2485index fe2f4fb..abffb7d 100644
2486--- a/src/http-header-glue.c
2487+++ b/src/http-header-glue.c
2488@@ -123,7 +123,7 @@ int http_response_redirect_to_directory(server *srv, connection *con) {
2489
2490 o = buffer_init();
2491
2492- buffer_copy_string_buffer(o, con->uri.scheme);
2493+ buffer_copy_buffer(o, con->uri.scheme);
2494 buffer_append_string_len(o, CONST_STR_LEN("://"));
2495 if (con->uri.authority->used) {
2496 buffer_append_string_buffer(o, con->uri.authority);
2497@@ -197,13 +197,13 @@ int http_response_redirect_to_directory(server *srv, connection *con) {
2498 }
2499 if (default_port != srv->srvconf.port) {
2500 buffer_append_string_len(o, CONST_STR_LEN(":"));
2501- buffer_append_long(o, srv->srvconf.port);
2502+ buffer_append_int(o, srv->srvconf.port);
2503 }
2504 }
2505 }
2506 buffer_append_string_buffer(o, con->uri.path);
2507 buffer_append_string_len(o, CONST_STR_LEN("/"));
2508- if (!buffer_is_empty(con->uri.query)) {
2509+ if (!buffer_string_is_empty(con->uri.query)) {
2510 buffer_append_string_len(o, CONST_STR_LEN("?"));
2511 buffer_append_string_buffer(o, con->uri.query);
2512 }
2513diff --git a/src/http_auth.c b/src/http_auth.c
2514index e1d15e0..91e388c 100644
2515--- a/src/http_auth.c
2516+++ b/src/http_auth.c
2517@@ -172,7 +172,7 @@ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *
2518 stream f;
2519 char * f_line;
2520
2521- if (buffer_is_empty(p->conf.auth_htdigest_userfile)) return -1;
2522+ if (buffer_string_is_empty(p->conf.auth_htdigest_userfile)) return -1;
2523
2524 if (0 != stream_open(&f, p->conf.auth_htdigest_userfile)) {
2525 log_error_write(srv, __FILE__, __LINE__, "sbss", "opening digest-userfile", p->conf.auth_htdigest_userfile, "failed:", strerror(errno));
2526@@ -253,7 +253,7 @@ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *
2527
2528 auth_fn = (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) ? p->conf.auth_htpasswd_userfile : p->conf.auth_plain_userfile;
2529
2530- if (buffer_is_empty(auth_fn)) return -1;
2531+ if (buffer_string_is_empty(auth_fn)) return -1;
2532
2533 if (0 != stream_open(&f, auth_fn)) {
2534 log_error_write(srv, __FILE__, __LINE__, "sbss",
2535@@ -748,7 +748,7 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
2536 return -1;
2537
2538 /* build filter */
2539- buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
2540+ buffer_copy_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
2541 buffer_append_string_buffer(p->ldap_filter, username);
2542 buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post);
2543
2544@@ -903,7 +903,7 @@ int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p,
2545 }
2546
2547 /* remember the username */
2548- buffer_copy_string_buffer(p->auth_user, username);
2549+ buffer_copy_buffer(p->auth_user, username);
2550
2551 buffer_free(username);
2552 buffer_free(password);
2553@@ -1192,7 +1192,7 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
2554 int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer *fn, char out[33]) {
2555 HASH h;
2556 li_MD5_CTX Md5Ctx;
2557- char hh[32];
2558+ char hh[LI_ITOSTRING_LENGTH];
2559
2560 UNUSED(p);
2561
2562@@ -1202,10 +1202,10 @@ int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer
2563 li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
2564
2565 /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
2566- LI_ltostr(hh, srv->cur_ts);
2567+ li_itostr(hh, srv->cur_ts);
2568 li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
2569 li_MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy));
2570- LI_ltostr(hh, rand());
2571+ li_itostr(hh, rand());
2572 li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
2573
2574 li_MD5_Final(h, &Md5Ctx);
2575diff --git a/src/http_chunk.c b/src/http_chunk.c
2576index 5557edc..e3647e6 100644
2577--- a/src/http_chunk.c
2578+++ b/src/http_chunk.c
2579@@ -20,21 +20,23 @@
2580 #include <errno.h>
2581 #include <string.h>
2582
2583-static int http_chunk_append_len(server *srv, connection *con, size_t len) {
2584+static void http_chunk_append_len(server *srv, connection *con, size_t len) {
2585 size_t i, olen = len, j;
2586 buffer *b;
2587
2588+ force_assert(NULL != srv);
2589+
2590 b = srv->tmp_chunk_len;
2591
2592 if (len == 0) {
2593- buffer_copy_string_len(b, CONST_STR_LEN("0"));
2594+ buffer_copy_string_len(b, CONST_STR_LEN("0\r\n"));
2595 } else {
2596 for (i = 0; i < 8 && len; i++) {
2597 len >>= 4;
2598 }
2599
2600 /* i is the number of hex digits we have */
2601- buffer_prepare_copy(b, i + 1);
2602+ buffer_prepare_copy(b, i + 2);
2603
2604 for (j = i-1, len = olen; j+1 > 0; j--) {
2605 b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
2606@@ -42,39 +44,40 @@ static int http_chunk_append_len(server *srv, connection *con, size_t len) {
2607 }
2608 b->used = i;
2609 b->ptr[b->used++] = '\0';
2610+
2611+ buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
2612 }
2613
2614- buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
2615 chunkqueue_append_buffer(con->write_queue, b);
2616-
2617- return 0;
2618 }
2619
2620
2621-int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
2622+void http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
2623 chunkqueue *cq;
2624
2625- if (!con) return -1;
2626+ force_assert(NULL != con);
2627+ if (0 == len) return;
2628
2629 cq = con->write_queue;
2630
2631+
2632 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
2633 http_chunk_append_len(srv, con, len);
2634 }
2635
2636 chunkqueue_append_file(cq, fn, offset, len);
2637
2638- if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) {
2639- chunkqueue_append_mem(cq, "\r\n", 2 + 1);
2640+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
2641+ chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n"));
2642 }
2643-
2644- return 0;
2645 }
2646
2647-int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
2648+void http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
2649 chunkqueue *cq;
2650
2651- if (!con) return -1;
2652+ force_assert(NULL != con);
2653+
2654+ if (buffer_string_is_empty(mem)) return;
2655
2656 cq = con->write_queue;
2657
2658@@ -84,49 +87,37 @@ int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
2659
2660 chunkqueue_append_buffer(cq, mem);
2661
2662- if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) {
2663- chunkqueue_append_mem(cq, "\r\n", 2 + 1);
2664+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
2665+ chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n"));
2666 }
2667-
2668- return 0;
2669 }
2670
2671-int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
2672+void http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
2673 chunkqueue *cq;
2674
2675- if (!con) return -1;
2676+ force_assert(NULL != con);
2677+ force_assert(NULL != mem || 0 == len);
2678
2679- cq = con->write_queue;
2680+ if (NULL == mem || 0 == len) return;
2681
2682- if (len == 0) {
2683- if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
2684- chunkqueue_append_mem(cq, "0\r\n\r\n", 5 + 1);
2685- } else {
2686- chunkqueue_append_mem(cq, "", 1);
2687- }
2688- return 0;
2689- }
2690+ cq = con->write_queue;
2691
2692 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
2693- http_chunk_append_len(srv, con, len - 1);
2694+ http_chunk_append_len(srv, con, len);
2695 }
2696
2697 chunkqueue_append_mem(cq, mem, len);
2698
2699 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
2700- chunkqueue_append_mem(cq, "\r\n", 2 + 1);
2701+ chunkqueue_append_mem(cq, CONST_STR_LEN("\r\n"));
2702 }
2703-
2704- return 0;
2705 }
2706
2707+void http_chunk_close(server *srv, connection *con) {
2708+ UNUSED(srv);
2709+ force_assert(NULL != con);
2710
2711-off_t http_chunkqueue_length(server *srv, connection *con) {
2712- if (!con) {
2713- log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!");
2714-
2715- return 0;
2716+ if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
2717+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("0\r\n\r\n"));
2718 }
2719-
2720- return chunkqueue_length(con->write_queue);
2721 }
2722diff --git a/src/http_chunk.h b/src/http_chunk.h
2723index 4ba24a2..127a116 100644
2724--- a/src/http_chunk.h
2725+++ b/src/http_chunk.h
2726@@ -4,9 +4,9 @@
2727 #include "server.h"
2728 #include <sys/types.h>
2729
2730-int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len);
2731-int http_chunk_append_buffer(server *srv, connection *con, buffer *mem);
2732-int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len);
2733-off_t http_chunkqueue_length(server *srv, connection *con);
2734+void http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len); /* copies memory */
2735+void http_chunk_append_buffer(server *srv, connection *con, buffer *mem); /* may reset "mem" */
2736+void http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len); /* copies "fn" */
2737+void http_chunk_close(server *srv, connection *con);
2738
2739 #endif
2740diff --git a/src/log.c b/src/log.c
2741index 8033d17..75decfe 100644
2742--- a/src/log.c
2743+++ b/src/log.c
2744@@ -152,7 +152,7 @@ int log_error_open(server *srv) {
2745
2746 if (srv->srvconf.errorlog_use_syslog) {
2747 srv->errorlog_mode = ERRORLOG_SYSLOG;
2748- } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
2749+ } else if (!buffer_string_is_empty(srv->srvconf.errorlog_file)) {
2750 const char *logfile = srv->srvconf.errorlog_file->ptr;
2751
2752 if (-1 == (srv->errorlog_fd = open_logfile_or_pipe(srv, logfile))) {
2753@@ -170,7 +170,7 @@ int log_error_open(server *srv) {
2754 srv->errorlog_fd = -1;
2755 }
2756
2757- if (!buffer_is_empty(srv->srvconf.breakagelog_file)) {
2758+ if (!buffer_string_is_empty(srv->srvconf.breakagelog_file)) {
2759 int breakage_fd;
2760 const char *logfile = srv->srvconf.breakagelog_file->ptr;
2761
2762@@ -277,12 +277,12 @@ static void log_buffer_append_printf(buffer *out, const char *fmt, va_list ap) {
2763 break;
2764 case 'd': /* int */
2765 d = va_arg(ap, int);
2766- buffer_append_long(out, d);
2767+ buffer_append_int(out, d);
2768 buffer_append_string_len(out, CONST_STR_LEN(" "));
2769 break;
2770 case 'o': /* off_t */
2771 o = va_arg(ap, off_t);
2772- buffer_append_off_t(out, o);
2773+ buffer_append_int(out, o);
2774 buffer_append_string_len(out, CONST_STR_LEN(" "));
2775 break;
2776 case 'x': /* int (hex) */
2777@@ -301,11 +301,11 @@ static void log_buffer_append_printf(buffer *out, const char *fmt, va_list ap) {
2778 break;
2779 case 'D': /* int */
2780 d = va_arg(ap, int);
2781- buffer_append_long(out, d);
2782+ buffer_append_int(out, d);
2783 break;
2784 case 'O': /* off_t */
2785 o = va_arg(ap, off_t);
2786- buffer_append_off_t(out, o);
2787+ buffer_append_int(out, o);
2788 break;
2789 case 'X': /* int (hex) */
2790 d = va_arg(ap, int);
2791@@ -339,7 +339,7 @@ static int log_buffer_prepare(buffer *b, server *srv, const char *filename, unsi
2792 srv->last_generated_debug_ts = srv->cur_ts;
2793 }
2794
2795- buffer_copy_string_buffer(b, srv->ts_debug_str);
2796+ buffer_copy_buffer(b, srv->ts_debug_str);
2797 buffer_append_string_len(b, CONST_STR_LEN(": ("));
2798 break;
2799 case ERRORLOG_SYSLOG:
2800@@ -350,7 +350,7 @@ static int log_buffer_prepare(buffer *b, server *srv, const char *filename, unsi
2801
2802 buffer_append_string(b, filename);
2803 buffer_append_string_len(b, CONST_STR_LEN("."));
2804- buffer_append_long(b, line);
2805+ buffer_append_int(b, line);
2806 buffer_append_string_len(b, CONST_STR_LEN(") "));
2807
2808 return 0;
2809diff --git a/src/mod_access.c b/src/mod_access.c
2810index c4774b8..7b88e19 100644
2811--- a/src/mod_access.c
2812+++ b/src/mod_access.c
2813@@ -132,7 +132,7 @@ URIHANDLER_FUNC(mod_access_uri_handler) {
2814 s_len = con->uri.path->used - 1;
2815
2816 if (con->conf.log_request_handling) {
2817- log_error_write(srv, __FILE__, __LINE__, "s",
2818+ log_error_write(srv, __FILE__, __LINE__, "s",
2819 "-- mod_access_uri_handler called");
2820 }
2821
2822diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
2823index 21a7764..89fd7f5 100644
2824--- a/src/mod_accesslog.c
2825+++ b/src/mod_accesslog.c
2826@@ -494,7 +494,7 @@ SETDEFAULTS_FUNC(log_access_open) {
2827 return HANDLER_ERROR;
2828 }
2829
2830- if (i == 0 && buffer_is_empty(s->format)) {
2831+ if (i == 0 && buffer_string_is_empty(s->format)) {
2832 /* set a default logfile string */
2833
2834 buffer_copy_string_len(s->format, CONST_STR_LEN("%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""));
2835@@ -523,7 +523,7 @@ SETDEFAULTS_FUNC(log_access_open) {
2836 for (j = 0; j < s->parsed_format->used; j++) {
2837 if (FIELD_FORMAT == s->parsed_format->ptr[j]->type) {
2838 if (FORMAT_TIMESTAMP == s->parsed_format->ptr[j]->field) {
2839- if (!buffer_is_empty(s->parsed_format->ptr[j]->string)) {
2840+ if (!buffer_string_is_empty(s->parsed_format->ptr[j]->string)) {
2841 buffer_copy_string(s->ts_accesslog_fmt_str, s->parsed_format->ptr[j]->string->ptr);
2842 }
2843
2844@@ -558,7 +558,7 @@ SETDEFAULTS_FUNC(log_access_open) {
2845 }
2846
2847 s->append_tz_offset = 0;
2848- if (buffer_is_empty(s->ts_accesslog_fmt_str)) {
2849+ if (buffer_string_is_empty(s->ts_accesslog_fmt_str)) {
2850 #if defined(HAVE_STRUCT_TM_GMTOFF)
2851 BUFFER_COPY_STRING_CONST(s->ts_accesslog_fmt_str, "[%d/%b/%Y:%H:%M:%S ");
2852 s->append_tz_offset = 1;
2853@@ -730,10 +730,10 @@ REQUESTDONE_FUNC(log_access_write) {
2854
2855 /* hours */
2856 if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
2857- buffer_append_long(p->conf.ts_accesslog_str, hrs);
2858+ buffer_append_int(p->conf.ts_accesslog_str, hrs);
2859
2860 if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0"));
2861- buffer_append_long(p->conf.ts_accesslog_str, min);
2862+ buffer_append_int(p->conf.ts_accesslog_str, min);
2863 buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]"));
2864 }
2865 #else /* HAVE_STRUCT_TM_GMTOFF */
2866@@ -777,12 +777,12 @@ REQUESTDONE_FUNC(log_access_write) {
2867 }
2868 break;
2869 case FORMAT_STATUS:
2870- buffer_append_long(b, con->http_status);
2871+ buffer_append_int(b, con->http_status);
2872 break;
2873
2874 case FORMAT_BYTES_OUT_NO_HEADER:
2875 if (con->bytes_written > 0) {
2876- buffer_append_off_t(b,
2877+ buffer_append_int(b,
2878 con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header);
2879 } else {
2880 buffer_append_string_len(b, CONST_STR_LEN("-"));
2881@@ -818,20 +818,20 @@ REQUESTDONE_FUNC(log_access_write) {
2882 break;
2883 case FORMAT_BYTES_OUT:
2884 if (con->bytes_written > 0) {
2885- buffer_append_off_t(b, con->bytes_written);
2886+ buffer_append_int(b, con->bytes_written);
2887 } else {
2888 buffer_append_string_len(b, CONST_STR_LEN("-"));
2889 }
2890 break;
2891 case FORMAT_BYTES_IN:
2892 if (con->bytes_read > 0) {
2893- buffer_append_off_t(b, con->bytes_read);
2894+ buffer_append_int(b, con->bytes_read);
2895 } else {
2896 buffer_append_string_len(b, CONST_STR_LEN("-"));
2897 }
2898 break;
2899 case FORMAT_TIME_USED:
2900- buffer_append_long(b, srv->cur_ts - con->request_start);
2901+ buffer_append_int(b, srv->cur_ts - con->request_start);
2902 break;
2903 case FORMAT_SERVER_NAME:
2904 if (con->server_name->used > 1) {
2905@@ -869,7 +869,7 @@ REQUESTDONE_FUNC(log_access_write) {
2906 if (colon) {
2907 buffer_append_string(b, colon+1);
2908 } else {
2909- buffer_append_long(b, srv->srvconf.port);
2910+ buffer_append_int(b, srv->srvconf.port);
2911 }
2912 }
2913 break;
2914diff --git a/src/mod_alias.c b/src/mod_alias.c
2915index 062c268..bf22b5f 100644
2916--- a/src/mod_alias.c
2917+++ b/src/mod_alias.c
2918@@ -173,10 +173,10 @@ PHYSICALPATH_FUNC(mod_alias_physical_handler) {
2919 strncmp(uri_ptr, ds->key->ptr, alias_len))) {
2920 /* matched */
2921
2922- buffer_copy_string_buffer(con->physical.basedir, ds->value);
2923- buffer_copy_string_buffer(srv->tmp_buf, ds->value);
2924+ buffer_copy_buffer(con->physical.basedir, ds->value);
2925+ buffer_copy_buffer(srv->tmp_buf, ds->value);
2926 buffer_append_string(srv->tmp_buf, uri_ptr + alias_len);
2927- buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
2928+ buffer_copy_buffer(con->physical.path, srv->tmp_buf);
2929
2930 return HANDLER_GO_ON;
2931 }
2932diff --git a/src/mod_auth.c b/src/mod_auth.c
2933index 31e1140..d5a3f1c 100644
2934--- a/src/mod_auth.c
2935+++ b/src/mod_auth.c
2936@@ -324,7 +324,7 @@ static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
2937 buffer_copy_string(ds->key, "REMOTE_USER");
2938 array_insert_unique(con->environment, (data_unset *)ds);
2939 }
2940- buffer_copy_string_buffer(ds->value, p->auth_user);
2941+ buffer_copy_buffer(ds->value, p->auth_user);
2942
2943 /* AUTH_TYPE environment */
2944
2945@@ -535,7 +535,7 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) {
2946 data_array *a;
2947
2948 a = data_array_init();
2949- buffer_copy_string_buffer(a->key, da_file->key);
2950+ buffer_copy_buffer(a->key, da_file->key);
2951
2952 ds = data_string_init();
2953
2954@@ -608,7 +608,7 @@ handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
2955 if (s->auth_ldap_starttls) {
2956 /* if no CA file is given, it is ok, as we will use encryption
2957 * if the server requires a CAfile it will tell us */
2958- if (!buffer_is_empty(s->auth_ldap_cafile)) {
2959+ if (!buffer_string_is_empty(s->auth_ldap_cafile)) {
2960 if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
2961 s->auth_ldap_cafile->ptr))) {
2962 log_error_write(srv, __FILE__, __LINE__, "ss",
2963diff --git a/src/mod_cgi.c b/src/mod_cgi.c
2964index 734ecee..76882e8 100644
2965--- a/src/mod_cgi.c
2966+++ b/src/mod_cgi.c
2967@@ -235,7 +235,7 @@ static int cgi_response_parse(server *srv, connection *con, plugin_data *p, buff
2968
2969 UNUSED(srv);
2970
2971- buffer_copy_string_buffer(p->parse_response, in);
2972+ buffer_copy_buffer(p->parse_response, in);
2973
2974 for (s = p->parse_response->ptr;
2975 NULL != (ns = strchr(s, '\n'));
2976@@ -350,7 +350,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
2977 buffer_prepare_copy(hctx->response, 4 * 1024);
2978 } else {
2979 if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
2980- buffer_prepare_copy(hctx->response, toread + 1);
2981+ buffer_prepare_copy(hctx->response, toread);
2982 }
2983 #endif
2984
2985@@ -370,7 +370,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
2986 con->file_finished = 1;
2987
2988 /* send final chunk */
2989- http_chunk_append_mem(srv, con, NULL, 0);
2990+ http_chunk_close(srv, con);
2991 joblist_append(srv, con);
2992
2993 return FDEVENT_HANDLED_FINISHED;
2994@@ -458,7 +458,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
2995 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
2996 }
2997
2998- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
2999+ http_chunk_append_buffer(srv, con, hctx->response_header);
3000 joblist_append(srv, con);
3001 } else {
3002 const char *bstart;
3003@@ -493,7 +493,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
3004 }
3005
3006 if (blen > 0) {
3007- http_chunk_append_mem(srv, con, bstart, blen + 1);
3008+ http_chunk_append_mem(srv, con, bstart, blen);
3009 joblist_append(srv, con);
3010 }
3011 }
3012@@ -501,7 +501,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
3013 con->file_started = 1;
3014 }
3015 } else {
3016- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
3017+ http_chunk_append_buffer(srv, con, hctx->response);
3018 joblist_append(srv, con);
3019 }
3020
3021@@ -668,27 +668,17 @@ static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) {
3022 /* perhaps this issue is already handled */
3023 if (revents & FDEVENT_HUP) {
3024 /* check if we still have a unfinished header package which is a body in reality */
3025- if (con->file_started == 0 &&
3026- hctx->response_header->used) {
3027+ if (con->file_started == 0 && !buffer_string_is_empty(hctx->response_header)) {
3028 con->file_started = 1;
3029- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
3030- joblist_append(srv, con);
3031+ http_chunk_append_buffer(srv, con, hctx->response_header);
3032 }
3033
3034 if (con->file_finished == 0) {
3035- http_chunk_append_mem(srv, con, NULL, 0);
3036- joblist_append(srv, con);
3037+ http_chunk_close(srv, con);
3038 }
3039-
3040 con->file_finished = 1;
3041
3042- if (chunkqueue_is_empty(con->write_queue)) {
3043- /* there is nothing left to write */
3044- connection_set_state(srv, con, CON_STATE_RESPONSE_END);
3045- } else {
3046- /* used the write-handler to finish the request on demand */
3047-
3048- }
3049+ joblist_append(srv, con);
3050
3051 # if 0
3052 log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
3053@@ -777,7 +767,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
3054 char **args;
3055 int argc;
3056 int i = 0;
3057- char buf[32];
3058+ char buf[LI_ITOSTRING_LENGTH];
3059 size_t n;
3060 char_array env;
3061 char *c;
3062@@ -809,7 +799,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
3063 cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag));
3064 }
3065
3066- if (!buffer_is_empty(con->server_name)) {
3067+ if (!buffer_string_is_empty(con->server_name)) {
3068 size_t len = con->server_name->used - 1;
3069
3070 if (con->server_name->ptr[0] == '[') {
3071@@ -839,7 +829,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
3072
3073 cgi_env_add(&env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
3074
3075- LI_ltostr(buf,
3076+ li_utostr(buf,
3077 #ifdef HAVE_IPV6
3078 ntohs(srv_sock->addr.plain.sa_family == AF_INET6 ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
3079 #else
3080@@ -874,14 +864,14 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
3081 s = get_http_method_name(con->request.http_method);
3082 cgi_env_add(&env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
3083
3084- if (!buffer_is_empty(con->request.pathinfo)) {
3085+ if (!buffer_string_is_empty(con->request.pathinfo)) {
3086 cgi_env_add(&env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
3087 }
3088 cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200"));
3089- if (!buffer_is_empty(con->uri.query)) {
3090+ if (!buffer_string_is_empty(con->uri.query)) {
3091 cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
3092 }
3093- if (!buffer_is_empty(con->request.orig_uri)) {
3094+ if (!buffer_string_is_empty(con->request.orig_uri)) {
3095 cgi_env_add(&env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
3096 }
3097
3098@@ -909,7 +899,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
3099 }
3100 cgi_env_add(&env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
3101
3102- LI_ltostr(buf,
3103+ li_utostr(buf,
3104 #ifdef HAVE_IPV6
3105 ntohs(con->dst_addr.plain.sa_family == AF_INET6 ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
3106 #else
3107@@ -922,8 +912,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
3108 cgi_env_add(&env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
3109 }
3110
3111- /* request.content_length < SSIZE_MAX, see request.c */
3112- LI_ltostr(buf, con->request.content_length);
3113+ li_itostr(buf, con->request.content_length);
3114 cgi_env_add(&env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
3115 cgi_env_add(&env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
3116 cgi_env_add(&env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
3117@@ -1134,8 +1123,6 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
3118 }
3119 }
3120 break;
3121- case UNUSED_CHUNK:
3122- break;
3123 }
3124
3125 if (r > 0) {
3126diff --git a/src/mod_cml.c b/src/mod_cml.c
3127index b5b5ac2..3033d42 100644
3128--- a/src/mod_cml.c
3129+++ b/src/mod_cml.c
3130@@ -184,7 +184,7 @@ static int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *
3131
3132 /* cleanup basedir */
3133 b = p->baseurl;
3134- buffer_copy_string_buffer(b, con->uri.path);
3135+ buffer_copy_buffer(b, con->uri.path);
3136 for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
3137
3138 if (*c == '/') {
3139@@ -193,7 +193,7 @@ static int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *
3140 }
3141
3142 b = p->basedir;
3143- buffer_copy_string_buffer(b, con->physical.path);
3144+ buffer_copy_buffer(b, con->physical.path);
3145 for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
3146
3147 if (*c == '/') {
3148@@ -218,7 +218,7 @@ URIHANDLER_FUNC(mod_cml_power_magnet) {
3149 buffer_reset(p->baseurl);
3150 buffer_reset(p->trigger_handler);
3151
3152- if (buffer_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON;
3153+ if (buffer_string_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON;
3154
3155 /*
3156 * power-magnet:
3157@@ -264,7 +264,7 @@ URIHANDLER_FUNC(mod_cml_power_magnet) {
3158 URIHANDLER_FUNC(mod_cml_is_handled) {
3159 plugin_data *p = p_d;
3160
3161- if (buffer_is_empty(con->physical.path)) return HANDLER_ERROR;
3162+ if (buffer_string_is_empty(con->physical.path)) return HANDLER_ERROR;
3163
3164 mod_cml_patch_connection(srv, con, p);
3165
3166@@ -272,7 +272,7 @@ URIHANDLER_FUNC(mod_cml_is_handled) {
3167 buffer_reset(p->baseurl);
3168 buffer_reset(p->trigger_handler);
3169
3170- if (buffer_is_empty(p->conf.ext)) return HANDLER_GO_ON;
3171+ if (buffer_string_is_empty(p->conf.ext)) return HANDLER_GO_ON;
3172
3173 if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, p->conf.ext->used - 1)) {
3174 return HANDLER_GO_ON;
3175diff --git a/src/mod_cml_lua.c b/src/mod_cml_lua.c
3176index d05e854..63dd1e7 100644
3177--- a/src/mod_cml_lua.c
3178+++ b/src/mod_cml_lua.c
3179@@ -260,7 +260,7 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
3180 c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
3181 c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
3182 c_to_lua_push(L, header_tbl, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
3183- if (!buffer_is_empty(con->request.pathinfo)) {
3184+ if (!buffer_string_is_empty(con->request.pathinfo)) {
3185 c_to_lua_push(L, header_tbl, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
3186 }
3187
3188@@ -276,7 +276,7 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
3189 header_tbl = lua_gettop(L);
3190 lua_gettable(L, LUA_GLOBALSINDEX);
3191
3192- buffer_copy_string_buffer(b, con->uri.query);
3193+ buffer_copy_buffer(b, con->uri.query);
3194 cache_export_get_params(L, header_tbl, b);
3195 buffer_reset(b);
3196
3197@@ -346,7 +346,7 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
3198
3199 /* the file is relative, make it absolute */
3200 if (s[0] != '/') {
3201- buffer_copy_string_buffer(b, p->basedir);
3202+ buffer_copy_buffer(b, p->basedir);
3203 buffer_append_string(b, lua_tostring(L, -1));
3204 } else {
3205 buffer_copy_string(b, lua_tostring(L, -1));
3206@@ -358,7 +358,7 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
3207 switch(errno) {
3208 case ENOENT:
3209 /* a file is missing, call the handler to generate it */
3210- if (!buffer_is_empty(p->trigger_handler)) {
3211+ if (!buffer_string_is_empty(p->trigger_handler)) {
3212 ret = 1; /* cache-miss */
3213
3214 log_error_write(srv, __FILE__, __LINE__, "s",
3215@@ -433,12 +433,12 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
3216 }
3217 }
3218
3219- if (ret == 1 && !buffer_is_empty(p->trigger_handler)) {
3220+ if (ret == 1 && !buffer_string_is_empty(p->trigger_handler)) {
3221 /* cache-miss */
3222- buffer_copy_string_buffer(con->uri.path, p->baseurl);
3223+ buffer_copy_buffer(con->uri.path, p->baseurl);
3224 buffer_append_string_buffer(con->uri.path, p->trigger_handler);
3225
3226- buffer_copy_string_buffer(con->physical.path, p->basedir);
3227+ buffer_copy_buffer(con->physical.path, p->basedir);
3228 buffer_append_string_buffer(con->physical.path, p->trigger_handler);
3229
3230 chunkqueue_reset(con->write_queue);
3231diff --git a/src/mod_compress.c b/src/mod_compress.c
3232index c4183bb..ad6e9f2 100644
3233--- a/src/mod_compress.c
3234+++ b/src/mod_compress.c
3235@@ -222,7 +222,7 @@ SETDEFAULTS_FUNC(mod_compress_setdefaults) {
3236
3237 array_free(encodings_arr);
3238
3239- if (!buffer_is_empty(s->compress_cache_dir)) {
3240+ if (!buffer_string_is_empty(s->compress_cache_dir)) {
3241 struct stat st;
3242 mkdir_recursive(s->compress_cache_dir->ptr);
3243
3244@@ -351,7 +351,7 @@ static int deflate_file_to_buffer_deflate(server *srv, connection *con, plugin_d
3245 }
3246
3247 /* trailer */
3248- p->b->used += z.total_out;
3249+ p->b->used = z.total_out;
3250
3251 if (Z_OK != deflateEnd(&z)) {
3252 return -1;
3253@@ -429,12 +429,12 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
3254 if (sce->st.st_size > 128 * 1024 * 1024) return -1;
3255
3256 buffer_reset(p->ofn);
3257- buffer_copy_string_buffer(p->ofn, p->conf.compress_cache_dir);
3258- BUFFER_APPEND_SLASH(p->ofn);
3259+ buffer_copy_buffer(p->ofn, p->conf.compress_cache_dir);
3260+ buffer_append_slash(p->ofn);
3261
3262 if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) {
3263 buffer_append_string(p->ofn, con->physical.path->ptr + con->physical.doc_root->used - 1);
3264- buffer_copy_string_buffer(p->b, p->ofn);
3265+ buffer_copy_buffer(p->b, p->ofn);
3266 } else {
3267 buffer_append_string_buffer(p->ofn, con->uri.path);
3268 }
3269@@ -469,7 +469,7 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
3270 #if 0
3271 log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit");
3272 #endif
3273- buffer_copy_string_buffer(con->physical.path, p->ofn);
3274+ buffer_copy_buffer(con->physical.path, p->ofn);
3275
3276 return 0;
3277 }
3278@@ -574,7 +574,7 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
3279 return -1;
3280 }
3281
3282- buffer_copy_string_buffer(con->physical.path, p->ofn);
3283+ buffer_copy_buffer(con->physical.path, p->ofn);
3284
3285 return 0;
3286 }
3287@@ -652,7 +652,7 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
3288
3289 chunkqueue_reset(con->write_queue);
3290 b = chunkqueue_get_append_buffer(con->write_queue);
3291- buffer_copy_memory(b, p->b->ptr, p->b->used + 1);
3292+ buffer_copy_string_len(b, p->b->ptr, p->b->used);
3293
3294 buffer_reset(con->physical.path);
3295
3296@@ -732,7 +732,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
3297 return HANDLER_GO_ON;
3298 }
3299
3300- if (buffer_is_empty(con->physical.path)) {
3301+ if (buffer_string_is_empty(con->physical.path)) {
3302 return HANDLER_GO_ON;
3303 }
3304
3305@@ -867,7 +867,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
3306
3307 if (use_etag) {
3308 /* try matching etag of compressed version */
3309- buffer_copy_string_buffer(srv->tmp_buf, sce->etag);
3310+ buffer_copy_buffer(srv->tmp_buf, sce->etag);
3311 buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("-"));
3312 buffer_append_string(srv->tmp_buf, compression_name);
3313 etag_mutate(con->physical.etag, srv->tmp_buf);
3314diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
3315index 6a2b139..4b7106a 100644
3316--- a/src/mod_dirlisting.c
3317+++ b/src/mod_dirlisting.c
3318@@ -124,7 +124,7 @@ static int excludes_buffer_append(excludes_buffer *exb, buffer *string) {
3319 }
3320
3321 exb->ptr[exb->used]->string = buffer_init();
3322- buffer_copy_string_buffer(exb->ptr[exb->used]->string, string);
3323+ buffer_copy_buffer(exb->ptr[exb->used]->string, string);
3324
3325 exb->used++;
3326
3327@@ -469,7 +469,8 @@ static int http_list_directory_sizefmt(char *buf, off_t size) {
3328 u++;
3329 }
3330
3331- out += LI_ltostr(out, size);
3332+ li_itostr(out, size);
3333+ out += strlen(out);
3334 out[0] = '.';
3335 out[1] = remain + '0';
3336 out[2] = *u;
3337@@ -539,8 +540,8 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
3338 stream s;
3339 /* if we have a HEADER file, display it in <pre class="header"></pre> */
3340
3341- buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
3342- BUFFER_APPEND_SLASH(p->tmp_buf);
3343+ buffer_copy_buffer(p->tmp_buf, con->physical.path);
3344+ buffer_append_slash(p->tmp_buf);
3345 buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("HEADER.txt"));
3346
3347 if (-1 != stream_open(&s, p->tmp_buf)) {
3348@@ -592,8 +593,8 @@ static void http_list_directory_footer(server *srv, connection *con, plugin_data
3349 stream s;
3350 /* if we have a README file, display it in <pre class="readme"></pre> */
3351
3352- buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
3353- BUFFER_APPEND_SLASH(p->tmp_buf);
3354+ buffer_copy_buffer(p->tmp_buf, con->physical.path);
3355+ buffer_append_slash(p->tmp_buf);
3356 buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("README.txt"));
3357
3358 if (-1 != stream_open(&s, p->tmp_buf)) {
3359@@ -785,7 +786,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
3360
3361 out = chunkqueue_get_append_buffer(con->write_queue);
3362 buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\""));
3363- if (buffer_is_empty(p->conf.encoding)) {
3364+ if (buffer_string_is_empty(p->conf.encoding)) {
3365 buffer_append_string_len(out, CONST_STR_LEN("iso-8859-1"));
3366 } else {
3367 buffer_append_string_buffer(out, p->conf.encoding);
3368@@ -889,7 +890,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
3369 http_list_directory_footer(srv, con, p, out);
3370
3371 /* Insert possible charset to Content-Type */
3372- if (buffer_is_empty(p->conf.encoding)) {
3373+ if (buffer_string_is_empty(p->conf.encoding)) {
3374 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
3375 } else {
3376 buffer_copy_string_len(p->content_charset, CONST_STR_LEN("text/html; charset="));
3377diff --git a/src/mod_evhost.c b/src/mod_evhost.c
3378index a491baa..5281523 100644
3379--- a/src/mod_evhost.c
3380+++ b/src/mod_evhost.c
3381@@ -200,7 +200,7 @@ static int mod_evhost_parse_host(connection *con,array *host) {
3382 /* is something between the dots */
3383 ds = data_string_init();
3384 buffer_copy_string_len(ds->key,CONST_STR_LEN("%"));
3385- buffer_append_long(ds->key, i++);
3386+ buffer_append_int(ds->key, i++);
3387 buffer_copy_string_len(ds->value,ptr+1,colon-ptr-1);
3388
3389 array_insert_unique(host,(data_unset *)ds);
3390@@ -213,7 +213,7 @@ static int mod_evhost_parse_host(connection *con,array *host) {
3391 if (colon != ptr) {
3392 ds = data_string_init();
3393 buffer_copy_string_len(ds->key,CONST_STR_LEN("%"));
3394- buffer_append_long(ds->key, i /* ++ */);
3395+ buffer_append_int(ds->key, i /* ++ */);
3396 buffer_copy_string_len(ds->value,ptr,colon-ptr);
3397
3398 array_insert_unique(host,(data_unset *)ds);
3399@@ -311,7 +311,7 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
3400 }
3401 }
3402
3403- BUFFER_APPEND_SLASH(p->tmp_buf);
3404+ buffer_append_slash(p->tmp_buf);
3405
3406 array_free(parsed_host);
3407
3408@@ -324,7 +324,7 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
3409 }
3410
3411 if (!not_good) {
3412- buffer_copy_string_buffer(con->physical.doc_root, p->tmp_buf);
3413+ buffer_copy_buffer(con->physical.doc_root, p->tmp_buf);
3414 }
3415
3416 return HANDLER_GO_ON;
3417diff --git a/src/mod_expire.c b/src/mod_expire.c
3418index 476261f..41895f9 100644
3419--- a/src/mod_expire.c
3420+++ b/src/mod_expire.c
3421@@ -346,7 +346,7 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
3422
3423 /* HTTP/1.1 */
3424 buffer_copy_string_len(p->expire_tstmp, CONST_STR_LEN("max-age="));
3425- buffer_append_long(p->expire_tstmp, expires - srv->cur_ts); /* as expires >= srv->cur_ts the difference is >= 0 */
3426+ buffer_append_int(p->expire_tstmp, expires - srv->cur_ts); /* as expires >= srv->cur_ts the difference is >= 0 */
3427
3428 response_header_append(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp));
3429
3430diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
3431index ad1ec18..01e72e5 100644
3432--- a/src/mod_fastcgi.c
3433+++ b/src/mod_fastcgi.c
3434@@ -391,7 +391,7 @@ static void fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, f
3435 buffer_append_string_buffer(b, host->id);
3436 if (proc) {
3437 buffer_append_string_len(b, CONST_STR_LEN("."));
3438- buffer_append_long(b, proc->id);
3439+ buffer_append_int(b, proc->id);
3440 }
3441 }
3442
3443@@ -637,7 +637,7 @@ static int fastcgi_extension_insert(fcgi_exts *ext, buffer *key, fcgi_extension_
3444 force_assert(fe);
3445 fe->key = buffer_init();
3446 fe->last_used_ndx = -1;
3447- buffer_copy_string_buffer(fe->key, key);
3448+ buffer_copy_buffer(fe->key, key);
3449
3450 /* */
3451
3452@@ -724,7 +724,7 @@ FREE_FUNC(mod_fastcgi_free) {
3453 }
3454
3455 if (proc->is_local &&
3456- !buffer_is_empty(proc->unixsocket)) {
3457+ !buffer_string_is_empty(proc->unixsocket)) {
3458 unlink(proc->unixsocket->ptr);
3459 }
3460 }
3461@@ -734,7 +734,7 @@ FREE_FUNC(mod_fastcgi_free) {
3462 kill(proc->pid, host->kill_signal);
3463 }
3464 if (proc->is_local &&
3465- !buffer_is_empty(proc->unixsocket)) {
3466+ !buffer_string_is_empty(proc->unixsocket)) {
3467 unlink(proc->unixsocket->ptr);
3468 }
3469 }
3470@@ -868,7 +868,7 @@ static int fcgi_spawn_connection(server *srv,
3471 "new proc, socket:", proc->port, proc->unixsocket);
3472 }
3473
3474- if (!buffer_is_empty(proc->unixsocket)) {
3475+ if (!buffer_string_is_empty(proc->unixsocket)) {
3476 memset(&fcgi_addr, 0, sizeof(fcgi_addr));
3477
3478 #ifdef HAVE_SYS_UN_H
3479@@ -901,7 +901,7 @@ static int fcgi_spawn_connection(server *srv,
3480 } else {
3481 fcgi_addr_in.sin_family = AF_INET;
3482
3483- if (buffer_is_empty(host->host)) {
3484+ if (buffer_string_is_empty(host->host)) {
3485 fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3486 } else {
3487 struct hostent *he;
3488@@ -937,13 +937,13 @@ static int fcgi_spawn_connection(server *srv,
3489 fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
3490
3491 buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));
3492- if (!buffer_is_empty(host->host)) {
3493+ if (!buffer_string_is_empty(host->host)) {
3494 buffer_append_string_buffer(proc->connection_name, host->host);
3495 } else {
3496 buffer_append_string_len(proc->connection_name, CONST_STR_LEN("localhost"));
3497 }
3498 buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":"));
3499- buffer_append_long(proc->connection_name, proc->port);
3500+ buffer_append_int(proc->connection_name, proc->port);
3501 }
3502
3503 if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
3504@@ -958,7 +958,7 @@ static int fcgi_spawn_connection(server *srv,
3505 int val;
3506
3507 if (errno != ENOENT &&
3508- !buffer_is_empty(proc->unixsocket)) {
3509+ !buffer_string_is_empty(proc->unixsocket)) {
3510 unlink(proc->unixsocket->ptr);
3511 }
3512
3513@@ -1285,7 +1285,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
3514 host = fastcgi_host_init();
3515 buffer_reset(fcgi_mode);
3516
3517- buffer_copy_string_buffer(host->id, da_host->key);
3518+ buffer_copy_buffer(host->id, da_host->key);
3519
3520 host->check_local = 1;
3521 host->max_procs = 4;
3522@@ -1319,8 +1319,8 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
3523 goto error;
3524 }
3525
3526- if ((!buffer_is_empty(host->host) || host->port) &&
3527- !buffer_is_empty(host->unixsocket)) {
3528+ if ((!buffer_string_is_empty(host->host) || host->port) &&
3529+ !buffer_string_is_empty(host->unixsocket)) {
3530 log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
3531 "either host/port or socket have to be set in:",
3532 da->key, "= (",
3533@@ -1330,7 +1330,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
3534 goto error;
3535 }
3536
3537- if (!buffer_is_empty(host->unixsocket)) {
3538+ if (!buffer_string_is_empty(host->unixsocket)) {
3539 /* unix domain socket */
3540 struct sockaddr_un un;
3541
3542@@ -1346,8 +1346,8 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
3543 } else {
3544 /* tcp/ip */
3545
3546- if (buffer_is_empty(host->host) &&
3547- buffer_is_empty(host->bin_path)) {
3548+ if (buffer_string_is_empty(host->host) &&
3549+ buffer_string_is_empty(host->bin_path)) {
3550 log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
3551 "host or binpath have to be set in:",
3552 da->key, "= (",
3553@@ -1366,7 +1366,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
3554 }
3555 }
3556
3557- if (!buffer_is_empty(host->bin_path)) {
3558+ if (!buffer_string_is_empty(host->bin_path)) {
3559 /* a local socket + self spawning */
3560 size_t pno;
3561
3562@@ -1386,12 +1386,12 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
3563 proc->id = host->num_procs++;
3564 host->max_id++;
3565
3566- if (buffer_is_empty(host->unixsocket)) {
3567+ if (buffer_string_is_empty(host->unixsocket)) {
3568 proc->port = host->port + pno;
3569 } else {
3570- buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
3571+ buffer_copy_buffer(proc->unixsocket, host->unixsocket);
3572 buffer_append_string_len(proc->unixsocket, CONST_STR_LEN("-"));
3573- buffer_append_long(proc->unixsocket, pno);
3574+ buffer_append_int(proc->unixsocket, pno);
3575 }
3576
3577 if (s->debug) {
3578@@ -1425,10 +1425,10 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
3579 host->active_procs++;
3580 proc->state = PROC_STATE_RUNNING;
3581
3582- if (buffer_is_empty(host->unixsocket)) {
3583+ if (buffer_string_is_empty(host->unixsocket)) {
3584 proc->port = host->port;
3585 } else {
3586- buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
3587+ buffer_copy_buffer(proc->unixsocket, host->unixsocket);
3588 }
3589
3590 fastcgi_status_init(srv, p->statuskey, host, proc);
3591@@ -1438,12 +1438,12 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
3592 host->max_procs = 1;
3593 }
3594
3595- if (!buffer_is_empty(fcgi_mode)) {
3596+ if (!buffer_string_is_empty(fcgi_mode)) {
3597 if (strcmp(fcgi_mode->ptr, "responder") == 0) {
3598 host->mode = FCGI_RESPONDER;
3599 } else if (strcmp(fcgi_mode->ptr, "authorizer") == 0) {
3600 host->mode = FCGI_AUTHORIZER;
3601- if (buffer_is_empty(host->docroot)) {
3602+ if (buffer_string_is_empty(host->docroot)) {
3603 log_error_write(srv, __FILE__, __LINE__, "s",
3604 "ERROR: docroot is required for authorizer mode.");
3605 goto error;
3606@@ -1672,7 +1672,7 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
3607
3608 memset(&fcgi_addr, 0, sizeof(fcgi_addr));
3609
3610- if (!buffer_is_empty(proc->unixsocket)) {
3611+ if (!buffer_string_is_empty(proc->unixsocket)) {
3612 #ifdef HAVE_SYS_UN_H
3613 /* use the unix domain socket */
3614 fcgi_addr_un.sun_family = AF_UNIX;
3615@@ -1692,7 +1692,7 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
3616 #endif
3617 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
3618
3619- if (buffer_is_empty(proc->connection_name)) {
3620+ if (buffer_string_is_empty(proc->connection_name)) {
3621 /* on remote spawing we have to set the connection-name now */
3622 buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("unix:"));
3623 buffer_append_string_buffer(proc->connection_name, proc->unixsocket);
3624@@ -1702,7 +1702,7 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
3625 #endif
3626 } else {
3627 fcgi_addr_in.sin_family = AF_INET;
3628- if (!buffer_is_empty(host->host)) {
3629+ if (!buffer_string_is_empty(host->host)) {
3630 if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
3631 log_error_write(srv, __FILE__, __LINE__, "sbs",
3632 "converting IP address failed for", host->host,
3633@@ -1718,16 +1718,16 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
3634
3635 fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
3636
3637- if (buffer_is_empty(proc->connection_name)) {
3638+ if (buffer_string_is_empty(proc->connection_name)) {
3639 /* on remote spawing we have to set the connection-name now */
3640 buffer_copy_string_len(proc->connection_name, CONST_STR_LEN("tcp:"));
3641- if (!buffer_is_empty(host->host)) {
3642+ if (!buffer_string_is_empty(host->host)) {
3643 buffer_append_string_buffer(proc->connection_name, host->host);
3644 } else {
3645 buffer_append_string_len(proc->connection_name, CONST_STR_LEN("localhost"));
3646 }
3647 buffer_append_string_len(proc->connection_name, CONST_STR_LEN(":"));
3648- buffer_append_long(proc->connection_name, proc->port);
3649+ buffer_append_int(proc->connection_name, proc->port);
3650 }
3651 }
3652
3653@@ -1840,7 +1840,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3654 FCGI_Header header;
3655 buffer *b;
3656
3657- char buf[32];
3658+ char buf[LI_ITOSTRING_LENGTH];
3659 const char *s;
3660 #ifdef HAVE_IPV6
3661 char b2[INET6_ADDRSTRLEN + 1];
3662@@ -1865,7 +1865,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3663
3664 b = chunkqueue_get_append_buffer(hctx->wb);
3665
3666- buffer_copy_memory(b, (const char *)&beginRecord, sizeof(beginRecord));
3667+ buffer_copy_string_len(b, (const char *)&beginRecord, sizeof(beginRecord));
3668
3669 /* send FCGI_PARAMS */
3670 buffer_prepare_copy(p->fcgi_env, 1024);
3671@@ -1904,7 +1904,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3672
3673 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1")),con)
3674
3675- LI_ltostr(buf,
3676+ li_utostr(buf,
3677 #ifdef HAVE_IPV6
3678 ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
3679 #else
3680@@ -1924,7 +1924,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3681 }
3682 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s)),con)
3683
3684- LI_ltostr(buf,
3685+ li_utostr(buf,
3686 #ifdef HAVE_IPV6
3687 ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
3688 #else
3689@@ -1940,8 +1940,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3690 if (con->request.content_length > 0 && host->mode != FCGI_AUTHORIZER) {
3691 /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
3692
3693- /* request.content_length < SSIZE_MAX, see request.c */
3694- LI_ltostr(buf, con->request.content_length);
3695+ li_itostr(buf, con->request.content_length);
3696 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)),con)
3697 }
3698
3699@@ -1955,15 +1954,15 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3700
3701 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path)),con)
3702
3703- if (!buffer_is_empty(con->request.pathinfo)) {
3704+ if (!buffer_string_is_empty(con->request.pathinfo)) {
3705 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo)),con)
3706
3707 /* PATH_TRANSLATED is only defined if PATH_INFO is set */
3708
3709- if (!buffer_is_empty(host->docroot)) {
3710- buffer_copy_string_buffer(p->path, host->docroot);
3711+ if (!buffer_string_is_empty(host->docroot)) {
3712+ buffer_copy_buffer(p->path, host->docroot);
3713 } else {
3714- buffer_copy_string_buffer(p->path, con->physical.basedir);
3715+ buffer_copy_buffer(p->path, con->physical.basedir);
3716 }
3717 buffer_append_string_buffer(p->path, con->request.pathinfo);
3718 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_TRANSLATED"), CONST_BUF_LEN(p->path)),con)
3719@@ -1980,19 +1979,19 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3720 * parameter.
3721 */
3722
3723- if (!buffer_is_empty(host->docroot)) {
3724+ if (!buffer_string_is_empty(host->docroot)) {
3725 /*
3726 * rewrite SCRIPT_FILENAME
3727 *
3728 */
3729
3730- buffer_copy_string_buffer(p->path, host->docroot);
3731+ buffer_copy_buffer(p->path, host->docroot);
3732 buffer_append_string_buffer(p->path, con->uri.path);
3733
3734 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)),con)
3735 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot)),con)
3736 } else {
3737- buffer_copy_string_buffer(p->path, con->physical.path);
3738+ buffer_copy_buffer(p->path, con->physical.path);
3739
3740 /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself
3741 *
3742@@ -2037,7 +2036,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3743 if (!buffer_is_equal(con->request.uri, con->request.orig_uri)) {
3744 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_URI"), CONST_BUF_LEN(con->request.uri)),con)
3745 }
3746- if (!buffer_is_empty(con->uri.query)) {
3747+ if (!buffer_string_is_empty(con->uri.query)) {
3748 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query)),con)
3749 } else {
3750 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN("")),con)
3751@@ -2056,135 +2055,43 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
3752 FCGI_ENV_ADD_CHECK(fcgi_env_add_request_headers(srv, con, p), con);
3753
3754 fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0);
3755- buffer_append_memory(b, (const char *)&header, sizeof(header));
3756- buffer_append_memory(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
3757+ buffer_append_string_len(b, (const char *)&header, sizeof(header));
3758+ buffer_append_string_len(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
3759
3760 fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
3761- buffer_append_memory(b, (const char *)&header, sizeof(header));
3762+ buffer_append_string_len(b, (const char *)&header, sizeof(header));
3763
3764- b->used++; /* add virtual \0 */
3765 hctx->wb->bytes_in += b->used - 1;
3766
3767 if (con->request.content_length) {
3768 chunkqueue *req_cq = con->request_content_queue;
3769- chunk *req_c;
3770 off_t offset;
3771
3772 /* something to send ? */
3773- for (offset = 0, req_c = req_cq->first; offset != req_cq->bytes_in; ) {
3774+ for (offset = 0; offset != req_cq->bytes_in; ) {
3775 off_t weWant = req_cq->bytes_in - offset > FCGI_MAX_LENGTH ? FCGI_MAX_LENGTH : req_cq->bytes_in - offset;
3776- off_t written = 0;
3777- off_t weHave = 0;
3778
3779 /* we announce toWrite octets
3780 * now take all the request_content chunks that we need to fill this request
3781 * */
3782
3783- b = chunkqueue_get_append_buffer(hctx->wb);
3784 fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
3785- buffer_copy_memory(b, (const char *)&header, sizeof(header));
3786+ chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header));
3787 hctx->wb->bytes_in += sizeof(header);
3788
3789 if (p->conf.debug > 10) {
3790 log_error_write(srv, __FILE__, __LINE__, "soso", "tosend:", offset, "/", req_cq->bytes_in);
3791 }
3792
3793- for (written = 0; written != weWant; ) {
3794- if (p->conf.debug > 10) {
3795- log_error_write(srv, __FILE__, __LINE__, "soso", "chunk:", written, "/", weWant);
3796- }
3797-
3798- switch (req_c->type) {
3799- case FILE_CHUNK:
3800- weHave = req_c->file.length - req_c->offset;
3801-
3802- if (weHave > weWant - written) weHave = weWant - written;
3803-
3804- if (p->conf.debug > 10) {
3805- log_error_write(srv, __FILE__, __LINE__, "soSosOsb",
3806- "sending", weHave, "bytes from (",
3807- req_c->offset, "/", req_c->file.length, ")",
3808- req_c->file.name);
3809- }
3810-
3811- force_assert(weHave != 0);
3812-
3813- chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
3814-
3815- req_c->offset += weHave;
3816- req_cq->bytes_out += weHave;
3817- written += weHave;
3818-
3819- hctx->wb->bytes_in += weHave;
3820-
3821- /* steal the tempfile
3822- *
3823- * This is tricky:
3824- * - we reference the tempfile from the request-content-queue several times
3825- * if the req_c is larger than FCGI_MAX_LENGTH
3826- * - we can't simply cleanup the request-content-queue as soon as possible
3827- * as it would remove the tempfiles
3828- * - the idea is to 'steal' the tempfiles and attach the is_temp flag to the last
3829- * referencing chunk of the fastcgi-write-queue
3830- *
3831- * */
3832-
3833- if (req_c->offset == req_c->file.length) {
3834- chunk *c;
3835-
3836- if (p->conf.debug > 10) {
3837- log_error_write(srv, __FILE__, __LINE__, "s", "next chunk");
3838- }
3839- c = hctx->wb->last;
3840-
3841- force_assert(c->type == FILE_CHUNK);
3842- force_assert(req_c->file.is_temp == 1);
3843-
3844- c->file.is_temp = 1;
3845- req_c->file.is_temp = 0;
3846-
3847- chunkqueue_remove_finished_chunks(req_cq);
3848-
3849- req_c = req_cq->first;
3850- }
3851-
3852- break;
3853- case MEM_CHUNK:
3854- /* append to the buffer */
3855- weHave = req_c->mem->used - 1 - req_c->offset;
3856-
3857- if (weHave > weWant - written) weHave = weWant - written;
3858-
3859- buffer_append_memory(b, req_c->mem->ptr + req_c->offset, weHave);
3860+ chunkqueue_steal(hctx->wb, req_cq, weWant);
3861
3862- req_c->offset += weHave;
3863- req_cq->bytes_out += weHave;
3864- written += weHave;
3865-
3866- hctx->wb->bytes_in += weHave;
3867-
3868- if (req_c->offset == (off_t) req_c->mem->used - 1) {
3869- chunkqueue_remove_finished_chunks(req_cq);
3870-
3871- req_c = req_cq->first;
3872- }
3873-
3874- break;
3875- default:
3876- break;
3877- }
3878- }
3879-
3880- b->used++; /* add virtual \0 */
3881 offset += weWant;
3882 }
3883 }
3884
3885- b = chunkqueue_get_append_buffer(hctx->wb);
3886 /* terminate STDIN */
3887 fcgi_header(&(header), FCGI_STDIN, request_id, 0, 0);
3888- buffer_copy_memory(b, (const char *)&header, sizeof(header));
3889- b->used++; /* add virtual \0 */
3890+ chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header));
3891
3892 hctx->wb->bytes_in += sizeof(header);
3893
3894@@ -2201,7 +2108,7 @@ static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buf
3895
3896 UNUSED(srv);
3897
3898- buffer_copy_string_buffer(p->parse_response, in);
3899+ buffer_copy_buffer(p->parse_response, in);
3900
3901 /* search for \n */
3902 for (s = p->parse_response->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) {
3903@@ -2381,7 +2288,7 @@ range_success: ;
3904 }
3905
3906 buffer_copy_string_len(dcls->key, "Content-Length", sizeof("Content-Length")-1);
3907- buffer_copy_off_t(dcls->value, sendfile2_content_length);
3908+ buffer_copy_int(dcls->value, sendfile2_content_length);
3909 dcls = (data_string*) array_replace(con->response.headers, (data_unset *)dcls);
3910 if (dcls) dcls->free((data_unset*)dcls);
3911
3912@@ -2599,17 +2506,17 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
3913 */
3914
3915 if (hctx->response_header->used == 0) {
3916- buffer_copy_string_buffer(hctx->response_header, packet.b);
3917+ buffer_copy_buffer(hctx->response_header, packet.b);
3918 } else {
3919 buffer_append_string_buffer(hctx->response_header, packet.b);
3920 }
3921
3922 if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\r\n\r\n")))) {
3923- blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4;
3924+ blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4 - 1;
3925 hctx->response_header->used = (c - hctx->response_header->ptr) + 3;
3926 c += 4; /* point the the start of the response */
3927 } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) {
3928- blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2;
3929+ blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2 - 1;
3930 hctx->response_header->used = c - hctx->response_header->ptr + 2;
3931 c += 2; /* point the the start of the response */
3932 } else {
3933@@ -2650,7 +2557,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
3934 joblist_append(srv, con);
3935
3936 buffer_copy_string_len(dcls->key, "Content-Length", sizeof("Content-Length")-1);
3937- buffer_copy_off_t(dcls->value, sce->st.st_size);
3938+ buffer_copy_int(dcls->value, sce->st.st_size);
3939 dcls = (data_string*) array_replace(con->response.headers, (data_unset *)dcls);
3940 if (dcls) dcls->free((data_unset*)dcls);
3941
3942@@ -2668,7 +2575,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
3943 }
3944
3945
3946- if (hctx->send_content_body && blen > 1) {
3947+ if (hctx->send_content_body && blen > 0) {
3948 /* enable chunked-transfer-encoding */
3949 if (con->request.http_version == HTTP_VERSION_1_1 &&
3950 !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
3951@@ -2685,7 +2592,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
3952 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
3953 }
3954
3955- http_chunk_append_mem(srv, con, packet.b->ptr, packet.b->used);
3956+ http_chunk_append_buffer(srv, con, packet.b);
3957 joblist_append(srv, con);
3958 }
3959 break;
3960@@ -2703,7 +2610,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
3961 !(con->http_status == 0 ||
3962 con->http_status == 200)) {
3963 /* send chunk-end if necessary */
3964- http_chunk_append_mem(srv, con, NULL, 0);
3965+ http_chunk_close(srv, con);
3966 joblist_append(srv, con);
3967 }
3968
3969@@ -2820,7 +2727,7 @@ static int fcgi_restart_dead_procs(server *srv, plugin_data *p, fcgi_extension_h
3970 /* local procs get restarted by us,
3971 * remote ones hopefully by the admin */
3972
3973- if (!buffer_is_empty(host->bin_path)) {
3974+ if (!buffer_string_is_empty(host->bin_path)) {
3975 /* we still have connections bound to this proc,
3976 * let them terminate first */
3977 if (proc->load != 0) break;
3978@@ -3264,10 +3171,10 @@ static handler_t fcgi_handle_fdevent(server *srv, void *ctx, int revents) {
3979 * now to handle authorized request.
3980 */
3981
3982- buffer_copy_string_buffer(con->physical.doc_root, host->docroot);
3983- buffer_copy_string_buffer(con->physical.basedir, host->docroot);
3984+ buffer_copy_buffer(con->physical.doc_root, host->docroot);
3985+ buffer_copy_buffer(con->physical.basedir, host->docroot);
3986
3987- buffer_copy_string_buffer(con->physical.path, host->docroot);
3988+ buffer_copy_buffer(con->physical.path, host->docroot);
3989 buffer_append_string_buffer(con->physical.path, con->uri.path);
3990 fcgi_connection_close(srv, hctx);
3991
3992@@ -3486,7 +3393,7 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
3993
3994 fn = uri_path_handler ? con->uri.path : con->physical.path;
3995
3996- if (buffer_is_empty(fn)) return HANDLER_GO_ON;
3997+ if (buffer_string_is_empty(fn)) return HANDLER_GO_ON;
3998
3999 s_len = fn->used - 1;
4000
4001diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c
4002index 8041507..501f8e8 100644
4003--- a/src/mod_flv_streaming.c
4004+++ b/src/mod_flv_streaming.c
4005@@ -191,7 +191,7 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
4006
4007 if (con->mode != DIRECT) return HANDLER_GO_ON;
4008
4009- if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
4010+ if (buffer_string_is_empty(con->physical.path)) return HANDLER_GO_ON;
4011
4012 mod_flv_streaming_patch_connection(srv, con, p);
4013
4014@@ -214,7 +214,7 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
4015 * otherwise send the full file */
4016
4017 array_reset(p->get_params);
4018- buffer_copy_string_buffer(p->query_str, con->uri.query);
4019+ buffer_copy_buffer(p->query_str, con->uri.query);
4020 split_get_params(p->get_params, p->query_str);
4021
4022 if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {
4023diff --git a/src/mod_indexfile.c b/src/mod_indexfile.c
4024index b46ead6..fe750c1 100644
4025--- a/src/mod_indexfile.c
4026+++ b/src/mod_indexfile.c
4027@@ -158,9 +158,9 @@ URIHANDLER_FUNC(mod_indexfile_subrequest) {
4028 if (ds->value && ds->value->ptr[0] == '/') {
4029 /* if the index-file starts with a prefix as use this file as
4030 * index-generator */
4031- buffer_copy_string_buffer(p->tmp_buf, con->physical.doc_root);
4032+ buffer_copy_buffer(p->tmp_buf, con->physical.doc_root);
4033 } else {
4034- buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
4035+ buffer_copy_buffer(p->tmp_buf, con->physical.path);
4036 }
4037 buffer_append_string_buffer(p->tmp_buf, ds->value);
4038
4039@@ -192,7 +192,7 @@ URIHANDLER_FUNC(mod_indexfile_subrequest) {
4040
4041 /* rewrite uri.path to the real path (/ -> /index.php) */
4042 buffer_append_string_buffer(con->uri.path, ds->value);
4043- buffer_copy_string_buffer(con->physical.path, p->tmp_buf);
4044+ buffer_copy_buffer(con->physical.path, p->tmp_buf);
4045
4046 /* fce is already set up a few lines above */
4047
4048diff --git a/src/mod_magnet.c b/src/mod_magnet.c
4049index cfdc976..80cb799 100644
4050--- a/src/mod_magnet.c
4051+++ b/src/mod_magnet.c
4052@@ -319,7 +319,7 @@ static int magnet_stat(lua_State *L) {
4053 lua_setfield(L, -2, "st_ino");
4054
4055
4056- if (!buffer_is_empty(sce->etag)) {
4057+ if (!buffer_string_is_empty(sce->etag)) {
4058 /* we have to mutate the etag */
4059 buffer *b = buffer_init();
4060 etag_mutate(b, sce->etag);
4061@@ -331,7 +331,7 @@ static int magnet_stat(lua_State *L) {
4062 }
4063 lua_setfield(L, -2, "etag");
4064
4065- if (!buffer_is_empty(sce->content_type)) {
4066+ if (!buffer_string_is_empty(sce->content_type)) {
4067 lua_pushlstring(L, sce->content_type->ptr, sce->content_type->used - 1);
4068 } else {
4069 lua_pushnil(L);
4070@@ -759,7 +759,7 @@ static int magnet_attach_content(server *srv, connection *con, plugin_data *p, l
4071 size_t s_len = 0;
4072 const char *s = lua_tolstring(L, -1, &s_len);
4073
4074- chunkqueue_append_mem(con->write_queue, s, s_len + 1);
4075+ chunkqueue_append_mem(con->write_queue, s, s_len);
4076 } else if (lua_istable(L, -1)) {
4077 lua_getfield(L, -1, "filename");
4078 lua_getfield(L, -2, "length");
4079@@ -1066,7 +1066,7 @@ static handler_t magnet_attract_array(server *srv, connection *con, plugin_data
4080 data_string *ds = (data_string *)files->data[i];
4081 handler_t ret;
4082
4083- if (buffer_is_empty(ds->value)) continue;
4084+ if (buffer_string_is_empty(ds->value)) continue;
4085
4086 ret = magnet_attract(srv, con, p, ds->value);
4087
4088diff --git a/src/mod_magnet_cache.c b/src/mod_magnet_cache.c
4089index 90c633e..0e9f72f 100644
4090--- a/src/mod_magnet_cache.c
4091+++ b/src/mod_magnet_cache.c
4092@@ -104,7 +104,7 @@ lua_State *script_cache_get_script(server *srv, connection *con, script_cache *c
4093
4094 cache->ptr[cache->used++] = sc;
4095
4096- buffer_copy_string_buffer(sc->name, name);
4097+ buffer_copy_buffer(sc->name, name);
4098
4099 sc->L = luaL_newstate();
4100 luaL_openlibs(sc->L);
4101@@ -119,7 +119,7 @@ lua_State *script_cache_get_script(server *srv, connection *con, script_cache *c
4102 }
4103
4104 if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, sc->name, &sce)) {
4105- buffer_copy_string_buffer(sc->etag, sce->etag);
4106+ buffer_copy_buffer(sc->etag, sce->etag);
4107 }
4108
4109 /**
4110diff --git a/src/mod_mysql_vhost.c b/src/mod_mysql_vhost.c
4111index a02ed2c..8442f76 100644
4112--- a/src/mod_mysql_vhost.c
4113+++ b/src/mod_mysql_vhost.c
4114@@ -227,7 +227,7 @@ SERVER_FUNC(mod_mysql_vhost_set_defaults) {
4115 buffer_copy_string(s->mysql_pre, sel->ptr);
4116 buffer_copy_string(s->mysql_post, qmark+1);
4117 } else {
4118- buffer_copy_string_buffer(s->mysql_pre, sel);
4119+ buffer_copy_buffer(s->mysql_pre, sel);
4120 }
4121
4122 /* required:
4123@@ -242,8 +242,8 @@ SERVER_FUNC(mod_mysql_vhost_set_defaults) {
4124 */
4125
4126 /* all have to be set */
4127- if (!(buffer_is_empty(s->myuser) ||
4128- buffer_is_empty(s->mydb))) {
4129+ if (!(buffer_string_is_empty(s->myuser) ||
4130+ buffer_string_is_empty(s->mydb))) {
4131 my_bool reconnect = 1;
4132
4133 if (NULL == (s->mysql = mysql_init(NULL))) {
4134@@ -349,7 +349,7 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
4135 buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON;
4136
4137 /* build and run SQL query */
4138- buffer_copy_string_buffer(p->tmp_buf, p->conf.mysql_pre);
4139+ buffer_copy_buffer(p->tmp_buf, p->conf.mysql_pre);
4140 if (p->conf.mysql_post->used) {
4141 /* escape the uri.authority */
4142 unsigned long to_len;
4143@@ -382,7 +382,7 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
4144
4145 /* sanity check that really is a directory */
4146 buffer_copy_string(p->tmp_buf, row[0]);
4147- BUFFER_APPEND_SLASH(p->tmp_buf);
4148+ buffer_append_slash(p->tmp_buf);
4149
4150 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
4151 log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
4152@@ -394,8 +394,8 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
4153 }
4154
4155 /* cache the data */
4156- buffer_copy_string_buffer(c->server_name, con->uri.authority);
4157- buffer_copy_string_buffer(c->document_root, p->tmp_buf);
4158+ buffer_copy_buffer(c->server_name, con->uri.authority);
4159+ buffer_copy_buffer(c->document_root, p->tmp_buf);
4160
4161 /* fcgi_offset and fcgi_arg are optional */
4162 if (cols > 1 && row[1]) {
4163@@ -416,8 +416,8 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
4164
4165 /* fix virtual server and docroot */
4166 GO_ON:
4167- buffer_copy_string_buffer(con->server_name, c->server_name);
4168- buffer_copy_string_buffer(con->physical.doc_root, c->document_root);
4169+ buffer_copy_buffer(con->server_name, c->server_name);
4170+ buffer_copy_buffer(con->physical.doc_root, c->document_root);
4171
4172 #ifdef DEBUG
4173 log_error_write(srv, __FILE__, __LINE__, "sbbdb",
4174diff --git a/src/mod_proxy.c b/src/mod_proxy.c
4175index 957a5a2..3bfc78f 100644
4176--- a/src/mod_proxy.c
4177+++ b/src/mod_proxy.c
4178@@ -217,7 +217,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
4179 return HANDLER_ERROR;
4180 }
4181
4182- if (buffer_is_empty(p->balance_buf)) {
4183+ if (buffer_string_is_empty(p->balance_buf)) {
4184 s->balance = PROXY_BALANCE_FAIR;
4185 } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("fair"))) {
4186 s->balance = PROXY_BALANCE_FAIR;
4187@@ -292,7 +292,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
4188
4189 df->port = 80;
4190
4191- buffer_copy_string_buffer(df->key, da_host->key);
4192+ buffer_copy_buffer(df->key, da_host->key);
4193
4194 pcv[0].destination = df->host;
4195 pcv[1].destination = &(df->port);
4196@@ -302,7 +302,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
4197 return HANDLER_ERROR;
4198 }
4199
4200- if (buffer_is_empty(df->host)) {
4201+ if (buffer_string_is_empty(df->host)) {
4202 log_error_write(srv, __FILE__, __LINE__, "sbbbs",
4203 "missing key (string):",
4204 da->key,
4205@@ -319,7 +319,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
4206 if (NULL == (dfa = (data_array *)array_get_element(s->extensions, da_ext->key->ptr))) {
4207 dfa = data_array_init();
4208
4209- buffer_copy_string_buffer(dfa->key, da_ext->key);
4210+ buffer_copy_buffer(dfa->key, da_ext->key);
4211
4212 array_insert_unique(dfa->value, (data_unset *)df);
4213 array_insert_unique(s->extensions, (data_unset *)dfa);
4214@@ -461,8 +461,7 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
4215 proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
4216 /* http_host is NOT is just a pointer to a buffer
4217 * which is NULL if it is not set */
4218- if (con->request.http_host &&
4219- !buffer_is_empty(con->request.http_host)) {
4220+ if (!buffer_string_is_empty(con->request.http_host)) {
4221 proxy_set_header(con, "X-Host", con->request.http_host->ptr);
4222 }
4223 proxy_set_header(con, "X-Forwarded-Proto", con->uri.scheme->ptr);
4224@@ -491,55 +490,8 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
4225
4226 if (con->request.content_length) {
4227 chunkqueue *req_cq = con->request_content_queue;
4228- chunk *req_c;
4229- off_t offset;
4230-
4231- /* something to send ? */
4232- for (offset = 0, req_c = req_cq->first; offset != req_cq->bytes_in; req_c = req_c->next) {
4233- off_t weWant = req_cq->bytes_in - offset;
4234- off_t weHave = 0;
4235-
4236- /* we announce toWrite octects
4237- * now take all the request_content chunk that we need to fill this request
4238- * */
4239-
4240- switch (req_c->type) {
4241- case FILE_CHUNK:
4242- weHave = req_c->file.length - req_c->offset;
4243-
4244- if (weHave > weWant) weHave = weWant;
4245-
4246- chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
4247-
4248- req_c->offset += weHave;
4249- req_cq->bytes_out += weHave;
4250-
4251- hctx->wb->bytes_in += weHave;
4252-
4253- break;
4254- case MEM_CHUNK:
4255- /* append to the buffer */
4256- weHave = req_c->mem->used - 1 - req_c->offset;
4257-
4258- if (weHave > weWant) weHave = weWant;
4259-
4260- b = chunkqueue_get_append_buffer(hctx->wb);
4261- buffer_append_memory(b, req_c->mem->ptr + req_c->offset, weHave);
4262- b->used++; /* add virtual \0 */
4263-
4264- req_c->offset += weHave;
4265- req_cq->bytes_out += weHave;
4266-
4267- hctx->wb->bytes_in += weHave;
4268-
4269- break;
4270- default:
4271- break;
4272- }
4273-
4274- offset += weHave;
4275- }
4276
4277+ chunkqueue_steal(hctx->wb, req_cq, req_cq->bytes_in);
4278 }
4279
4280 return 0;
4281@@ -561,7 +513,7 @@ static int proxy_response_parse(server *srv, connection *con, plugin_data *p, bu
4282
4283 /* \r\n -> \0\0 */
4284
4285- buffer_copy_string_buffer(p->parse_response, in);
4286+ buffer_copy_buffer(p->parse_response, in);
4287
4288 for (s = p->parse_response->ptr; NULL != (ns = strstr(s, "\r\n")); s = ns + 2) {
4289 char *key, *value;
4290@@ -705,12 +657,12 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
4291 char *c;
4292
4293 /* search for the \r\n\r\n in the string */
4294- if (NULL != (c = buffer_search_string_len(hctx->response, "\r\n\r\n", 4))) {
4295+ if (NULL != (c = buffer_search_string_len(hctx->response, CONST_STR_LEN("\r\n\r\n")))) {
4296 size_t hlen = c - hctx->response->ptr + 4;
4297 size_t blen = hctx->response->used - hlen - 1;
4298 /* found */
4299
4300- buffer_append_string_len(hctx->response_header, hctx->response->ptr, c - hctx->response->ptr + 4);
4301+ buffer_append_string_len(hctx->response_header, hctx->response->ptr, hlen);
4302 #if 0
4303 log_error_write(srv, __FILE__, __LINE__, "sb", "Header:", hctx->response_header);
4304 #endif
4305@@ -724,14 +676,12 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
4306 }
4307
4308 con->file_started = 1;
4309- if (blen) {
4310- http_chunk_append_mem(srv, con, c + 4, blen + 1);
4311- }
4312+ if (blen > 0) http_chunk_append_mem(srv, con, c + 4, blen);
4313 hctx->response->used = 0;
4314 joblist_append(srv, con);
4315 }
4316 } else {
4317- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
4318+ http_chunk_append_buffer(srv, con, hctx->response);
4319 joblist_append(srv, con);
4320 hctx->response->used = 0;
4321 }
4322@@ -740,7 +690,7 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
4323 /* reading from upstream done */
4324 con->file_finished = 1;
4325
4326- http_chunk_append_mem(srv, con, NULL, 0);
4327+ http_chunk_close(srv, con);
4328 joblist_append(srv, con);
4329
4330 fin = 1;
4331@@ -976,6 +926,7 @@ static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) {
4332 case 1:
4333 /* we are done */
4334 proxy_connection_close(srv, hctx);
4335+ log_error_write(srv, __FILE__, __LINE__, "s", "proxy request finished");
4336
4337 joblist_append(srv, con);
4338 return HANDLER_FINISHED;
4339@@ -1092,7 +1043,7 @@ static handler_t proxy_handle_fdevent(server *srv, void *ctx, int revents) {
4340 }
4341
4342 if (!con->file_finished) {
4343- http_chunk_append_mem(srv, con, NULL, 0);
4344+ http_chunk_close(srv, con);
4345 }
4346
4347 con->file_finished = 1;
4348diff --git a/src/mod_redirect.c b/src/mod_redirect.c
4349index bfc00d7..93cecb7 100644
4350--- a/src/mod_redirect.c
4351+++ b/src/mod_redirect.c
4352@@ -183,7 +183,7 @@ static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_
4353
4354 mod_redirect_patch_connection(srv, con, p);
4355
4356- buffer_copy_string_buffer(p->match_buf, con->request.uri);
4357+ buffer_copy_buffer(p->match_buf, con->request.uri);
4358
4359 for (i = 0; i < p->conf.redirect->used; i++) {
4360 pcre *match;
4361diff --git a/src/mod_rewrite.c b/src/mod_rewrite.c
4362index 381f0ed..48c0987 100644
4363--- a/src/mod_rewrite.c
4364+++ b/src/mod_rewrite.c
4365@@ -101,7 +101,7 @@ static int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buf
4366 }
4367
4368 kvb->ptr[kvb->used]->value = buffer_init();
4369- buffer_copy_string_buffer(kvb->ptr[kvb->used]->value, value);
4370+ buffer_copy_buffer(kvb->ptr[kvb->used]->value, value);
4371 kvb->ptr[kvb->used]->once = once;
4372
4373 kvb->used++;
4374@@ -359,7 +359,7 @@ static int process_rewrite_rules(server *srv, connection *con, plugin_data *p, r
4375 if (hctx->state == REWRITE_STATE_FINISHED) return HANDLER_GO_ON;
4376 }
4377
4378- buffer_copy_string_buffer(p->match_buf, con->request.uri);
4379+ buffer_copy_buffer(p->match_buf, con->request.uri);
4380
4381 for (i = 0; i < kvb->used; i++) {
4382 pcre *match;
4383diff --git a/src/mod_rrdtool.c b/src/mod_rrdtool.c
4384index df2a781..4986ea3 100644
4385--- a/src/mod_rrdtool.c
4386+++ b/src/mod_rrdtool.c
4387@@ -366,7 +366,7 @@ SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
4388 return HANDLER_ERROR;
4389 }
4390
4391- if (i > 0 && !buffer_is_empty(s->path_rrdtool_bin)) {
4392+ if (i > 0 && !buffer_string_is_empty(s->path_rrdtool_bin)) {
4393 /* path_rrdtool_bin is a global option */
4394
4395 log_error_write(srv, __FILE__, __LINE__, "s",
4396@@ -382,7 +382,7 @@ SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
4397
4398 /* check for dir */
4399
4400- if (buffer_is_empty(p->conf.path_rrdtool_bin)) {
4401+ if (buffer_string_is_empty(p->conf.path_rrdtool_bin)) {
4402 log_error_write(srv, __FILE__, __LINE__, "s",
4403 "rrdtool.binary has to be set");
4404 return HANDLER_ERROR;
4405@@ -409,7 +409,7 @@ TRIGGER_FUNC(mod_rrd_trigger) {
4406 plugin_config *s = p->config_storage[i];
4407 int r;
4408
4409- if (buffer_is_empty(s->path_rrd)) continue;
4410+ if (buffer_string_is_empty(s->path_rrd)) continue;
4411
4412 /* write the data down every minute */
4413
4414@@ -418,11 +418,11 @@ TRIGGER_FUNC(mod_rrd_trigger) {
4415 buffer_copy_string_len(p->cmd, CONST_STR_LEN("update "));
4416 buffer_append_string_buffer(p->cmd, s->path_rrd);
4417 buffer_append_string_len(p->cmd, CONST_STR_LEN(" N:"));
4418- buffer_append_off_t(p->cmd, s->bytes_read);
4419+ buffer_append_int(p->cmd, s->bytes_read);
4420 buffer_append_string_len(p->cmd, CONST_STR_LEN(":"));
4421- buffer_append_off_t(p->cmd, s->bytes_written);
4422+ buffer_append_int(p->cmd, s->bytes_written);
4423 buffer_append_string_len(p->cmd, CONST_STR_LEN(":"));
4424- buffer_append_long(p->cmd, s->requests);
4425+ buffer_append_int(p->cmd, s->requests);
4426 buffer_append_string_len(p->cmd, CONST_STR_LEN("\n"));
4427
4428 if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
4429diff --git a/src/mod_scgi.c b/src/mod_scgi.c
4430index 1c16c2d..66dce5e 100644
4431--- a/src/mod_scgi.c
4432+++ b/src/mod_scgi.c
4433@@ -306,7 +306,6 @@ typedef struct {
4434
4435 int reconnects; /* number of reconnect attempts */
4436
4437- read_buffer *rb;
4438 chunkqueue *wb;
4439
4440 buffer *response_header;
4441@@ -380,11 +379,6 @@ static void handler_ctx_free(handler_ctx *hctx) {
4442
4443 chunkqueue_free(hctx->wb);
4444
4445- if (hctx->rb) {
4446- if (hctx->rb->ptr) free(hctx->rb->ptr);
4447- free(hctx->rb);
4448- }
4449-
4450 free(hctx);
4451 }
4452
4453@@ -497,7 +491,7 @@ static int scgi_extension_insert(scgi_exts *ext, buffer *key, scgi_extension_hos
4454 fe = calloc(1, sizeof(*fe));
4455 force_assert(fe);
4456 fe->key = buffer_init();
4457- buffer_copy_string_buffer(fe->key, key);
4458+ buffer_copy_buffer(fe->key, key);
4459
4460 /* */
4461
4462@@ -579,7 +573,7 @@ FREE_FUNC(mod_scgi_free) {
4463 if (proc->pid != 0) kill(proc->pid, SIGTERM);
4464
4465 if (proc->is_local &&
4466- !buffer_is_empty(proc->socket)) {
4467+ !buffer_string_is_empty(proc->socket)) {
4468 unlink(proc->socket->ptr);
4469 }
4470 }
4471@@ -588,7 +582,7 @@ FREE_FUNC(mod_scgi_free) {
4472 if (proc->pid != 0) kill(proc->pid, SIGTERM);
4473
4474 if (proc->is_local &&
4475- !buffer_is_empty(proc->socket)) {
4476+ !buffer_string_is_empty(proc->socket)) {
4477 unlink(proc->socket->ptr);
4478 }
4479 }
4480@@ -665,7 +659,7 @@ static int scgi_spawn_connection(server *srv,
4481 "new proc, socket:", proc->port, proc->socket);
4482 }
4483
4484- if (!buffer_is_empty(proc->socket)) {
4485+ if (!buffer_string_is_empty(proc->socket)) {
4486 memset(&scgi_addr, 0, sizeof(scgi_addr));
4487
4488 #ifdef HAVE_SYS_UN_H
4489@@ -694,7 +688,7 @@ static int scgi_spawn_connection(server *srv,
4490 } else {
4491 scgi_addr_in.sin_family = AF_INET;
4492
4493- if (buffer_is_empty(host->host)) {
4494+ if (buffer_string_is_empty(host->host)) {
4495 scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
4496 } else {
4497 struct hostent *he;
4498@@ -741,7 +735,7 @@ static int scgi_spawn_connection(server *srv,
4499 pid_t child;
4500 int val;
4501
4502- if (!buffer_is_empty(proc->socket)) {
4503+ if (!buffer_string_is_empty(proc->socket)) {
4504 unlink(proc->socket->ptr);
4505 }
4506
4507@@ -1066,15 +1060,15 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
4508 goto error;
4509 }
4510
4511- if ((!buffer_is_empty(df->host) || df->port) &&
4512- !buffer_is_empty(df->unixsocket)) {
4513+ if ((!buffer_string_is_empty(df->host) || df->port) &&
4514+ !buffer_string_is_empty(df->unixsocket)) {
4515 log_error_write(srv, __FILE__, __LINE__, "s",
4516 "either host+port or socket");
4517
4518 goto error;
4519 }
4520
4521- if (!buffer_is_empty(df->unixsocket)) {
4522+ if (!buffer_string_is_empty(df->unixsocket)) {
4523 /* unix domain socket */
4524 struct sockaddr_un un;
4525
4526@@ -1086,8 +1080,8 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
4527 } else {
4528 /* tcp/ip */
4529
4530- if (buffer_is_empty(df->host) &&
4531- buffer_is_empty(df->bin_path)) {
4532+ if (buffer_string_is_empty(df->host) &&
4533+ buffer_string_is_empty(df->bin_path)) {
4534 log_error_write(srv, __FILE__, __LINE__, "sbbbs",
4535 "missing key (string):",
4536 da->key,
4537@@ -1107,7 +1101,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
4538 }
4539 }
4540
4541- if (!buffer_is_empty(df->bin_path)) {
4542+ if (!buffer_string_is_empty(df->bin_path)) {
4543 /* a local socket + self spawning */
4544 size_t pno;
4545
4546@@ -1134,12 +1128,12 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
4547 proc->id = df->num_procs++;
4548 df->max_id++;
4549
4550- if (buffer_is_empty(df->unixsocket)) {
4551+ if (buffer_string_is_empty(df->unixsocket)) {
4552 proc->port = df->port + pno;
4553 } else {
4554- buffer_copy_string_buffer(proc->socket, df->unixsocket);
4555+ buffer_copy_buffer(proc->socket, df->unixsocket);
4556 buffer_append_string_len(proc->socket, CONST_STR_LEN("-"));
4557- buffer_append_long(proc->socket, pno);
4558+ buffer_append_int(proc->socket, pno);
4559 }
4560
4561 if (s->debug) {
4562@@ -1171,10 +1165,10 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
4563 df->active_procs++;
4564 fp->state = PROC_STATE_RUNNING;
4565
4566- if (buffer_is_empty(df->unixsocket)) {
4567+ if (buffer_string_is_empty(df->unixsocket)) {
4568 fp->port = df->port;
4569 } else {
4570- buffer_copy_string_buffer(fp->socket, df->unixsocket);
4571+ buffer_copy_buffer(fp->socket, df->unixsocket);
4572 }
4573
4574 df->first = fp;
4575@@ -1342,7 +1336,7 @@ static int scgi_establish_connection(server *srv, handler_ctx *hctx) {
4576
4577 memset(&scgi_addr, 0, sizeof(scgi_addr));
4578
4579- if (!buffer_is_empty(proc->socket)) {
4580+ if (!buffer_string_is_empty(proc->socket)) {
4581 #ifdef HAVE_SYS_UN_H
4582 /* use the unix domain socket */
4583 scgi_addr_un.sun_family = AF_UNIX;
4584@@ -1471,7 +1465,7 @@ static int scgi_env_add_request_headers(server *srv, connection *con, plugin_dat
4585
4586
4587 static int scgi_create_env(server *srv, handler_ctx *hctx) {
4588- char buf[32];
4589+ char buf[LI_ITOSTRING_LENGTH];
4590 const char *s;
4591 #ifdef HAVE_IPV6
4592 char b2[INET6_ADDRSTRLEN + 1];
4593@@ -1491,8 +1485,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
4594
4595 /* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */
4596
4597- /* request.content_length < SSIZE_MAX, see request.c */
4598- LI_ltostr(buf, con->request.content_length);
4599+ li_itostr(buf, con->request.content_length);
4600 scgi_env_add(p->scgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
4601 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCGI"), CONST_STR_LEN("1"));
4602
4603@@ -1530,7 +1523,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
4604
4605 scgi_env_add(p->scgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
4606
4607- LI_ltostr(buf,
4608+ li_utostr(buf,
4609 #ifdef HAVE_IPV6
4610 ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
4611 #else
4612@@ -1550,7 +1543,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
4613 }
4614 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
4615
4616- LI_ltostr(buf,
4617+ li_utostr(buf,
4618 #ifdef HAVE_IPV6
4619 ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
4620 #else
4621@@ -1571,15 +1564,15 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
4622
4623 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
4624
4625- if (!buffer_is_empty(con->request.pathinfo)) {
4626+ if (!buffer_string_is_empty(con->request.pathinfo)) {
4627 scgi_env_add(p->scgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
4628
4629 /* PATH_TRANSLATED is only defined if PATH_INFO is set */
4630
4631- if (!buffer_is_empty(host->docroot)) {
4632- buffer_copy_string_buffer(p->path, host->docroot);
4633+ if (!buffer_string_is_empty(host->docroot)) {
4634+ buffer_copy_buffer(p->path, host->docroot);
4635 } else {
4636- buffer_copy_string_buffer(p->path, con->physical.basedir);
4637+ buffer_copy_buffer(p->path, con->physical.basedir);
4638 }
4639 buffer_append_string_buffer(p->path, con->request.pathinfo);
4640 scgi_env_add(p->scgi_env, CONST_STR_LEN("PATH_TRANSLATED"), CONST_BUF_LEN(p->path));
4641@@ -1595,19 +1588,19 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
4642 * parameter.
4643 */
4644
4645- if (!buffer_is_empty(host->docroot)) {
4646+ if (!buffer_string_is_empty(host->docroot)) {
4647 /*
4648 * rewrite SCRIPT_FILENAME
4649 *
4650 */
4651
4652- buffer_copy_string_buffer(p->path, host->docroot);
4653+ buffer_copy_buffer(p->path, host->docroot);
4654 buffer_append_string_buffer(p->path, con->uri.path);
4655
4656 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
4657 scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot));
4658 } else {
4659- buffer_copy_string_buffer(p->path, con->physical.path);
4660+ buffer_copy_buffer(p->path, con->physical.path);
4661
4662 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
4663 scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.basedir));
4664@@ -1616,7 +1609,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
4665 if (!buffer_is_equal(con->request.uri, con->request.orig_uri)) {
4666 scgi_env_add(p->scgi_env, CONST_STR_LEN("REDIRECT_URI"), CONST_BUF_LEN(con->request.uri));
4667 }
4668- if (!buffer_is_empty(con->uri.query)) {
4669+ if (!buffer_string_is_empty(con->uri.query)) {
4670 scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
4671 } else {
4672 scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
4673@@ -1638,7 +1631,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
4674
4675 b = chunkqueue_get_append_buffer(hctx->wb);
4676
4677- buffer_append_long(b, p->scgi_env->used);
4678+ buffer_append_int(b, p->scgi_env->used);
4679 buffer_append_string_len(b, CONST_STR_LEN(":"));
4680 buffer_append_string_len(b, (const char *)p->scgi_env->ptr, p->scgi_env->used);
4681 buffer_append_string_len(b, CONST_STR_LEN(","));
4682@@ -1647,54 +1640,8 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
4683
4684 if (con->request.content_length) {
4685 chunkqueue *req_cq = con->request_content_queue;
4686- chunk *req_c;
4687- off_t offset;
4688-
4689- /* something to send ? */
4690- for (offset = 0, req_c = req_cq->first; offset != req_cq->bytes_in; req_c = req_c->next) {
4691- off_t weWant = req_cq->bytes_in - offset;
4692- off_t weHave = 0;
4693-
4694- /* we announce toWrite octects
4695- * now take all the request_content chunk that we need to fill this request
4696- * */
4697-
4698- switch (req_c->type) {
4699- case FILE_CHUNK:
4700- weHave = req_c->file.length - req_c->offset;
4701-
4702- if (weHave > weWant) weHave = weWant;
4703-
4704- chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
4705-
4706- req_c->offset += weHave;
4707- req_cq->bytes_out += weHave;
4708-
4709- hctx->wb->bytes_in += weHave;
4710-
4711- break;
4712- case MEM_CHUNK:
4713- /* append to the buffer */
4714- weHave = req_c->mem->used - 1 - req_c->offset;
4715
4716- if (weHave > weWant) weHave = weWant;
4717-
4718- b = chunkqueue_get_append_buffer(hctx->wb);
4719- buffer_append_memory(b, req_c->mem->ptr + req_c->offset, weHave);
4720- b->used++; /* add virtual \0 */
4721-
4722- req_c->offset += weHave;
4723- req_cq->bytes_out += weHave;
4724-
4725- hctx->wb->bytes_in += weHave;
4726-
4727- break;
4728- default:
4729- break;
4730- }
4731-
4732- offset += weHave;
4733- }
4734+ chunkqueue_steal(hctx->wb, req_cq, req_cq->bytes_in);
4735 }
4736
4737 return 0;
4738@@ -1707,7 +1654,7 @@ static int scgi_response_parse(server *srv, connection *con, plugin_data *p, buf
4739
4740 UNUSED(srv);
4741
4742- buffer_copy_string_buffer(p->parse_response, in);
4743+ buffer_copy_buffer(p->parse_response, in);
4744
4745 for (s = p->parse_response->ptr;
4746 NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
4747@@ -1827,7 +1774,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
4748 con->file_finished = 1;
4749
4750 /* send final chunk */
4751- http_chunk_append_mem(srv, con, NULL, 0);
4752+ http_chunk_close(srv, con);
4753 joblist_append(srv, con);
4754
4755 return 1;
4756@@ -1905,7 +1852,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
4757 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
4758 }
4759
4760- http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
4761+ http_chunk_append_buffer(srv, con, hctx->response_header);
4762 joblist_append(srv, con);
4763 } else {
4764 size_t blen = hctx->response_header->used - hlen - 1;
4765@@ -1924,7 +1871,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
4766 }
4767
4768 if ((hctx->response->used != hlen) && blen > 0) {
4769- http_chunk_append_mem(srv, con, hctx->response_header->ptr + hlen, blen + 1);
4770+ http_chunk_append_mem(srv, con, hctx->response_header->ptr + hlen, blen);
4771 joblist_append(srv, con);
4772 }
4773 }
4774@@ -1932,7 +1879,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
4775 con->file_started = 1;
4776 }
4777 } else {
4778- http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
4779+ http_chunk_append_buffer(srv, con, hctx->response);
4780 joblist_append(srv, con);
4781 }
4782
4783@@ -2727,7 +2674,7 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
4784
4785 fn = uri_path_handler ? con->uri.path : con->physical.path;
4786
4787- if (buffer_is_empty(fn)) return HANDLER_GO_ON;
4788+ if (buffer_string_is_empty(fn)) return HANDLER_GO_ON;
4789
4790 s_len = fn->used - 1;
4791
4792@@ -3007,12 +2954,12 @@ TRIGGER_FUNC(mod_scgi_handle_trigger) {
4793
4794 host->num_procs++;
4795
4796- if (buffer_is_empty(host->unixsocket)) {
4797+ if (buffer_string_is_empty(host->unixsocket)) {
4798 fp->port = host->port + fp->id;
4799 } else {
4800- buffer_copy_string_buffer(fp->socket, host->unixsocket);
4801+ buffer_copy_buffer(fp->socket, host->unixsocket);
4802 buffer_append_string_len(fp->socket, CONST_STR_LEN("-"));
4803- buffer_append_long(fp->socket, fp->id);
4804+ buffer_append_int(fp->socket, fp->id);
4805 }
4806
4807 if (scgi_spawn_connection(srv, p, host, fp)) {
4808diff --git a/src/mod_secure_download.c b/src/mod_secure_download.c
4809index c32a3ac..d94482e 100644
4810--- a/src/mod_secure_download.c
4811+++ b/src/mod_secure_download.c
4812@@ -204,13 +204,13 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
4813
4814 if (buffer_is_empty(p->conf.uri_prefix)) return HANDLER_GO_ON;
4815
4816- if (buffer_is_empty(p->conf.secret)) {
4817+ if (buffer_string_is_empty(p->conf.secret)) {
4818 log_error_write(srv, __FILE__, __LINE__, "s",
4819 "secdownload.secret has to be set");
4820 return HANDLER_ERROR;
4821 }
4822
4823- if (buffer_is_empty(p->conf.doc_root)) {
4824+ if (buffer_string_is_empty(p->conf.doc_root)) {
4825 log_error_write(srv, __FILE__, __LINE__, "s",
4826 "secdownload.document-root has to be set");
4827 return HANDLER_ERROR;
4828@@ -233,7 +233,7 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
4829 if (*(ts_str + 8) != '/') return HANDLER_GO_ON;
4830
4831 for (i = 0; i < 8; i++) {
4832- ts = (ts << 4) + hex2int(*(ts_str + i));
4833+ ts = (ts << 4) + hex2int(ts_str[i]);
4834 }
4835
4836 /* timed-out */
4837@@ -252,7 +252,7 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
4838 * <secret><rel-path><timestamp-hex>
4839 */
4840
4841- buffer_copy_string_buffer(p->md5, p->conf.secret);
4842+ buffer_copy_buffer(p->md5, p->conf.secret);
4843 buffer_append_string(p->md5, rel_uri);
4844 buffer_append_string_len(p->md5, ts_str, 8);
4845 force_assert(p->md5->used > 0);
4846@@ -276,10 +276,10 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
4847 /* starting with the last / we should have relative-path to the docroot
4848 */
4849
4850- buffer_copy_string_buffer(con->physical.doc_root, p->conf.doc_root);
4851- buffer_copy_string_buffer(con->physical.basedir, p->conf.doc_root);
4852+ buffer_copy_buffer(con->physical.doc_root, p->conf.doc_root);
4853+ buffer_copy_buffer(con->physical.basedir, p->conf.doc_root);
4854 buffer_copy_string(con->physical.rel_path, rel_uri);
4855- buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
4856+ buffer_copy_buffer(con->physical.path, con->physical.doc_root);
4857 buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
4858
4859 return HANDLER_GO_ON;
4860diff --git a/src/mod_setenv.c b/src/mod_setenv.c
4861index ad91609..60e9b55 100644
4862--- a/src/mod_setenv.c
4863+++ b/src/mod_setenv.c
4864@@ -185,8 +185,8 @@ URIHANDLER_FUNC(mod_setenv_uri_handler) {
4865 ds_dst = data_string_init();
4866 }
4867
4868- buffer_copy_string_buffer(ds_dst->key, ds->key);
4869- buffer_copy_string_buffer(ds_dst->value, ds->value);
4870+ buffer_copy_buffer(ds_dst->key, ds->key);
4871+ buffer_copy_buffer(ds_dst->value, ds->value);
4872
4873 array_insert_unique(con->request.headers, (data_unset *)ds_dst);
4874 }
4875@@ -199,8 +199,8 @@ URIHANDLER_FUNC(mod_setenv_uri_handler) {
4876 ds_dst = data_string_init();
4877 }
4878
4879- buffer_copy_string_buffer(ds_dst->key, ds->key);
4880- buffer_copy_string_buffer(ds_dst->value, ds->value);
4881+ buffer_copy_buffer(ds_dst->key, ds->key);
4882+ buffer_copy_buffer(ds_dst->value, ds->value);
4883
4884 array_insert_unique(con->environment, (data_unset *)ds_dst);
4885 }
4886diff --git a/src/mod_simple_vhost.c b/src/mod_simple_vhost.c
4887index 1240fda..7245fd5 100644
4888--- a/src/mod_simple_vhost.c
4889+++ b/src/mod_simple_vhost.c
4890@@ -127,7 +127,7 @@ static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *
4891 force_assert(p->conf.server_root->used > 1);
4892
4893 buffer_prepare_copy(out, 128);
4894- buffer_copy_string_buffer(out, p->conf.server_root);
4895+ buffer_copy_buffer(out, p->conf.server_root);
4896
4897 if (host->used) {
4898 /* a hostname has to start with a alpha-numerical character
4899@@ -135,7 +135,7 @@ static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *
4900 */
4901 char *dp;
4902
4903- BUFFER_APPEND_SLASH(out);
4904+ buffer_append_slash(out);
4905
4906 if (NULL == (dp = strchr(host->ptr, ':'))) {
4907 buffer_append_string_buffer(out, host);
4908@@ -143,13 +143,13 @@ static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *
4909 buffer_append_string_len(out, host->ptr, dp - host->ptr);
4910 }
4911 }
4912- BUFFER_APPEND_SLASH(out);
4913+ buffer_append_slash(out);
4914
4915 if (p->conf.document_root->used > 2 && p->conf.document_root->ptr[0] == '/') {
4916 buffer_append_string_len(out, p->conf.document_root->ptr + 1, p->conf.document_root->used - 2);
4917 } else {
4918 buffer_append_string_buffer(out, p->conf.document_root);
4919- BUFFER_APPEND_SLASH(out);
4920+ buffer_append_slash(out);
4921 }
4922
4923 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, out, &sce)) {
4924@@ -233,8 +233,8 @@ static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_
4925 con->uri.authority->used &&
4926 buffer_is_equal(p->conf.docroot_cache_key, con->uri.authority)) {
4927 /* cache hit */
4928- buffer_copy_string_buffer(con->server_name, p->conf.docroot_cache_servername);
4929- buffer_copy_string_buffer(con->physical.doc_root, p->conf.docroot_cache_value);
4930+ buffer_copy_buffer(con->server_name, p->conf.docroot_cache_servername);
4931+ buffer_copy_buffer(con->physical.doc_root, p->conf.docroot_cache_value);
4932 } else {
4933 /* build document-root */
4934 if ((con->uri.authority->used == 0) ||
4935@@ -244,21 +244,21 @@ static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_
4936 p->doc_root,
4937 p->conf.default_host)) {
4938 /* default host worked */
4939- buffer_copy_string_buffer(con->server_name, p->conf.default_host);
4940- buffer_copy_string_buffer(con->physical.doc_root, p->doc_root);
4941+ buffer_copy_buffer(con->server_name, p->conf.default_host);
4942+ buffer_copy_buffer(con->physical.doc_root, p->doc_root);
4943 /* do not cache default host */
4944 }
4945 return HANDLER_GO_ON;
4946 }
4947
4948 /* found host */
4949- buffer_copy_string_buffer(con->server_name, con->uri.authority);
4950- buffer_copy_string_buffer(con->physical.doc_root, p->doc_root);
4951+ buffer_copy_buffer(con->server_name, con->uri.authority);
4952+ buffer_copy_buffer(con->physical.doc_root, p->doc_root);
4953
4954 /* copy to cache */
4955- buffer_copy_string_buffer(p->conf.docroot_cache_key, con->uri.authority);
4956- buffer_copy_string_buffer(p->conf.docroot_cache_value, p->doc_root);
4957- buffer_copy_string_buffer(p->conf.docroot_cache_servername, con->server_name);
4958+ buffer_copy_buffer(p->conf.docroot_cache_key, con->uri.authority);
4959+ buffer_copy_buffer(p->conf.docroot_cache_value, p->doc_root);
4960+ buffer_copy_buffer(p->conf.docroot_cache_servername, con->server_name);
4961 }
4962
4963 return HANDLER_GO_ON;
4964diff --git a/src/mod_ssi.c b/src/mod_ssi.c
4965index 0c1cdba..38eeac5 100644
4966--- a/src/mod_ssi.c
4967+++ b/src/mod_ssi.c
4968@@ -236,7 +236,7 @@ static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data
4969 }
4970
4971 static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
4972- char buf[32];
4973+ char buf[LI_ITOSTRING_LENGTH];
4974
4975 server_socket *srv_sock = con->srv_socket;
4976
4977@@ -263,7 +263,7 @@ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
4978 );
4979 ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1");
4980
4981- LI_ltostr(buf,
4982+ li_utostr(buf,
4983 #ifdef HAVE_IPV6
4984 ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
4985 #else
4986@@ -279,8 +279,7 @@ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
4987 if (con->request.content_length > 0) {
4988 /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
4989
4990- /* request.content_length < SSIZE_MAX, see request.c */
4991- LI_ltostr(buf, con->request.content_length);
4992+ li_itostr(buf, con->request.content_length);
4993 ssi_env_add(p->ssi_cgi_env, CONST_STRING("CONTENT_LENGTH"), buf);
4994 }
4995
4996@@ -434,12 +433,12 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
4997 b = chunkqueue_get_append_buffer(con->write_queue);
4998 #ifdef HAVE_PWD_H
4999 if (NULL == (pw = getpwuid(sce->st.st_uid))) {
5000- buffer_copy_long(b, sce->st.st_uid);
5001+ buffer_copy_int(b, sce->st.st_uid);
5002 } else {
5003 buffer_copy_string(b, pw->pw_name);
5004 }
5005 #else
5006- buffer_copy_long(b, sce->st.st_uid);
5007+ buffer_copy_int(b, sce->st.st_uid);
5008 #endif
5009 break;
5010 }
5011@@ -481,7 +480,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
5012
5013 b = chunkqueue_get_append_buffer(con->write_queue);
5014 if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
5015- buffer_copy_string_buffer(b, con->physical.path);
5016+ buffer_copy_buffer(b, con->physical.path);
5017 } else {
5018 buffer_copy_string(b, sl + 1);
5019 }
5020@@ -489,7 +488,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
5021 }
5022 case SSI_ECHO_DOCUMENT_URI: {
5023 b = chunkqueue_get_append_buffer(con->write_queue);
5024- buffer_copy_string_buffer(b, con->uri.path);
5025+ buffer_copy_buffer(b, con->uri.path);
5026 break;
5027 }
5028 default: {
5029@@ -499,7 +498,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
5030 b = chunkqueue_get_append_buffer(con->write_queue);
5031
5032 if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) {
5033- buffer_copy_string_buffer(b, ds->value);
5034+ buffer_copy_buffer(b, ds->value);
5035 } else {
5036 buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
5037 }
5038@@ -575,7 +574,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
5039
5040 /* we have an uri */
5041
5042- buffer_copy_string_buffer(p->stat_fn, con->physical.doc_root);
5043+ buffer_copy_buffer(p->stat_fn, con->physical.doc_root);
5044 buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
5045 }
5046
5047@@ -593,10 +592,10 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
5048
5049 for (j = 0; s > 1024 && abr[j+1]; s /= 1024, j++);
5050
5051- buffer_copy_off_t(b, s);
5052+ buffer_copy_int(b, s);
5053 buffer_append_string(b, abr[j]);
5054 } else {
5055- buffer_copy_off_t(b, st.st_size);
5056+ buffer_copy_int(b, st.st_size);
5057 }
5058 break;
5059 case SSI_FLASTMOD:
5060@@ -783,19 +782,19 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
5061 int toread;
5062 /* read everything from client and paste it into the output */
5063 was_interrupted = 0;
5064-
5065+
5066 while(1) {
5067 if (ioctl(from_exec_fds[0], FIONREAD, &toread)) {
5068 log_error_write(srv, __FILE__, __LINE__, "s",
5069 "unexpected end-of-file (perhaps the ssi-exec process died)");
5070 return -1;
5071 }
5072-
5073+
5074 if (toread > 0) {
5075 b = chunkqueue_get_append_buffer(con->write_queue);
5076-
5077- buffer_prepare_copy(b, toread + 1);
5078-
5079+
5080+ buffer_prepare_copy(b, toread);
5081+
5082 if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) {
5083 /* read failed */
5084 break;
5085diff --git a/src/mod_ssi_expr.c b/src/mod_ssi_expr.c
5086index f839987..140d086 100644
5087--- a/src/mod_ssi_expr.c
5088+++ b/src/mod_ssi_expr.c
5089@@ -215,9 +215,9 @@ static int ssi_expr_tokenizer(server *srv, connection *con, plugin_data *p,
5090 tid = TK_VALUE;
5091
5092 if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, token->ptr))) {
5093- buffer_copy_string_buffer(token, ds->value);
5094+ buffer_copy_buffer(token, ds->value);
5095 } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) {
5096- buffer_copy_string_buffer(token, ds->value);
5097+ buffer_copy_buffer(token, ds->value);
5098 } else {
5099 buffer_copy_string_len(token, CONST_STR_LEN(""));
5100 }
5101diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c
5102index af0718e..931bc57 100644
5103--- a/src/mod_staticfile.c
5104+++ b/src/mod_staticfile.c
5105@@ -294,11 +294,11 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
5106
5107 /* write Content-Range */
5108 buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Range: bytes "));
5109- buffer_append_off_t(b, start);
5110+ buffer_append_int(b, start);
5111 buffer_append_string_len(b, CONST_STR_LEN("-"));
5112- buffer_append_off_t(b, end);
5113+ buffer_append_int(b, end);
5114 buffer_append_string_len(b, CONST_STR_LEN("/"));
5115- buffer_append_off_t(b, sce->st.st_size);
5116+ buffer_append_int(b, sce->st.st_size);
5117
5118 buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Type: "));
5119 buffer_append_string_buffer(b, content_type);
5120@@ -341,11 +341,11 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
5121 /* add Content-Range-header */
5122
5123 buffer_copy_string_len(p->range_buf, CONST_STR_LEN("bytes "));
5124- buffer_append_off_t(p->range_buf, start);
5125+ buffer_append_int(p->range_buf, start);
5126 buffer_append_string_len(p->range_buf, CONST_STR_LEN("-"));
5127- buffer_append_off_t(p->range_buf, end);
5128+ buffer_append_int(p->range_buf, end);
5129 buffer_append_string_len(p->range_buf, CONST_STR_LEN("/"));
5130- buffer_append_off_t(p->range_buf, sce->st.st_size);
5131+ buffer_append_int(p->range_buf, sce->st.st_size);
5132
5133 response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(p->range_buf));
5134 }
5135@@ -449,7 +449,7 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
5136 /* set response content-type, if not set already */
5137
5138 if (NULL == array_get_element(con->response.headers, "Content-Type")) {
5139- if (buffer_is_empty(sce->content_type)) {
5140+ if (buffer_string_is_empty(sce->content_type)) {
5141 /* we are setting application/octet-stream, but also announce that
5142 * this header field might change in the seconds few requests
5143 *
5144@@ -469,7 +469,7 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
5145 }
5146
5147 if (allow_caching) {
5148- if (p->conf.etags_used && con->etag_flags != 0 && !buffer_is_empty(sce->etag)) {
5149+ if (p->conf.etags_used && con->etag_flags != 0 && !buffer_string_is_empty(sce->etag)) {
5150 if (NULL == array_get_element(con->response.headers, "ETag")) {
5151 /* generate e-tag */
5152 etag_mutate(con->physical.etag, sce->etag);
5153diff --git a/src/mod_status.c b/src/mod_status.c
5154index f0d753b..e8da0a8 100644
5155--- a/src/mod_status.c
5156+++ b/src/mod_status.c
5157@@ -323,21 +323,21 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
5158 seconds = ts;
5159
5160 if (days) {
5161- buffer_append_long(b, days);
5162+ buffer_append_int(b, days);
5163 buffer_append_string_len(b, CONST_STR_LEN(" days "));
5164 }
5165
5166 if (hours) {
5167- buffer_append_long(b, hours);
5168+ buffer_append_int(b, hours);
5169 buffer_append_string_len(b, CONST_STR_LEN(" hours "));
5170 }
5171
5172 if (mins) {
5173- buffer_append_long(b, mins);
5174+ buffer_append_int(b, mins);
5175 buffer_append_string_len(b, CONST_STR_LEN(" min "));
5176 }
5177
5178- buffer_append_long(b, seconds);
5179+ buffer_append_int(b, seconds);
5180 buffer_append_string_len(b, CONST_STR_LEN(" s"));
5181
5182 buffer_append_string_len(b, CONST_STR_LEN("</td></tr>\n"));
5183@@ -357,7 +357,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
5184
5185 mod_status_get_multiplier(&avg, &multiplier, 1000);
5186
5187- buffer_append_long(b, avg);
5188+ buffer_append_int(b, avg);
5189 buffer_append_string_len(b, CONST_STR_LEN(" "));
5190 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
5191 buffer_append_string_len(b, CONST_STR_LEN("req</td></tr>\n"));
5192@@ -382,7 +382,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
5193
5194 mod_status_get_multiplier(&avg, &multiplier, 1000);
5195
5196- buffer_append_long(b, avg);
5197+ buffer_append_int(b, avg);
5198 buffer_append_string_len(b, CONST_STR_LEN(" "));
5199 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
5200 buffer_append_string_len(b, CONST_STR_LEN("req/s</td></tr>\n"));
5201@@ -411,7 +411,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
5202
5203 mod_status_get_multiplier(&avg, &multiplier, 1000);
5204
5205- buffer_append_long(b, avg);
5206+ buffer_append_int(b, avg);
5207 buffer_append_string_len(b, CONST_STR_LEN(" "));
5208 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
5209
5210@@ -444,7 +444,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
5211 "s = response-start, S = response-end\n"));
5212
5213 buffer_append_string_len(b, CONST_STR_LEN("<b>"));
5214- buffer_append_long(b, srv->conns->used);
5215+ buffer_append_int(b, srv->conns->used);
5216 buffer_append_string_len(b, CONST_STR_LEN(" connections</b>\n"));
5217
5218 for (j = 0; j < srv->conns->used; j++) {
5219@@ -488,18 +488,18 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
5220 buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
5221
5222 if (c->request.content_length) {
5223- buffer_append_long(b, c->request_content_queue->bytes_in);
5224+ buffer_append_int(b, c->request_content_queue->bytes_in);
5225 buffer_append_string_len(b, CONST_STR_LEN("/"));
5226- buffer_append_long(b, c->request.content_length);
5227+ buffer_append_int(b, c->request.content_length);
5228 } else {
5229 buffer_append_string_len(b, CONST_STR_LEN("0/0"));
5230 }
5231
5232 buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
5233
5234- buffer_append_off_t(b, chunkqueue_written(c->write_queue));
5235+ buffer_append_int(b, c->write_queue->bytes_out);
5236 buffer_append_string_len(b, CONST_STR_LEN("/"));
5237- buffer_append_off_t(b, chunkqueue_length(c->write_queue));
5238+ buffer_append_int(b, c->write_queue->bytes_out + chunkqueue_length(c->write_queue));
5239
5240 buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
5241
5242@@ -511,11 +511,11 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
5243
5244 buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"int\">"));
5245
5246- buffer_append_long(b, srv->cur_ts - c->request_start);
5247+ buffer_append_int(b, srv->cur_ts - c->request_start);
5248
5249 buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
5250
5251- if (buffer_is_empty(c->server_name)) {
5252+ if (buffer_string_is_empty(c->server_name)) {
5253 buffer_append_string_buffer(b, c->uri.authority);
5254 }
5255 else {
5256@@ -524,16 +524,16 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
5257
5258 buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
5259
5260- if (!buffer_is_empty(c->uri.path)) {
5261+ if (!buffer_string_is_empty(c->uri.path)) {
5262 buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
5263 }
5264
5265- if (!buffer_is_empty(c->uri.query)) {
5266+ if (!buffer_string_is_empty(c->uri.query)) {
5267 buffer_append_string_len(b, CONST_STR_LEN("?"));
5268 buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.query), ENCODING_HTML);
5269 }
5270
5271- if (!buffer_is_empty(c->request.orig_uri)) {
5272+ if (!buffer_string_is_empty(c->request.orig_uri)) {
5273 buffer_append_string_len(b, CONST_STR_LEN(" ("));
5274 buffer_append_string_encoded(b, CONST_BUF_LEN(c->request.orig_uri), ENCODING_HTML);
5275 buffer_append_string_len(b, CONST_STR_LEN(")"));
5276@@ -589,16 +589,16 @@ static handler_t mod_status_handle_server_status_text(server *srv, connection *c
5277 /* output uptime */
5278 buffer_append_string_len(b, CONST_STR_LEN("Uptime: "));
5279 ts = srv->cur_ts - srv->startup_ts;
5280- buffer_append_long(b, ts);
5281+ buffer_append_int(b, ts);
5282 buffer_append_string_len(b, CONST_STR_LEN("\n"));
5283
5284 /* output busy servers */
5285 buffer_append_string_len(b, CONST_STR_LEN("BusyServers: "));
5286- buffer_append_long(b, srv->conns->used);
5287+ buffer_append_int(b, srv->conns->used);
5288 buffer_append_string_len(b, CONST_STR_LEN("\n"));
5289
5290 buffer_append_string_len(b, CONST_STR_LEN("IdleServers: "));
5291- buffer_append_long(b, srv->conns->size - srv->conns->used);
5292+ buffer_append_int(b, srv->conns->size - srv->conns->used);
5293 buffer_append_string_len(b, CONST_STR_LEN("\n"));
5294
5295 /* output scoreboard */
5296@@ -641,7 +641,7 @@ static handler_t mod_status_handle_server_statistics(server *srv, connection *co
5297
5298 buffer_append_string_buffer(b, st->data[ndx]->key);
5299 buffer_append_string_len(b, CONST_STR_LEN(": "));
5300- buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value);
5301+ buffer_append_int(b, ((data_integer *)(st->data[ndx]))->value);
5302 buffer_append_string_len(b, CONST_STR_LEN("\n"));
5303 }
5304
5305@@ -740,7 +740,7 @@ static handler_t mod_status_handle_server_config(server *srv, connection *con, v
5306 plugin *pl = ps[i];
5307
5308 if (i == 0) {
5309- buffer_copy_string_buffer(m, pl->name);
5310+ buffer_copy_buffer(m, pl->name);
5311 } else {
5312 buffer_append_string_len(m, CONST_STR_LEN("<br />"));
5313 buffer_append_string_buffer(m, pl->name);
5314@@ -809,13 +809,13 @@ static handler_t mod_status_handler(server *srv, connection *con, void *p_d) {
5315
5316 mod_status_patch_connection(srv, con, p);
5317
5318- if (!buffer_is_empty(p->conf.status_url) &&
5319+ if (!buffer_string_is_empty(p->conf.status_url) &&
5320 buffer_is_equal(p->conf.status_url, con->uri.path)) {
5321 return mod_status_handle_server_status(srv, con, p_d);
5322- } else if (!buffer_is_empty(p->conf.config_url) &&
5323+ } else if (!buffer_string_is_empty(p->conf.config_url) &&
5324 buffer_is_equal(p->conf.config_url, con->uri.path)) {
5325 return mod_status_handle_server_config(srv, con, p_d);
5326- } else if (!buffer_is_empty(p->conf.statistics_url) &&
5327+ } else if (!buffer_string_is_empty(p->conf.statistics_url) &&
5328 buffer_is_equal(p->conf.statistics_url, con->uri.path)) {
5329 return mod_status_handle_server_statistics(srv, con, p_d);
5330 }
5331diff --git a/src/mod_trigger_b4_dl.c b/src/mod_trigger_b4_dl.c
5332index 6d9010d..cff125c 100644
5333--- a/src/mod_trigger_b4_dl.c
5334+++ b/src/mod_trigger_b4_dl.c
5335@@ -175,7 +175,7 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
5336 return HANDLER_ERROR;
5337 }
5338 #if defined(HAVE_GDBM_H)
5339- if (!buffer_is_empty(s->db_filename)) {
5340+ if (!buffer_string_is_empty(s->db_filename)) {
5341 if (NULL == (s->db = gdbm_open(s->db_filename->ptr, 4096, GDBM_WRCREAT | GDBM_NOLOCK, S_IRUSR | S_IWUSR, 0))) {
5342 log_error_write(srv, __FILE__, __LINE__, "s",
5343 "gdbm-open failed");
5344@@ -185,7 +185,7 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
5345 }
5346 #endif
5347 #if defined(HAVE_PCRE_H)
5348- if (!buffer_is_empty(s->download_url)) {
5349+ if (!buffer_string_is_empty(s->download_url)) {
5350 if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr,
5351 0, &errptr, &erroff, NULL))) {
5352
5353@@ -196,7 +196,7 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
5354 }
5355 }
5356
5357- if (!buffer_is_empty(s->trigger_url)) {
5358+ if (!buffer_string_is_empty(s->trigger_url)) {
5359 if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr,
5360 0, &errptr, &erroff, NULL))) {
5361
5362@@ -384,7 +384,7 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
5363 # if defined(HAVE_MEMCACHE_H)
5364 if (p->conf.mc) {
5365 size_t i;
5366- buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
5367+ buffer_copy_buffer(p->tmp_buf, p->conf.mc_namespace);
5368 buffer_append_string(p->tmp_buf, remote_ip);
5369
5370 for (i = 0; i < p->tmp_buf->used - 1; i++) {
5371@@ -471,7 +471,7 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
5372 void *r;
5373 size_t i;
5374
5375- buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
5376+ buffer_copy_buffer(p->tmp_buf, p->conf.mc_namespace);
5377 buffer_append_string(p->tmp_buf, remote_ip);
5378
5379 for (i = 0; i < p->tmp_buf->used - 1; i++) {
5380diff --git a/src/mod_userdir.c b/src/mod_userdir.c
5381index 572b5e7..392f4b2 100644
5382--- a/src/mod_userdir.c
5383+++ b/src/mod_userdir.c
5384@@ -209,7 +209,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
5385
5386 buffer_copy_string_len(p->username, con->uri.path->ptr + 2, rel_url - (con->uri.path->ptr + 2));
5387
5388- if (buffer_is_empty(p->conf.basepath)
5389+ if (buffer_string_is_empty(p->conf.basepath)
5390 #ifdef HAVE_PWD_H
5391 && NULL == (pwd = getpwnam(p->username->ptr))
5392 #endif
5393@@ -245,7 +245,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
5394
5395 /* we build the physical path */
5396
5397- if (buffer_is_empty(p->conf.basepath)) {
5398+ if (buffer_string_is_empty(p->conf.basepath)) {
5399 #ifdef HAVE_PWD_H
5400 buffer_copy_string(p->temp_path, pwd->pw_dir);
5401 #endif
5402@@ -272,18 +272,18 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
5403 buffer_to_lower(p->username);
5404 }
5405
5406- buffer_copy_string_buffer(p->temp_path, p->conf.basepath);
5407- BUFFER_APPEND_SLASH(p->temp_path);
5408+ buffer_copy_buffer(p->temp_path, p->conf.basepath);
5409+ buffer_append_slash(p->temp_path);
5410 if (p->conf.letterhomes) {
5411 buffer_append_string_len(p->temp_path, p->username->ptr, 1);
5412- BUFFER_APPEND_SLASH(p->temp_path);
5413+ buffer_append_slash(p->temp_path);
5414 }
5415 buffer_append_string_buffer(p->temp_path, p->username);
5416 }
5417- BUFFER_APPEND_SLASH(p->temp_path);
5418+ buffer_append_slash(p->temp_path);
5419 buffer_append_string_buffer(p->temp_path, p->conf.path);
5420
5421- if (buffer_is_empty(p->conf.basepath)) {
5422+ if (buffer_string_is_empty(p->conf.basepath)) {
5423 struct stat st;
5424 int ret;
5425
5426@@ -293,7 +293,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
5427 }
5428 }
5429
5430- buffer_copy_string_buffer(con->physical.basedir, p->temp_path);
5431+ buffer_copy_buffer(con->physical.basedir, p->temp_path);
5432
5433 /* the physical rel_path is basically the same as uri.path;
5434 * but it is converted to lowercase in case of force_lowercase_filenames and some special handling
5435@@ -302,7 +302,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
5436 * (docroot should only set the docroot/server name, phyiscal should only change the phyiscal.path;
5437 * the exception mod_secure_download doesn't work with userdir anyway)
5438 */
5439- BUFFER_APPEND_SLASH(p->temp_path);
5440+ buffer_append_slash(p->temp_path);
5441 /* if no second '/' is found, we assume that it was stripped from the uri.path for the special handling
5442 * on windows.
5443 * we do not care about the trailing slash here on windows, as we already ensured it is a directory
5444@@ -313,7 +313,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
5445 if (NULL != (rel_url = strchr(con->physical.rel_path->ptr + 2, '/'))) {
5446 buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */
5447 }
5448- buffer_copy_string_buffer(con->physical.path, p->temp_path);
5449+ buffer_copy_buffer(con->physical.path, p->temp_path);
5450
5451 buffer_reset(p->temp_path);
5452
5453diff --git a/src/mod_usertrack.c b/src/mod_usertrack.c
5454index 4f4f264..29e9fdf 100644
5455--- a/src/mod_usertrack.c
5456+++ b/src/mod_usertrack.c
5457@@ -98,7 +98,7 @@ SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
5458 return HANDLER_ERROR;
5459 }
5460
5461- if (buffer_is_empty(s->cookie_name)) {
5462+ if (buffer_string_is_empty(s->cookie_name)) {
5463 buffer_copy_string_len(s->cookie_name, CONST_STR_LEN("TRACKID"));
5464 } else {
5465 size_t j;
5466@@ -114,7 +114,7 @@ SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
5467 }
5468 }
5469
5470- if (!buffer_is_empty(s->cookie_domain)) {
5471+ if (!buffer_string_is_empty(s->cookie_domain)) {
5472 size_t j;
5473 for (j = 0; j < s->cookie_domain->used - 1; j++) {
5474 char c = s->cookie_domain->ptr[j];
5475@@ -173,7 +173,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
5476 data_string *ds;
5477 unsigned char h[16];
5478 li_MD5_CTX Md5Ctx;
5479- char hh[32];
5480+ char hh[LI_ITOSTRING_LENGTH];
5481
5482 if (con->uri.path->used == 0) return HANDLER_GO_ON;
5483
5484@@ -211,7 +211,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
5485 ds = data_response_init();
5486 }
5487 buffer_copy_string_len(ds->key, CONST_STR_LEN("Set-Cookie"));
5488- buffer_copy_string_buffer(ds->value, p->conf.cookie_name);
5489+ buffer_copy_buffer(ds->value, p->conf.cookie_name);
5490 buffer_append_string_len(ds->value, CONST_STR_LEN("="));
5491
5492
5493@@ -223,10 +223,10 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
5494 li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
5495
5496 /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
5497- LI_ltostr(hh, srv->cur_ts);
5498+ li_itostr(hh, srv->cur_ts);
5499 li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
5500 li_MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy));
5501- LI_ltostr(hh, rand());
5502+ li_itostr(hh, rand());
5503 li_MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
5504
5505 li_MD5_Final(h, &Md5Ctx);
5506@@ -235,14 +235,14 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
5507 buffer_append_string_len(ds->value, CONST_STR_LEN("; Path=/"));
5508 buffer_append_string_len(ds->value, CONST_STR_LEN("; Version=1"));
5509
5510- if (!buffer_is_empty(p->conf.cookie_domain)) {
5511+ if (!buffer_string_is_empty(p->conf.cookie_domain)) {
5512 buffer_append_string_len(ds->value, CONST_STR_LEN("; Domain="));
5513 buffer_append_string_encoded(ds->value, CONST_BUF_LEN(p->conf.cookie_domain), ENCODING_REL_URI);
5514 }
5515
5516 if (p->conf.cookie_max_age) {
5517 buffer_append_string_len(ds->value, CONST_STR_LEN("; max-age="));
5518- buffer_append_long(ds->value, p->conf.cookie_max_age);
5519+ buffer_append_int(ds->value, p->conf.cookie_max_age);
5520 }
5521
5522 array_insert_unique(con->response.headers, (data_unset *)ds);
5523diff --git a/src/mod_webdav.c b/src/mod_webdav.c
5524index 04b2161..a3807c0 100644
5525--- a/src/mod_webdav.c
5526+++ b/src/mod_webdav.c
5527@@ -198,7 +198,7 @@ SETDEFAULTS_FUNC(mod_webdav_set_defaults) {
5528 return HANDLER_ERROR;
5529 }
5530
5531- if (!buffer_is_empty(s->sqlite_db_name)) {
5532+ if (!buffer_string_is_empty(s->sqlite_db_name)) {
5533 #ifdef USE_PROPPATCH
5534 const char *next_stmt;
5535 char *err;
5536@@ -519,7 +519,7 @@ static int webdav_gen_response_status_tag(server *srv, connection *con, physical
5537 } else {
5538 buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
5539 }
5540- buffer_append_long(b, status);
5541+ buffer_append_int(b, status);
5542 buffer_append_string_len(b, CONST_STR_LEN(" "));
5543 buffer_append_string(b, get_http_status_name(status));
5544
5545@@ -595,12 +595,12 @@ static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physi
5546 /* ignore the parent dir */
5547 }
5548
5549- buffer_copy_string_buffer(d.path, dst->path);
5550- BUFFER_APPEND_SLASH(d.path);
5551+ buffer_copy_buffer(d.path, dst->path);
5552+ buffer_append_slash(d.path);
5553 buffer_append_string(d.path, de->d_name);
5554
5555- buffer_copy_string_buffer(d.rel_path, dst->rel_path);
5556- BUFFER_APPEND_SLASH(d.rel_path);
5557+ buffer_copy_buffer(d.rel_path, dst->rel_path);
5558+ buffer_append_slash(d.rel_path);
5559 buffer_append_string(d.rel_path, de->d_name);
5560
5561 /* stat and unlink afterwards */
5562@@ -756,20 +756,20 @@ static int webdav_copy_dir(server *srv, connection *con, plugin_data *p, physica
5563 continue;
5564 }
5565
5566- buffer_copy_string_buffer(s.path, src->path);
5567- BUFFER_APPEND_SLASH(s.path);
5568+ buffer_copy_buffer(s.path, src->path);
5569+ buffer_append_slash(s.path);
5570 buffer_append_string(s.path, de->d_name);
5571
5572- buffer_copy_string_buffer(d.path, dst->path);
5573- BUFFER_APPEND_SLASH(d.path);
5574+ buffer_copy_buffer(d.path, dst->path);
5575+ buffer_append_slash(d.path);
5576 buffer_append_string(d.path, de->d_name);
5577
5578- buffer_copy_string_buffer(s.rel_path, src->rel_path);
5579- BUFFER_APPEND_SLASH(s.rel_path);
5580+ buffer_copy_buffer(s.rel_path, src->rel_path);
5581+ buffer_append_slash(s.rel_path);
5582 buffer_append_string(s.rel_path, de->d_name);
5583
5584- buffer_copy_string_buffer(d.rel_path, dst->rel_path);
5585- BUFFER_APPEND_SLASH(d.rel_path);
5586+ buffer_copy_buffer(d.rel_path, dst->rel_path);
5587+ buffer_append_slash(d.rel_path);
5588 buffer_append_string(d.rel_path, de->d_name);
5589
5590 if (-1 == stat(s.path->ptr, &st)) {
5591@@ -877,7 +877,7 @@ static int webdav_get_live_property(server *srv, connection *con, plugin_data *p
5592 found = 1;
5593 } else if (0 == strcmp(prop_name, "getcontentlength")) {
5594 buffer_append_string_len(b,CONST_STR_LEN("<D:getcontentlength>"));
5595- buffer_append_off_t(b, sce->st.st_size);
5596+ buffer_append_int(b, sce->st.st_size);
5597 buffer_append_string_len(b, CONST_STR_LEN("</D:getcontentlength>"));
5598 found = 1;
5599 } else if (0 == strcmp(prop_name, "getcontentlanguage")) {
5600@@ -1062,8 +1062,6 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
5601 cq->bytes_out += weHave;
5602
5603 break;
5604- case UNUSED_CHUNK:
5605- break;
5606 }
5607 chunkqueue_remove_finished_chunks(cq);
5608 }
5609@@ -1367,7 +1365,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
5610 buffer_append_string_encoded(b, CONST_BUF_LEN(con->uri.path), ENCODING_REL_URI);
5611 buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
5612
5613- if (!buffer_is_empty(prop_200)) {
5614+ if (!buffer_string_is_empty(prop_200)) {
5615 buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
5616 buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
5617
5618@@ -1379,7 +1377,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
5619
5620 buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
5621 }
5622- if (!buffer_is_empty(prop_404)) {
5623+ if (!buffer_string_is_empty(prop_404)) {
5624 buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
5625 buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
5626
5627@@ -1410,11 +1408,11 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
5628 /* ignore the parent dir */
5629 }
5630
5631- buffer_copy_string_buffer(d.path, dst->path);
5632- BUFFER_APPEND_SLASH(d.path);
5633+ buffer_copy_buffer(d.path, dst->path);
5634+ buffer_append_slash(d.path);
5635
5636- buffer_copy_string_buffer(d.rel_path, dst->rel_path);
5637- BUFFER_APPEND_SLASH(d.rel_path);
5638+ buffer_copy_buffer(d.rel_path, dst->rel_path);
5639+ buffer_append_slash(d.rel_path);
5640
5641 if (de->d_name[0] == '.' && de->d_name[1] == '\0') {
5642 /* don't append the . */
5643@@ -1436,7 +1434,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
5644 buffer_append_string_encoded(b, CONST_BUF_LEN(d.rel_path), ENCODING_REL_URI);
5645 buffer_append_string_len(b,CONST_STR_LEN("</D:href>\n"));
5646
5647- if (!buffer_is_empty(prop_200)) {
5648+ if (!buffer_string_is_empty(prop_200)) {
5649 buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
5650 buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
5651
5652@@ -1448,7 +1446,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
5653
5654 buffer_append_string_len(b,CONST_STR_LEN("</D:propstat>\n"));
5655 }
5656- if (!buffer_is_empty(prop_404)) {
5657+ if (!buffer_string_is_empty(prop_404)) {
5658 buffer_append_string_len(b,CONST_STR_LEN("<D:propstat>\n"));
5659 buffer_append_string_len(b,CONST_STR_LEN("<D:prop>\n"));
5660
5661@@ -1763,8 +1761,6 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
5662 }
5663 }
5664 break;
5665- case UNUSED_CHUNK:
5666- break;
5667 }
5668
5669 if (r > 0) {
5670@@ -1862,21 +1858,21 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
5671 return HANDLER_FINISHED;
5672 }
5673
5674- buffer_copy_string_buffer(p->tmp_buf, p->uri.path_raw);
5675+ buffer_copy_buffer(p->tmp_buf, p->uri.path_raw);
5676 buffer_urldecode_path(p->tmp_buf);
5677 buffer_path_simplify(p->uri.path, p->tmp_buf);
5678
5679 /* we now have a URI which is clean. transform it into a physical path */
5680- buffer_copy_string_buffer(p->physical.doc_root, con->physical.doc_root);
5681- buffer_copy_string_buffer(p->physical.rel_path, p->uri.path);
5682+ buffer_copy_buffer(p->physical.doc_root, con->physical.doc_root);
5683+ buffer_copy_buffer(p->physical.rel_path, p->uri.path);
5684
5685 if (con->conf.force_lowercase_filenames) {
5686 buffer_to_lower(p->physical.rel_path);
5687 }
5688
5689- buffer_copy_string_buffer(p->physical.path, p->physical.doc_root);
5690- BUFFER_APPEND_SLASH(p->physical.path);
5691- buffer_copy_string_buffer(p->physical.basedir, p->physical.path);
5692+ buffer_copy_buffer(p->physical.path, p->physical.doc_root);
5693+ buffer_append_slash(p->physical.path);
5694+ buffer_copy_buffer(p->physical.basedir, p->physical.path);
5695
5696 /* don't add a second / */
5697 if (p->physical.rel_path->ptr[0] == '/') {
5698diff --git a/src/network.c b/src/network.c
5699index 776a86c..f1c9489 100644
5700--- a/src/network.c
5701+++ b/src/network.c
5702@@ -187,10 +187,10 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
5703 srv_socket->fde_ndx = -1;
5704
5705 srv_socket->srv_token = buffer_init();
5706- buffer_copy_string_buffer(srv_socket->srv_token, host_token);
5707+ buffer_copy_buffer(srv_socket->srv_token, host_token);
5708
5709 b = buffer_init();
5710- buffer_copy_string_buffer(b, host_token);
5711+ buffer_copy_buffer(b, host_token);
5712
5713 /* ipv4:port
5714 * [ipv6]:port
5715@@ -701,7 +701,7 @@ int network_init(server *srv) {
5716 long ssloptions =
5717 SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_COMPRESSION;
5718
5719- if (buffer_is_empty(s->ssl_pemfile) && buffer_is_empty(s->ssl_ca_file)) continue;
5720+ if (buffer_string_is_empty(s->ssl_pemfile) && buffer_string_is_empty(s->ssl_ca_file)) continue;
5721
5722 if (srv->ssl_is_init == 0) {
5723 SSL_load_error_strings();
5724@@ -716,7 +716,7 @@ int network_init(server *srv) {
5725 }
5726 }
5727
5728- if (!buffer_is_empty(s->ssl_pemfile)) {
5729+ if (!buffer_string_is_empty(s->ssl_pemfile)) {
5730 #ifdef OPENSSL_NO_TLSEXT
5731 data_config *dc = (data_config *)srv->config_context->data[i];
5732 if (COMP_HTTP_HOST == dc->comp) {
5733@@ -729,7 +729,7 @@ int network_init(server *srv) {
5734 }
5735
5736
5737- if (!buffer_is_empty(s->ssl_ca_file)) {
5738+ if (!buffer_string_is_empty(s->ssl_ca_file)) {
5739 s->ssl_ca_file_cert_names = SSL_load_client_CA_file(s->ssl_ca_file->ptr);
5740 if (NULL == s->ssl_ca_file_cert_names) {
5741 log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
5742@@ -737,7 +737,7 @@ int network_init(server *srv) {
5743 }
5744 }
5745
5746- if (buffer_is_empty(s->ssl_pemfile) || !s->ssl_enabled) continue;
5747+ if (buffer_string_is_empty(s->ssl_pemfile) || !s->ssl_enabled) continue;
5748
5749 if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
5750 log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
5751@@ -784,7 +784,7 @@ int network_init(server *srv) {
5752 }
5753 }
5754
5755- if (!buffer_is_empty(s->ssl_cipher_list)) {
5756+ if (!buffer_string_is_empty(s->ssl_cipher_list)) {
5757 /* Disable support for low encryption ciphers */
5758 if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
5759 log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
5760@@ -799,7 +799,7 @@ int network_init(server *srv) {
5761
5762 #ifndef OPENSSL_NO_DH
5763 /* Support for Diffie-Hellman key exchange */
5764- if (!buffer_is_empty(s->ssl_dh_file)) {
5765+ if (!buffer_string_is_empty(s->ssl_dh_file)) {
5766 /* DH parameters from file */
5767 bio = BIO_new_file((char *) s->ssl_dh_file->ptr, "r");
5768 if (bio == NULL) {
5769@@ -832,7 +832,7 @@ int network_init(server *srv) {
5770 SSL_CTX_set_options(s->ssl_ctx,SSL_OP_SINGLE_DH_USE);
5771 DH_free(dh);
5772 #else
5773- if (!buffer_is_empty(s->ssl_dh_file)) {
5774+ if (!buffer_string_is_empty(s->ssl_dh_file)) {
5775 log_error_write(srv, __FILE__, __LINE__, "ss", "SSL: openssl compiled without DH support, can't load parameters from", s->ssl_dh_file->ptr);
5776 }
5777 #endif
5778@@ -840,7 +840,7 @@ int network_init(server *srv) {
5779 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
5780 #ifndef OPENSSL_NO_ECDH
5781 /* Support for Elliptic-Curve Diffie-Hellman key exchange */
5782- if (!buffer_is_empty(s->ssl_ec_curve)) {
5783+ if (!buffer_string_is_empty(s->ssl_ec_curve)) {
5784 /* OpenSSL only supports the "named curves" from RFC 4492, section 5.1.1. */
5785 nid = OBJ_sn2nid((char *) s->ssl_ec_curve->ptr);
5786 if (nid == 0) {
5787@@ -866,7 +866,7 @@ int network_init(server *srv) {
5788 for (j = 0; j < srv->config_context->used; j++) {
5789 specific_config *s1 = srv->config_storage[j];
5790
5791- if (!buffer_is_empty(s1->ssl_ca_file)) {
5792+ if (!buffer_string_is_empty(s1->ssl_ca_file)) {
5793 if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s1->ssl_ca_file->ptr, NULL)) {
5794 log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
5795 ERR_error_string(ERR_get_error(), NULL), s1->ssl_ca_file);
5796@@ -926,9 +926,9 @@ int network_init(server *srv) {
5797
5798 b = buffer_init();
5799
5800- buffer_copy_string_buffer(b, srv->srvconf.bindhost);
5801+ buffer_copy_buffer(b, srv->srvconf.bindhost);
5802 buffer_append_string_len(b, CONST_STR_LEN(":"));
5803- buffer_append_long(b, srv->srvconf.port);
5804+ buffer_append_int(b, srv->srvconf.port);
5805
5806 if (0 != network_server_init(srv, b, srv->config_storage[0])) {
5807 buffer_free(b);
5808@@ -944,7 +944,7 @@ int network_init(server *srv) {
5809 backend = network_backends[0].nb;
5810
5811 /* match name against known types */
5812- if (!buffer_is_empty(srv->srvconf.network_backend)) {
5813+ if (!buffer_string_is_empty(srv->srvconf.network_backend)) {
5814 for (i = 0; network_backends[i].name; i++) {
5815 /**/
5816 if (buffer_is_equal_string(srv->srvconf.network_backend, network_backends[i].name, strlen(network_backends[i].name))) {
5817diff --git a/src/plugin.c b/src/plugin.c
5818index 55f8b03..d587308 100644
5819--- a/src/plugin.c
5820+++ b/src/plugin.c
5821@@ -133,7 +133,7 @@ int plugins_load(server *srv) {
5822 }
5823 }
5824
5825- buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir);
5826+ buffer_copy_buffer(srv->tmp_buf, srv->srvconf.modules_dir);
5827
5828 buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("/"));
5829 buffer_append_string(srv->tmp_buf, modules);
5830diff --git a/src/request.c b/src/request.c
5831index 2eb0b0e..65d0a0e 100644
5832--- a/src/request.c
5833+++ b/src/request.c
5834@@ -322,7 +322,7 @@ int http_request_parse(server *srv, connection *con) {
5835 buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, con->request.request->used - 1 - 2);
5836 } else {
5837 /* fill the local request buffer */
5838- buffer_copy_string_buffer(con->parse_request, con->request.request);
5839+ buffer_copy_buffer(con->parse_request, con->request.request);
5840 }
5841
5842 keep_alive_set = 0;
5843@@ -508,7 +508,7 @@ int http_request_parse(server *srv, connection *con) {
5844 }
5845 }
5846
5847- buffer_copy_string_buffer(con->request.orig_uri, con->request.uri);
5848+ buffer_copy_buffer(con->request.orig_uri, con->request.uri);
5849
5850 con->http_status = 0;
5851
5852@@ -1061,7 +1061,7 @@ int http_request_parse(server *srv, connection *con) {
5853
5854 /* RFC 2616, 14.23 */
5855 if (con->request.http_host == NULL ||
5856- buffer_is_empty(con->request.http_host)) {
5857+ buffer_string_is_empty(con->request.http_host)) {
5858 con->http_status = 400;
5859 con->response.keep_alive = 0;
5860 con->keep_alive = 0;
5861diff --git a/src/response.c b/src/response.c
5862index eb5c2f2..bde381f 100644
5863--- a/src/response.c
5864+++ b/src/response.c
5865@@ -40,7 +40,7 @@ int http_response_write_header(server *srv, connection *con) {
5866 } else {
5867 buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.0 "));
5868 }
5869- buffer_append_long(b, con->http_status);
5870+ buffer_append_int(b, con->http_status);
5871 buffer_append_string_len(b, CONST_STR_LEN(" "));
5872 buffer_append_string(b, get_http_status_name(con->http_status));
5873
5874@@ -181,7 +181,7 @@ static void https_add_ssl_entries(connection *con) {
5875 buffer_copy_string(ds->key, "REMOTE_USER");
5876 array_insert_unique(con->environment, (data_unset *)ds);
5877 }
5878- buffer_copy_string_buffer(ds->value, envds->value);
5879+ buffer_copy_buffer(ds->value, envds->value);
5880 }
5881 array_insert_unique(con->environment, (data_unset *)envds);
5882 }
5883@@ -199,7 +199,7 @@ static void https_add_ssl_entries(connection *con) {
5884 }
5885
5886 buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT"));
5887- buffer_prepare_copy(envds->value, n+1);
5888+ buffer_prepare_copy(envds->value, n);
5889 BIO_read(bio, envds->value->ptr, n);
5890 BIO_free(bio);
5891 envds->value->ptr[n] = '\0';
5892@@ -278,7 +278,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
5893 } else {
5894 buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http"));
5895 }
5896- buffer_copy_string_buffer(con->uri.authority, con->request.http_host);
5897+ buffer_copy_buffer(con->uri.authority, con->request.http_host);
5898 buffer_to_lower(con->uri.authority);
5899
5900 config_patch_connection(srv, con, COMP_HTTP_SCHEME); /* Scheme: */
5901@@ -302,7 +302,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
5902 buffer_copy_string_len(con->uri.path_raw, con->request.uri->ptr, qstr - con->request.uri->ptr);
5903 } else {
5904 buffer_reset (con->uri.query);
5905- buffer_copy_string_buffer(con->uri.path_raw, con->request.uri);
5906+ buffer_copy_buffer(con->uri.path_raw, con->request.uri);
5907 }
5908
5909 /* decode url to path
5910@@ -314,9 +314,9 @@ handler_t http_response_prepare(server *srv, connection *con) {
5911 if (con->request.http_method == HTTP_METHOD_OPTIONS &&
5912 con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
5913 /* OPTIONS * ... */
5914- buffer_copy_string_buffer(con->uri.path, con->uri.path_raw);
5915+ buffer_copy_buffer(con->uri.path, con->uri.path_raw);
5916 } else {
5917- buffer_copy_string_buffer(srv->tmp_buf, con->uri.path_raw);
5918+ buffer_copy_buffer(srv->tmp_buf, con->uri.path_raw);
5919 buffer_urldecode_path(srv->tmp_buf);
5920 buffer_path_simplify(con->uri.path, srv->tmp_buf);
5921 }
5922@@ -430,8 +430,8 @@ handler_t http_response_prepare(server *srv, connection *con) {
5923
5924 /* set a default */
5925
5926- buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root);
5927- buffer_copy_string_buffer(con->physical.rel_path, con->uri.path);
5928+ buffer_copy_buffer(con->physical.doc_root, con->conf.document_root);
5929+ buffer_copy_buffer(con->physical.rel_path, con->uri.path);
5930
5931 #if defined(__WIN32) || defined(__CYGWIN__)
5932 /* strip dots from the end and spaces
5933@@ -500,8 +500,8 @@ handler_t http_response_prepare(server *srv, connection *con) {
5934 }
5935
5936 /* the docroot plugins might set the servername, if they don't we take http-host */
5937- if (buffer_is_empty(con->server_name)) {
5938- buffer_copy_string_buffer(con->server_name, con->uri.authority);
5939+ if (buffer_string_is_empty(con->server_name)) {
5940+ buffer_copy_buffer(con->server_name, con->uri.authority);
5941 }
5942
5943 /**
5944@@ -510,9 +510,9 @@ handler_t http_response_prepare(server *srv, connection *con) {
5945 *
5946 */
5947
5948- buffer_copy_string_buffer(con->physical.basedir, con->physical.doc_root);
5949- buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
5950- BUFFER_APPEND_SLASH(con->physical.path);
5951+ buffer_copy_buffer(con->physical.basedir, con->physical.doc_root);
5952+ buffer_copy_buffer(con->physical.path, con->physical.doc_root);
5953+ buffer_append_slash(con->physical.path);
5954 if (con->physical.rel_path->used &&
5955 con->physical.rel_path->ptr[0] == '/') {
5956 buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
5957@@ -645,13 +645,13 @@ handler_t http_response_prepare(server *srv, connection *con) {
5958
5959 /* not found, perhaps PATHINFO */
5960
5961- buffer_copy_string_buffer(srv->tmp_buf, con->physical.path);
5962+ buffer_copy_buffer(srv->tmp_buf, con->physical.path);
5963
5964 do {
5965 if (slash) {
5966 buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
5967 } else {
5968- buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
5969+ buffer_copy_buffer(con->physical.path, srv->tmp_buf);
5970 }
5971
5972 if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
5973diff --git a/src/server.c b/src/server.c
5974index d47fd62..71d3538 100644
5975--- a/src/server.c
5976+++ b/src/server.c
5977@@ -999,7 +999,7 @@ int main (int argc, char **argv) {
5978
5979 /* write pid file */
5980 if (pid_fd != -1) {
5981- buffer_copy_long(srv->tmp_buf, getpid());
5982+ buffer_copy_int(srv->tmp_buf, getpid());
5983 buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
5984 force_assert(srv->tmp_buf->used > 0);
5985 write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
5986diff --git a/src/stat_cache.c b/src/stat_cache.c
5987index 9007325..b5aa9ce 100644
5988--- a/src/stat_cache.c
5989+++ b/src/stat_cache.c
5990@@ -221,7 +221,7 @@ static int stat_cache_attr_get(buffer *buf, char *name) {
5991
5992 attrlen = 1024;
5993 buffer_prepare_copy(buf, attrlen);
5994- attrlen--;
5995+ attrlen = buf->size - 1;
5996 if(0 == (ret = attr_get(name, "Content-Type", buf->ptr, &attrlen, 0))) {
5997 buf->used = attrlen + 1;
5998 buf->ptr[attrlen] = '\0';
5999@@ -234,7 +234,7 @@ static int stat_cache_attr_get(buffer *buf, char *name) {
6000
6001 buffer_prepare_copy(buf, attrlen);
6002
6003- if (-1 != (attrlen = extattr_get_file(name, EXTATTR_NAMESPACE_USER, "Content-Type", buf->ptr, attrlen-1))) {
6004+ if (-1 != (attrlen = extattr_get_file(name, EXTATTR_NAMESPACE_USER, "Content-Type", buf->ptr, buf->size - 1))) {
6005 buf->used = attrlen + 1;
6006 buf->ptr[attrlen] = '\0';
6007 return 0;
6008@@ -294,7 +294,7 @@ handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent) {
6009
6010 for (j = 0; j < 2; j++) {
6011 buffer_copy_string(sc->hash_key, fe.filename);
6012- buffer_append_long(sc->hash_key, j);
6013+ buffer_append_int(sc->hash_key, j);
6014
6015 ndx = hashme(sc->hash_key);
6016
6017@@ -331,7 +331,7 @@ handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent) {
6018 static int buffer_copy_dirname(buffer *dst, buffer *file) {
6019 size_t i;
6020
6021- if (buffer_is_empty(file)) return -1;
6022+ if (buffer_string_is_empty(file)) return -1;
6023
6024 for (i = file->used - 1; i+1 > 0; i--) {
6025 if (file->ptr[i] == '/') {
6026@@ -394,8 +394,8 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
6027
6028 sc = srv->stat_cache;
6029
6030- buffer_copy_string_buffer(sc->hash_key, name);
6031- buffer_append_long(sc->hash_key, con->conf.follow_symlink);
6032+ buffer_copy_buffer(sc->hash_key, name);
6033+ buffer_append_int(sc->hash_key, con->conf.follow_symlink);
6034
6035 file_ndx = hashme(sc->hash_key);
6036 sc->files = splaytree_splay(sc->files, file_ndx);
6037@@ -460,8 +460,8 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
6038 return HANDLER_ERROR;
6039 }
6040
6041- buffer_copy_string_buffer(sc->hash_key, sc->dir_name);
6042- buffer_append_long(sc->hash_key, con->conf.follow_symlink);
6043+ buffer_copy_buffer(sc->hash_key, sc->dir_name);
6044+ buffer_append_int(sc->hash_key, con->conf.follow_symlink);
6045
6046 dir_ndx = hashme(sc->hash_key);
6047
6048@@ -518,7 +518,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
6049 #endif
6050
6051 sce = stat_cache_entry_init();
6052- buffer_copy_string_buffer(sce->name, name);
6053+ buffer_copy_buffer(sce->name, name);
6054
6055 sc->files = splaytree_insert(sc->files, file_ndx, sce);
6056 #ifdef DEBUG_STAT_CACHE
6057@@ -577,7 +577,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
6058 char *s_cur;
6059
6060 dname = buffer_init();
6061- buffer_copy_string_buffer(dname, name);
6062+ buffer_copy_buffer(dname, name);
6063
6064 while ((s_cur = strrchr(dname->ptr,'/'))) {
6065 *s_cur = '\0';
6066@@ -615,7 +615,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
6067 }
6068 #endif
6069 /* xattr did not set a content-type. ask the config */
6070- if (buffer_is_empty(sce->content_type)) {
6071+ if (buffer_string_is_empty(sce->content_type)) {
6072 for (k = 0; k < con->conf.mimetypes->used; k++) {
6073 data_string *ds = (data_string *)con->conf.mimetypes->data[k];
6074 buffer *type = ds->key;
6075@@ -626,7 +626,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
6076 if (type->used > name->used) continue;
6077
6078 if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
6079- buffer_copy_string_buffer(sce->content_type, ds->value);
6080+ buffer_copy_buffer(sce->content_type, ds->value);
6081 break;
6082 }
6083 }
6084@@ -642,7 +642,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
6085 if (!dir_node) {
6086 fam_dir = fam_dir_entry_init();
6087
6088- buffer_copy_string_buffer(fam_dir->name, sc->dir_name);
6089+ buffer_copy_buffer(fam_dir->name, sc->dir_name);
6090
6091 fam_dir->version = 1;
6092
6093--
60942.4.5
6095
diff --git a/main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch b/main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch
new file mode 100644
index 0000000000..6f265d155b
--- /dev/null
+++ b/main/lighttpd/0016-Remove-chunkqueue_get_-append-prepend-API.patch
@@ -0,0 +1,1537 @@
1From 1be163b44a53eebb0a7b0ed562d12e3f252794e1 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:36 +0000
4Subject: [PATCH 16/29] Remove chunkqueue_get_{append,prepend}* API
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9 Although those were "easy" to use, they violated the abstraction:
10 content of the chunkqueue should only be modified via the API.
11 Replace with chunkqueue_get_memory() and chunkqueue_use_memory() for
12 functions that read data from network (reusing large buffers),
13 chunkqueue_steal_with_tempfiles() to store request bodies on disk
14 temporarily.
15 Modules that were generating content and need a buffer maintain the
16 buffer manually (have to be careful to free the buffer on errors, as
17 it isn't part of the chunkqueue yet).
18
19From: Stefan Bühler <stbuehler@web.de>
20
21git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2976 152afb58-edef-0310-8abb-c4023f1b3aa9
22---
23 src/buffer.c | 23 +++-
24 src/buffer.h | 12 ++
25 src/chunk.c | 295 +++++++++++++++++++++++++++++++++++++++--------
26 src/chunk.h | 39 ++++---
27 src/connections.c | 195 +++++--------------------------
28 src/mod_compress.c | 4 +-
29 src/mod_dirlisting.c | 4 +-
30 src/mod_fastcgi.c | 76 +++++-------
31 src/mod_flv_streaming.c | 6 +-
32 src/mod_proxy.c | 5 +-
33 src/mod_scgi.c | 4 +-
34 src/mod_ssi.c | 63 +++++-----
35 src/mod_staticfile.c | 13 +--
36 src/mod_status.c | 42 ++++---
37 src/mod_uploadprogress.c | 11 +-
38 src/mod_webdav.c | 18 ++-
39 src/response.c | 6 +-
40 17 files changed, 465 insertions(+), 351 deletions(-)
41
42diff --git a/src/buffer.c b/src/buffer.c
43index caaa5bb..019abb7 100644
44--- a/src/buffer.c
45+++ b/src/buffer.c
46@@ -139,6 +139,27 @@ char* buffer_prepare_append(buffer *b, size_t size) {
47 return b->ptr + b->used - 1;
48 }
49
50+char* buffer_string_prepare_copy(buffer *b, size_t size) {
51+ force_assert(NULL != b);
52+
53+ buffer_prepare_copy(b, size);
54+ b->used = 1;
55+
56+ return b->ptr;
57+}
58+
59+char* buffer_string_prepare_append(buffer *b, size_t size) {
60+ force_assert(NULL != b);
61+
62+ if (0 == b->used) {
63+ return buffer_string_prepare_copy(b, size);
64+ } else {
65+ force_assert('\0' == b->ptr[b->used - 1]);
66+ return buffer_prepare_append(b, size);
67+ }
68+}
69+
70+
71 void buffer_commit(buffer *b, size_t size)
72 {
73 force_assert(NULL != b);
74@@ -231,7 +252,7 @@ void buffer_append_long_hex(buffer *b, unsigned long value) {
75 } while (0 != copy);
76 }
77
78- buf = buffer_prepare_append(b, shift);
79+ buf = buffer_string_prepare_append(b, shift);
80 buffer_commit(b, shift); /* will fill below */
81
82 shift <<= 2; /* count bits now */
83diff --git a/src/buffer.h b/src/buffer.h
84index ff57d68..5d540a4 100644
85--- a/src/buffer.h
86+++ b/src/buffer.h
87@@ -62,6 +62,11 @@ char* buffer_prepare_copy(buffer *b, size_t size);
88 */
89 char* buffer_prepare_append(buffer *b, size_t size);
90
91+/* similar to buffer_prepare_copy(b, size), but sets b->used = 1 */
92+char* buffer_string_prepare_copy(buffer *b, size_t size);
93+/* similar to buffer_prepare_append(b, size), but sets b->used = 1 if used was b->0 before */
94+char* buffer_string_prepare_append(buffer *b, size_t size);
95+
96 /* use after prepare_(copy,append) when you have written data to the buffer
97 * to increase the buffer length by size. also sets the terminating zero.
98 * requires enough space is present for the terminating zero (prepare with the
99@@ -136,6 +141,7 @@ int light_isalpha(int c);
100 int light_isalnum(int c);
101
102 static inline size_t buffer_string_length(const buffer *b); /* buffer string length without terminating 0 */
103+static inline size_t buffer_string_space(const buffer *b); /* maximum length of string that can be stored without reallocating */
104 static inline void buffer_append_slash(buffer *b); /* append '/' no non-empty strings not ending in '/' */
105
106 #define BUFFER_APPEND_STRING_CONST(x, y) \
107@@ -161,6 +167,12 @@ static inline size_t buffer_string_length(const buffer *b) {
108 return NULL != b && 0 != b->used ? b->used - 1 : 0;
109 }
110
111+static inline size_t buffer_string_space(const buffer *b) {
112+ if (NULL == b || b->size == 0) return 0;
113+ if (0 == b->used) return b->size - 1;
114+ return b->size - b->used;
115+}
116+
117 static inline void buffer_append_slash(buffer *b) {
118 size_t len = buffer_string_length(b);
119 if (len > 0 && '/' != b->ptr[len-1]) BUFFER_APPEND_STRING_CONST(b, "/");
120diff --git a/src/chunk.c b/src/chunk.c
121index c991b82..83adc15 100644
122--- a/src/chunk.c
123+++ b/src/chunk.c
124@@ -5,6 +5,8 @@
125 */
126
127 #include "chunk.h"
128+#include "base.h"
129+#include "log.h"
130
131 #include <sys/types.h>
132 #include <sys/stat.h>
133@@ -233,28 +235,84 @@ void chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
134 chunkqueue_append_chunk(cq, c);
135 }
136
137-buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) {
138+void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_size, size_t alloc_size) {
139+ static const size_t REALLOC_MAX_SIZE = 256;
140 chunk *c;
141+ buffer *b;
142+ char *dummy_mem;
143+ size_t dummy_len;
144
145- c = chunkqueue_get_unused_chunk(cq);
146+ force_assert(NULL != cq);
147+ if (NULL == mem) mem = &dummy_mem;
148+ if (NULL == len) len = &dummy_len;
149
150- c->type = MEM_CHUNK;
151+ /* default values: */
152+ if (0 == min_size) min_size = 1024;
153+ if (0 == alloc_size) alloc_size = 4096;
154+ if (alloc_size < min_size) alloc_size = min_size;
155
156- chunkqueue_prepend_chunk(cq, c);
157+ if (NULL != cq->last && MEM_CHUNK == cq->last->type) {
158+ size_t have;
159
160- return c->mem;
161-}
162+ b = cq->last->mem;
163+ have = buffer_string_space(b);
164
165-buffer *chunkqueue_get_append_buffer(chunkqueue *cq) {
166- chunk *c;
167+ /* unused buffer: allocate space */
168+ if (buffer_string_is_empty(b)) {
169+ buffer_string_prepare_copy(b, alloc_size);
170+ have = buffer_string_space(b);
171+ }
172+ /* if buffer is really small just make it bigger */
173+ else if (have < min_size && b->size <= REALLOC_MAX_SIZE) {
174+ size_t new_size = b->used + min_size, append;
175+ if (new_size < alloc_size) new_size = alloc_size;
176+
177+ append = new_size - b->used;
178+ if (append >= min_size) {
179+ buffer_string_prepare_append(b, append);
180+ have = buffer_string_space(b);
181+ }
182+ }
183
184- c = chunkqueue_get_unused_chunk(cq);
185+ /* return pointer into existing buffer if large enough */
186+ if (have >= min_size) {
187+ *mem = b->ptr + buffer_string_length(b);
188+ *len = have;
189+ return;
190+ }
191+ }
192
193+ /* allocate new chunk */
194+ c = chunkqueue_get_unused_chunk(cq);
195 c->type = MEM_CHUNK;
196-
197 chunkqueue_append_chunk(cq, c);
198
199- return c->mem;
200+ b = c->mem;
201+ buffer_string_prepare_append(b, alloc_size);
202+
203+ *mem = b->ptr + buffer_string_length(b);
204+ *len = buffer_string_space(b);
205+}
206+
207+void chunkqueue_use_memory(chunkqueue *cq, size_t len) {
208+ buffer *b;
209+
210+ force_assert(NULL != cq);
211+ force_assert(NULL != cq->last && MEM_CHUNK == cq->last->type);
212+ b = cq->last->mem;
213+
214+ force_assert(b->used > 0);
215+ force_assert(len <= buffer_string_space(b));
216+
217+ if (len > 0) {
218+ b->used += len;
219+ b->ptr[b->used - 1] = '\0';
220+ } else if (buffer_string_is_empty(b)) {
221+ /* unused buffer: can't remove chunk easily from
222+ * end of list, so just reset the buffer
223+ */
224+ buffer_reset(b);
225+ }
226 }
227
228 void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs) {
229@@ -262,13 +320,67 @@ void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs) {
230 cq->tempdirs = tempdirs;
231 }
232
233-chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
234- chunk *c;
235- buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX");
236+void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) {
237+ while (len > 0) {
238+ chunk *c = src->first;
239+ off_t clen = 0, use;
240
241- c = chunkqueue_get_unused_chunk(cq);
242+ if (NULL == c) break;
243
244- c->type = FILE_CHUNK;
245+ switch (c->type) {
246+ case MEM_CHUNK:
247+ clen = buffer_string_length(c->mem);
248+ break;
249+ case FILE_CHUNK:
250+ clen = c->file.length;
251+ break;
252+ }
253+ force_assert(clen >= c->offset);
254+ clen -= c->offset;
255+ use = len >= clen ? clen : len;
256+
257+ src->bytes_out += use;
258+ dest->bytes_in += use;
259+ len -= use;
260+
261+ if (0 == clen) {
262+ /* drop empty chunk */
263+ src->first = c->next;
264+ if (c == src->last) src->last = NULL;
265+ chunkqueue_push_unused_chunk(src, c);
266+ continue;
267+ }
268+
269+ if (use == clen) {
270+ /* move complete chunk */
271+ src->first = c->next;
272+ if (c == src->last) src->last = NULL;
273+
274+ chunkqueue_append_chunk(dest, c);
275+ continue;
276+ }
277+
278+ /* partial chunk with length "use" */
279+
280+ switch (c->type) {
281+ case MEM_CHUNK:
282+ chunkqueue_append_mem(dest, c->mem->ptr + c->offset, use);
283+ break;
284+ case FILE_CHUNK:
285+ /* tempfile flag is in "last" chunk after the split */
286+ chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, use);
287+ break;
288+ }
289+
290+ c->offset += use;
291+ force_assert(0 == len);
292+ }
293+}
294+
295+static chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
296+ chunk *c;
297+ buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX");
298+ int fd;
299
300 if (cq->tempdirs && cq->tempdirs->used) {
301 size_t i;
302@@ -282,19 +394,21 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
303 buffer_append_slash(template);
304 buffer_append_string_len(template, CONST_STR_LEN("lighttpd-upload-XXXXXX"));
305
306- if (-1 != (c->file.fd = mkstemp(template->ptr))) {
307- /* only trigger the unlink if we created the temp-file successfully */
308- c->file.is_temp = 1;
309- break;
310- }
311+ if (-1 != (fd = mkstemp(template->ptr))) break;
312 }
313 } else {
314- if (-1 != (c->file.fd = mkstemp(template->ptr))) {
315- /* only trigger the unlink if we created the temp-file successfully */
316- c->file.is_temp = 1;
317- }
318+ fd = mkstemp(template->ptr);
319 }
320
321+ if (-1 == fd) {
322+ buffer_free(template);
323+ return NULL;
324+ }
325+
326+ c = chunkqueue_get_unused_chunk(cq);
327+ c->type = FILE_CHUNK;
328+ c->file.fd = fd;
329+ c->file.is_temp = 1;
330 buffer_copy_buffer(c->file.name, template);
331 c->file.length = 0;
332
333@@ -305,10 +419,76 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
334 return c;
335 }
336
337-void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) {
338+static int chunkqueue_append_to_tempfile(server *srv, chunkqueue *dest, const char *mem, size_t len) {
339+ chunk *dst_c = NULL;
340+ ssize_t written;
341+ /* copy everything to max 1Mb sized tempfiles */
342+
343+ /*
344+ * if the last chunk is
345+ * - smaller than 1Mb (size < 1Mb)
346+ * - not read yet (offset == 0)
347+ * -> append to it
348+ * otherwise
349+ * -> create a new chunk
350+ *
351+ * */
352+
353+ if (NULL != dest->last
354+ && FILE_CHUNK != dest->last->type
355+ && dest->last->file.is_temp
356+ && -1 != dest->last->file.fd
357+ && 0 == dest->last->offset) {
358+ /* ok, take the last chunk for our job */
359+ dst_c = dest->last;
360+
361+ if (dest->last->file.length >= 1 * 1024 * 1024) {
362+ /* the chunk is too large now, close it */
363+ if (-1 != dst_c->file.fd) {
364+ close(dst_c->file.fd);
365+ dst_c->file.fd = -1;
366+ }
367+ dst_c = chunkqueue_get_append_tempfile(dest);
368+ }
369+ } else {
370+ dst_c = chunkqueue_get_append_tempfile(dest);
371+ }
372+
373+ if (NULL == dst_c) {
374+ /* we don't have file to write to,
375+ * EACCES might be one reason.
376+ *
377+ * Instead of sending 500 we send 413 and say the request is too large
378+ */
379+
380+ log_error_write(srv, __FILE__, __LINE__, "sbs",
381+ "denying upload as opening temp-file for upload failed:",
382+ dst_c->file.name, strerror(errno));
383+
384+ return -1;
385+ }
386+
387+ if (0 > (written = write(dst_c->file.fd, mem, len)) || (size_t) written != len) {
388+ /* write failed for some reason ... disk full ? */
389+ log_error_write(srv, __FILE__, __LINE__, "sbs",
390+ "denying upload as writing to file failed:",
391+ dst_c->file.name, strerror(errno));
392+
393+ close(dst_c->file.fd);
394+ dst_c->file.fd = -1;
395+
396+ return -1;
397+ }
398+
399+ dst_c->file.length += len;
400+
401+ return 0;
402+}
403+
404+int chunkqueue_steal_with_tempfiles(server *srv, chunkqueue *dest, chunkqueue *src, off_t len) {
405 while (len > 0) {
406 chunk *c = src->first;
407- off_t clen = 0;
408+ off_t clen = 0, use;
409
410 if (NULL == c) break;
411
412@@ -322,36 +502,57 @@ void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) {
413 }
414 force_assert(clen >= c->offset);
415 clen -= c->offset;
416+ use = len >= clen ? clen : len;
417
418- if (len >= clen) {
419- /* move complete chunk */
420+ src->bytes_out += use;
421+ dest->bytes_in += use;
422+ len -= use;
423+
424+ if (0 == clen) {
425+ /* drop empty chunk */
426 src->first = c->next;
427 if (c == src->last) src->last = NULL;
428-
429- chunkqueue_append_chunk(dest, c);
430- src->bytes_out += clen;
431- dest->bytes_in += clen;
432- len -= clen;
433+ chunkqueue_push_unused_chunk(src, c);
434 continue;
435 }
436
437- /* partial chunk with length "len" */
438+ if (FILE_CHUNK == c->type) {
439+ if (use == clen) {
440+ /* move complete chunk */
441+ src->first = c->next;
442+ if (c == src->last) src->last = NULL;
443
444- switch (c->type) {
445- case MEM_CHUNK:
446- chunkqueue_append_mem(dest, c->mem->ptr + c->offset, len);
447- break;
448- case FILE_CHUNK:
449- /* tempfile flag is in "last" chunk after the split */
450- chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, len);
451- break;
452+ chunkqueue_append_chunk(dest, c);
453+ } else {
454+ /* partial chunk with length "use" */
455+ /* tempfile flag is in "last" chunk after the split */
456+ chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, use);
457+
458+ c->offset += use;
459+ force_assert(0 == len);
460+ }
461+ continue;
462 }
463
464- c->offset += len;
465- src->bytes_out += len;
466- dest->bytes_in += len;
467- len = 0;
468+ /* store "use" bytes from memory chunk in tempfile */
469+ if (0 != chunkqueue_append_to_tempfile(srv, dest, c->mem->ptr + c->offset, use)) {
470+ /* undo counters */
471+ src->bytes_out -= use;
472+ dest->bytes_in -= use;
473+ return -1;
474+ }
475+
476+
477+ c->offset += use;
478+ if (use == clen) {
479+ /* finished chunk */
480+ src->first = c->next;
481+ if (c == src->last) src->last = NULL;
482+ chunkqueue_push_unused_chunk(src, c);
483+ }
484 }
485+
486+ return 0;
487 }
488
489 off_t chunkqueue_length(chunkqueue *cq) {
490diff --git a/src/chunk.h b/src/chunk.h
491index 6559000..33b7e27 100644
492--- a/src/chunk.h
493+++ b/src/chunk.h
494@@ -48,24 +48,37 @@ typedef struct {
495 } chunkqueue;
496
497 chunkqueue *chunkqueue_init(void);
498-void chunkqueue_set_tempdirs(chunkqueue *c, array *tempdirs);
499-void chunkqueue_append_file(chunkqueue *c, buffer *fn, off_t offset, off_t len); /* copies "fn" */
500-void chunkqueue_append_mem(chunkqueue *c, const char *mem, size_t len); /* copies memory */
501-void chunkqueue_append_buffer(chunkqueue *c, buffer *mem); /* may reset "mem" */
502-void chunkqueue_prepend_buffer(chunkqueue *c, buffer *mem); /* may reset "mem" */
503-
504-buffer * chunkqueue_get_append_buffer(chunkqueue *c);
505-buffer * chunkqueue_get_prepend_buffer(chunkqueue *c);
506-chunk * chunkqueue_get_append_tempfile(chunkqueue *cq);
507+void chunkqueue_set_tempdirs(chunkqueue *cq, array *tempdirs);
508+void chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len); /* copies "fn" */
509+void chunkqueue_append_mem(chunkqueue *cq, const char *mem, size_t len); /* copies memory */
510+void chunkqueue_append_buffer(chunkqueue *cq, buffer *mem); /* may reset "mem" */
511+void chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem); /* may reset "mem" */
512+
513+/* functions to handle buffers to read into: */
514+/* return a pointer to a buffer in *mem with size *len;
515+ * it should be at least min_size big, and use alloc_size if
516+ * new memory is allocated.
517+ * modifying the chunkqueue invalidates the memory area.
518+ * should always be followed by chunkqueue_get_memory(),
519+ * even if nothing was read.
520+ * pass 0 for min_size/alloc_size for default values
521+ */
522+void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_size, size_t alloc_size);
523+/* append first len bytes of the memory queried with
524+ * chunkqueue_get_memory to the chunkqueue
525+ */
526+void chunkqueue_use_memory(chunkqueue *cq, size_t len);
527
528 void chunkqueue_remove_finished_chunks(chunkqueue *cq);
529
530 void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len);
531+struct server;
532+int chunkqueue_steal_with_tempfiles(struct server *srv, chunkqueue *dest, chunkqueue *src, off_t len);
533
534-off_t chunkqueue_length(chunkqueue *c);
535-void chunkqueue_free(chunkqueue *c);
536-void chunkqueue_reset(chunkqueue *c);
537+off_t chunkqueue_length(chunkqueue *cq);
538+void chunkqueue_free(chunkqueue *cq);
539+void chunkqueue_reset(chunkqueue *cq);
540
541-int chunkqueue_is_empty(chunkqueue *c);
542+int chunkqueue_is_empty(chunkqueue *cq);
543
544 #endif
545diff --git a/src/connections.c b/src/connections.c
546index bc770bf..3fab768 100644
547--- a/src/connections.c
548+++ b/src/connections.c
549@@ -197,31 +197,22 @@ static void dump_packet(const unsigned char *data, size_t len) {
550
551 static int connection_handle_read_ssl(server *srv, connection *con) {
552 #ifdef USE_OPENSSL
553- int r, ssl_err, len, count = 0, read_offset, toread;
554- buffer *b = NULL;
555+ int r, ssl_err, len, count = 0;
556+ char *mem = NULL;
557+ size_t mem_len = 0;
558
559 if (!con->srv_socket->is_ssl) return -1;
560
561 ERR_clear_error();
562 do {
563- if (NULL != con->read_queue->last) {
564- b = con->read_queue->last->mem;
565- }
566-
567- if (NULL == b || b->size - b->used < 1024) {
568- b = chunkqueue_get_append_buffer(con->read_queue);
569- len = SSL_pending(con->ssl);
570- if (len < 4*1024) len = 4*1024; /* always alloc >= 4k buffer */
571- buffer_prepare_copy(b, len);
572-
573- /* overwrite everything with 0 */
574- memset(b->ptr, 0, b->size);
575- }
576-
577- read_offset = (b->used > 0) ? b->used - 1 : 0;
578- toread = b->size - 1 - read_offset;
579+ chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, SSL_pending(con->ssl));
580+#if 0
581+ /* overwrite everything with 0 */
582+ memset(mem, 0, mem_len);
583+#endif
584
585- len = SSL_read(con->ssl, b->ptr + read_offset, toread);
586+ len = SSL_read(con->ssl, mem, mem_len);
587+ chunkqueue_use_memory(con->read_queue, len > 0 ? len : 0);
588
589 if (con->renegotiations > 1 && con->conf.ssl_disable_client_renegotiation) {
590 log_error_write(srv, __FILE__, __LINE__, "s", "SSL: renegotiation initiated by client, killing connection");
591@@ -230,15 +221,10 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
592 }
593
594 if (len > 0) {
595- if (b->used > 0) b->used--;
596- b->used += len;
597- b->ptr[b->used++] = '\0';
598-
599 con->bytes_read += len;
600-
601 count += len;
602 }
603- } while (len == toread && count < MAX_READ_LIMIT);
604+ } while (len == (ssize_t) mem_len && count < MAX_READ_LIMIT);
605
606
607 if (len < 0) {
608@@ -331,44 +317,36 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
609 /* 0: everything ok, -1: error, -2: con closed */
610 static int connection_handle_read(server *srv, connection *con) {
611 int len;
612- buffer *b;
613- int toread, read_offset;
614+ char *mem = NULL;
615+ size_t mem_len = 0;
616+ int toread;
617
618 if (con->srv_socket->is_ssl) {
619 return connection_handle_read_ssl(srv, con);
620 }
621
622- b = (NULL != con->read_queue->last) ? con->read_queue->last->mem : NULL;
623-
624 /* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
625 * us more than 4kb is available
626 * if FIONREAD doesn't signal a big chunk we fill the previous buffer
627 * if it has >= 1kb free
628 */
629 #if defined(__WIN32)
630- if (NULL == b || b->size - b->used < 1024) {
631- b = chunkqueue_get_append_buffer(con->read_queue);
632- buffer_prepare_copy(b, 4 * 1024);
633- }
634+ chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, 4096);
635
636- read_offset = (b->used == 0) ? 0 : b->used - 1;
637- len = recv(con->fd, b->ptr + read_offset, b->size - 1 - read_offset, 0);
638+ len = recv(con->fd, mem, mem_len, 0);
639 #else
640 if (ioctl(con->fd, FIONREAD, &toread) || toread == 0 || toread <= 4*1024) {
641- if (NULL == b || b->size - b->used < 1024) {
642- b = chunkqueue_get_append_buffer(con->read_queue);
643- buffer_prepare_copy(b, 4 * 1024);
644- }
645- } else {
646 if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
647- b = chunkqueue_get_append_buffer(con->read_queue);
648- buffer_prepare_copy(b, toread);
649+ } else {
650+ toread = 4096;
651 }
652+ chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, toread);
653
654- read_offset = (b->used == 0) ? 0 : b->used - 1;
655- len = read(con->fd, b->ptr + read_offset, b->size - 1 - read_offset);
656+ len = read(con->fd, mem, mem_len);
657 #endif
658
659+ chunkqueue_use_memory(con->read_queue, len > 0 ? len : 0);
660+
661 if (len < 0) {
662 con->is_readable = 0;
663
664@@ -394,16 +372,12 @@ static int connection_handle_read(server *srv, connection *con) {
665 /* pipelining */
666
667 return -2;
668- } else if ((size_t)len < b->size - 1) {
669+ } else if (len != (ssize_t) mem_len) {
670 /* we got less then expected, wait for the next fd-event */
671
672 con->is_readable = 0;
673 }
674
675- if (b->used > 0) b->used--;
676- b->used += len;
677- b->ptr[b->used++] = '\0';
678-
679 con->bytes_read += len;
680 #if 0
681 dump_packet(b->ptr, len);
682@@ -494,7 +468,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
683 buffer_reset(con->physical.path);
684
685 con->file_finished = 1;
686- b = chunkqueue_get_append_buffer(con->write_queue);
687+ b = buffer_init();
688
689 /* build default error-page */
690 buffer_copy_string_len(b, CONST_STR_LEN(
691@@ -522,6 +496,10 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
692 "</html>\n"
693 ));
694
695+ http_chunk_append_buffer(srv, con, b);
696+ buffer_free(b);
697+ http_chunk_close(srv, con);
698+
699 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
700 }
701 break;
702@@ -1029,119 +1007,10 @@ found_header_end:
703 }
704 break;
705 case CON_STATE_READ_POST:
706- for (c = cq->first; c && (dst_cq->bytes_in != (off_t)con->request.content_length); c = c->next) {
707- off_t weWant, weHave, toRead;
708-
709- weWant = con->request.content_length - dst_cq->bytes_in;
710-
711- force_assert(c->mem->used);
712-
713- weHave = c->mem->used - c->offset - 1;
714-
715- toRead = weHave > weWant ? weWant : weHave;
716-
717- /* the new way, copy everything into a chunkqueue whcih might use tempfiles */
718- if (con->request.content_length > 64 * 1024) {
719- chunk *dst_c = NULL;
720- /* copy everything to max 1Mb sized tempfiles */
721-
722- /*
723- * if the last chunk is
724- * - smaller than 1Mb (size < 1Mb)
725- * - not read yet (offset == 0)
726- * -> append to it
727- * otherwise
728- * -> create a new chunk
729- *
730- * */
731-
732- if (dst_cq->last &&
733- dst_cq->last->type == FILE_CHUNK &&
734- dst_cq->last->file.is_temp &&
735- dst_cq->last->offset == 0) {
736- /* ok, take the last chunk for our job */
737-
738- if (dst_cq->last->file.length < 1 * 1024 * 1024) {
739- dst_c = dst_cq->last;
740-
741- if (dst_c->file.fd == -1) {
742- /* this should not happen as we cache the fd, but you never know */
743- dst_c->file.fd = open(dst_c->file.name->ptr, O_WRONLY | O_APPEND);
744- fd_close_on_exec(dst_c->file.fd);
745- }
746- } else {
747- /* the chunk is too large now, close it */
748- dst_c = dst_cq->last;
749-
750- if (dst_c->file.fd != -1) {
751- close(dst_c->file.fd);
752- dst_c->file.fd = -1;
753- }
754- dst_c = chunkqueue_get_append_tempfile(dst_cq);
755- }
756- } else {
757- dst_c = chunkqueue_get_append_tempfile(dst_cq);
758- }
759-
760- /* we have a chunk, let's write to it */
761-
762- if (dst_c->file.fd == -1) {
763- /* we don't have file to write to,
764- * EACCES might be one reason.
765- *
766- * Instead of sending 500 we send 413 and say the request is too large
767- * */
768-
769- log_error_write(srv, __FILE__, __LINE__, "sbs",
770- "denying upload as opening to temp-file for upload failed:",
771- dst_c->file.name, strerror(errno));
772-
773- con->http_status = 413; /* Request-Entity too large */
774- con->keep_alive = 0;
775- connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
776-
777- break;
778- }
779-
780- if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
781- /* write failed for some reason ... disk full ? */
782- log_error_write(srv, __FILE__, __LINE__, "sbs",
783- "denying upload as writing to file failed:",
784- dst_c->file.name, strerror(errno));
785-
786- con->http_status = 413; /* Request-Entity too large */
787- con->keep_alive = 0;
788- connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
789-
790- close(dst_c->file.fd);
791- dst_c->file.fd = -1;
792-
793- break;
794- }
795-
796- dst_c->file.length += toRead;
797-
798- if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) {
799- /* we read everything, close the chunk */
800- close(dst_c->file.fd);
801- dst_c->file.fd = -1;
802- }
803- } else {
804- buffer *b;
805-
806- if (dst_cq->last &&
807- dst_cq->last->type == MEM_CHUNK) {
808- b = dst_cq->last->mem;
809- } else {
810- b = chunkqueue_get_append_buffer(dst_cq);
811- /* prepare buffer size for remaining POST data; is < 64kb */
812- buffer_prepare_copy(b, con->request.content_length - dst_cq->bytes_in);
813- }
814- buffer_append_string_len(b, c->mem->ptr + c->offset, toRead);
815- }
816-
817- c->offset += toRead;
818- dst_cq->bytes_in += toRead;
819+ if (0 != chunkqueue_steal_with_tempfiles(srv, dst_cq, cq, con->request.content_length - dst_cq->bytes_in )) {
820+ con->http_status = 413; /* Request-Entity too large */
821+ con->keep_alive = 0;
822+ connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
823 }
824
825 /* Content is ready */
826diff --git a/src/mod_compress.c b/src/mod_compress.c
827index ad6e9f2..b428cd0 100644
828--- a/src/mod_compress.c
829+++ b/src/mod_compress.c
830@@ -583,7 +583,6 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
831 int ifd;
832 int ret = -1;
833 void *start;
834- buffer *b;
835
836 /* overflow */
837 if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1;
838@@ -651,8 +650,7 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
839 if (ret != 0) return -1;
840
841 chunkqueue_reset(con->write_queue);
842- b = chunkqueue_get_append_buffer(con->write_queue);
843- buffer_copy_string_len(b, p->b->ptr, p->b->used);
844+ chunkqueue_append_mem(con->write_queue, p->b->ptr, p->b->used);
845
846 buffer_reset(con->physical.path);
847
848diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
849index 4b7106a..e2e0bfa 100644
850--- a/src/mod_dirlisting.c
851+++ b/src/mod_dirlisting.c
852@@ -784,7 +784,7 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
853
854 if (files.used) http_dirls_sort(files.ent, files.used);
855
856- out = chunkqueue_get_append_buffer(con->write_queue);
857+ out = buffer_init();
858 buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\""));
859 if (buffer_string_is_empty(p->conf.encoding)) {
860 buffer_append_string_len(out, CONST_STR_LEN("iso-8859-1"));
861@@ -899,6 +899,8 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
862 }
863
864 con->file_finished = 1;
865+ chunkqueue_append_buffer(con->write_queue, out);
866+ buffer_free(out);
867
868 return 0;
869 }
870diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
871index 01e72e5..e7b62f6 100644
872--- a/src/mod_fastcgi.c
873+++ b/src/mod_fastcgi.c
874@@ -52,13 +52,6 @@
875
876 #include "version.h"
877
878-#define FCGI_ENV_ADD_CHECK(ret, con) \
879- if (ret == -1) { \
880- con->http_status = 400; \
881- con->file_finished = 1; \
882- return -1; \
883- };
884-
885 /*
886 *
887 * TODO:
888@@ -1769,6 +1762,12 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
889 return CONNECTION_OK;
890 }
891
892+#define FCGI_ENV_ADD_CHECK(ret, con) \
893+ if (ret == -1) { \
894+ con->http_status = 400; \
895+ con->file_finished = 1; \
896+ return -1; \
897+ };
898 static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
899 size_t i;
900
901@@ -1834,11 +1833,9 @@ static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_dat
902 return 0;
903 }
904
905-
906 static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
907 FCGI_BeginRequestRecord beginRecord;
908 FCGI_Header header;
909- buffer *b;
910
911 char buf[LI_ITOSTRING_LENGTH];
912 const char *s;
913@@ -1863,10 +1860,6 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
914 beginRecord.body.flags = 0;
915 memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved));
916
917- b = chunkqueue_get_append_buffer(hctx->wb);
918-
919- buffer_copy_string_len(b, (const char *)&beginRecord, sizeof(beginRecord));
920-
921 /* send FCGI_PARAMS */
922 buffer_prepare_copy(p->fcgi_env, 1024);
923
924@@ -2054,14 +2047,22 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
925
926 FCGI_ENV_ADD_CHECK(fcgi_env_add_request_headers(srv, con, p), con);
927
928- fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0);
929- buffer_append_string_len(b, (const char *)&header, sizeof(header));
930- buffer_append_string_len(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
931+ {
932+ buffer *b = buffer_init();
933
934- fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
935- buffer_append_string_len(b, (const char *)&header, sizeof(header));
936+ buffer_copy_string_len(b, (const char *)&beginRecord, sizeof(beginRecord));
937
938- hctx->wb->bytes_in += b->used - 1;
939+ fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0);
940+ buffer_append_string_len(b, (const char *)&header, sizeof(header));
941+ buffer_append_string_len(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
942+
943+ fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
944+ buffer_append_string_len(b, (const char *)&header, sizeof(header));
945+
946+ hctx->wb->bytes_in += b->used - 1;
947+ chunkqueue_append_buffer(hctx->wb, b);
948+ buffer_free(b);
949+ }
950
951 if (con->request.content_length) {
952 chunkqueue *req_cq = con->request_content_queue;
953@@ -2433,38 +2434,21 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
954 return -1;
955 }
956
957- /* init read-buffer */
958-
959 if (toread > 0) {
960- buffer *b;
961- chunk *cq_first = hctx->rb->first;
962- chunk *cq_last = hctx->rb->last;
963-
964- b = chunkqueue_get_append_buffer(hctx->rb);
965- buffer_prepare_copy(b, toread + 1);
966-
967- /* append to read-buffer */
968- if (-1 == (r = read(hctx->fd, b->ptr, toread))) {
969- if (errno == EAGAIN) {
970- /* roll back the last chunk allocation,
971- and continue on next iteration */
972- buffer_free(hctx->rb->last->mem);
973- free(hctx->rb->last);
974- hctx->rb->first = cq_first;
975- hctx->rb->last = cq_last;
976- return 0;
977- }
978+ char *mem;
979+ size_t mem_len;
980+
981+ chunkqueue_get_memory(hctx->rb, &mem, &mem_len, 0, toread);
982+ r = read(hctx->fd, mem, mem_len);
983+ chunkqueue_use_memory(hctx->rb, r > 0 ? r : 0);
984+
985+ if (-1 == r) {
986+ if (errno == EAGAIN) return 0;
987 log_error_write(srv, __FILE__, __LINE__, "sds",
988 "unexpected end-of-file (perhaps the fastcgi process died):",
989 fcgi_fd, strerror(errno));
990 return -1;
991 }
992-
993- /* this should be catched by the b > 0 above */
994- force_assert(r);
995-
996- b->used = r + 1; /* one extra for the fake \0 */
997- b->ptr[b->used - 1] = '\0';
998 } else {
999 log_error_write(srv, __FILE__, __LINE__, "ssdsb",
1000 "unexpected end-of-file (perhaps the fastcgi process died):",
1001@@ -2973,8 +2957,8 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
1002 "fcgi-request is already in use:", hctx->request_id);
1003 }
1004
1005- /* fall through */
1006 if (-1 == fcgi_create_env(srv, hctx, hctx->request_id)) return HANDLER_ERROR;
1007+
1008 fcgi_set_state(srv, hctx, FCGI_STATE_WRITE);
1009 /* fall through */
1010 case FCGI_STATE_WRITE:
1011diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c
1012index 501f8e8..1c1a356 100644
1013--- a/src/mod_flv_streaming.c
1014+++ b/src/mod_flv_streaming.c
1015@@ -207,7 +207,6 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
1016 if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
1017 data_string *get_param;
1018 stat_cache_entry *sce = NULL;
1019- buffer *b;
1020 int start;
1021 char *err = NULL;
1022 /* if there is a start=[0-9]+ in the header use it as start,
1023@@ -242,10 +241,9 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
1024 }
1025
1026 /* we are safe now, let's build a flv header */
1027- b = chunkqueue_get_append_buffer(con->write_queue);
1028- buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));
1029-
1030+ http_chunk_append_mem(srv, con, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));
1031 http_chunk_append_file(srv, con, con->physical.path, start, sce->st.st_size - start);
1032+ http_chunk_close(srv, con);
1033
1034 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));
1035
1036diff --git a/src/mod_proxy.c b/src/mod_proxy.c
1037index 3bfc78f..2b5a740 100644
1038--- a/src/mod_proxy.c
1039+++ b/src/mod_proxy.c
1040@@ -449,7 +449,7 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
1041
1042 /* build header */
1043
1044- b = chunkqueue_get_append_buffer(hctx->wb);
1045+ b = buffer_init();
1046
1047 /* request line */
1048 buffer_copy_string(b, get_http_method_name(con->request.http_method));
1049@@ -486,6 +486,9 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
1050 buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
1051
1052 hctx->wb->bytes_in += b->used - 1;
1053+ chunkqueue_append_buffer(hctx->wb, b);
1054+ buffer_free(b);
1055+
1056 /* body */
1057
1058 if (con->request.content_length) {
1059diff --git a/src/mod_scgi.c b/src/mod_scgi.c
1060index 66dce5e..2fa265d 100644
1061--- a/src/mod_scgi.c
1062+++ b/src/mod_scgi.c
1063@@ -1629,7 +1629,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
1064
1065 scgi_env_add_request_headers(srv, con, p);
1066
1067- b = chunkqueue_get_append_buffer(hctx->wb);
1068+ b = buffer_init();
1069
1070 buffer_append_int(b, p->scgi_env->used);
1071 buffer_append_string_len(b, CONST_STR_LEN(":"));
1072@@ -1637,6 +1637,8 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
1073 buffer_append_string_len(b, CONST_STR_LEN(","));
1074
1075 hctx->wb->bytes_in += b->used - 1;
1076+ chunkqueue_append_buffer(hctx->wb, b);
1077+ buffer_free(b);
1078
1079 if (con->request.content_length) {
1080 chunkqueue *req_cq = con->request_content_queue;
1081diff --git a/src/mod_ssi.c b/src/mod_ssi.c
1082index 38eeac5..ecdfb99 100644
1083--- a/src/mod_ssi.c
1084+++ b/src/mod_ssi.c
1085@@ -430,7 +430,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
1086 case SSI_ECHO_USER_NAME: {
1087 struct passwd *pw;
1088
1089- b = chunkqueue_get_append_buffer(con->write_queue);
1090+ b = buffer_init();
1091 #ifdef HAVE_PWD_H
1092 if (NULL == (pw = getpwuid(sce->st.st_uid))) {
1093 buffer_copy_int(b, sce->st.st_uid);
1094@@ -440,67 +440,62 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
1095 #else
1096 buffer_copy_int(b, sce->st.st_uid);
1097 #endif
1098+ chunkqueue_append_buffer(con->write_queue, b);
1099+ buffer_free(b);
1100 break;
1101 }
1102 case SSI_ECHO_LAST_MODIFIED: {
1103 time_t t = sce->st.st_mtime;
1104
1105- b = chunkqueue_get_append_buffer(con->write_queue);
1106 if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
1107- buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
1108+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
1109 } else {
1110- buffer_copy_string(b, buf);
1111+ chunkqueue_append_mem(con->write_queue, buf, strlen(buf));
1112 }
1113 break;
1114 }
1115 case SSI_ECHO_DATE_LOCAL: {
1116 time_t t = time(NULL);
1117
1118- b = chunkqueue_get_append_buffer(con->write_queue);
1119 if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
1120- buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
1121+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
1122 } else {
1123- buffer_copy_string(b, buf);
1124+ chunkqueue_append_mem(con->write_queue, buf, strlen(buf));
1125 }
1126 break;
1127 }
1128 case SSI_ECHO_DATE_GMT: {
1129 time_t t = time(NULL);
1130
1131- b = chunkqueue_get_append_buffer(con->write_queue);
1132 if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) {
1133- buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
1134+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
1135 } else {
1136- buffer_copy_string(b, buf);
1137+ chunkqueue_append_mem(con->write_queue, buf, strlen(buf));
1138 }
1139 break;
1140 }
1141 case SSI_ECHO_DOCUMENT_NAME: {
1142 char *sl;
1143
1144- b = chunkqueue_get_append_buffer(con->write_queue);
1145 if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
1146- buffer_copy_buffer(b, con->physical.path);
1147+ chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->physical.path));
1148 } else {
1149- buffer_copy_string(b, sl + 1);
1150+ chunkqueue_append_mem(con->write_queue, sl + 1, strlen(sl + 1));
1151 }
1152 break;
1153 }
1154 case SSI_ECHO_DOCUMENT_URI: {
1155- b = chunkqueue_get_append_buffer(con->write_queue);
1156- buffer_copy_buffer(b, con->uri.path);
1157+ chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(con->uri.path));
1158 break;
1159 }
1160 default: {
1161 data_string *ds;
1162 /* check if it is a cgi-var */
1163
1164- b = chunkqueue_get_append_buffer(con->write_queue);
1165-
1166 if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) {
1167- buffer_copy_buffer(b, ds->value);
1168+ chunkqueue_append_mem(con->write_queue, CONST_BUF_LEN(ds->value));
1169 } else {
1170- buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
1171+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
1172 }
1173
1174 break;
1175@@ -583,7 +578,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
1176
1177 switch (ssicmd) {
1178 case SSI_FSIZE:
1179- b = chunkqueue_get_append_buffer(con->write_queue);
1180+ b = buffer_init();
1181 if (p->sizefmt) {
1182 int j = 0;
1183 const char *abr[] = { " B", " kB", " MB", " GB", " TB", NULL };
1184@@ -597,13 +592,14 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
1185 } else {
1186 buffer_copy_int(b, st.st_size);
1187 }
1188+ chunkqueue_append_buffer(con->write_queue, b);
1189+ buffer_free(b);
1190 break;
1191 case SSI_FLASTMOD:
1192- b = chunkqueue_get_append_buffer(con->write_queue);
1193 if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
1194- buffer_copy_string_len(b, CONST_STR_LEN("(none)"));
1195+ chunkqueue_append_mem(con->write_queue, CONST_STR_LEN("(none)"));
1196 } else {
1197- buffer_copy_string(b, buf);
1198+ chunkqueue_append_mem(con->write_queue, buf, strlen(buf));
1199 }
1200 break;
1201 case SSI_INCLUDE:
1202@@ -611,7 +607,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
1203
1204 /* Keep the newest mtime of included files */
1205 if (st.st_mtime > include_file_last_mtime)
1206- include_file_last_mtime = st.st_mtime;
1207+ include_file_last_mtime = st.st_mtime;
1208
1209 break;
1210 }
1211@@ -683,7 +679,7 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
1212 case SSI_PRINTENV:
1213 if (p->if_is_false) break;
1214
1215- b = chunkqueue_get_append_buffer(con->write_queue);
1216+ b = buffer_init();
1217 for (i = 0; i < p->ssi_vars->used; i++) {
1218 data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]];
1219
1220@@ -700,6 +696,8 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
1221 buffer_append_string_encoded(b, CONST_BUF_LEN(ds->value), ENCODING_MINIMAL_XML);
1222 buffer_append_string_len(b, CONST_STR_LEN("\n"));
1223 }
1224+ chunkqueue_append_buffer(con->write_queue, b);
1225+ buffer_free(b);
1226
1227 break;
1228 case SSI_EXEC: {
1229@@ -791,17 +789,14 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const
1230 }
1231
1232 if (toread > 0) {
1233- b = chunkqueue_get_append_buffer(con->write_queue);
1234+ char *mem;
1235+ size_t mem_len;
1236
1237- buffer_prepare_copy(b, toread);
1238+ chunkqueue_get_memory(con->write_queue, &mem, &mem_len, 0, toread);
1239+ r = read(from_exec_fds[0], mem, mem_len);
1240+ chunkqueue_use_memory(con->write_queue, r > 0 ? r : 0);
1241
1242- if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) {
1243- /* read failed */
1244- break;
1245- } else {
1246- b->used = r;
1247- b->ptr[b->used++] = '\0';
1248- }
1249+ if (r < 0) break; /* read failed */
1250 } else {
1251 break;
1252 }
1253diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c
1254index 931bc57..e36c697 100644
1255--- a/src/mod_staticfile.c
1256+++ b/src/mod_staticfile.c
1257@@ -285,9 +285,7 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
1258 if (!error) {
1259 if (multipart) {
1260 /* write boundary-header */
1261- buffer *b;
1262-
1263- b = chunkqueue_get_append_buffer(con->write_queue);
1264+ buffer *b = buffer_init();
1265
1266 buffer_copy_string_len(b, CONST_STR_LEN("\r\n--"));
1267 buffer_append_string(b, boundary);
1268@@ -307,7 +305,8 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
1269 buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n"));
1270
1271 con->response.content_length += b->used - 1;
1272-
1273+ chunkqueue_append_buffer(con->write_queue, b);
1274+ buffer_free(b);
1275 }
1276
1277 chunkqueue_append_file(con->write_queue, con->physical.path, start, end - start + 1);
1278@@ -320,15 +319,15 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
1279
1280 if (multipart) {
1281 /* add boundary end */
1282- buffer *b;
1283-
1284- b = chunkqueue_get_append_buffer(con->write_queue);
1285+ buffer *b = buffer_init();
1286
1287 buffer_copy_string_len(b, "\r\n--", 4);
1288 buffer_append_string(b, boundary);
1289 buffer_append_string_len(b, "--\r\n", 4);
1290
1291 con->response.content_length += b->used - 1;
1292+ chunkqueue_append_buffer(con->write_queue, b);
1293+ buffer_free(b);
1294
1295 /* set header-fields */
1296
1297diff --git a/src/mod_status.c b/src/mod_status.c
1298index e8da0a8..99b332a 100644
1299--- a/src/mod_status.c
1300+++ b/src/mod_status.c
1301@@ -199,7 +199,7 @@ static int mod_status_get_multiplier(double *avg, char *multiplier, int size) {
1302
1303 static handler_t mod_status_handle_server_status_html(server *srv, connection *con, void *p_d) {
1304 plugin_data *p = p_d;
1305- buffer *b;
1306+ buffer *b = buffer_init();
1307 size_t j;
1308 double avg;
1309 char multiplier = '\0';
1310@@ -208,8 +208,6 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
1311
1312 int days, hours, mins, seconds;
1313
1314- b = chunkqueue_get_append_buffer(con->write_queue);
1315-
1316 buffer_copy_string_len(b, CONST_STR_LEN(
1317 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
1318 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
1319@@ -555,6 +553,9 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
1320 "</html>\n"
1321 ));
1322
1323+ chunkqueue_append_buffer(con->write_queue, b);
1324+ buffer_free(b);
1325+
1326 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
1327
1328 return 0;
1329@@ -563,15 +564,13 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
1330
1331 static handler_t mod_status_handle_server_status_text(server *srv, connection *con, void *p_d) {
1332 plugin_data *p = p_d;
1333- buffer *b;
1334+ buffer *b = buffer_init();
1335 double avg;
1336 time_t ts;
1337 char buf[32];
1338 unsigned int k;
1339 unsigned int l;
1340
1341- b = chunkqueue_get_append_buffer(con->write_queue);
1342-
1343 /* output total number of requests */
1344 buffer_append_string_len(b, CONST_STR_LEN("Total Accesses: "));
1345 avg = p->abs_requests;
1346@@ -598,13 +597,13 @@ static handler_t mod_status_handle_server_status_text(server *srv, connection *c
1347 buffer_append_string_len(b, CONST_STR_LEN("\n"));
1348
1349 buffer_append_string_len(b, CONST_STR_LEN("IdleServers: "));
1350- buffer_append_int(b, srv->conns->size - srv->conns->used);
1351- buffer_append_string_len(b, CONST_STR_LEN("\n"));
1352+ buffer_append_int(b, srv->conns->size - srv->conns->used);
1353+ buffer_append_string_len(b, CONST_STR_LEN("\n"));
1354
1355- /* output scoreboard */
1356- buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: "));
1357- for (k = 0; k < srv->conns->used; k++) {
1358- connection *c = srv->conns->ptr[k];
1359+ /* output scoreboard */
1360+ buffer_append_string_len(b, CONST_STR_LEN("Scoreboard: "));
1361+ for (k = 0; k < srv->conns->used; k++) {
1362+ connection *c = srv->conns->ptr[k];
1363 const char *state = connection_get_short_state(c->state);
1364 buffer_append_string_len(b, state, 1);
1365 }
1366@@ -613,15 +612,17 @@ static handler_t mod_status_handle_server_status_text(server *srv, connection *c
1367 }
1368 buffer_append_string_len(b, CONST_STR_LEN("\n"));
1369
1370- /* set text/plain output */
1371+ chunkqueue_append_buffer(con->write_queue, b);
1372+ buffer_free(b);
1373
1374+ /* set text/plain output */
1375 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
1376
1377 return 0;
1378 }
1379
1380 static handler_t mod_status_handle_server_statistics(server *srv, connection *con, void *p_d) {
1381- buffer *b;
1382+ buffer *b = buffer_init();
1383 size_t i;
1384 array *st = srv->status;
1385 UNUSED(p_d);
1386@@ -634,8 +635,6 @@ static handler_t mod_status_handle_server_statistics(server *srv, connection *co
1387 return HANDLER_FINISHED;
1388 }
1389
1390- b = chunkqueue_get_append_buffer(con->write_queue);
1391-
1392 for (i = 0; i < st->used; i++) {
1393 size_t ndx = st->sorted[i];
1394
1395@@ -645,6 +644,9 @@ static handler_t mod_status_handle_server_statistics(server *srv, connection *co
1396 buffer_append_string_len(b, CONST_STR_LEN("\n"));
1397 }
1398
1399+ chunkqueue_append_buffer(con->write_queue, b);
1400+ buffer_free(b);
1401+
1402 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
1403
1404 con->http_status = 200;
1405@@ -671,7 +673,8 @@ static handler_t mod_status_handle_server_status(server *srv, connection *con, v
1406
1407 static handler_t mod_status_handle_server_config(server *srv, connection *con, void *p_d) {
1408 plugin_data *p = p_d;
1409- buffer *b, *m = p->module_list;
1410+ buffer *b = buffer_init();
1411+ buffer *m = p->module_list;
1412 size_t i;
1413
1414 struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
1415@@ -703,8 +706,6 @@ static handler_t mod_status_handle_server_config(server *srv, connection *con, v
1416 { FDEVENT_HANDLER_UNSET, NULL }
1417 };
1418
1419- b = chunkqueue_get_append_buffer(con->write_queue);
1420-
1421 buffer_copy_string_len(b, CONST_STR_LEN(
1422 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
1423 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
1424@@ -756,6 +757,9 @@ static handler_t mod_status_handle_server_config(server *srv, connection *con, v
1425 "</html>\n"
1426 ));
1427
1428+ chunkqueue_append_buffer(con->write_queue, b);
1429+ buffer_free(b);
1430+
1431 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
1432
1433 con->http_status = 200;
1434diff --git a/src/mod_webdav.c b/src/mod_webdav.c
1435index a3807c0..433b904 100644
1436--- a/src/mod_webdav.c
1437+++ b/src/mod_webdav.c
1438@@ -1094,7 +1094,7 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
1439 static int webdav_lockdiscovery(server *srv, connection *con,
1440 buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
1441
1442- buffer *b;
1443+ buffer *b = buffer_init();
1444
1445 response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken));
1446
1447@@ -1102,8 +1102,6 @@ static int webdav_lockdiscovery(server *srv, connection *con,
1448 CONST_STR_LEN("Content-Type"),
1449 CONST_STR_LEN("text/xml; charset=\"utf-8\""));
1450
1451- b = chunkqueue_get_append_buffer(con->write_queue);
1452-
1453 buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
1454
1455 buffer_append_string_len(b,CONST_STR_LEN("<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n"));
1456@@ -1143,6 +1141,9 @@ static int webdav_lockdiscovery(server *srv, connection *con,
1457 buffer_append_string_len(b,CONST_STR_LEN("</D:lockdiscovery>\n"));
1458 buffer_append_string_len(b,CONST_STR_LEN("</D:prop>\n"));
1459
1460+ chunkqueue_append_buffer(con->write_queue, b);
1461+ buffer_free(b);
1462+
1463 return 0;
1464 }
1465 #endif
1466@@ -1341,7 +1342,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
1467
1468 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
1469
1470- b = chunkqueue_get_append_buffer(con->write_queue);
1471+ b = buffer_init();
1472
1473 buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
1474
1475@@ -1487,6 +1488,10 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
1476 if (p->conf.log_xml) {
1477 log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
1478 }
1479+
1480+ chunkqueue_append_buffer(con->write_queue, b);
1481+ buffer_free(b);
1482+
1483 con->file_finished = 1;
1484
1485 return HANDLER_FINISHED;
1486@@ -1555,7 +1560,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
1487 /* we got an error somewhere in between, build a 207 */
1488 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
1489
1490- b = chunkqueue_get_append_buffer(con->write_queue);
1491+ b = buffer_init();
1492
1493 buffer_copy_string_len(b, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
1494
1495@@ -1569,6 +1574,9 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
1496 log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
1497 }
1498
1499+ chunkqueue_append_buffer(con->write_queue, b);
1500+ buffer_free(b);
1501+
1502 con->http_status = 207;
1503 con->file_finished = 1;
1504 } else {
1505diff --git a/src/response.c b/src/response.c
1506index bde381f..31bcd69 100644
1507--- a/src/response.c
1508+++ b/src/response.c
1509@@ -33,7 +33,7 @@ int http_response_write_header(server *srv, connection *con) {
1510 int have_date = 0;
1511 int have_server = 0;
1512
1513- b = chunkqueue_get_prepend_buffer(con->write_queue);
1514+ b = buffer_init();
1515
1516 if (con->request.http_version == HTTP_VERSION_1_1) {
1517 buffer_copy_string_len(b, CONST_STR_LEN("HTTP/1.1 "));
1518@@ -121,13 +121,15 @@ int http_response_write_header(server *srv, connection *con) {
1519
1520 buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n"));
1521
1522-
1523 con->bytes_header = b->used - 1;
1524
1525 if (con->conf.log_response_header) {
1526 log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b);
1527 }
1528
1529+ chunkqueue_prepend_buffer(con->write_queue, b);
1530+ buffer_free(b);
1531+
1532 return 0;
1533 }
1534
1535--
15362.4.5
1537
diff --git a/main/lighttpd/0017-Remove-buffer_prepare_copy-and-buffer_prepare_append.patch b/main/lighttpd/0017-Remove-buffer_prepare_copy-and-buffer_prepare_append.patch
new file mode 100644
index 0000000000..97e6d3015b
--- /dev/null
+++ b/main/lighttpd/0017-Remove-buffer_prepare_copy-and-buffer_prepare_append.patch
@@ -0,0 +1,1182 @@
1From 4365bdbebe4542efc28ce6a79e1341870abc24d3 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:39 +0000
4Subject: [PATCH 17/29] Remove buffer_prepare_copy() and
5 buffer_prepare_append()
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10* removed almost all usages of buffer as "memory" (without terminating
11 zero)
12* refactored cgi variable name encoding
13
14From: Stefan Bühler <stbuehler@web.de>
15
16git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2977 152afb58-edef-0310-8abb-c4023f1b3aa9
17---
18 src/buffer.c | 99 ++++++++++++++++++++++----------------
19 src/buffer.h | 24 +++++-----
20 src/configfile.c | 4 +-
21 src/http-header-glue.c | 2 +-
22 src/http_auth.c | 2 +-
23 src/http_chunk.c | 4 +-
24 src/log.c | 2 +-
25 src/mod_accesslog.c | 8 ++--
26 src/mod_cgi.c | 49 ++-----------------
27 src/mod_compress.c | 27 ++++++-----
28 src/mod_expire.c | 2 +-
29 src/mod_fastcgi.c | 128 ++++++++++++++++---------------------------------
30 src/mod_mysql_vhost.c | 2 +-
31 src/mod_proxy.c | 12 ++---
32 src/mod_rrdtool.c | 11 +++--
33 src/mod_scgi.c | 47 +++++-------------
34 src/mod_simple_vhost.c | 2 +-
35 src/mod_ssi.c | 40 +---------------
36 src/network_write.c | 2 +-
37 src/proc_open.c | 6 +--
38 src/response.c | 4 +-
39 src/stat_cache.c | 7 ++-
40 22 files changed, 175 insertions(+), 309 deletions(-)
41
42diff --git a/src/buffer.c b/src/buffer.c
43index 019abb7..979d954 100644
44--- a/src/buffer.c
45+++ b/src/buffer.c
46@@ -83,7 +83,7 @@ static size_t buffer_align_size(size_t size) {
47 return size + align;
48 }
49
50-char* buffer_prepare_copy(buffer *b, size_t size) {
51+static char* buffer_prepare_copy(buffer *b, size_t size) {
52 force_assert(NULL != b);
53
54 /* also allocate space for terminating 0 */
55@@ -109,36 +109,6 @@ char* buffer_prepare_copy(buffer *b, size_t size) {
56 return b->ptr;
57 }
58
59-char* buffer_prepare_append(buffer *b, size_t size) {
60- size_t req_size;
61- force_assert(NULL != b);
62-
63- if (buffer_string_is_empty(b)) {
64- size_t old_used = b->used; /* either 0 or 1 */
65- /* just prepare copy (free+malloc instead of realloc) */
66- buffer_prepare_copy(b, size);
67- b->used = old_used; /* buffer_prepare_append mustn't modify b->used */
68- return b->ptr;
69- }
70-
71- /* not empty, b->used already includes a terminating 0 */
72- req_size = b->used + size;
73-
74- /* check for overflow: unsigned overflow is defined to wrap around */
75- force_assert(req_size >= b->used);
76-
77- if (req_size > b->size) {
78- char *ptr;
79- b->size = buffer_align_size(req_size);
80-
81- ptr = realloc(b->ptr, b->size);
82- force_assert(NULL != ptr);
83- b->ptr = ptr;
84- }
85-
86- return b->ptr + b->used - 1;
87-}
88-
89 char* buffer_string_prepare_copy(buffer *b, size_t size) {
90 force_assert(NULL != b);
91
92@@ -151,11 +121,28 @@ char* buffer_string_prepare_copy(buffer *b, size_t size) {
93 char* buffer_string_prepare_append(buffer *b, size_t size) {
94 force_assert(NULL != b);
95
96- if (0 == b->used) {
97+ if (buffer_string_is_empty(b)) {
98 return buffer_string_prepare_copy(b, size);
99 } else {
100+ /* not empty, b->used already includes a terminating 0 */
101+ size_t req_size = b->used + size;
102+
103+ /* check for overflow: unsigned overflow is defined to wrap around */
104+ force_assert(req_size >= b->used);
105+
106+ /* only append to 0-terminated string */
107 force_assert('\0' == b->ptr[b->used - 1]);
108- return buffer_prepare_append(b, size);
109+
110+ if (req_size > b->size) {
111+ char *ptr;
112+ b->size = buffer_align_size(req_size);
113+
114+ ptr = realloc(b->ptr, b->size);
115+ force_assert(NULL != ptr);
116+ b->ptr = ptr;
117+ }
118+
119+ return b->ptr + b->used - 1;
120 }
121 }
122
123@@ -186,7 +173,7 @@ void buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
124 force_assert(NULL != b);
125 force_assert(NULL != s || s_len == 0);
126
127- buffer_prepare_copy(b, s_len);
128+ buffer_string_prepare_copy(b, s_len);
129
130 if (0 != s_len) memcpy(b->ptr, s, s_len);
131
132@@ -222,12 +209,11 @@ void buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
133 force_assert(NULL != b);
134 force_assert(NULL != s || s_len == 0);
135
136- target_buf = buffer_prepare_append(b, s_len);
137+ target_buf = buffer_string_prepare_append(b, s_len);
138
139- /* only append to 0-terminated string */
140- force_assert('\0' == *target_buf);
141+ if (0 == s_len) return; /* nothing to append */
142
143- if (s_len > 0) memcpy(target_buf, s, s_len);
144+ memcpy(target_buf, s, s_len);
145
146 buffer_commit(b, s_len);
147 }
148@@ -667,7 +653,7 @@ void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer
149 }
150 }
151
152- d = (unsigned char*) buffer_prepare_append(b, d_len);
153+ d = (unsigned char*) buffer_string_prepare_append(b, d_len);
154 buffer_commit(b, d_len); /* fill below */
155 force_assert('\0' == *d);
156
157@@ -704,6 +690,35 @@ void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer
158 }
159 }
160
161+void buffer_copy_string_encoded_cgi_varnames(buffer *b, const char *s, size_t s_len, int is_http_header) {
162+ size_t i, j;
163+
164+ force_assert(NULL != b);
165+ force_assert(NULL != s || 0 == s_len);
166+
167+ buffer_reset(b);
168+
169+ if (is_http_header && NULL != s && 0 != strcasecmp(s, "CONTENT-TYPE")) {
170+ buffer_string_prepare_append(b, s_len + 5);
171+ buffer_copy_string_len(b, CONST_STR_LEN("HTTP_"));
172+ } else {
173+ buffer_string_prepare_append(b, s_len);
174+ }
175+
176+ j = buffer_string_length(b);
177+ for (i = 0; i < s_len; ++i) {
178+ unsigned char cr = s[i];
179+ if (light_isalpha(cr)) {
180+ /* upper-case */
181+ cr &= ~32;
182+ } else if (!light_isdigit(cr)) {
183+ cr = '_';
184+ }
185+ b->ptr[j++] = cr;
186+ }
187+ b->used = j;
188+ b->ptr[b->used++] = '\0';
189+}
190
191 /* decodes url-special-chars inplace.
192 * replaces non-printable characters with '_'
193@@ -790,7 +805,7 @@ void buffer_path_simplify(buffer *dest, buffer *src)
194 force_assert(NULL != dest && NULL != src);
195
196 if (buffer_string_is_empty(src)) {
197- buffer_copy_string_len(dest, NULL, 0);
198+ buffer_string_prepare_copy(dest, 0);
199 return;
200 }
201
202@@ -798,9 +813,9 @@ void buffer_path_simplify(buffer *dest, buffer *src)
203
204 /* might need one character more for the '/' prefix */
205 if (src == dest) {
206- buffer_prepare_append(dest, 1);
207+ buffer_string_prepare_append(dest, 1);
208 } else {
209- buffer_prepare_copy(dest, buffer_string_length(src) + 1);
210+ buffer_string_prepare_copy(dest, buffer_string_length(src) + 1);
211 }
212
213 #if defined(__WIN32) || defined(__CYGWIN__)
214diff --git a/src/buffer.h b/src/buffer.h
215index 5d540a4..7ea27f1 100644
216--- a/src/buffer.h
217+++ b/src/buffer.h
218@@ -49,22 +49,19 @@ void buffer_reset(buffer *b); /* b can be NULL */
219 /* reset b. if NULL != b && NULL != src, move src content to b. reset src. */
220 void buffer_move(buffer *b, buffer *src);
221
222-/* prepare for size bytes in the buffer (b->size > size), destroys content
223- * (sets used = 0 and ptr[0] = 0). allocates storage for terminating 0.
224+/* make sure buffer is large enough to store a string of given size
225+ * and a terminating zero.
226+ * sets b to an empty string, and may drop old content.
227 * @return b->ptr
228 */
229-char* buffer_prepare_copy(buffer *b, size_t size);
230+char* buffer_string_prepare_copy(buffer *b, size_t size);
231
232-/* prepare for appending size bytes to the buffer
233- * allocates storage for terminating 0; if used > 0 assumes ptr[used-1] == 0,
234- * i.e. doesn't allocate another byte for terminating 0.
235- * @return (b->used > 0 ? b->ptr + b->used - 1 : b->ptr) - first new character
236+/* allocate buffer large enough to be able to append a string of given size
237+ * if b was empty (used == 0) it will contain an empty string (used == 1)
238+ * afterwards
239+ * "used" data is preserved; if not empty buffer must contain a
240+ * zero terminated string.
241 */
242-char* buffer_prepare_append(buffer *b, size_t size);
243-
244-/* similar to buffer_prepare_copy(b, size), but sets b->used = 1 */
245-char* buffer_string_prepare_copy(buffer *b, size_t size);
246-/* similar to buffer_prepare_append(b, size), but sets b->used = 1 if used was b->0 before */
247 char* buffer_string_prepare_append(buffer *b, size_t size);
248
249 /* use after prepare_(copy,append) when you have written data to the buffer
250@@ -123,6 +120,9 @@ typedef enum {
251
252 void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding);
253
254+/* to upper case, replace non alpha-numerics with '_'; if is_http_header prefix with "HTTP_" unless s is "content-type" */
255+void buffer_copy_string_encoded_cgi_varnames(buffer *b, const char *s, size_t s_len, int is_http_header);
256+
257 void buffer_urldecode_path(buffer *url);
258 void buffer_urldecode_query(buffer *url);
259 void buffer_path_simplify(buffer *dest, buffer *src);
260diff --git a/src/configfile.c b/src/configfile.c
261index 2b09d86..1c36c3e 100644
262--- a/src/configfile.c
263+++ b/src/configfile.c
264@@ -1066,7 +1066,7 @@ int config_parse_cmd(server *srv, config_t *context, const char *cmd) {
265 "opening", source, "failed:", strerror(errno));
266 ret = -1;
267 } else {
268- tokenizer_init(&t, source, out->ptr, out->used);
269+ tokenizer_init(&t, source, CONST_BUF_LEN(out));
270 ret = config_parse(srv, context, &t);
271 }
272
273@@ -1128,7 +1128,7 @@ int config_read(server *srv, const char *fn) {
274 array_insert_unique(srv->config, (data_unset *)dpid);
275
276 dcwd = data_string_init();
277- buffer_prepare_copy(dcwd->value, 1024);
278+ buffer_string_prepare_copy(dcwd->value, 1023);
279 if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) {
280 dcwd->value->used = strlen(dcwd->value->ptr) + 1;
281 buffer_copy_string_len(dcwd->key, CONST_STR_LEN("var.CWD"));
282diff --git a/src/http-header-glue.c b/src/http-header-glue.c
283index abffb7d..f910f3f 100644
284--- a/src/http-header-glue.c
285+++ b/src/http-header-glue.c
286@@ -235,7 +235,7 @@ buffer * strftime_cache_get(server *srv, time_t last_mod) {
287 }
288
289 srv->mtime_cache[i].mtime = last_mod;
290- buffer_prepare_copy(srv->mtime_cache[i].str, 1024);
291+ buffer_string_prepare_copy(srv->mtime_cache[i].str, 1023);
292 tm = gmtime(&(srv->mtime_cache[i].mtime));
293 srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
294 srv->mtime_cache[i].str->size - 1,
295diff --git a/src/http_auth.c b/src/http_auth.c
296index 91e388c..c693645 100644
297--- a/src/http_auth.c
298+++ b/src/http_auth.c
299@@ -97,7 +97,7 @@ static unsigned char * base64_decode(buffer *out, const char *in) {
300
301 size_t in_len = strlen(in);
302
303- buffer_prepare_copy(out, in_len);
304+ buffer_string_prepare_copy(out, in_len);
305
306 result = (unsigned char *)out->ptr;
307
308diff --git a/src/http_chunk.c b/src/http_chunk.c
309index e3647e6..dd6a043 100644
310--- a/src/http_chunk.c
311+++ b/src/http_chunk.c
312@@ -35,8 +35,8 @@ static void http_chunk_append_len(server *srv, connection *con, size_t len) {
313 len >>= 4;
314 }
315
316- /* i is the number of hex digits we have */
317- buffer_prepare_copy(b, i + 2);
318+ /* i is the number of hex digits we have, + \r\n */
319+ buffer_string_prepare_copy(b, i + 2);
320
321 for (j = i-1, len = olen; j+1 > 0; j--) {
322 b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
323diff --git a/src/log.c b/src/log.c
324index 75decfe..097e59e 100644
325--- a/src/log.c
326+++ b/src/log.c
327@@ -332,7 +332,7 @@ static int log_buffer_prepare(buffer *b, server *srv, const char *filename, unsi
328 if (-1 == srv->errorlog_fd) return -1;
329 /* cache the generated timestamp */
330 if (srv->cur_ts != srv->last_generated_debug_ts) {
331- buffer_prepare_copy(srv->ts_debug_str, 255);
332+ buffer_string_prepare_copy(srv->ts_debug_str, 255);
333 strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
334 srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1;
335
336diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
337index 89fd7f5..20d52b9 100644
338--- a/src/mod_accesslog.c
339+++ b/src/mod_accesslog.c
340@@ -165,10 +165,10 @@ static void accesslog_append_escaped(buffer *dest, buffer *str) {
341
342 /* replaces non-printable chars with \xHH where HH is the hex representation of the byte */
343 /* exceptions: " => \", \ => \\, whitespace chars => \n \t etc. */
344- if (str->used == 0) return;
345- buffer_prepare_append(dest, str->used - 1);
346+ if (buffer_string_is_empty(str)) return;
347+ buffer_string_prepare_append(dest, buffer_string_length(str));
348
349- for (ptr = start = str->ptr, end = str->ptr + str->used - 1; ptr < end; ptr++) {
350+ for (ptr = start = str->ptr, end = str->ptr + buffer_string_length(str); ptr < end; ptr++) {
351 char const c = *ptr;
352 if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
353 /* nothing to change, add later as one block */
354@@ -711,7 +711,7 @@ REQUESTDONE_FUNC(log_access_write) {
355 long scd, hrs, min;
356 #endif
357
358- buffer_prepare_copy(p->conf.ts_accesslog_str, 255);
359+ buffer_string_prepare_copy(p->conf.ts_accesslog_str, 255);
360 #if defined(HAVE_STRUCT_TM_GMTOFF)
361 # ifdef HAVE_LOCALTIME_R
362 localtime_r(&(srv->cur_ts), &tm);
363diff --git a/src/mod_cgi.c b/src/mod_cgi.c
364index 76882e8..f132b8a 100644
365--- a/src/mod_cgi.c
366+++ b/src/mod_cgi.c
367@@ -344,13 +344,13 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
368 int toread;
369
370 #if defined(__WIN32)
371- buffer_prepare_copy(hctx->response, 4 * 1024);
372+ buffer_string_prepare_copy(hctx->response, 4 * 1024);
373 #else
374 if (ioctl(con->fd, FIONREAD, &toread) || toread == 0 || toread <= 4*1024) {
375- buffer_prepare_copy(hctx->response, 4 * 1024);
376+ buffer_string_prepare_copy(hctx->response, 4 * 1024);
377 } else {
378 if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
379- buffer_prepare_copy(hctx->response, toread);
380+ buffer_string_prepare_copy(hctx->response, toread);
381 }
382 #endif
383
384@@ -939,29 +939,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
385 ds = (data_string *)con->request.headers->data[n];
386
387 if (ds->value->used && ds->key->used) {
388- size_t j;
389-
390- buffer_reset(p->tmp_buf);
391-
392- if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
393- buffer_copy_string_len(p->tmp_buf, CONST_STR_LEN("HTTP_"));
394- p->tmp_buf->used--; /* strip \0 after HTTP_ */
395- }
396-
397- buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
398-
399- for (j = 0; j < ds->key->used - 1; j++) {
400- char cr = '_';
401- if (light_isalpha(ds->key->ptr[j])) {
402- /* upper-case */
403- cr = ds->key->ptr[j] & ~32;
404- } else if (light_isdigit(ds->key->ptr[j])) {
405- /* copy */
406- cr = ds->key->ptr[j];
407- }
408- p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
409- }
410- p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
411+ buffer_copy_string_encoded_cgi_varnames(p->tmp_buf, CONST_BUF_LEN(ds->key), 1);
412
413 cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
414 }
415@@ -973,24 +951,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
416 ds = (data_string *)con->environment->data[n];
417
418 if (ds->value->used && ds->key->used) {
419- size_t j;
420-
421- buffer_reset(p->tmp_buf);
422-
423- buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
424-
425- for (j = 0; j < ds->key->used - 1; j++) {
426- char cr = '_';
427- if (light_isalpha(ds->key->ptr[j])) {
428- /* upper-case */
429- cr = ds->key->ptr[j] & ~32;
430- } else if (light_isdigit(ds->key->ptr[j])) {
431- /* copy */
432- cr = ds->key->ptr[j];
433- }
434- p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
435- }
436- p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
437+ buffer_copy_string_encoded_cgi_varnames(p->tmp_buf, CONST_BUF_LEN(ds->key), 0);
438
439 cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
440 }
441diff --git a/src/mod_compress.c b/src/mod_compress.c
442index b428cd0..120b379 100644
443--- a/src/mod_compress.c
444+++ b/src/mod_compress.c
445@@ -266,7 +266,7 @@ static int deflate_file_to_buffer_gzip(server *srv, connection *con, plugin_data
446 z.total_in = 0;
447
448
449- buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12 + 18);
450+ buffer_string_prepare_copy(p->b, (z.avail_in * 1.1) + 12 + 18);
451
452 /* write gzip header */
453
454@@ -284,7 +284,7 @@ static int deflate_file_to_buffer_gzip(server *srv, connection *con, plugin_data
455
456 p->b->used = 10;
457 z.next_out = (unsigned char *)p->b->ptr + p->b->used;
458- z.avail_out = p->b->size - p->b->used - 8;
459+ z.avail_out = p->b->size - p->b->used - 9;
460 z.total_out = 0;
461
462 if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
463@@ -308,6 +308,7 @@ static int deflate_file_to_buffer_gzip(server *srv, connection *con, plugin_data
464 c[6] = (z.total_in >> 16) & 0xff;
465 c[7] = (z.total_in >> 24) & 0xff;
466 p->b->used += 8;
467+ p->b->ptr[p->b->used++] = '\0';
468
469 if (Z_OK != deflateEnd(&z)) {
470 return -1;
471@@ -339,10 +340,10 @@ static int deflate_file_to_buffer_deflate(server *srv, connection *con, plugin_d
472 z.avail_in = st_size;
473 z.total_in = 0;
474
475- buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12);
476+ buffer_string_prepare_copy(p->b, (z.avail_in * 1.1) + 12);
477
478 z.next_out = (unsigned char *)p->b->ptr;
479- z.avail_out = p->b->size;
480+ z.avail_out = p->b->size - 1;
481 z.total_out = 0;
482
483 if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
484@@ -350,13 +351,13 @@ static int deflate_file_to_buffer_deflate(server *srv, connection *con, plugin_d
485 return -1;
486 }
487
488- /* trailer */
489- p->b->used = z.total_out;
490-
491 if (Z_OK != deflateEnd(&z)) {
492 return -1;
493 }
494
495+ /* trailer */
496+ buffer_commit(p->b, z.total_out);
497+
498 return 0;
499 }
500
501@@ -385,10 +386,10 @@ static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_dat
502 bz.total_in_lo32 = 0;
503 bz.total_in_hi32 = 0;
504
505- buffer_prepare_copy(p->b, (bz.avail_in * 1.1) + 12);
506+ buffer_string_prepare_copy(p->b, (bz.avail_in * 1.1) + 12);
507
508 bz.next_out = p->b->ptr;
509- bz.avail_out = p->b->size;
510+ bz.avail_out = p->b->size - 1;
511 bz.total_out_lo32 = 0;
512 bz.total_out_hi32 = 0;
513
514@@ -402,6 +403,7 @@ static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_dat
515
516 /* trailer */
517 p->b->used = bz.total_out_lo32;
518+ p->b->ptr[p->b->used++] = '\0';
519
520 if (BZ_OK != BZ2_bzCompressEnd(&bz)) {
521 return -1;
522@@ -434,7 +436,6 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
523
524 if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) {
525 buffer_append_string(p->ofn, con->physical.path->ptr + con->physical.doc_root->used - 1);
526- buffer_copy_buffer(p->b, p->ofn);
527 } else {
528 buffer_append_string_buffer(p->ofn, con->uri.path);
529 }
530@@ -546,11 +547,11 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
531 }
532
533 if (ret == 0) {
534- r = write(ofd, p->b->ptr, p->b->used);
535+ r = write(ofd, CONST_BUF_LEN(p->b));
536 if (-1 == r) {
537 log_error_write(srv, __FILE__, __LINE__, "sbss", "writing cachefile", p->ofn, "failed:", strerror(errno));
538 ret = -1;
539- } else if ((size_t)r != p->b->used) {
540+ } else if ((size_t)r != buffer_string_length(p->b)) {
541 log_error_write(srv, __FILE__, __LINE__, "sbs", "writing cachefile", p->ofn, "failed: not enough bytes written");
542 ret = -1;
543 }
544@@ -650,7 +651,7 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
545 if (ret != 0) return -1;
546
547 chunkqueue_reset(con->write_queue);
548- chunkqueue_append_mem(con->write_queue, p->b->ptr, p->b->used);
549+ chunkqueue_append_buffer(con->write_queue, p->b);
550
551 buffer_reset(con->physical.path);
552
553diff --git a/src/mod_expire.c b/src/mod_expire.c
554index 41895f9..31a81b7 100644
555--- a/src/mod_expire.c
556+++ b/src/mod_expire.c
557@@ -43,7 +43,7 @@ INIT_FUNC(mod_expire_init) {
558
559 p->expire_tstmp = buffer_init();
560
561- buffer_prepare_copy(p->expire_tstmp, 255);
562+ buffer_string_prepare_copy(p->expire_tstmp, 255);
563
564 return p;
565 }
566diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
567index e7b62f6..a935961 100644
568--- a/src/mod_fastcgi.c
569+++ b/src/mod_fastcgi.c
570@@ -311,7 +311,6 @@ typedef struct {
571 buffer *fcgi_env;
572
573 buffer *path;
574- buffer *parse_response;
575
576 buffer *statuskey;
577
578@@ -672,7 +671,6 @@ INIT_FUNC(mod_fastcgi_init) {
579 p->fcgi_env = buffer_init();
580
581 p->path = buffer_init();
582- p->parse_response = buffer_init();
583
584 p->statuskey = buffer_init();
585
586@@ -687,7 +685,6 @@ FREE_FUNC(mod_fastcgi_free) {
587
588 buffer_free(p->fcgi_env);
589 buffer_free(p->path);
590- buffer_free(p->parse_response);
591 buffer_free(p->statuskey);
592
593 if (p->config_storage) {
594@@ -1578,6 +1575,8 @@ static handler_t fcgi_connection_reset(server *srv, connection *con, void *p_d)
595
596 static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) {
597 size_t len;
598+ char len_enc[8];
599+ size_t len_enc_len = 0;
600
601 if (!key || !val) return -1;
602
603@@ -1586,7 +1585,7 @@ static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char
604 len += key_len > 127 ? 4 : 1;
605 len += val_len > 127 ? 4 : 1;
606
607- if (env->used + len >= FCGI_MAX_LENGTH) {
608+ if (buffer_string_length(env) + len >= FCGI_MAX_LENGTH) {
609 /**
610 * we can't append more headers, ignore it
611 */
612@@ -1598,33 +1597,32 @@ static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char
613 *
614 * HINT: this can't happen as FCGI_MAX_LENGTH is only 16bit
615 */
616- if (key_len > 0x7fffffff) key_len = 0x7fffffff;
617- if (val_len > 0x7fffffff) val_len = 0x7fffffff;
618+ force_assert(key_len < 0x7fffffffu);
619+ force_assert(val_len < 0x7fffffffu);
620
621- buffer_prepare_append(env, len);
622+ buffer_string_prepare_append(env, len);
623
624 if (key_len > 127) {
625- env->ptr[env->used++] = ((key_len >> 24) & 0xff) | 0x80;
626- env->ptr[env->used++] = (key_len >> 16) & 0xff;
627- env->ptr[env->used++] = (key_len >> 8) & 0xff;
628- env->ptr[env->used++] = (key_len >> 0) & 0xff;
629+ len_enc[len_enc_len++] = ((key_len >> 24) & 0xff) | 0x80;
630+ len_enc[len_enc_len++] = (key_len >> 16) & 0xff;
631+ len_enc[len_enc_len++] = (key_len >> 8) & 0xff;
632+ len_enc[len_enc_len++] = (key_len >> 0) & 0xff;
633 } else {
634- env->ptr[env->used++] = (key_len >> 0) & 0xff;
635+ len_enc[len_enc_len++] = (key_len >> 0) & 0xff;
636 }
637
638 if (val_len > 127) {
639- env->ptr[env->used++] = ((val_len >> 24) & 0xff) | 0x80;
640- env->ptr[env->used++] = (val_len >> 16) & 0xff;
641- env->ptr[env->used++] = (val_len >> 8) & 0xff;
642- env->ptr[env->used++] = (val_len >> 0) & 0xff;
643+ len_enc[len_enc_len++] = ((val_len >> 24) & 0xff) | 0x80;
644+ len_enc[len_enc_len++] = (val_len >> 16) & 0xff;
645+ len_enc[len_enc_len++] = (val_len >> 8) & 0xff;
646+ len_enc[len_enc_len++] = (val_len >> 0) & 0xff;
647 } else {
648- env->ptr[env->used++] = (val_len >> 0) & 0xff;
649+ len_enc[len_enc_len++] = (val_len >> 0) & 0xff;
650 }
651
652- memcpy(env->ptr + env->used, key, key_len);
653- env->used += key_len;
654- memcpy(env->ptr + env->used, val, val_len);
655- env->used += val_len;
656+ buffer_append_string_len(env, len_enc, len_enc_len);
657+ buffer_append_string_len(env, key, key_len);
658+ buffer_append_string_len(env, val, val_len);
659
660 return 0;
661 }
662@@ -1777,27 +1775,7 @@ static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_dat
663 ds = (data_string *)con->request.headers->data[i];
664
665 if (ds->value->used && ds->key->used) {
666- size_t j;
667- buffer_reset(srv->tmp_buf);
668-
669- if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
670- buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_"));
671- srv->tmp_buf->used--;
672- }
673-
674- buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
675- for (j = 0; j < ds->key->used - 1; j++) {
676- char c = '_';
677- if (light_isalpha(ds->key->ptr[j])) {
678- /* upper-case */
679- c = ds->key->ptr[j] & ~32;
680- } else if (light_isdigit(ds->key->ptr[j])) {
681- /* copy */
682- c = ds->key->ptr[j];
683- }
684- srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
685- }
686- srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
687+ buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 1);
688
689 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)),con);
690 }
691@@ -1809,22 +1787,7 @@ static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_dat
692 ds = (data_string *)con->environment->data[i];
693
694 if (ds->value->used && ds->key->used) {
695- size_t j;
696- buffer_reset(srv->tmp_buf);
697-
698- buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
699- for (j = 0; j < ds->key->used - 1; j++) {
700- char c = '_';
701- if (light_isalpha(ds->key->ptr[j])) {
702- /* upper-case */
703- c = ds->key->ptr[j] & ~32;
704- } else if (light_isdigit(ds->key->ptr[j])) {
705- /* copy */
706- c = ds->key->ptr[j];
707- }
708- srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
709- }
710- srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
711+ buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 0);
712
713 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)), con);
714 }
715@@ -1861,7 +1824,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
716 memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved));
717
718 /* send FCGI_PARAMS */
719- buffer_prepare_copy(p->fcgi_env, 1024);
720+ buffer_string_prepare_copy(p->fcgi_env, 1023);
721
722
723 if (buffer_is_empty(con->conf.server_tag)) {
724@@ -2052,9 +2015,9 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
725
726 buffer_copy_string_len(b, (const char *)&beginRecord, sizeof(beginRecord));
727
728- fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0);
729+ fcgi_header(&(header), FCGI_PARAMS, request_id, buffer_string_length(p->fcgi_env), 0);
730 buffer_append_string_len(b, (const char *)&header, sizeof(header));
731- buffer_append_string_len(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
732+ buffer_append_string_buffer(b, p->fcgi_env);
733
734 fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
735 buffer_append_string_len(b, (const char *)&header, sizeof(header));
736@@ -2109,17 +2072,15 @@ static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buf
737
738 UNUSED(srv);
739
740- buffer_copy_buffer(p->parse_response, in);
741-
742 /* search for \n */
743- for (s = p->parse_response->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) {
744+ for (s = in->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) {
745 char *key, *value;
746 int key_len;
747 data_string *ds = NULL;
748
749 /* a good day. Someone has read the specs and is sending a \r\n to us */
750
751- if (ns > p->parse_response->ptr &&
752+ if (ns > in->ptr &&
753 *(ns-1) == '\r') {
754 *(ns-1) = '\0';
755 }
756@@ -2315,7 +2276,7 @@ typedef struct {
757 } fastcgi_response_packet;
758
759 static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_packet *packet) {
760- chunk * c;
761+ chunk *c;
762 size_t offset;
763 size_t toread;
764 FCGI_Header *header;
765@@ -2331,15 +2292,11 @@ static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_p
766 offset = 0; toread = 8;
767 /* get at least the FastCGI header */
768 for (c = hctx->rb->first; c; c = c->next) {
769- size_t weHave = c->mem->used - c->offset - 1;
770+ size_t weHave = buffer_string_length(c->mem) - c->offset;
771
772 if (weHave > toread) weHave = toread;
773
774- if (packet->b->used == 0) {
775- buffer_copy_string_len(packet->b, c->mem->ptr + c->offset, weHave);
776- } else {
777- buffer_append_string_len(packet->b, c->mem->ptr + c->offset, weHave);
778- }
779+ buffer_append_string_len(packet->b, c->mem->ptr + c->offset, weHave);
780 toread -= weHave;
781 offset = weHave; /* skip offset bytes in chunk for "real" data */
782
783@@ -2478,7 +2435,6 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
784 /* is the header already finished */
785 if (0 == con->file_started) {
786 char *c;
787- size_t blen;
788 data_string *ds;
789
790 /* search for header terminator
791@@ -2489,20 +2445,20 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
792 * search for \n\n
793 */
794
795- if (hctx->response_header->used == 0) {
796- buffer_copy_buffer(hctx->response_header, packet.b);
797- } else {
798- buffer_append_string_buffer(hctx->response_header, packet.b);
799- }
800+ buffer_append_string_buffer(hctx->response_header, packet.b);
801
802 if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\r\n\r\n")))) {
803- blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4 - 1;
804- hctx->response_header->used = (c - hctx->response_header->ptr) + 3;
805- c += 4; /* point the the start of the response */
806+ char *hend = c + 4; /* header end == body start */
807+ size_t hlen = hend - hctx->response_header->ptr;
808+ buffer_copy_string_len(packet.b, hend, buffer_string_length(hctx->response_header) - hlen);
809+ hctx->response_header->used = hlen;
810+ hctx->response_header->ptr[hctx->response_header->used++] = '\0';
811 } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) {
812- blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2 - 1;
813- hctx->response_header->used = c - hctx->response_header->ptr + 2;
814- c += 2; /* point the the start of the response */
815+ char *hend = c + 2; /* header end == body start */
816+ size_t hlen = hend - hctx->response_header->ptr;
817+ buffer_copy_string_len(packet.b, hend, buffer_string_length(hctx->response_header) - hlen);
818+ hctx->response_header->used = hlen;
819+ hctx->response_header->ptr[hctx->response_header->used++] = '\0';
820 } else {
821 /* no luck, no header found */
822 break;
823@@ -2559,14 +2515,14 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
824 }
825
826
827- if (hctx->send_content_body && blen > 0) {
828+ if (hctx->send_content_body && buffer_string_length(packet.b) > 0) {
829 /* enable chunked-transfer-encoding */
830 if (con->request.http_version == HTTP_VERSION_1_1 &&
831 !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
832 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
833 }
834
835- http_chunk_append_mem(srv, con, c, blen);
836+ http_chunk_append_buffer(srv, con, packet.b);
837 joblist_append(srv, con);
838 }
839 } else if (hctx->send_content_body && packet.b->used > 1) {
840diff --git a/src/mod_mysql_vhost.c b/src/mod_mysql_vhost.c
841index 8442f76..7d679fb 100644
842--- a/src/mod_mysql_vhost.c
843+++ b/src/mod_mysql_vhost.c
844@@ -355,7 +355,7 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
845 unsigned long to_len;
846
847 /* 'to' has to be 'from_len * 2 + 1' */
848- buffer_prepare_append(p->tmp_buf, (con->uri.authority->used - 1) * 2 + 1);
849+ buffer_string_prepare_append(p->tmp_buf, (con->uri.authority->used - 1) * 2 + 1);
850
851 to_len = mysql_real_escape_string(p->conf.mysql,
852 p->tmp_buf->ptr + p->tmp_buf->used - 1,
853diff --git a/src/mod_proxy.c b/src/mod_proxy.c
854index 2b5a740..fc2ca1a 100644
855--- a/src/mod_proxy.c
856+++ b/src/mod_proxy.c
857@@ -624,15 +624,9 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
858 }
859
860 if (b > 0) {
861- if (hctx->response->used == 0) {
862- /* avoid too small buffer */
863- buffer_prepare_append(hctx->response, b + 1);
864- hctx->response->used = 1;
865- } else {
866- buffer_prepare_append(hctx->response, b);
867- }
868+ buffer_string_prepare_append(hctx->response, b);
869
870- if (-1 == (r = read(hctx->fd, hctx->response->ptr + hctx->response->used - 1, b))) {
871+ if (-1 == (r = read(hctx->fd, hctx->response->ptr + buffer_string_length(hctx->response), buffer_string_space(hctx->response)))) {
872 if (errno == EAGAIN) return 0;
873 log_error_write(srv, __FILE__, __LINE__, "sds",
874 "unexpected end-of-file (perhaps the proxy process died):",
875@@ -653,7 +647,7 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
876
877 if (0 == con->got_response) {
878 con->got_response = 1;
879- buffer_prepare_copy(hctx->response_header, 128);
880+ buffer_string_prepare_copy(hctx->response_header, 1023);
881 }
882
883 if (0 == con->file_started) {
884diff --git a/src/mod_rrdtool.c b/src/mod_rrdtool.c
885index 4986ea3..5eb0d9d 100644
886--- a/src/mod_rrdtool.c
887+++ b/src/mod_rrdtool.c
888@@ -271,8 +271,8 @@ static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s)
889 return HANDLER_ERROR;
890 }
891
892- buffer_prepare_copy(p->resp, 4096);
893- if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size))) {
894+ buffer_string_prepare_copy(p->resp, 4095);
895+ if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size - 1))) {
896 log_error_write(srv, __FILE__, __LINE__, "ss",
897 "rrdtool-read: failed", strerror(errno));
898
899@@ -280,6 +280,7 @@ static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s)
900 }
901
902 p->resp->used = r;
903+ p->resp->ptr[p->resp->used++] = '\0';
904
905 if (p->resp->ptr[0] != 'O' ||
906 p->resp->ptr[1] != 'K') {
907@@ -434,7 +435,7 @@ TRIGGER_FUNC(mod_rrd_trigger) {
908 return HANDLER_ERROR;
909 }
910
911- buffer_prepare_copy(p->resp, 4096);
912+ buffer_string_prepare_copy(p->resp, 4096);
913 if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size - 1))) {
914 p->rrdtool_running = 0;
915
916@@ -444,8 +445,8 @@ TRIGGER_FUNC(mod_rrd_trigger) {
917 return HANDLER_ERROR;
918 }
919
920- p->resp->used = r + 1;
921- p->resp->ptr[r] = '\0';
922+ p->resp->used = r;
923+ p->resp->ptr[p->resp->used++] = '\0';
924
925 if (p->resp->ptr[0] != 'O' ||
926 p->resp->ptr[1] != 'K') {
927diff --git a/src/mod_scgi.c b/src/mod_scgi.c
928index 2fa265d..9ea16a4 100644
929--- a/src/mod_scgi.c
930+++ b/src/mod_scgi.c
931@@ -1301,14 +1301,12 @@ static int scgi_env_add(buffer *env, const char *key, size_t key_len, const char
932
933 len = key_len + val_len + 2;
934
935- buffer_prepare_append(env, len);
936+ buffer_string_prepare_append(env, len);
937
938- memcpy(env->ptr + env->used, key, key_len);
939- env->ptr[env->used + key_len] = '\0';
940- env->used += key_len + 1;
941- memcpy(env->ptr + env->used, val, val_len);
942- env->ptr[env->used + val_len] = '\0';
943- env->used += val_len + 1;
944+ buffer_append_string_len(env, key, key_len);
945+ buffer_append_string_len(env, "", 1);
946+ buffer_append_string_len(env, val, val_len);
947+ buffer_append_string_len(env, "", 1);
948
949 return 0;
950 }
951@@ -1419,21 +1417,7 @@ static int scgi_env_add_request_headers(server *srv, connection *con, plugin_dat
952 ds = (data_string *)con->request.headers->data[i];
953
954 if (ds->value->used && ds->key->used) {
955- size_t j;
956- buffer_reset(srv->tmp_buf);
957-
958- if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
959- buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_"));
960- srv->tmp_buf->used--;
961- }
962-
963- buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
964- for (j = 0; j < ds->key->used - 1; j++) {
965- srv->tmp_buf->ptr[srv->tmp_buf->used++] =
966- light_isalpha(ds->key->ptr[j]) ?
967- ds->key->ptr[j] & ~32 : '_';
968- }
969- srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
970+ buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 1);
971
972 scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
973 }
974@@ -1445,16 +1429,7 @@ static int scgi_env_add_request_headers(server *srv, connection *con, plugin_dat
975 ds = (data_string *)con->environment->data[i];
976
977 if (ds->value->used && ds->key->used) {
978- size_t j;
979- buffer_reset(srv->tmp_buf);
980-
981- buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
982- for (j = 0; j < ds->key->used - 1; j++) {
983- srv->tmp_buf->ptr[srv->tmp_buf->used++] =
984- light_isalnum((unsigned char)ds->key->ptr[j]) ?
985- toupper((unsigned char)ds->key->ptr[j]) : '_';
986- }
987- srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
988+ buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 0);
989
990 scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
991 }
992@@ -1481,7 +1456,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
993 sock_addr our_addr;
994 socklen_t our_addr_len;
995
996- buffer_prepare_copy(p->scgi_env, 1024);
997+ buffer_string_prepare_copy(p->scgi_env, 1023);
998
999 /* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */
1000
1001@@ -1631,9 +1606,9 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
1002
1003 b = buffer_init();
1004
1005- buffer_append_int(b, p->scgi_env->used);
1006+ buffer_append_int(b, buffer_string_length(p->scgi_env));
1007 buffer_append_string_len(b, CONST_STR_LEN(":"));
1008- buffer_append_string_len(b, (const char *)p->scgi_env->ptr, p->scgi_env->used);
1009+ buffer_append_string_buffer(b, p->scgi_env);
1010 buffer_append_string_len(b, CONST_STR_LEN(","));
1011
1012 hctx->wb->bytes_in += b->used - 1;
1013@@ -1759,7 +1734,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
1014 while(1) {
1015 int n;
1016
1017- buffer_prepare_copy(hctx->response, 1024);
1018+ buffer_string_prepare_copy(hctx->response, 1023);
1019 if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
1020 if (errno == EAGAIN || errno == EINTR) {
1021 /* would block, wait for signal */
1022diff --git a/src/mod_simple_vhost.c b/src/mod_simple_vhost.c
1023index 7245fd5..6bb850f 100644
1024--- a/src/mod_simple_vhost.c
1025+++ b/src/mod_simple_vhost.c
1026@@ -126,7 +126,7 @@ static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *
1027 stat_cache_entry *sce = NULL;
1028 force_assert(p->conf.server_root->used > 1);
1029
1030- buffer_prepare_copy(out, 128);
1031+ buffer_string_prepare_copy(out, 127);
1032 buffer_copy_buffer(out, p->conf.server_root);
1033
1034 if (host->used) {
1035diff --git a/src/mod_ssi.c b/src/mod_ssi.c
1036index ecdfb99..981fd76 100644
1037--- a/src/mod_ssi.c
1038+++ b/src/mod_ssi.c
1039@@ -173,32 +173,12 @@ static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data
1040 ds = (data_string *)con->request.headers->data[i];
1041
1042 if (ds->value->used && ds->key->used) {
1043- size_t j;
1044- buffer_reset(srv->tmp_buf);
1045-
1046 /* don't forward the Authorization: Header */
1047 if (0 == strcasecmp(ds->key->ptr, "AUTHORIZATION")) {
1048 continue;
1049 }
1050
1051- if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
1052- buffer_copy_string_len(srv->tmp_buf, CONST_STR_LEN("HTTP_"));
1053- srv->tmp_buf->used--;
1054- }
1055-
1056- buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
1057- for (j = 0; j < ds->key->used - 1; j++) {
1058- char c = '_';
1059- if (light_isalpha(ds->key->ptr[j])) {
1060- /* upper-case */
1061- c = ds->key->ptr[j] & ~32;
1062- } else if (light_isdigit(ds->key->ptr[j])) {
1063- /* copy */
1064- c = ds->key->ptr[j];
1065- }
1066- srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
1067- }
1068- srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0';
1069+ buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 1);
1070
1071 ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
1072 }
1073@@ -210,23 +190,7 @@ static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data
1074 ds = (data_string *)con->environment->data[i];
1075
1076 if (ds->value->used && ds->key->used) {
1077- size_t j;
1078-
1079- buffer_reset(srv->tmp_buf);
1080- buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
1081-
1082- for (j = 0; j < ds->key->used - 1; j++) {
1083- char c = '_';
1084- if (light_isalpha(ds->key->ptr[j])) {
1085- /* upper-case */
1086- c = ds->key->ptr[j] & ~32;
1087- } else if (light_isdigit(ds->key->ptr[j])) {
1088- /* copy */
1089- c = ds->key->ptr[j];
1090- }
1091- srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
1092- }
1093- srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0';
1094+ buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 0);
1095
1096 ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
1097 }
1098diff --git a/src/network_write.c b/src/network_write.c
1099index 930644e..d46649b 100644
1100--- a/src/network_write.c
1101+++ b/src/network_write.c
1102@@ -145,7 +145,7 @@ int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqu
1103
1104 munmap(p, sce->st.st_size);
1105 #else /* USE_MMAP */
1106- buffer_prepare_copy(srv->tmp_buf, toSend);
1107+ buffer_string_prepare_copy(srv->tmp_buf, toSend);
1108
1109 if (-1 == lseek(ifd, offset, SEEK_SET)) {
1110 log_error_write(srv, __FILE__, __LINE__, "ss", "lseek: ", strerror(errno));
1111diff --git a/src/proc_open.c b/src/proc_open.c
1112index e28b479..c29b9c6 100644
1113--- a/src/proc_open.c
1114+++ b/src/proc_open.c
1115@@ -280,13 +280,13 @@ static void proc_read_fd_to_buffer(int fd, buffer *b) {
1116 ssize_t s;
1117
1118 for (;;) {
1119- buffer_prepare_append(b, 512);
1120- if ((s = read(fd, (void *)(b->ptr + b->used), 512 - 1)) <= 0) {
1121+ buffer_string_prepare_append(b, 1024);
1122+ if ((s = read(fd, (void *)(b->ptr + buffer_string_length(b)), buffer_string_space(b))) <= 0) {
1123 break;
1124 }
1125 b->used += s;
1126+ b->ptr[b->used-1] = '\0';
1127 }
1128- b->ptr[b->used] = '\0';
1129 }
1130 /* }}} */
1131 /* {{{ proc_open_buffer */
1132diff --git a/src/response.c b/src/response.c
1133index 31bcd69..5072d05 100644
1134--- a/src/response.c
1135+++ b/src/response.c
1136@@ -97,7 +97,7 @@ int http_response_write_header(server *srv, connection *con) {
1137
1138 /* cache the generated timestamp */
1139 if (srv->cur_ts != srv->last_generated_date_ts) {
1140- buffer_prepare_copy(srv->ts_date_str, 255);
1141+ buffer_string_prepare_copy(srv->ts_date_str, 255);
1142
1143 strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
1144 "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
1145@@ -201,7 +201,7 @@ static void https_add_ssl_entries(connection *con) {
1146 }
1147
1148 buffer_copy_string_len(envds->key, CONST_STR_LEN("SSL_CLIENT_CERT"));
1149- buffer_prepare_copy(envds->value, n);
1150+ buffer_string_prepare_copy(envds->value, n);
1151 BIO_read(bio, envds->value->ptr, n);
1152 BIO_free(bio);
1153 envds->value->ptr[n] = '\0';
1154diff --git a/src/stat_cache.c b/src/stat_cache.c
1155index b5aa9ce..b63140e 100644
1156--- a/src/stat_cache.c
1157+++ b/src/stat_cache.c
1158@@ -219,8 +219,7 @@ static int stat_cache_attr_get(buffer *buf, char *name) {
1159 int attrlen;
1160 int ret;
1161
1162- attrlen = 1024;
1163- buffer_prepare_copy(buf, attrlen);
1164+ buffer_string_prepare_copy(buf, 1023);
1165 attrlen = buf->size - 1;
1166 if(0 == (ret = attr_get(name, "Content-Type", buf->ptr, &attrlen, 0))) {
1167 buf->used = attrlen + 1;
1168@@ -230,9 +229,9 @@ static int stat_cache_attr_get(buffer *buf, char *name) {
1169 }
1170 #elif defined(HAVE_EXTATTR)
1171 static int stat_cache_attr_get(buffer *buf, char *name) {
1172- ssize_t attrlen = 1024;
1173+ ssize_t attrlen;
1174
1175- buffer_prepare_copy(buf, attrlen);
1176+ buffer_prepare_copy(buf, 1023);
1177
1178 if (-1 != (attrlen = extattr_get_file(name, EXTATTR_NAMESPACE_USER, "Content-Type", buf->ptr, buf->size - 1))) {
1179 buf->used = attrlen + 1;
1180--
11812.4.5
1182
diff --git a/main/lighttpd/0018-tests-improve-valgrind-and-strace-TRACEME-disable-co.patch b/main/lighttpd/0018-tests-improve-valgrind-and-strace-TRACEME-disable-co.patch
new file mode 100644
index 0000000000..e56fa44244
--- /dev/null
+++ b/main/lighttpd/0018-tests-improve-valgrind-and-strace-TRACEME-disable-co.patch
@@ -0,0 +1,79 @@
1From adfa06de996944b495b878540464dd6e74563052 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:41 +0000
4Subject: [PATCH 18/29] [tests] improve valgrind and strace TRACEME, disable
5 condition logging in normal configs
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10- condition logging is way too noisy and rarely useful
11- increate timeout to wait for port bind; if the process dies we fail
12 early anyway
13
14From: Stefan Bühler <stbuehler@web.de>
15
16git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2978 152afb58-edef-0310-8abb-c4023f1b3aa9
17---
18 tests/LightyTest.pm | 6 +++---
19 tests/lighttpd.conf | 2 +-
20 tests/var-include.conf | 2 +-
21 3 files changed, 5 insertions(+), 5 deletions(-)
22
23diff --git a/tests/LightyTest.pm b/tests/LightyTest.pm
24index b92af87..36029dc 100755
25--- a/tests/LightyTest.pm
26+++ b/tests/LightyTest.pm
27@@ -87,7 +87,7 @@ sub wait_for_port_with_proc {
28 my $self = shift;
29 my $port = shift;
30 my $child = shift;
31- my $timeout = 5*10; # 5 secs, select waits 0.1 s
32+ my $timeout = 10*10; # 10 secs (valgrind might take a while), select waits 0.1 s
33
34 while (0 == $self->listening_on($port)) {
35 select(undef, undef, undef, 0.1);
36@@ -125,13 +125,13 @@ sub start_proc {
37
38 my @cmdline = ($self->{LIGHTTPD_PATH}, "-D", "-f", $self->{SRCDIR}."/".$self->{CONFIGFILE}, "-m", $self->{MODULES_PATH});
39 if (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'strace') {
40- @cmdline = (qw(strace -tt -s 512 -o strace), @cmdline);
41+ @cmdline = (qw(strace -tt -s 4096 -o strace -f -v), @cmdline);
42 } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'truss') {
43 @cmdline = (qw(truss -a -l -w all -v all -o strace), @cmdline);
44 } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'gdb') {
45 @cmdline = ('gdb', '--batch', '--ex', 'run', '--ex', 'bt full', '--args', @cmdline);
46 } elsif (defined $ENV{"TRACEME"} && $ENV{"TRACEME"} eq 'valgrind') {
47- @cmdline = (qw(valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --log-file=valgrind), @cmdline);
48+ @cmdline = (qw(valgrind --tool=memcheck --track-origins=yes --show-reachable=yes --leak-check=yes --log-file=valgrind.%p), @cmdline);
49 }
50 # diag("\nstarting lighttpd at :".$self->{PORT}.", cmdline: ".@cmdline );
51 my $child = fork();
52diff --git a/tests/lighttpd.conf b/tests/lighttpd.conf
53index a4b5cd8..a140002 100644
54--- a/tests/lighttpd.conf
55+++ b/tests/lighttpd.conf
56@@ -1,7 +1,7 @@
57 debug.log-request-handling = "enable"
58 debug.log-request-header = "enable"
59 debug.log-response-header = "enable"
60-debug.log-condition-handling = "enable"
61+#debug.log-condition-handling = "enable"
62 server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
63
64 ## 64 Mbyte ... nice limit
65diff --git a/tests/var-include.conf b/tests/var-include.conf
66index 04b8271..6a107c5 100644
67--- a/tests/var-include.conf
68+++ b/tests/var-include.conf
69@@ -1,6 +1,6 @@
70
71 debug.log-request-handling = "enable"
72-debug.log-condition-handling = "enable"
73+#debug.log-condition-handling = "enable"
74
75 server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
76
77--
782.4.5
79
diff --git a/main/lighttpd/0019-Use-buffer-API-to-read-and-modify-used-member.patch b/main/lighttpd/0019-Use-buffer-API-to-read-and-modify-used-member.patch
new file mode 100644
index 0000000000..d455ff9a67
--- /dev/null
+++ b/main/lighttpd/0019-Use-buffer-API-to-read-and-modify-used-member.patch
@@ -0,0 +1,4346 @@
1From ad3e93ea96d1cbaab00d07245dbd02f790060f85 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:44 +0000
4Subject: [PATCH 19/29] Use buffer API to read and modify "used" member
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9- a lot of code tried to handle manually adding terminating zeroes and
10 keeping track of the correct "used" count.
11 Replaced all "external" usages with simple wrapper functions:
12 * buffer_string_is_empty (used <= 1), buffer_is_empty (used == 0);
13 prefer buffer_string_is_empty
14 * buffer_string_set_length
15 * buffer_string_length
16 * CONST_BUF_LEN() macro
17- removed "static" buffer hacks (buffers pointing to constant/stack
18 memory instead of malloc()ed data)
19- buffer_append_strftime(): refactor buffer+strftime uses
20- li_tohex(): no need for a buffer for binary-to-hex conversion:
21 the output data length is easy to predict
22- remove "-Winline" from extra warnings: the "inline" keyword just
23 supresses the warning about unused but defined (static) functions;
24 don't care whether it actually gets inlined or not.
25
26From: Stefan Bühler <stbuehler@web.de>
27
28git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2979 152afb58-edef-0310-8abb-c4023f1b3aa9
29---
30 configure.ac | 2 +-
31 src/CMakeLists.txt | 2 +-
32 src/array.c | 12 +--
33 src/buffer.c | 128 ++++++++++++++++++++-----------
34 src/buffer.h | 13 ++++
35 src/chunk.c | 11 +--
36 src/configfile-glue.c | 2 +-
37 src/configfile.c | 4 +-
38 src/connections.c | 79 ++++---------------
39 src/data_string.c | 11 +--
40 src/etag.c | 5 +-
41 src/http-header-glue.c | 7 +-
42 src/http_auth.c | 71 ++++++++---------
43 src/http_chunk.c | 5 +-
44 src/log.c | 19 ++---
45 src/mod_access.c | 8 +-
46 src/mod_accesslog.c | 64 ++++++++--------
47 src/mod_alias.c | 14 ++--
48 src/mod_auth.c | 20 ++---
49 src/mod_cgi.c | 47 ++++++------
50 src/mod_cml.c | 12 ++-
51 src/mod_cml_funcs.c | 9 +--
52 src/mod_cml_lua.c | 22 ++----
53 src/mod_compress.c | 34 ++++-----
54 src/mod_dirlisting.c | 22 +++---
55 src/mod_evasive.c | 2 +-
56 src/mod_evhost.c | 11 +--
57 src/mod_expire.c | 21 ++---
58 src/mod_extforward.c | 2 +-
59 src/mod_fastcgi.c | 99 ++++++++++++------------
60 src/mod_flv_streaming.c | 13 ++--
61 src/mod_indexfile.c | 4 +-
62 src/mod_magnet.c | 43 +++++------
63 src/mod_mysql_vhost.c | 51 ++++---------
64 src/mod_proxy.c | 47 +++++-------
65 src/mod_redirect.c | 4 +-
66 src/mod_rewrite.c | 4 +-
67 src/mod_rrdtool.c | 12 ++-
68 src/mod_scgi.c | 61 +++++++--------
69 src/mod_secure_download.c | 9 +--
70 src/mod_simple_vhost.c | 16 ++--
71 src/mod_ssi.c | 16 ++--
72 src/mod_ssi_expr.c | 2 +-
73 src/mod_staticfile.c | 14 ++--
74 src/mod_status.c | 4 +-
75 src/mod_trigger_b4_dl.c | 16 ++--
76 src/mod_userdir.c | 4 +-
77 src/mod_usertrack.c | 16 ++--
78 src/mod_webdav.c | 177 ++++++++++++++++++++-----------------------
79 src/network_linux_sendfile.c | 4 +-
80 src/network_openssl.c | 6 +-
81 src/network_write.c | 6 +-
82 src/network_writev.c | 4 +-
83 src/proc_open.c | 7 +-
84 src/request.c | 49 ++++++------
85 src/response.c | 53 +++++--------
86 src/server.c | 23 +++---
87 src/stat_cache.c | 23 +++---
88 58 files changed, 668 insertions(+), 778 deletions(-)
89
90diff --git a/configure.ac b/configure.ac
91index 63261ca..c846d1a 100644
92--- a/configure.ac
93+++ b/configure.ac
94@@ -666,7 +666,7 @@ AC_ARG_ENABLE(extra-warnings,
95 esac],[extrawarnings=false])
96
97 if test x$extrawarnings = xtrue; then
98- TRY_CFLAGS([-g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security])
99+ TRY_CFLAGS([-g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security])
100 fi
101
102 dnl build version-id
103diff --git a/src/array.c b/src/array.c
104index 9a15abd..50f5e03 100644
105--- a/src/array.c
106+++ b/src/array.c
107@@ -98,7 +98,7 @@ static int array_get_index(array *a, const char *key, size_t keylen, int *rndx)
108 } else if (pos >= (int)a->used) {
109 pos -= i;
110 } else {
111- cmp = buffer_caseless_compare(key, keylen, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used);
112+ cmp = buffer_caseless_compare(key, keylen, CONST_BUF_LEN(a->data[a->sorted[pos]]->key));
113
114 if (cmp == 0) {
115 /* found */
116@@ -121,7 +121,7 @@ static int array_get_index(array *a, const char *key, size_t keylen, int *rndx)
117 data_unset *array_get_element(array *a, const char *key) {
118 int ndx;
119
120- if (-1 != (ndx = array_get_index(a, key, strlen(key) + 1, NULL))) {
121+ if (-1 != (ndx = array_get_index(a, key, strlen(key), NULL))) {
122 /* found, leave here */
123
124 return a->data[ndx];
125@@ -171,7 +171,7 @@ data_unset *array_replace(array *a, data_unset *du) {
126 int ndx;
127
128 force_assert(NULL != du);
129- if (-1 == (ndx = array_get_index(a, du->key->ptr, du->key->used, NULL))) {
130+ if (-1 == (ndx = array_get_index(a, CONST_BUF_LEN(du->key), NULL))) {
131 array_insert_unique(a, du);
132 return NULL;
133 } else {
134@@ -187,13 +187,13 @@ int array_insert_unique(array *a, data_unset *str) {
135 size_t j;
136
137 /* generate unique index if neccesary */
138- if (str->key->used == 0 || str->is_index_key) {
139+ if (buffer_is_empty(str->key) || str->is_index_key) {
140 buffer_copy_int(str->key, a->unique_ndx++);
141 str->is_index_key = 1;
142 }
143
144 /* try to find the string */
145- if (-1 != (ndx = array_get_index(a, str->key->ptr, str->key->used, &pos))) {
146+ if (-1 != (ndx = array_get_index(a, CONST_BUF_LEN(str->key), &pos))) {
147 /* found, leave here */
148 if (a->data[ndx]->type == str->type) {
149 str->insert_dup(a->data[ndx], str);
150@@ -235,7 +235,7 @@ int array_insert_unique(array *a, data_unset *str) {
151
152 if (pos != ndx &&
153 ((pos < 0) ||
154- buffer_caseless_compare(str->key->ptr, str->key->used, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used) > 0)) {
155+ buffer_caseless_compare(CONST_BUF_LEN(str->key), CONST_BUF_LEN(a->data[a->sorted[pos]]->key)) > 0)) {
156 pos++;
157 }
158
159diff --git a/src/buffer.c b/src/buffer.c
160index 979d954..d343731 100644
161--- a/src/buffer.c
162+++ b/src/buffer.c
163@@ -9,7 +9,6 @@
164
165 static const char hex_chars[] = "0123456789abcdef";
166
167-
168 /**
169 * init the buffer
170 *
171@@ -83,37 +82,44 @@ static size_t buffer_align_size(size_t size) {
172 return size + align;
173 }
174
175-static char* buffer_prepare_copy(buffer *b, size_t size) {
176+/* make sure buffer is at least "size" big. discard old data */
177+static void buffer_alloc(buffer *b, size_t size) {
178 force_assert(NULL != b);
179+ if (0 == size) size = 1;
180
181- /* also allocate space for terminating 0 */
182- /* check for overflow: unsigned overflow is defined to wrap around */
183- force_assert(1 + size > size);
184- ++size;
185+ if (size <= b->size) return;
186
187- if (0 == b->size || size > b->size) {
188- if (NULL != b->ptr) free(b->ptr);
189- b->ptr = NULL;
190+ if (NULL != b->ptr) free(b->ptr);
191
192- b->size = buffer_align_size(size);
193- force_assert(b->size > 0);
194+ b->used = 0;
195+ b->size = buffer_align_size(size);
196+ b->ptr = malloc(b->size);
197
198- b->ptr = malloc(b->size);
199- force_assert(NULL != b->ptr);
200- }
201+ force_assert(NULL != b->ptr);
202+}
203
204- /* reset */
205- b->used = 0;
206- b->ptr[0] = '\0';
207+/* make sure buffer is at least "size" big. keep old data */
208+static void buffer_realloc(buffer *b, size_t size) {
209+ force_assert(NULL != b);
210+ if (0 == size) size = 1;
211
212- return b->ptr;
213+ if (size <= b->size) return;
214+
215+ b->size = buffer_align_size(size);
216+ b->ptr = realloc(b->ptr, b->size);
217+
218+ force_assert(NULL != b->ptr);
219 }
220
221+
222 char* buffer_string_prepare_copy(buffer *b, size_t size) {
223 force_assert(NULL != b);
224+ force_assert(size + 1 > size);
225+
226+ buffer_alloc(b, size + 1);
227
228- buffer_prepare_copy(b, size);
229 b->used = 1;
230+ b->ptr[0] = '\0';
231
232 return b->ptr;
233 }
234@@ -124,28 +130,29 @@ char* buffer_string_prepare_append(buffer *b, size_t size) {
235 if (buffer_string_is_empty(b)) {
236 return buffer_string_prepare_copy(b, size);
237 } else {
238- /* not empty, b->used already includes a terminating 0 */
239 size_t req_size = b->used + size;
240
241- /* check for overflow: unsigned overflow is defined to wrap around */
242+ /* not empty, b->used already includes a terminating 0 */
243 force_assert(req_size >= b->used);
244
245- /* only append to 0-terminated string */
246- force_assert('\0' == b->ptr[b->used - 1]);
247-
248- if (req_size > b->size) {
249- char *ptr;
250- b->size = buffer_align_size(req_size);
251+ /* check for overflow: unsigned overflow is defined to wrap around */
252+ force_assert(req_size >= b->used);
253
254- ptr = realloc(b->ptr, b->size);
255- force_assert(NULL != ptr);
256- b->ptr = ptr;
257- }
258+ buffer_realloc(b, req_size);
259
260 return b->ptr + b->used - 1;
261 }
262 }
263
264+void buffer_string_set_length(buffer *b, size_t len) {
265+ force_assert(NULL != b);
266+ force_assert(len + 1 > len);
267+
268+ buffer_realloc(b, len + 1);
269+
270+ b->used = len + 1;
271+ b->ptr[len] = '\0';
272+}
273
274 void buffer_commit(buffer *b, size_t size)
275 {
276@@ -182,7 +189,8 @@ void buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
277
278 void buffer_copy_buffer(buffer *b, const buffer *src) {
279 if (NULL == src || 0 == src->used) {
280- buffer_prepare_copy(b, 0);
281+ buffer_string_prepare_copy(b, 0);
282+ b->used = 0; /* keep special empty state for now */
283 } else {
284 buffer_copy_string_len(b, src->ptr, buffer_string_length(src));
285 }
286@@ -301,6 +309,37 @@ void buffer_copy_int(buffer *b, intmax_t val) {
287 buffer_append_int(b, val);
288 }
289
290+void buffer_append_strftime(buffer *b, const char *format, const struct tm *tm) {
291+ size_t r;
292+ char* buf;
293+ force_assert(NULL != b);
294+ force_assert(NULL != tm);
295+
296+ if (NULL == format || '\0' == format[0]) {
297+ /* empty format */
298+ buffer_string_prepare_append(b, 0);
299+ return;
300+ }
301+
302+ buf = buffer_string_prepare_append(b, 255);
303+ r = strftime(buf, buffer_string_space(b), format, tm);
304+
305+ /* 0 (in some apis buffer_string_space(b)) signals the string may have
306+ * been too small; but the format could also just have lead to an empty
307+ * string
308+ */
309+ if (0 == r || r >= buffer_string_space(b)) {
310+ /* give it a second try with a larger string */
311+ buf = buffer_string_prepare_append(b, 4095);
312+ r = strftime(buf, buffer_string_space(b), format, tm);
313+ }
314+
315+ if (r >= buffer_string_space(b)) r = 0;
316+
317+ buffer_commit(b, r);
318+}
319+
320+
321 void li_itostrn(char *buf, size_t buf_len, intmax_t val) {
322 char p_buf[LI_ITOSTRING_LENGTH];
323 char* const p_buf_end = p_buf + sizeof(p_buf);
324@@ -446,20 +485,22 @@ int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
325 return 0 == memcmp(b1->ptr + b1->used - 1 - len, b2->ptr + b2->used - 1 - len, len);
326 }
327
328-void buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
329+void li_tohex(char *buf, const char *s, size_t s_len) {
330 size_t i;
331
332- /* overflow protection */
333- force_assert(in_len * 2 + 1 > in_len);
334+ for (i = 0; i < s_len; i++) {
335+ buf[2*i] = hex_chars[(s[i] >> 4) & 0x0F];
336+ buf[2*i+1] = hex_chars[s[i] & 0x0F];
337+ }
338+ buf[2*s_len] = '\0';
339+}
340
341- buffer_prepare_copy(b, in_len * 2);
342+void buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
343+ /* overflow protection */
344+ force_assert(in_len * 2 > in_len);
345
346- b->used = 0;
347- for (i = 0; i < in_len; i++) {
348- b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
349- b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
350- }
351- b->ptr[b->used++] = '\0';
352+ buffer_string_set_length(b, 2 * in_len);
353+ li_tohex(b->ptr, in, in_len);
354 }
355
356 /* everything except: ! ( ) * - . 0-9 A-Z _ a-z */
357@@ -882,8 +923,7 @@ void buffer_path_simplify(buffer *dest, buffer *src)
358 walk++;
359 }
360
361- *out = '\0';
362- dest->used = (out - start) + 1;
363+ buffer_string_set_length(dest, out - start);
364 }
365
366 int light_isdigit(int c) {
367diff --git a/src/buffer.h b/src/buffer.h
368index 7ea27f1..e2ac778 100644
369--- a/src/buffer.h
370+++ b/src/buffer.h
371@@ -10,6 +10,7 @@
372 #include <stdlib.h>
373 #include <sys/types.h>
374 #include <stdio.h>
375+#include <time.h>
376
377 #if defined HAVE_STDINT_H
378 # include <stdint.h>
379@@ -71,6 +72,13 @@ char* buffer_string_prepare_append(buffer *b, size_t size);
380 */
381 void buffer_commit(buffer *b, size_t size);
382
383+/* sets string length:
384+ * - always stores a terminating zero to terminate the "new" string
385+ * - does not modify the string data apart from terminating zero
386+ * - reallocates the buffer iff needed
387+ */
388+void buffer_string_set_length(buffer *b, size_t len);
389+
390 void buffer_copy_string(buffer *b, const char *s);
391 void buffer_copy_string_len(buffer *b, const char *s, size_t s_len);
392 void buffer_copy_buffer(buffer *b, const buffer *src);
393@@ -85,6 +93,8 @@ void buffer_append_long_hex(buffer *b, unsigned long len);
394 void buffer_append_int(buffer *b, intmax_t val);
395 void buffer_copy_int(buffer *b, intmax_t val);
396
397+void buffer_append_strftime(buffer *b, const char *format, const struct tm *tm);
398+
399 /* '-', log_10 (2^bits) = bits * log 2 / log 10 < bits * 0.31, terminating 0 */
400 #define LI_ITOSTRING_LENGTH (2 + (8 * sizeof(intmax_t) * 31 + 99) / 100)
401
402@@ -93,6 +103,9 @@ void li_itostr(char *buf, intmax_t val); /* buf must have at least LI_ITOSTRING_
403 void li_utostrn(char *buf, size_t buf_len, uintmax_t val);
404 void li_utostr(char *buf, uintmax_t val); /* buf must have at least LI_ITOSTRING_LENGTH bytes */
405
406+/* buf must be (at least) 2*s_len + 1 big. uses lower-case hex letters. */
407+void li_tohex(char *buf, const char *s, size_t s_len);
408+
409 char * buffer_search_string_len(buffer *b, const char *needle, size_t len);
410
411 /* NULL buffer or empty buffer (used == 0);
412diff --git a/src/chunk.c b/src/chunk.c
413index 83adc15..ccdae9a 100644
414--- a/src/chunk.c
415+++ b/src/chunk.c
416@@ -264,10 +264,11 @@ void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_s
417 }
418 /* if buffer is really small just make it bigger */
419 else if (have < min_size && b->size <= REALLOC_MAX_SIZE) {
420- size_t new_size = b->used + min_size, append;
421+ size_t cur_len = buffer_string_length(b);
422+ size_t new_size = cur_len + min_size, append;
423 if (new_size < alloc_size) new_size = alloc_size;
424
425- append = new_size - b->used;
426+ append = new_size - cur_len;
427 if (append >= min_size) {
428 buffer_string_prepare_append(b, append);
429 have = buffer_string_space(b);
430@@ -301,12 +302,8 @@ void chunkqueue_use_memory(chunkqueue *cq, size_t len) {
431 force_assert(NULL != cq->last && MEM_CHUNK == cq->last->type);
432 b = cq->last->mem;
433
434- force_assert(b->used > 0);
435- force_assert(len <= buffer_string_space(b));
436-
437 if (len > 0) {
438- b->used += len;
439- b->ptr[b->used - 1] = '\0';
440+ buffer_commit(b, len);
441 } else if (buffer_string_is_empty(b)) {
442 /* unused buffer: can't remove chunk easily from
443 * end of list, so just reset the buffer
444diff --git a/src/configfile-glue.c b/src/configfile-glue.c
445index 2fb8c62..f411d72 100644
446--- a/src/configfile-glue.c
447+++ b/src/configfile-glue.c
448@@ -491,7 +491,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
449 #ifndef elementsof
450 #define elementsof(x) (sizeof(x) / sizeof(x[0]))
451 #endif
452- n = pcre_exec(dc->regex, dc->regex_study, l->ptr, l->used - 1, 0, 0,
453+ n = pcre_exec(dc->regex, dc->regex_study, CONST_BUF_LEN(l), 0, 0,
454 cache->matches, elementsof(cache->matches));
455
456 cache->patterncount = n;
457diff --git a/src/configfile.c b/src/configfile.c
458index 1c36c3e..929d292 100644
459--- a/src/configfile.c
460+++ b/src/configfile.c
461@@ -1130,7 +1130,7 @@ int config_read(server *srv, const char *fn) {
462 dcwd = data_string_init();
463 buffer_string_prepare_copy(dcwd->value, 1023);
464 if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) {
465- dcwd->value->used = strlen(dcwd->value->ptr) + 1;
466+ buffer_commit(dcwd->value, strlen(dcwd->value->ptr));
467 buffer_copy_string_len(dcwd->key, CONST_STR_LEN("var.CWD"));
468 array_insert_unique(srv->config, (data_unset *)dcwd);
469 } else {
470@@ -1320,7 +1320,7 @@ int config_set_defaults(server *srv) {
471 srv->srvconf.port = s->ssl_enabled ? 443 : 80;
472 }
473
474- if (srv->srvconf.event_handler->used == 0) {
475+ if (buffer_string_is_empty(srv->srvconf.event_handler)) {
476 /* choose a good default
477 *
478 * the event_handler list is sorted by 'goodness'
479diff --git a/src/connections.c b/src/connections.c
480index 3fab768..8f26a30 100644
481--- a/src/connections.c
482+++ b/src/connections.c
483@@ -400,7 +400,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
484 * 403 is from the response handler when noone else catched it
485 *
486 * */
487- if ((!con->http_status || con->http_status == 200) && con->uri.path->used &&
488+ if ((!con->http_status || con->http_status == 200) && !buffer_string_is_empty(con->uri.path) &&
489 con->uri.path->ptr[0] != '*') {
490 response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
491
492@@ -873,42 +873,7 @@ static int connection_handle_read_state(server *srv, connection *con) {
493 }
494 }
495
496- /* the last chunk might be empty */
497- for (c = cq->first; c;) {
498- if (cq->first == c && c->mem->used == 0) {
499- /* the first node is empty */
500- /* ... and it is empty, move it to unused */
501-
502- cq->first = c->next;
503- if (cq->first == NULL) cq->last = NULL;
504-
505- c->next = cq->unused;
506- cq->unused = c;
507- cq->unused_chunks++;
508-
509- c = cq->first;
510- } else if (c->next && c->next->mem->used == 0) {
511- chunk *fc;
512- /* next node is the last one */
513- /* ... and it is empty, move it to unused */
514-
515- fc = c->next;
516- c->next = fc->next;
517-
518- fc->next = cq->unused;
519- cq->unused = fc;
520- cq->unused_chunks++;
521-
522- /* the last node was empty */
523- if (c->next == NULL) {
524- cq->last = c;
525- }
526-
527- c = c->next;
528- } else {
529- c = c->next;
530- }
531- }
532+ chunkqueue_remove_finished_chunks(cq);
533
534 /* we might have got several packets at once
535 */
536@@ -927,15 +892,12 @@ static int connection_handle_read_state(server *srv, connection *con) {
537 last_offset = 0;
538
539 for (c = cq->first; c; c = c->next) {
540- buffer b;
541 size_t i;
542+ size_t len = buffer_string_length(c->mem) - c->offset;
543+ const char *b = c->mem->ptr + c->offset;
544
545- b.ptr = c->mem->ptr + c->offset;
546- b.used = c->mem->used - c->offset;
547- if (b.used > 0) b.used--; /* buffer "used" includes terminating zero */
548-
549- for (i = 0; i < b.used; i++) {
550- char ch = b.ptr[i];
551+ for (i = 0; i < len; ++i) {
552+ char ch = b[i];
553
554 if ('\r' == ch) {
555 /* chec if \n\r\n follows */
556@@ -945,13 +907,11 @@ static int connection_handle_read_state(server *srv, connection *con) {
557 int header_end_match_pos = 1;
558
559 for ( ; cc; cc = cc->next, j = 0 ) {
560- buffer bb;
561- bb.ptr = cc->mem->ptr + cc->offset;
562- bb.used = cc->mem->used - cc->offset;
563- if (bb.used > 0) bb.used--; /* buffer "used" includes terminating zero */
564+ size_t bblen = buffer_string_length(cc->mem) - cc->offset;
565+ const char *bb = c->mem->ptr + cc->offset;
566
567- for ( ; j < bb.used; j++) {
568- ch = bb.ptr[j];
569+ for ( ; j < bblen; j++) {
570+ ch = bb[j];
571
572 if (ch == header_end[header_end_match_pos]) {
573 header_end_match_pos++;
574@@ -976,25 +936,16 @@ found_header_end:
575 buffer_reset(con->request.request);
576
577 for (c = cq->first; c; c = c->next) {
578- buffer b;
579-
580- b.ptr = c->mem->ptr + c->offset;
581- b.used = c->mem->used - c->offset;
582+ size_t len = buffer_string_length(c->mem) - c->offset;
583
584 if (c == last_chunk) {
585- b.used = last_offset + 1;
586+ len = last_offset;
587 }
588
589- buffer_append_string_buffer(con->request.request, &b);
590+ buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, len);
591+ c->offset += len;
592
593- if (c == last_chunk) {
594- c->offset += last_offset;
595-
596- break;
597- } else {
598- /* the whole packet was copied */
599- c->offset = c->mem->used - 1;
600- }
601+ if (c == last_chunk) break;
602 }
603
604 connection_set_state(srv, con, CON_STATE_REQUEST_END);
605diff --git a/src/data_string.c b/src/data_string.c
606index fc57de2..d65b3be 100644
607--- a/src/data_string.c
608+++ b/src/data_string.c
609@@ -36,7 +36,7 @@ static int data_string_insert_dup(data_unset *dst, data_unset *src) {
610 data_string *ds_dst = (data_string *)dst;
611 data_string *ds_src = (data_string *)src;
612
613- if (ds_dst->value->used) {
614+ if (!buffer_is_empty(ds_dst->value)) {
615 buffer_append_string_len(ds_dst->value, CONST_STR_LEN(", "));
616 buffer_append_string_buffer(ds_dst->value, ds_src->value);
617 } else {
618@@ -52,7 +52,7 @@ static int data_response_insert_dup(data_unset *dst, data_unset *src) {
619 data_string *ds_dst = (data_string *)dst;
620 data_string *ds_src = (data_string *)src;
621
622- if (ds_dst->value->used) {
623+ if (!buffer_is_empty(ds_dst->value)) {
624 buffer_append_string_len(ds_dst->value, CONST_STR_LEN("\r\n"));
625 buffer_append_string_buffer(ds_dst->value, ds_dst->key);
626 buffer_append_string_len(ds_dst->value, CONST_STR_LEN(": "));
627@@ -69,18 +69,19 @@ static int data_response_insert_dup(data_unset *dst, data_unset *src) {
628
629 static void data_string_print(const data_unset *d, int depth) {
630 data_string *ds = (data_string *)d;
631- unsigned int i;
632+ size_t i, len;
633 UNUSED(depth);
634
635 /* empty and uninitialized strings */
636- if (ds->value->used < 1) {
637+ if (buffer_string_is_empty(ds->value)) {
638 fputs("\"\"", stdout);
639 return;
640 }
641
642 /* print out the string as is, except prepend " with backslash */
643 putc('"', stdout);
644- for (i = 0; i < ds->value->used - 1; i++) {
645+ len = buffer_string_length(ds->value);
646+ for (i = 0; i < len; i++) {
647 unsigned char c = ds->value->ptr[i];
648 if (c == '"') {
649 fputs("\\\"", stdout);
650diff --git a/src/etag.c b/src/etag.c
651index bf63d94..f8fb609 100644
652--- a/src/etag.c
653+++ b/src/etag.c
654@@ -37,10 +37,11 @@ int etag_create(buffer *etag, struct stat *st,etag_flags_t flags) {
655 }
656
657 int etag_mutate(buffer *mut, buffer *etag) {
658- size_t i;
659+ size_t i, len;
660 uint32_t h;
661
662- for (h=0, i=0; i < etag->used-1; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
663+ len = buffer_string_length(etag);
664+ for (h=0, i=0; i < len; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
665
666 buffer_reset(mut);
667 buffer_copy_string_len(mut, CONST_STR_LEN("\""));
668diff --git a/src/http-header-glue.c b/src/http-header-glue.c
669index f910f3f..752d91e 100644
670--- a/src/http-header-glue.c
671+++ b/src/http-header-glue.c
672@@ -125,7 +125,7 @@ int http_response_redirect_to_directory(server *srv, connection *con) {
673
674 buffer_copy_buffer(o, con->uri.scheme);
675 buffer_append_string_len(o, CONST_STR_LEN("://"));
676- if (con->uri.authority->used) {
677+ if (!buffer_is_empty(con->uri.authority)) {
678 buffer_append_string_buffer(o, con->uri.authority);
679 } else {
680 /* get the name of the currently connected socket */
681@@ -237,10 +237,7 @@ buffer * strftime_cache_get(server *srv, time_t last_mod) {
682 srv->mtime_cache[i].mtime = last_mod;
683 buffer_string_prepare_copy(srv->mtime_cache[i].str, 1023);
684 tm = gmtime(&(srv->mtime_cache[i].mtime));
685- srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
686- srv->mtime_cache[i].str->size - 1,
687- "%a, %d %b %Y %H:%M:%S GMT", tm);
688- srv->mtime_cache[i].str->used++;
689+ buffer_append_strftime(srv->mtime_cache[i].str, "%a, %d %b %Y %H:%M:%S GMT", tm);
690
691 return srv->mtime_cache[i].str;
692 }
693diff --git a/src/http_auth.c b/src/http_auth.c
694index c693645..a98ea62 100644
695--- a/src/http_auth.c
696+++ b/src/http_auth.c
697@@ -39,13 +39,7 @@ typedef unsigned char HASH[HASHLEN];
698 typedef char HASHHEX[HASHHEXLEN+1];
699
700 static void CvtHex(const HASH Bin, char Hex[33]) {
701- unsigned short i;
702-
703- for (i = 0; i < 16; i++) {
704- Hex[i*2] = int2hex((Bin[i] >> 4) & 0xf);
705- Hex[i*2+1] = int2hex(Bin[i] & 0xf);
706- }
707- Hex[32] = '\0';
708+ li_tohex(Hex, (const char*) Bin, 16);
709 }
710
711 /**
712@@ -97,9 +91,7 @@ static unsigned char * base64_decode(buffer *out, const char *in) {
713
714 size_t in_len = strlen(in);
715
716- buffer_string_prepare_copy(out, in_len);
717-
718- result = (unsigned char *)out->ptr;
719+ result = (unsigned char *) buffer_string_prepare_copy(out, in_len);
720
721 /* run through the whole string, converting as we go */
722 for (i = 0; i < in_len; i++) {
723@@ -157,8 +149,7 @@ static unsigned char * base64_decode(buffer *out, const char *in) {
724 break;
725 }
726
727- result[j] = '\0';
728- out->used = j;
729+ buffer_commit(out, j);
730
731 return result;
732 }
733@@ -166,7 +157,7 @@ static unsigned char * base64_decode(buffer *out, const char *in) {
734 static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *username, buffer *realm, buffer *password) {
735 int ret = -1;
736
737- if (!username->used|| !realm->used) return -1;
738+ if (buffer_is_empty(username) || buffer_is_empty(realm)) return -1;
739
740 if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
741 stream f;
742@@ -226,8 +217,8 @@ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *
743 pwd_len = f.size - (f_pwd - f.start);
744 }
745
746- if (username->used - 1 == u_len &&
747- (realm->used - 1 == r_len) &&
748+ if (buffer_string_length(username) == u_len &&
749+ (buffer_string_length(realm) == r_len) &&
750 (0 == strncmp(username->ptr, f_user, u_len)) &&
751 (0 == strncmp(realm->ptr, f_realm, r_len))) {
752 /* found */
753@@ -296,7 +287,7 @@ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *
754 pwd_len = f.size - (f_pwd - f.start);
755 }
756
757- if (username->used - 1 == u_len &&
758+ if (buffer_string_length(username) == u_len &&
759 (0 == strncmp(username->ptr, f_user, u_len))) {
760 /* found */
761
762@@ -652,10 +643,10 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
763 char a1[256];
764
765 li_MD5_Init(&Md5Ctx);
766- li_MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1);
767- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
768- li_MD5_Update(&Md5Ctx, (unsigned char *)realm->ptr, realm->used - 1);
769- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
770+ li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(username));
771+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
772+ li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(realm));
773+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
774 li_MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw));
775 li_MD5_Final(HA1, &Md5Ctx);
776
777@@ -682,7 +673,7 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
778 char *crypted;
779
780 /* a simple DES password is 2 + 11 characters. everything else should be longer. */
781- if (password->used < 13 + 1) {
782+ if (buffer_string_length(password) < 13) {
783 return -1;
784 }
785
786@@ -707,7 +698,7 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
787 char *dn;
788 int ret;
789 char *attrs[] = { LDAP_NO_ATTRS, NULL };
790- size_t i;
791+ size_t i, len;
792
793 /* for now we stay synchronous */
794
795@@ -726,7 +717,8 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
796 * a unpleasant way
797 */
798
799- for (i = 0; i < username->used - 1; i++) {
800+ len = buffer_string_length(username);
801+ for (i = 0; i < len; i++) {
802 char c = username->ptr[i];
803
804 if (!isalpha(c) &&
805@@ -863,9 +855,8 @@ int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p,
806 return 0;
807 }
808
809- *pw++ = '\0';
810-
811- username->used = pw - username->ptr;
812+ buffer_string_set_length(username, pw - username->ptr);
813+ pw++;
814
815 password = buffer_init();
816 /* copy password to r1 */
817@@ -1084,10 +1075,10 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
818 /* generate password from plain-text */
819 li_MD5_Init(&Md5Ctx);
820 li_MD5_Update(&Md5Ctx, (unsigned char *)username, strlen(username));
821- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
822+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
823 li_MD5_Update(&Md5Ctx, (unsigned char *)realm, strlen(realm));
824- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
825- li_MD5_Update(&Md5Ctx, (unsigned char *)password->ptr, password->used - 1);
826+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
827+ li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(password));
828 li_MD5_Final(HA1, &Md5Ctx);
829 } else if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
830 /* HA1 */
831@@ -1109,9 +1100,9 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
832 /* Errata ID 1649: http://www.rfc-editor.org/errata_search.php?rfc=2617 */
833 CvtHex(HA1, a1);
834 li_MD5_Update(&Md5Ctx, (unsigned char *)a1, 32);
835- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
836+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
837 li_MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce));
838- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
839+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
840 li_MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
841 li_MD5_Final(HA1, &Md5Ctx);
842 }
843@@ -1121,12 +1112,12 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
844 /* calculate H(A2) */
845 li_MD5_Init(&Md5Ctx);
846 li_MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m));
847- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
848+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
849 li_MD5_Update(&Md5Ctx, (unsigned char *)uri, strlen(uri));
850 /* qop=auth-int not supported, already checked above */
851 /*
852 if (qop && strcasecmp(qop, "auth-int") == 0) {
853- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
854+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
855 li_MD5_Update(&Md5Ctx, (unsigned char *) [body checksum], HASHHEXLEN);
856 }
857 */
858@@ -1136,16 +1127,16 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
859 /* calculate response */
860 li_MD5_Init(&Md5Ctx);
861 li_MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN);
862- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
863+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
864 li_MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce));
865- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
866+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
867 if (qop && *qop) {
868 li_MD5_Update(&Md5Ctx, (unsigned char *)nc, strlen(nc));
869- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
870+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
871 li_MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
872- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
873+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
874 li_MD5_Update(&Md5Ctx, (unsigned char *)qop, strlen(qop));
875- li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
876+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
877 };
878 li_MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN);
879 li_MD5_Final(RespHash, &Md5Ctx);
880@@ -1198,8 +1189,8 @@ int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer
881
882 /* generate shared-secret */
883 li_MD5_Init(&Md5Ctx);
884- li_MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1);
885- li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
886+ li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(fn));
887+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN("+"));
888
889 /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
890 li_itostr(hh, srv->cur_ts);
891diff --git a/src/http_chunk.c b/src/http_chunk.c
892index dd6a043..79e4586 100644
893--- a/src/http_chunk.c
894+++ b/src/http_chunk.c
895@@ -42,8 +42,7 @@ static void http_chunk_append_len(server *srv, connection *con, size_t len) {
896 b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
897 len >>= 4;
898 }
899- b->used = i;
900- b->ptr[b->used++] = '\0';
901+ buffer_commit(b, i);
902
903 buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
904 }
905@@ -82,7 +81,7 @@ void http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
906 cq = con->write_queue;
907
908 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
909- http_chunk_append_len(srv, con, mem->used - 1);
910+ http_chunk_append_len(srv, con, buffer_string_length(mem));
911 }
912
913 chunkqueue_append_buffer(cq, mem);
914diff --git a/src/log.c b/src/log.c
915index 097e59e..6c9c38d 100644
916--- a/src/log.c
917+++ b/src/log.c
918@@ -333,8 +333,7 @@ static int log_buffer_prepare(buffer *b, server *srv, const char *filename, unsi
919 /* cache the generated timestamp */
920 if (srv->cur_ts != srv->last_generated_debug_ts) {
921 buffer_string_prepare_copy(srv->ts_debug_str, 255);
922- strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
923- srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1;
924+ buffer_append_strftime(srv->ts_debug_str, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
925
926 srv->last_generated_debug_ts = srv->cur_ts;
927 }
928@@ -362,8 +361,7 @@ static void log_write(server *srv, buffer *b) {
929 case ERRORLOG_FILE:
930 case ERRORLOG_FD:
931 buffer_append_string_len(b, CONST_STR_LEN("\n"));
932- force_assert(b->used > 0);
933- write(srv->errorlog_fd, b->ptr, b->used - 1);
934+ write(srv->errorlog_fd, CONST_BUF_LEN(b));
935 break;
936 case ERRORLOG_SYSLOG:
937 syslog(LOG_ERR, "%s", b->ptr);
938@@ -387,11 +385,11 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const
939
940 int log_error_write_multiline_buffer(server *srv, const char *filename, unsigned int line, buffer *multiline, const char *fmt, ...) {
941 va_list ap;
942- size_t prefix_used;
943+ size_t prefix_len;
944 buffer *b = srv->errorlog_buf;
945 char *pos, *end, *current_line;
946
947- if (multiline->used < 2) return 0;
948+ if (buffer_string_is_empty(multiline)) return 0;
949
950 if (-1 == log_buffer_prepare(b, srv, filename, line)) return 0;
951
952@@ -399,20 +397,19 @@ int log_error_write_multiline_buffer(server *srv, const char *filename, unsigned
953 log_buffer_append_printf(b, fmt, ap);
954 va_end(ap);
955
956- prefix_used = b->used;
957+ prefix_len = buffer_string_length(b);
958
959 current_line = pos = multiline->ptr;
960- end = multiline->ptr + multiline->used;
961+ end = multiline->ptr + buffer_string_length(multiline);
962
963- for ( ; pos < end ; ++pos) {
964+ for ( ; pos <= end ; ++pos) {
965 switch (*pos) {
966 case '\n':
967 case '\r':
968 case '\0': /* handles end of string */
969 if (current_line < pos) {
970 /* truncate to prefix */
971- b->used = prefix_used;
972- b->ptr[b->used - 1] = '\0';
973+ buffer_string_set_length(b, prefix_len);
974
975 buffer_append_string_len(b, current_line, pos - current_line);
976 log_write(srv, b);
977diff --git a/src/mod_access.c b/src/mod_access.c
978index 7b88e19..a6c25a4 100644
979--- a/src/mod_access.c
980+++ b/src/mod_access.c
981@@ -125,11 +125,11 @@ URIHANDLER_FUNC(mod_access_uri_handler) {
982 int s_len;
983 size_t k;
984
985- if (con->uri.path->used == 0) return HANDLER_GO_ON;
986+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
987
988 mod_access_patch_connection(srv, con, p);
989
990- s_len = con->uri.path->used - 1;
991+ s_len = buffer_string_length(con->uri.path);
992
993 if (con->conf.log_request_handling) {
994 log_error_write(srv, __FILE__, __LINE__, "s",
995@@ -138,12 +138,12 @@ URIHANDLER_FUNC(mod_access_uri_handler) {
996
997 for (k = 0; k < p->conf.access_deny->used; k++) {
998 data_string *ds = (data_string *)p->conf.access_deny->data[k];
999- int ct_len = ds->value->used - 1;
1000+ int ct_len = buffer_string_length(ds->value);
1001 int denied = 0;
1002
1003
1004 if (ct_len > s_len) continue;
1005- if (ds->value->used == 0) continue;
1006+ if (buffer_is_empty(ds->value)) continue;
1007
1008 /* if we have a case-insensitive FS we have to lower-case the URI here too */
1009
1010diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
1011index 20d52b9..9bb3fe2 100644
1012--- a/src/mod_accesslog.c
1013+++ b/src/mod_accesslog.c
1014@@ -223,9 +223,9 @@ static void accesslog_append_escaped(buffer *dest, buffer *str) {
1015 static int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
1016 size_t i, j, k = 0, start = 0;
1017
1018- if (format->used == 0) return -1;
1019+ if (buffer_is_empty(format)) return -1;
1020
1021- for (i = 0; i < format->used - 1; i++) {
1022+ for (i = 0; i < buffer_string_length(format); i++) {
1023 switch(format->ptr[i]) {
1024 case '%':
1025 if (i > 0 && start != i) {
1026@@ -297,11 +297,11 @@ static int accesslog_parse_format(server *srv, format_fields *fields, buffer *fo
1027 case '{':
1028 /* go forward to } */
1029
1030- for (k = i+2; k < format->used - 1; k++) {
1031+ for (k = i+2; k < buffer_string_length(format); k++) {
1032 if (format->ptr[k] == '}') break;
1033 }
1034
1035- if (k == format->used - 1) {
1036+ if (k == buffer_string_length(format)) {
1037 log_error_write(srv, __FILE__, __LINE__, "s", "%{ has to be terminated by a }");
1038 return -1;
1039 }
1040@@ -416,9 +416,9 @@ FREE_FUNC(mod_accesslog_free) {
1041
1042 if (!s) continue;
1043
1044- if (s->access_logbuffer->used) {
1045+ if (!buffer_string_is_empty(s->access_logbuffer)) {
1046 if (s->log_access_fd != -1) {
1047- write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
1048+ write(s->log_access_fd, CONST_BUF_LEN(s->access_logbuffer));
1049 }
1050 }
1051
1052@@ -502,7 +502,7 @@ SETDEFAULTS_FUNC(log_access_open) {
1053
1054 /* parse */
1055
1056- if (s->format->used) {
1057+ if (!buffer_is_empty(s->format)) {
1058 size_t j, count;
1059
1060 s->parsed_format = calloc(1, sizeof(*(s->parsed_format)));
1061@@ -572,7 +572,7 @@ SETDEFAULTS_FUNC(log_access_open) {
1062 continue;
1063 }
1064
1065- if (s->access_logfile->used < 2) continue;
1066+ if (buffer_string_is_empty(s->access_logfile)) continue;
1067
1068 if (-1 == (s->log_access_fd = open_logfile_or_pipe(srv, s->access_logfile->ptr)))
1069 return HANDLER_ERROR;
1070@@ -591,17 +591,17 @@ SIGHUP_FUNC(log_access_cycle) {
1071 for (i = 0; i < srv->config_context->used; i++) {
1072 plugin_config *s = p->config_storage[i];
1073
1074- if (s->access_logbuffer->used) {
1075+ if (!buffer_string_is_empty(s->access_logbuffer)) {
1076 if (s->log_access_fd != -1) {
1077- write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
1078+ write(s->log_access_fd, CONST_BUF_LEN(s->access_logbuffer));
1079 }
1080
1081 buffer_reset(s->access_logbuffer);
1082 }
1083
1084- if (s->use_syslog == 0 &&
1085- s->access_logfile->used > 1 &&
1086- s->access_logfile->ptr[0] != '|') {
1087+ if (s->use_syslog == 0
1088+ && !buffer_string_is_empty(s->access_logfile)
1089+ && s->access_logfile->ptr[0] != '|') {
1090
1091 if (-1 != s->log_access_fd) close(s->log_access_fd);
1092
1093@@ -691,8 +691,8 @@ REQUESTDONE_FUNC(log_access_write) {
1094 b = p->conf.access_logbuffer;
1095 }
1096
1097- if (b->used == 0) {
1098- buffer_copy_string_len(b, CONST_STR_LEN(""));
1099+ if (buffer_is_empty(b)) {
1100+ buffer_string_set_length(b, 0);
1101 }
1102
1103 for (j = 0; j < p->conf.parsed_format->used; j++) {
1104@@ -715,11 +715,10 @@ REQUESTDONE_FUNC(log_access_write) {
1105 #if defined(HAVE_STRUCT_TM_GMTOFF)
1106 # ifdef HAVE_LOCALTIME_R
1107 localtime_r(&(srv->cur_ts), &tm);
1108- strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, &tm);
1109+ buffer_append_strftime(p->conf.ts_accesslog_str, p->conf.ts_accesslog_fmt_str->ptr, &tm);
1110 # else /* HAVE_LOCALTIME_R */
1111- strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, localtime_r(&(srv->cur_ts)));
1112+ buffer_append_strftime(p->conf.ts_accesslog_str, p->conf.ts_accesslog_fmt_str->ptr, localtime(&(srv->cur_ts)));
1113 # endif /* HAVE_LOCALTIME_R */
1114- p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
1115
1116 if (p->conf.append_tz_offset) {
1117 buffer_append_string_len(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-", 1);
1118@@ -739,11 +738,10 @@ REQUESTDONE_FUNC(log_access_write) {
1119 #else /* HAVE_STRUCT_TM_GMTOFF */
1120 # ifdef HAVE_GMTIME_R
1121 gmtime_r(&(srv->cur_ts), &tm);
1122- strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, &tm);
1123+ buffer_append_strftime(p->conf.ts_accesslog_str, p->conf.ts_accesslog_fmt_str->ptr, &tm);
1124 # else /* HAVE_GMTIME_R */
1125- strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, gmtime(&(srv->cur_ts)));
1126+ buffer_append_strftime(p->conf.ts_accesslog_str, p->conf.ts_accesslog_fmt_str->ptr, gmtime(&(srv->cur_ts)));
1127 # endif /* HAVE_GMTIME_R */
1128- p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
1129 #endif /* HAVE_STRUCT_TM_GMTOFF */
1130
1131 *(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts;
1132@@ -765,14 +763,14 @@ REQUESTDONE_FUNC(log_access_write) {
1133 buffer_append_string_len(b, CONST_STR_LEN("-"));
1134 break;
1135 case FORMAT_REMOTE_USER:
1136- if (NULL != (ds = (data_string *)array_get_element(con->environment, "REMOTE_USER")) && ds->value->used > 1) {
1137+ if (NULL != (ds = (data_string *)array_get_element(con->environment, "REMOTE_USER")) && !buffer_string_is_empty(ds->value)) {
1138 accesslog_append_escaped(b, ds->value);
1139 } else {
1140 buffer_append_string_len(b, CONST_STR_LEN("-"));
1141 }
1142 break;
1143 case FORMAT_REQUEST_LINE:
1144- if (con->request.request_line->used) {
1145+ if (!buffer_string_is_empty(con->request.request_line)) {
1146 accesslog_append_escaped(b, con->request.request_line);
1147 }
1148 break;
1149@@ -810,7 +808,7 @@ REQUESTDONE_FUNC(log_access_write) {
1150 }
1151 break;
1152 case FORMAT_FILENAME:
1153- if (con->physical.path->used > 1) {
1154+ if (!buffer_string_is_empty(con->physical.path)) {
1155 buffer_append_string_buffer(b, con->physical.path);
1156 } else {
1157 buffer_append_string_len(b, CONST_STR_LEN("-"));
1158@@ -834,14 +832,14 @@ REQUESTDONE_FUNC(log_access_write) {
1159 buffer_append_int(b, srv->cur_ts - con->request_start);
1160 break;
1161 case FORMAT_SERVER_NAME:
1162- if (con->server_name->used > 1) {
1163+ if (!buffer_string_is_empty(con->server_name)) {
1164 buffer_append_string_buffer(b, con->server_name);
1165 } else {
1166 buffer_append_string_len(b, CONST_STR_LEN("-"));
1167 }
1168 break;
1169 case FORMAT_HTTP_HOST:
1170- if (con->uri.authority->used > 1) {
1171+ if (!buffer_string_is_empty(con->uri.authority)) {
1172 accesslog_append_escaped(b, con->uri.authority);
1173 } else {
1174 buffer_append_string_len(b, CONST_STR_LEN("-"));
1175@@ -849,7 +847,7 @@ REQUESTDONE_FUNC(log_access_write) {
1176 break;
1177 case FORMAT_REQUEST_PROTOCOL:
1178 buffer_append_string_len(b,
1179- con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0", 8);
1180+ con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0", 8);
1181 break;
1182 case FORMAT_REQUEST_METHOD:
1183 buffer_append_string(b, get_http_method_name(con->request.http_method));
1184@@ -904,19 +902,19 @@ REQUESTDONE_FUNC(log_access_write) {
1185 buffer_append_string_len(b, CONST_STR_LEN("\n"));
1186
1187 if (p->conf.use_syslog || /* syslog doesn't cache */
1188- (p->conf.access_logfile->used && p->conf.access_logfile->ptr[0] == '|') || /* pipes don't cache */
1189+ (!buffer_string_is_empty(p->conf.access_logfile) && p->conf.access_logfile->ptr[0] == '|') || /* pipes don't cache */
1190 newts ||
1191- b->used > BUFFER_MAX_REUSE_SIZE) {
1192+ buffer_string_length(b) >= BUFFER_MAX_REUSE_SIZE) {
1193 if (p->conf.use_syslog) {
1194 #ifdef HAVE_SYSLOG_H
1195- if (b->used > 2) {
1196+ if (!buffer_string_is_empty(b)) {
1197 /* syslog appends a \n on its own */
1198- syslog(p->conf.syslog_level, "%*s", (int) b->used - 2, b->ptr);
1199+ buffer_string_set_length(b, buffer_string_length(b) - 1);
1200+ syslog(p->conf.syslog_level, "%s", b->ptr);
1201 }
1202 #endif
1203 } else if (p->conf.log_access_fd != -1) {
1204- force_assert(b->used > 0);
1205- write(p->conf.log_access_fd, b->ptr, b->used - 1);
1206+ write(p->conf.log_access_fd, CONST_BUF_LEN(b));
1207 }
1208 buffer_reset(b);
1209 }
1210diff --git a/src/mod_alias.c b/src/mod_alias.c
1211index bf22b5f..4625973 100644
1212--- a/src/mod_alias.c
1213+++ b/src/mod_alias.c
1214@@ -95,10 +95,10 @@ SETDEFAULTS_FUNC(mod_alias_set_defaults) {
1215 for (k = j + 1; k < a->used; k ++) {
1216 const buffer *key = a->data[a->sorted[k]]->key;
1217
1218- if (key->used < prefix->used) {
1219+ if (buffer_string_length(key) < buffer_string_length(prefix)) {
1220 break;
1221 }
1222- if (memcmp(key->ptr, prefix->ptr, prefix->used - 1) != 0) {
1223+ if (memcmp(key->ptr, prefix->ptr, buffer_string_length(prefix)) != 0) {
1224 break;
1225 }
1226 /* ok, they have same prefix. check position */
1227@@ -151,22 +151,22 @@ PHYSICALPATH_FUNC(mod_alias_physical_handler) {
1228 char *uri_ptr;
1229 size_t k;
1230
1231- if (con->physical.path->used == 0) return HANDLER_GO_ON;
1232+ if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
1233
1234 mod_alias_patch_connection(srv, con, p);
1235
1236 /* not to include the tailing slash */
1237- basedir_len = (con->physical.basedir->used - 1);
1238+ basedir_len = buffer_string_length(con->physical.basedir);
1239 if ('/' == con->physical.basedir->ptr[basedir_len-1]) --basedir_len;
1240- uri_len = con->physical.path->used - 1 - basedir_len;
1241+ uri_len = buffer_string_length(con->physical.path) - basedir_len;
1242 uri_ptr = con->physical.path->ptr + basedir_len;
1243
1244 for (k = 0; k < p->conf.alias->used; k++) {
1245 data_string *ds = (data_string *)p->conf.alias->data[k];
1246- int alias_len = ds->key->used - 1;
1247+ int alias_len = buffer_string_length(ds->key);
1248
1249 if (alias_len > uri_len) continue;
1250- if (ds->key->used == 0) continue;
1251+ if (buffer_is_empty(ds->key)) continue;
1252
1253 if (0 == (con->conf.force_lowercase_filenames ?
1254 strncasecmp(uri_ptr, ds->key->ptr, alias_len) :
1255diff --git a/src/mod_auth.c b/src/mod_auth.c
1256index d5a3f1c..1870893 100644
1257--- a/src/mod_auth.c
1258+++ b/src/mod_auth.c
1259@@ -206,18 +206,18 @@ static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
1260 for (k = 0; k < p->conf.auth_require->used; k++) {
1261 buffer *require = p->conf.auth_require->data[k]->key;
1262
1263- if (require->used == 0) continue;
1264- if (con->uri.path->used < require->used) continue;
1265+ if (buffer_is_empty(require)) continue;
1266+ if (buffer_string_length(con->uri.path) < buffer_string_length(require)) continue;
1267
1268 /* if we have a case-insensitive FS we have to lower-case the URI here too */
1269
1270 if (con->conf.force_lowercase_filenames) {
1271- if (0 == strncasecmp(con->uri.path->ptr, require->ptr, require->used - 1)) {
1272+ if (0 == strncasecmp(con->uri.path->ptr, require->ptr, buffer_string_length(require))) {
1273 auth_required = 1;
1274 break;
1275 }
1276 } else {
1277- if (0 == strncmp(con->uri.path->ptr, require->ptr, require->used - 1)) {
1278+ if (0 == strncmp(con->uri.path->ptr, require->ptr, buffer_string_length(require))) {
1279 auth_required = 1;
1280 break;
1281 }
1282@@ -248,7 +248,7 @@ static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
1283
1284 /* try to get Authorization-header */
1285
1286- if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization")) && ds->value->used) {
1287+ if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization")) && !buffer_is_empty(ds->value)) {
1288 char *auth_realm;
1289
1290 http_authorization = ds->value->ptr;
1291@@ -419,7 +419,7 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) {
1292 return HANDLER_ERROR;
1293 }
1294
1295- if (s->auth_backend_conf->used) {
1296+ if (!buffer_string_is_empty(s->auth_backend_conf)) {
1297 if (0 == strcmp(s->auth_backend_conf->ptr, "htpasswd")) {
1298 s->auth_backend = AUTH_BACKEND_HTPASSWD;
1299 } else if (0 == strcmp(s->auth_backend_conf->ptr, "htdigest")) {
1300@@ -436,7 +436,7 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) {
1301 }
1302
1303 #ifdef USE_LDAP
1304- if (s->auth_ldap_filter->used) {
1305+ if (!buffer_string_is_empty(s->auth_ldap_filter)) {
1306 char *dollar;
1307
1308 /* parse filter */
1309@@ -562,7 +562,7 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) {
1310 }
1311 }
1312
1313- switch(s->auth_ldap_hostname->used) {
1314+ switch(s->auth_backend) {
1315 case AUTH_BACKEND_LDAP: {
1316 handler_t ret = auth_ldap_init(srv, s);
1317 if (ret == HANDLER_ERROR)
1318@@ -588,7 +588,7 @@ handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
1319 }
1320 #endif
1321
1322- if (s->auth_ldap_hostname->used) {
1323+ if (!buffer_string_is_empty(s->auth_ldap_hostname)) {
1324 /* free old context */
1325 if (NULL != s->ldap) ldap_unbind_s(s->ldap);
1326
1327@@ -627,7 +627,7 @@ handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
1328
1329
1330 /* 1. */
1331- if (s->auth_ldap_binddn->used) {
1332+ if (!buffer_string_is_empty(s->auth_ldap_binddn)) {
1333 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) {
1334 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
1335
1336diff --git a/src/mod_cgi.c b/src/mod_cgi.c
1337index f132b8a..8a7cc2b 100644
1338--- a/src/mod_cgi.c
1339+++ b/src/mod_cgi.c
1340@@ -376,8 +376,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
1341 return FDEVENT_HANDLED_FINISHED;
1342 }
1343
1344- hctx->response->ptr[n] = '\0';
1345- hctx->response->used = n+1;
1346+ buffer_commit(hctx->response, n);
1347
1348 /* split header from body */
1349
1350@@ -385,7 +384,7 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
1351 int is_header = 0;
1352 int is_header_end = 0;
1353 size_t last_eol = 0;
1354- size_t i;
1355+ size_t i, header_len;
1356
1357 buffer_append_string_buffer(hctx->response_header, hctx->response);
1358
1359@@ -412,8 +411,9 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
1360
1361 /* nph (non-parsed headers) */
1362 if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) is_header = 1;
1363-
1364- for (i = 0; !is_header_end && i < hctx->response_header->used - 1; i++) {
1365+
1366+ header_len = buffer_string_length(hctx->response_header);
1367+ for (i = 0; !is_header_end && i < header_len; i++) {
1368 char c = hctx->response_header->ptr[i];
1369
1370 switch (c) {
1371@@ -463,26 +463,25 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
1372 } else {
1373 const char *bstart;
1374 size_t blen;
1375-
1376+
1377+ /* the body starts after the EOL */
1378+ bstart = hctx->response_header->ptr + i;
1379+ blen = header_len - i;
1380+
1381 /**
1382 * i still points to the char after the terminating EOL EOL
1383 *
1384 * put it on the last \n again
1385 */
1386 i--;
1387-
1388- /* the body starts after the EOL */
1389- bstart = hctx->response_header->ptr + (i + 1);
1390- blen = (hctx->response_header->used - 1) - (i + 1);
1391-
1392+
1393 /* string the last \r?\n */
1394 if (i > 0 && (hctx->response_header->ptr[i - 1] == '\r')) {
1395 i--;
1396 }
1397
1398- hctx->response_header->ptr[i] = '\0';
1399- hctx->response_header->used = i + 1; /* the string + \0 */
1400-
1401+ buffer_string_set_length(hctx->response_header, i);
1402+
1403 /* parse the response header */
1404 cgi_response_parse(srv, con, p, hctx->response_header);
1405
1406@@ -738,7 +737,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
1407
1408 #ifndef __WIN32
1409
1410- if (cgi_handler->used > 1) {
1411+ if (!buffer_string_is_empty(cgi_handler)) {
1412 /* stat the exec file */
1413 if (-1 == (stat(cgi_handler->ptr, &st))) {
1414 log_error_write(srv, __FILE__, __LINE__, "sbss",
1415@@ -800,7 +799,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
1416 }
1417
1418 if (!buffer_string_is_empty(con->server_name)) {
1419- size_t len = con->server_name->used - 1;
1420+ size_t len = buffer_string_length(con->server_name);
1421
1422 if (con->server_name->ptr[0] == '[') {
1423 const char *colon = strstr(con->server_name->ptr, "]:");
1424@@ -938,7 +937,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
1425
1426 ds = (data_string *)con->request.headers->data[n];
1427
1428- if (ds->value->used && ds->key->used) {
1429+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
1430 buffer_copy_string_encoded_cgi_varnames(p->tmp_buf, CONST_BUF_LEN(ds->key), 1);
1431
1432 cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
1433@@ -950,7 +949,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
1434
1435 ds = (data_string *)con->environment->data[n];
1436
1437- if (ds->value->used && ds->key->used) {
1438+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
1439 buffer_copy_string_encoded_cgi_varnames(p->tmp_buf, CONST_BUF_LEN(ds->key), 0);
1440
1441 cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
1442@@ -969,7 +968,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
1443 args = malloc(sizeof(*args) * argc);
1444 i = 0;
1445
1446- if (cgi_handler->used > 1) {
1447+ if (!buffer_string_is_empty(cgi_handler)) {
1448 args[i++] = cgi_handler->ptr;
1449 }
1450 args[i++] = con->physical.path->ptr;
1451@@ -1071,7 +1070,7 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
1452 }
1453 break;
1454 case MEM_CHUNK:
1455- if ((r = write(to_cgi_fds[1], c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
1456+ if ((r = write(to_cgi_fds[1], c->mem->ptr + c->offset, buffer_string_length(c->mem) - c->offset)) < 0) {
1457 switch(errno) {
1458 case ENOSPC:
1459 con->http_status = 507;
1460@@ -1185,7 +1184,7 @@ URIHANDLER_FUNC(cgi_is_handled) {
1461
1462 if (con->mode != DIRECT) return HANDLER_GO_ON;
1463
1464- if (fn->used == 0) return HANDLER_GO_ON;
1465+ if (buffer_is_empty(fn)) return HANDLER_GO_ON;
1466
1467 mod_cgi_patch_connection(srv, con, p);
1468
1469@@ -1193,13 +1192,13 @@ URIHANDLER_FUNC(cgi_is_handled) {
1470 if (!S_ISREG(sce->st.st_mode)) return HANDLER_GO_ON;
1471 if (p->conf.execute_x_only == 1 && (sce->st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) return HANDLER_GO_ON;
1472
1473- s_len = fn->used - 1;
1474+ s_len = buffer_string_length(fn);
1475
1476 for (k = 0; k < p->conf.cgi->used; k++) {
1477 data_string *ds = (data_string *)p->conf.cgi->data[k];
1478- size_t ct_len = ds->key->used - 1;
1479+ size_t ct_len = buffer_string_length(ds->key);
1480
1481- if (ds->key->used == 0) continue;
1482+ if (buffer_is_empty(ds->key)) continue;
1483 if (s_len < ct_len) continue;
1484
1485 if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) {
1486diff --git a/src/mod_cml.c b/src/mod_cml.c
1487index 3033d42..baa23b3 100644
1488--- a/src/mod_cml.c
1489+++ b/src/mod_cml.c
1490@@ -185,20 +185,18 @@ static int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *
1491 /* cleanup basedir */
1492 b = p->baseurl;
1493 buffer_copy_buffer(b, con->uri.path);
1494- for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
1495+ for (c = b->ptr + buffer_string_length(b); c > b->ptr && *c != '/'; c--);
1496
1497 if (*c == '/') {
1498- b->used = c - b->ptr + 2;
1499- *(c+1) = '\0';
1500+ buffer_string_set_length(b, c - b->ptr + 1);
1501 }
1502
1503 b = p->basedir;
1504 buffer_copy_buffer(b, con->physical.path);
1505- for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
1506+ for (c = b->ptr + buffer_string_length(b); c > b->ptr && *c != '/'; c--);
1507
1508 if (*c == '/') {
1509- b->used = c - b->ptr + 2;
1510- *(c+1) = '\0';
1511+ buffer_string_set_length(b, c - b->ptr + 1);
1512 }
1513
1514
1515@@ -274,7 +272,7 @@ URIHANDLER_FUNC(mod_cml_is_handled) {
1516
1517 if (buffer_string_is_empty(p->conf.ext)) return HANDLER_GO_ON;
1518
1519- if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, p->conf.ext->used - 1)) {
1520+ if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, buffer_string_length(p->conf.ext))) {
1521 return HANDLER_GO_ON;
1522 }
1523
1524diff --git a/src/mod_cml_funcs.c b/src/mod_cml_funcs.c
1525index 9d859c7..a377edd 100644
1526--- a/src/mod_cml_funcs.c
1527+++ b/src/mod_cml_funcs.c
1528@@ -35,14 +35,9 @@ typedef char HASHHEX[HASHHEXLEN+1];
1529 int f_crypto_md5(lua_State *L) {
1530 li_MD5_CTX Md5Ctx;
1531 HASH HA1;
1532- buffer b;
1533 char hex[33];
1534 int n = lua_gettop(L);
1535
1536- b.ptr = hex;
1537- b.used = 0;
1538- b.size = sizeof(hex);
1539-
1540 if (n != 1) {
1541 lua_pushstring(L, "md5: expected one argument");
1542 lua_error(L);
1543@@ -57,9 +52,9 @@ int f_crypto_md5(lua_State *L) {
1544 li_MD5_Update(&Md5Ctx, (unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1));
1545 li_MD5_Final(HA1, &Md5Ctx);
1546
1547- buffer_copy_string_hex(&b, (char *)HA1, 16);
1548+ li_tohex(hex, (const char*) HA1, 16);
1549
1550- lua_pushstring(L, b.ptr);
1551+ lua_pushstring(L, hex);
1552
1553 return 1;
1554 }
1555diff --git a/src/mod_cml_lua.c b/src/mod_cml_lua.c
1556index 63dd1e7..895a709 100644
1557--- a/src/mod_cml_lua.c
1558+++ b/src/mod_cml_lua.c
1559@@ -102,13 +102,14 @@ static int c_to_lua_push(lua_State *L, int tbl, const char *key, size_t key_len,
1560
1561 static int cache_export_get_params(lua_State *L, int tbl, buffer *qrystr) {
1562 size_t is_key = 1;
1563- size_t i;
1564+ size_t i, len;
1565 char *key = NULL, *val = NULL;
1566
1567 key = qrystr->ptr;
1568
1569 /* we need the \0 */
1570- for (i = 0; i < qrystr->used; i++) {
1571+ len = buffer_string_length(qrystr);
1572+ for (i = 0; i <= len; i++) {
1573 switch(qrystr->ptr[i]) {
1574 case '=':
1575 if (is_key) {
1576@@ -129,8 +130,8 @@ static int cache_export_get_params(lua_State *L, int tbl, buffer *qrystr) {
1577 qrystr->ptr[i] = '\0';
1578
1579 c_to_lua_push(L, tbl,
1580- key, strlen(key),
1581- val, strlen(val));
1582+ key, strlen(key),
1583+ val, strlen(val));
1584 }
1585
1586 key = qrystr->ptr + i + 1;
1587@@ -398,7 +399,6 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
1588 if (ret == 0) {
1589 data_string *ds;
1590 char timebuf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
1591- buffer tbuf;
1592
1593 con->file_finished = 1;
1594
1595@@ -411,17 +411,11 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
1596 strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&mtime));
1597
1598 response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), timebuf, sizeof(timebuf) - 1);
1599-
1600- tbuf.ptr = timebuf;
1601- tbuf.used = sizeof(timebuf);
1602- tbuf.size = sizeof(timebuf);
1603- } else {
1604- tbuf.ptr = ds->value->ptr;
1605- tbuf.used = ds->value->used;
1606- tbuf.size = ds->value->size;
1607+ ds = (data_string *)array_get_element(con->response.headers, "Last-Modified");
1608+ force_assert(NULL != ds);
1609 }
1610
1611- if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, &tbuf)) {
1612+ if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, ds->value)) {
1613 /* ok, the client already has our content,
1614 * no need to send it again */
1615
1616diff --git a/src/mod_compress.c b/src/mod_compress.c
1617index 120b379..f0ffa1c 100644
1618--- a/src/mod_compress.c
1619+++ b/src/mod_compress.c
1620@@ -244,6 +244,7 @@ static int deflate_file_to_buffer_gzip(server *srv, connection *con, plugin_data
1621 unsigned char *c;
1622 unsigned long crc;
1623 z_stream z;
1624+ size_t outlen;
1625
1626 UNUSED(srv);
1627 UNUSED(con);
1628@@ -282,9 +283,9 @@ static int deflate_file_to_buffer_gzip(server *srv, connection *con, plugin_data
1629 c[8] = 0x00; /* extra flags */
1630 c[9] = 0x03; /* UNIX */
1631
1632- p->b->used = 10;
1633- z.next_out = (unsigned char *)p->b->ptr + p->b->used;
1634- z.avail_out = p->b->size - p->b->used - 9;
1635+ outlen = 10;
1636+ z.next_out = (unsigned char *)p->b->ptr + outlen;
1637+ z.avail_out = p->b->size - outlen - 9;
1638 z.total_out = 0;
1639
1640 if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
1641@@ -293,11 +294,11 @@ static int deflate_file_to_buffer_gzip(server *srv, connection *con, plugin_data
1642 }
1643
1644 /* trailer */
1645- p->b->used += z.total_out;
1646+ outlen += z.total_out;
1647
1648 crc = generate_crc32c(start, st_size);
1649
1650- c = (unsigned char *)p->b->ptr + p->b->used;
1651+ c = (unsigned char *)p->b->ptr + outlen;
1652
1653 c[0] = (crc >> 0) & 0xff;
1654 c[1] = (crc >> 8) & 0xff;
1655@@ -307,8 +308,8 @@ static int deflate_file_to_buffer_gzip(server *srv, connection *con, plugin_data
1656 c[5] = (z.total_in >> 8) & 0xff;
1657 c[6] = (z.total_in >> 16) & 0xff;
1658 c[7] = (z.total_in >> 24) & 0xff;
1659- p->b->used += 8;
1660- p->b->ptr[p->b->used++] = '\0';
1661+ outlen += 8;
1662+ buffer_commit(p->b, outlen);
1663
1664 if (Z_OK != deflateEnd(&z)) {
1665 return -1;
1666@@ -398,16 +399,15 @@ static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_dat
1667 return -1;
1668 }
1669
1670+ if (BZ_OK != BZ2_bzCompressEnd(&bz)) {
1671+ return -1;
1672+ }
1673+
1674 /* file is too large for now */
1675 if (bz.total_out_hi32) return -1;
1676
1677 /* trailer */
1678- p->b->used = bz.total_out_lo32;
1679- p->b->ptr[p->b->used++] = '\0';
1680-
1681- if (BZ_OK != BZ2_bzCompressEnd(&bz)) {
1682- return -1;
1683- }
1684+ buffer_commit(p->b, bz.total_out_lo32);
1685
1686 return 0;
1687 }
1688@@ -434,8 +434,8 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
1689 buffer_copy_buffer(p->ofn, p->conf.compress_cache_dir);
1690 buffer_append_slash(p->ofn);
1691
1692- if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) {
1693- buffer_append_string(p->ofn, con->physical.path->ptr + con->physical.doc_root->used - 1);
1694+ if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, buffer_string_length(con->physical.doc_root))) {
1695+ buffer_append_string(p->ofn, con->physical.path->ptr + buffer_string_length(con->physical.doc_root));
1696 } else {
1697 buffer_append_string_buffer(p->ofn, con->uri.path);
1698 }
1699@@ -883,7 +883,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
1700 }
1701
1702 /* deflate it */
1703- if (use_etag && p->conf.compress_cache_dir->used) {
1704+ if (use_etag && !buffer_string_is_empty(p->conf.compress_cache_dir)) {
1705 if (0 != deflate_file_to_file(srv, con, p, con->physical.path, sce, compression_type))
1706 return HANDLER_GO_ON;
1707 } else {
1708@@ -897,7 +897,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
1709 }
1710 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
1711 /* let mod_staticfile handle the cached compressed files, physical path was modified */
1712- return (use_etag && p->conf.compress_cache_dir->used) ? HANDLER_GO_ON : HANDLER_FINISHED;
1713+ return (use_etag && !buffer_string_is_empty(p->conf.compress_cache_dir)) ? HANDLER_GO_ON : HANDLER_FINISHED;
1714 }
1715 }
1716 }
1717diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
1718index e2e0bfa..d8bf3a3 100644
1719--- a/src/mod_dirlisting.c
1720+++ b/src/mod_dirlisting.c
1721@@ -492,7 +492,7 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
1722 buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
1723 buffer_append_string_len(out, CONST_STR_LEN("</title>\n"));
1724
1725- if (p->conf.external_css->used > 1) {
1726+ if (!buffer_string_is_empty(p->conf.external_css)) {
1727 buffer_append_string_len(out, CONST_STR_LEN("<link rel=\"stylesheet\" type=\"text/css\" href=\""));
1728 buffer_append_string_buffer(out, p->conf.external_css);
1729 buffer_append_string_len(out, CONST_STR_LEN("\" />\n"));
1730@@ -614,7 +614,7 @@ static void http_list_directory_footer(server *srv, connection *con, plugin_data
1731 "<div class=\"foot\">"
1732 ));
1733
1734- if (p->conf.set_footer->used > 1) {
1735+ if (buffer_string_is_empty(p->conf.set_footer)) {
1736 buffer_append_string_buffer(out, p->conf.set_footer);
1737 } else if (buffer_is_empty(con->conf.server_tag)) {
1738 buffer_append_string_len(out, CONST_STR_LEN(PACKAGE_DESC));
1739@@ -653,9 +653,9 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
1740 struct tm tm;
1741 #endif
1742
1743- if (dir->used == 0) return -1;
1744+ if (buffer_string_is_empty(dir)) return -1;
1745
1746- i = dir->used - 1;
1747+ i = buffer_string_length(dir);
1748
1749 #ifdef HAVE_PATHCONF
1750 if (0 >= (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) {
1751@@ -672,8 +672,8 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
1752 name_max = NAME_MAX;
1753 #endif
1754
1755- path = malloc(dir->used + name_max);
1756- force_assert(path);
1757+ path = malloc(buffer_string_length(dir) + name_max + 1);
1758+ force_assert(NULL != path);
1759 strcpy(path, dir->ptr);
1760 path_file = path + i;
1761
1762@@ -846,10 +846,10 @@ static int http_list_directory(server *srv, connection *con, plugin_data *p, buf
1763 data_string *ds = (data_string *)con->conf.mimetypes->data[k];
1764 size_t ct_len;
1765
1766- if (ds->key->used == 0)
1767+ if (buffer_is_empty(ds->key))
1768 continue;
1769
1770- ct_len = ds->key->used - 1;
1771+ ct_len = buffer_string_length(ds->key);
1772 if (tmp->namelen < ct_len)
1773 continue;
1774
1775@@ -925,9 +925,9 @@ URIHANDLER_FUNC(mod_dirlisting_subrequest) {
1776
1777 if (con->mode != DIRECT) return HANDLER_GO_ON;
1778
1779- if (con->physical.path->used == 0) return HANDLER_GO_ON;
1780- if (con->uri.path->used == 0) return HANDLER_GO_ON;
1781- if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
1782+ if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
1783+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
1784+ if (con->uri.path->ptr[buffer_string_length(con->uri.path) - 1] != '/') return HANDLER_GO_ON;
1785
1786 mod_dirlisting_patch_connection(srv, con, p);
1787
1788diff --git a/src/mod_evasive.c b/src/mod_evasive.c
1789index a20aff5..d9b8732 100644
1790--- a/src/mod_evasive.c
1791+++ b/src/mod_evasive.c
1792@@ -138,7 +138,7 @@ URIHANDLER_FUNC(mod_evasive_uri_handler) {
1793 size_t conns_by_ip = 0;
1794 size_t j;
1795
1796- if (con->uri.path->used == 0) return HANDLER_GO_ON;
1797+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
1798
1799 mod_evasive_patch_connection(srv, con, p);
1800
1801diff --git a/src/mod_evhost.c b/src/mod_evhost.c
1802index 5281523..e728551 100644
1803--- a/src/mod_evhost.c
1804+++ b/src/mod_evhost.c
1805@@ -146,7 +146,7 @@ SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
1806 return HANDLER_ERROR;
1807 }
1808
1809- if (s->path_pieces_raw->used != 0) {
1810+ if (!buffer_string_is_empty(s->path_pieces_raw)) {
1811 mod_evhost_parse_pattern(s);
1812 }
1813 }
1814@@ -164,8 +164,7 @@ SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
1815 */
1816
1817 static int mod_evhost_parse_host(connection *con,array *host) {
1818- /* con->uri.authority->used is always > 0 if we come here */
1819- register char *ptr = con->uri.authority->ptr + con->uri.authority->used - 1;
1820+ register char *ptr = con->uri.authority->ptr + buffer_string_length(con->uri.authority);
1821 char *colon = ptr; /* needed to filter out the colon (if exists) */
1822 int first = 1;
1823 data_string *ds;
1824@@ -265,7 +264,7 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
1825 stat_cache_entry *sce = NULL;
1826
1827 /* not authority set */
1828- if (con->uri.authority->used == 0) return HANDLER_GO_ON;
1829+ if (buffer_string_is_empty(con->uri.authority)) return HANDLER_GO_ON;
1830
1831 mod_evhost_patch_connection(srv, con, p);
1832
1833@@ -300,9 +299,7 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
1834 buffer_append_string_len(p->tmp_buf, con->uri.authority->ptr, colon - con->uri.authority->ptr); /* adds fqdn */
1835 }
1836 } else if (NULL != (ds = (data_string *)array_get_element(parsed_host,p->conf.path_pieces[i]->ptr))) {
1837- if (ds->value->used) {
1838- buffer_append_string_buffer(p->tmp_buf,ds->value);
1839- }
1840+ buffer_append_string_buffer(p->tmp_buf,ds->value);
1841 } else {
1842 /* unhandled %-sequence */
1843 }
1844diff --git a/src/mod_expire.c b/src/mod_expire.c
1845index 31a81b7..e26c3c6 100644
1846--- a/src/mod_expire.c
1847+++ b/src/mod_expire.c
1848@@ -90,7 +90,7 @@ static int mod_expire_get_offset(server *srv, plugin_data *p, buffer *expire, ti
1849 * e.g. 'access 1 years'
1850 */
1851
1852- if (expire->used == 0) {
1853+ if (buffer_string_is_empty(expire)) {
1854 log_error_write(srv, __FILE__, __LINE__, "s",
1855 "empty:");
1856 return -1;
1857@@ -288,22 +288,21 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
1858 int s_len;
1859 size_t k;
1860
1861- if (con->uri.path->used == 0) return HANDLER_GO_ON;
1862+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
1863
1864 mod_expire_patch_connection(srv, con, p);
1865
1866- s_len = con->uri.path->used - 1;
1867+ s_len = buffer_string_length(con->uri.path);
1868
1869 for (k = 0; k < p->conf.expire_url->used; k++) {
1870 data_string *ds = (data_string *)p->conf.expire_url->data[k];
1871- int ct_len = ds->key->used - 1;
1872+ int ct_len = buffer_string_length(ds->key);
1873
1874 if (ct_len > s_len) continue;
1875- if (ds->key->used == 0) continue;
1876+ if (buffer_is_empty(ds->key)) continue;
1877
1878 if (0 == strncmp(con->uri.path->ptr, ds->key->ptr, ct_len)) {
1879 time_t ts, expires;
1880- size_t len;
1881 stat_cache_entry *sce = NULL;
1882
1883 /* if stat fails => sce == NULL, ignore return value */
1884@@ -332,14 +331,8 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
1885 /* expires should be at least srv->cur_ts */
1886 if (expires < srv->cur_ts) expires = srv->cur_ts;
1887
1888- if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1,
1889- "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(expires))))) {
1890- /* could not set expire header, out of mem */
1891-
1892- return HANDLER_GO_ON;
1893- }
1894-
1895- p->expire_tstmp->used = len + 1;
1896+ buffer_string_prepare_copy(p->expire_tstmp, 255);
1897+ buffer_append_strftime(p->expire_tstmp, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(expires)));
1898
1899 /* HTTP/1.0 */
1900 response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_BUF_LEN(p->expire_tstmp));
1901diff --git a/src/mod_extforward.c b/src/mod_extforward.c
1902index 99c4af5..7f77982 100644
1903--- a/src/mod_extforward.c
1904+++ b/src/mod_extforward.c
1905@@ -236,7 +236,7 @@ static void put_string_into_array_len(array *ary, const char *str, int len)
1906 static array *extract_forward_array(buffer *pbuffer)
1907 {
1908 array *result = array_init();
1909- if (pbuffer->used > 0) {
1910+ if (!buffer_string_is_empty(pbuffer)) {
1911 char *base, *curr;
1912 /* state variable, 0 means not in string, 1 means in string */
1913 int in_str = 0;
1914diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
1915index a935961..d16306c 100644
1916--- a/src/mod_fastcgi.c
1917+++ b/src/mod_fastcgi.c
1918@@ -784,7 +784,7 @@ static int parse_binpath(char_array *env, buffer *b) {
1919 /* search for spaces */
1920
1921 start = b->ptr;
1922- for (i = 0; i < b->used - 1; i++) {
1923+ for (i = 0; i < buffer_string_length(b); i++) {
1924 switch(b->ptr[i]) {
1925 case ' ':
1926 case '\t':
1927@@ -863,19 +863,19 @@ static int fcgi_spawn_connection(server *srv,
1928
1929 #ifdef HAVE_SYS_UN_H
1930 fcgi_addr_un.sun_family = AF_UNIX;
1931- if (proc->unixsocket->used > sizeof(fcgi_addr_un.sun_path)) {
1932+ if (buffer_string_length(proc->unixsocket) + 1 > sizeof(fcgi_addr_un.sun_path)) {
1933 log_error_write(srv, __FILE__, __LINE__, "sB",
1934 "ERROR: Unix Domain socket filename too long:",
1935 proc->unixsocket);
1936 return -1;
1937 }
1938- memcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr, proc->unixsocket->used);
1939+ memcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr, buffer_string_length(proc->unixsocket) + 1);
1940
1941 #ifdef SUN_LEN
1942 servlen = SUN_LEN(&fcgi_addr_un);
1943 #else
1944 /* stevens says: */
1945- servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
1946+ servlen = buffer_string_length(proc->unixsocket) + 1 + sizeof(fcgi_addr_un.sun_family);
1947 #endif
1948 socket_type = AF_UNIX;
1949 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
1950@@ -1324,7 +1324,7 @@ SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
1951 /* unix domain socket */
1952 struct sockaddr_un un;
1953
1954- if (host->unixsocket->used > sizeof(un.sun_path) - 2) {
1955+ if (buffer_string_length(host->unixsocket) + 1 > sizeof(un.sun_path) - 2) {
1956 log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
1957 "unixsocket is too long in:",
1958 da->key, "= (",
1959@@ -1667,19 +1667,19 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h
1960 #ifdef HAVE_SYS_UN_H
1961 /* use the unix domain socket */
1962 fcgi_addr_un.sun_family = AF_UNIX;
1963- if (proc->unixsocket->used > sizeof(fcgi_addr_un.sun_path)) {
1964+ if (buffer_string_length(proc->unixsocket) + 1 > sizeof(fcgi_addr_un.sun_path)) {
1965 log_error_write(srv, __FILE__, __LINE__, "sB",
1966 "ERROR: Unix Domain socket filename too long:",
1967 proc->unixsocket);
1968 return -1;
1969 }
1970- memcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr, proc->unixsocket->used);
1971+ memcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr, buffer_string_length(proc->unixsocket) + 1);
1972
1973 #ifdef SUN_LEN
1974 servlen = SUN_LEN(&fcgi_addr_un);
1975 #else
1976 /* stevens says: */
1977- servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
1978+ servlen = buffer_string_length(proc->unixsocket) + 1 + sizeof(fcgi_addr_un.sun_family);
1979 #endif
1980 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
1981
1982@@ -1774,7 +1774,7 @@ static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_dat
1983
1984 ds = (data_string *)con->request.headers->data[i];
1985
1986- if (ds->value->used && ds->key->used) {
1987+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
1988 buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 1);
1989
1990 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)),con);
1991@@ -1786,7 +1786,7 @@ static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_dat
1992
1993 ds = (data_string *)con->environment->data[i];
1994
1995- if (ds->value->used && ds->key->used) {
1996+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
1997 buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 0);
1998
1999 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)), con);
2000@@ -1833,8 +1833,8 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
2001 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag)),con)
2002 }
2003
2004- if (con->server_name->used) {
2005- size_t len = con->server_name->used - 1;
2006+ if (!buffer_is_empty(con->server_name)) {
2007+ size_t len = buffer_string_length(con->server_name);
2008
2009 if (con->server_name->ptr[0] == '[') {
2010 const char *colon = strstr(con->server_name->ptr, "]:");
2011@@ -1961,7 +1961,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
2012 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.basedir)),con)
2013 }
2014
2015- if (host->strip_request_uri->used > 1) {
2016+ if (!buffer_string_is_empty(host->strip_request_uri)) {
2017 /* we need at least one char to strip off */
2018 /**
2019 * /app1/index/list
2020@@ -1971,18 +1971,18 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
2021 * /index/list
2022 *
2023 */
2024- if ('/' != host->strip_request_uri->ptr[host->strip_request_uri->used - 2]) {
2025+ if ('/' != host->strip_request_uri->ptr[buffer_string_length(host->strip_request_uri) - 1]) {
2026 /* fix the user-input to have / as last char */
2027 buffer_append_string_len(host->strip_request_uri, CONST_STR_LEN("/"));
2028 }
2029
2030- if (con->request.orig_uri->used >= host->strip_request_uri->used &&
2031- 0 == strncmp(con->request.orig_uri->ptr, host->strip_request_uri->ptr, host->strip_request_uri->used - 1)) {
2032+ if (buffer_string_length(con->request.orig_uri) >= buffer_string_length(host->strip_request_uri) &&
2033+ 0 == strncmp(con->request.orig_uri->ptr, host->strip_request_uri->ptr, buffer_string_length(host->strip_request_uri))) {
2034 /* the left is the same */
2035
2036 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"),
2037- con->request.orig_uri->ptr + (host->strip_request_uri->used - 2),
2038- con->request.orig_uri->used - (host->strip_request_uri->used - 2) - 1);
2039+ con->request.orig_uri->ptr + (buffer_string_length(host->strip_request_uri) - 1),
2040+ buffer_string_length(con->request.orig_uri) - (buffer_string_length(host->strip_request_uri) - 1));
2041 } else {
2042 FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)),con)
2043 }
2044@@ -2022,7 +2022,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
2045 fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
2046 buffer_append_string_len(b, (const char *)&header, sizeof(header));
2047
2048- hctx->wb->bytes_in += b->used - 1;
2049+ hctx->wb->bytes_in += buffer_string_length(b);
2050 chunkqueue_append_buffer(hctx->wb, b);
2051 buffer_free(b);
2052 }
2053@@ -2303,11 +2303,10 @@ static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_p
2054 if (0 == toread) break;
2055 }
2056
2057- if ((packet->b->used == 0) ||
2058- (packet->b->used - 1 < sizeof(FCGI_Header))) {
2059+ if (buffer_string_length(packet->b) < sizeof(FCGI_Header)) {
2060 /* no header */
2061 if (hctx->plugin_data->conf.debug) {
2062- log_error_write(srv, __FILE__, __LINE__, "sdsds", "FastCGI: header too small:", packet->b->used, "bytes <", sizeof(FCGI_Header), "bytes, waiting for more data");
2063+ log_error_write(srv, __FILE__, __LINE__, "sdsds", "FastCGI: header too small:", buffer_string_length(packet->b), "bytes <", sizeof(FCGI_Header), "bytes, waiting for more data");
2064 }
2065
2066 buffer_free(packet->b);
2067@@ -2324,13 +2323,13 @@ static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_p
2068 packet->padding = header->paddingLength;
2069
2070 /* ->b should only be the content */
2071- buffer_copy_string_len(packet->b, CONST_STR_LEN("")); /* used == 1 */
2072+ buffer_string_set_length(packet->b, 0);
2073
2074 if (packet->len) {
2075 /* copy the content */
2076- for (; c && (packet->b->used < packet->len + 1); c = c->next) {
2077- size_t weWant = packet->len - (packet->b->used - 1);
2078- size_t weHave = c->mem->used - c->offset - offset - 1;
2079+ for (; c && (buffer_string_length(packet->b) < packet->len); c = c->next) {
2080+ size_t weWant = packet->len - buffer_string_length(packet->b);
2081+ size_t weHave = buffer_string_length(c->mem) - c->offset - offset;
2082
2083 if (weHave > weWant) weHave = weWant;
2084
2085@@ -2340,24 +2339,23 @@ static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_p
2086 offset = 0;
2087 }
2088
2089- if (packet->b->used < packet->len + 1) {
2090+ if (buffer_string_length(packet->b) < packet->len) {
2091 /* we didn't get the full packet */
2092
2093 buffer_free(packet->b);
2094 return -1;
2095 }
2096
2097- packet->b->used -= packet->padding;
2098- packet->b->ptr[packet->b->used - 1] = '\0';
2099+ buffer_string_set_length(packet->b, buffer_string_length(packet->b) - packet->padding);
2100 }
2101
2102 /* tag the chunks as read */
2103 toread = packet->len + sizeof(FCGI_Header);
2104 for (c = hctx->rb->first; c && toread; c = c->next) {
2105- if (c->mem->used - c->offset - 1 <= toread) {
2106+ if (buffer_string_length(c->mem) - c->offset <= toread) {
2107 /* we read this whole buffer, move it to unused */
2108- toread -= c->mem->used - c->offset - 1;
2109- c->offset = c->mem->used - 1; /* everthing has been written */
2110+ toread -= buffer_string_length(c->mem) - c->offset;
2111+ c->offset = buffer_string_length(c->mem); /* everthing has been written */
2112 } else {
2113 c->offset += toread;
2114 toread = 0;
2115@@ -2451,14 +2449,12 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
2116 char *hend = c + 4; /* header end == body start */
2117 size_t hlen = hend - hctx->response_header->ptr;
2118 buffer_copy_string_len(packet.b, hend, buffer_string_length(hctx->response_header) - hlen);
2119- hctx->response_header->used = hlen;
2120- hctx->response_header->ptr[hctx->response_header->used++] = '\0';
2121+ buffer_string_set_length(hctx->response_header, hlen);
2122 } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) {
2123 char *hend = c + 2; /* header end == body start */
2124 size_t hlen = hend - hctx->response_header->ptr;
2125 buffer_copy_string_len(packet.b, hend, buffer_string_length(hctx->response_header) - hlen);
2126- hctx->response_header->used = hlen;
2127- hctx->response_header->ptr[hctx->response_header->used++] = '\0';
2128+ buffer_string_set_length(hctx->response_header, hlen);
2129 } else {
2130 /* no luck, no header found */
2131 break;
2132@@ -2525,7 +2521,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
2133 http_chunk_append_buffer(srv, con, packet.b);
2134 joblist_append(srv, con);
2135 }
2136- } else if (hctx->send_content_body && packet.b->used > 1) {
2137+ } else if (hctx->send_content_body && !buffer_string_is_empty(packet.b)) {
2138 if (con->request.http_version == HTTP_VERSION_1_1 &&
2139 !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
2140 /* enable chunked-transfer-encoding */
2141@@ -2721,7 +2717,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
2142 log_error_write(srv, __FILE__, __LINE__, "s", "fatal error: host = NULL");
2143 return HANDLER_ERROR;
2144 }
2145- if ((!host->port && !host->unixsocket->used)) {
2146+ if ((!host->port && buffer_string_is_empty(host->unixsocket))) {
2147 log_error_write(srv, __FILE__, __LINE__, "s", "fatal error: neither host->port nor host->unixsocket is set");
2148 return HANDLER_ERROR;
2149 }
2150@@ -2794,7 +2790,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
2151 if (proc->load < hctx->proc->load) hctx->proc = proc;
2152 }
2153
2154- ret = host->unixsocket->used ? AF_UNIX : AF_INET;
2155+ ret = buffer_string_is_empty(host->unixsocket) ? AF_INET : AF_UNIX;
2156
2157 if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
2158 if (errno == EMFILE ||
2159@@ -3335,7 +3331,7 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
2160
2161 if (buffer_string_is_empty(fn)) return HANDLER_GO_ON;
2162
2163- s_len = fn->used - 1;
2164+ s_len = buffer_string_length(fn);
2165
2166 fcgi_patch_connection(srv, con, p);
2167
2168@@ -3352,9 +3348,9 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
2169 data_string *ds = (data_string *)p->conf.ext_mapping->data[k];
2170 size_t ct_len; /* length of the config entry */
2171
2172- if (ds->key->used == 0) continue;
2173+ if (buffer_is_empty(ds->key)) continue;
2174
2175- ct_len = ds->key->used - 1;
2176+ ct_len = buffer_string_length(ds->key);
2177
2178 if (s_len < ct_len) continue;
2179
2180@@ -3380,18 +3376,20 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
2181 }
2182
2183 if (extension == NULL) {
2184+ size_t uri_path_len = buffer_string_length(con->uri.path);
2185+
2186 /* check if extension matches */
2187 for (k = 0; k < p->conf.exts->used; k++) {
2188 size_t ct_len; /* length of the config entry */
2189 fcgi_extension *ext = p->conf.exts->exts[k];
2190
2191- if (ext->key->used == 0) continue;
2192+ if (buffer_is_empty(ext->key)) continue;
2193
2194- ct_len = ext->key->used - 1;
2195+ ct_len = buffer_string_length(ext->key);
2196
2197 /* check _url_ in the form "/fcgi_pattern" */
2198 if (ext->key->ptr[0] == '/') {
2199- if ((ct_len <= con->uri.path->used -1) &&
2200+ if ((ct_len <= uri_path_len) &&
2201 (strncmp(con->uri.path->ptr, ext->key->ptr, ct_len) == 0)) {
2202 extension = ext;
2203 break;
2204@@ -3506,17 +3504,14 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
2205 /* the rewrite is only done for /prefix/? matches */
2206 if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
2207 buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
2208- con->uri.path->used = 1;
2209- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
2210+ buffer_string_set_length(con->uri.path, 0);
2211 } else if (extension->key->ptr[0] == '/' &&
2212- con->uri.path->used > extension->key->used &&
2213- NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
2214+ buffer_string_length(con->uri.path) > buffer_string_length(extension->key) &&
2215+ NULL != (pathinfo = strchr(con->uri.path->ptr + buffer_string_length(extension->key), '/'))) {
2216 /* rewrite uri.path and pathinfo */
2217
2218 buffer_copy_string(con->request.pathinfo, pathinfo);
2219-
2220- con->uri.path->used -= con->request.pathinfo->used - 1;
2221- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
2222+ buffer_string_set_length(con->uri.path, buffer_string_length(con->uri.path) - buffer_string_length(con->request.pathinfo));
2223 }
2224 }
2225 }
2226diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c
2227index 1c1a356..db041e2 100644
2228--- a/src/mod_flv_streaming.c
2229+++ b/src/mod_flv_streaming.c
2230@@ -136,13 +136,14 @@ static int mod_flv_streaming_patch_connection(server *srv, connection *con, plug
2231
2232 static int split_get_params(array *get_params, buffer *qrystr) {
2233 size_t is_key = 1;
2234- size_t i;
2235+ size_t i, len;
2236 char *key = NULL, *val = NULL;
2237
2238 key = qrystr->ptr;
2239
2240 /* we need the \0 */
2241- for (i = 0; i < qrystr->used; i++) {
2242+ len = buffer_string_length(qrystr);
2243+ for (i = 0; i <= len; i++) {
2244 switch(qrystr->ptr[i]) {
2245 case '=':
2246 if (is_key) {
2247@@ -195,14 +196,14 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
2248
2249 mod_flv_streaming_patch_connection(srv, con, p);
2250
2251- s_len = con->physical.path->used - 1;
2252+ s_len = buffer_string_length(con->physical.path);
2253
2254 for (k = 0; k < p->conf.extensions->used; k++) {
2255 data_string *ds = (data_string *)p->conf.extensions->data[k];
2256- int ct_len = ds->value->used - 1;
2257+ int ct_len = buffer_string_length(ds->value);
2258
2259 if (ct_len > s_len) continue;
2260- if (ds->value->used == 0) continue;
2261+ if (buffer_is_empty(ds->value)) continue;
2262
2263 if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
2264 data_string *get_param;
2265@@ -221,7 +222,7 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
2266 }
2267
2268 /* too short */
2269- if (get_param->value->used < 2) return HANDLER_GO_ON;
2270+ if (buffer_string_is_empty(get_param->value)) return HANDLER_GO_ON;
2271
2272 /* check if it is a number */
2273 start = strtol(get_param->value->ptr, &err, 10);
2274diff --git a/src/mod_indexfile.c b/src/mod_indexfile.c
2275index fe750c1..13d18e2 100644
2276--- a/src/mod_indexfile.c
2277+++ b/src/mod_indexfile.c
2278@@ -141,8 +141,8 @@ URIHANDLER_FUNC(mod_indexfile_subrequest) {
2279
2280 if (con->mode != DIRECT) return HANDLER_GO_ON;
2281
2282- if (con->uri.path->used == 0) return HANDLER_GO_ON;
2283- if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
2284+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
2285+ if (con->uri.path->ptr[buffer_string_length(con->uri.path) - 1] != '/') return HANDLER_GO_ON;
2286
2287 mod_indexfile_patch_connection(srv, con, p);
2288
2289diff --git a/src/mod_magnet.c b/src/mod_magnet.c
2290index 80cb799..8f89d4e 100644
2291--- a/src/mod_magnet.c
2292+++ b/src/mod_magnet.c
2293@@ -189,17 +189,12 @@ static int magnet_array_next(lua_State *L) {
2294
2295 if (pos >= a->used) return 0;
2296 if (NULL != (du = a->data[pos])) {
2297- if (du->key->used) {
2298- lua_pushlstring(L, du->key->ptr, du->key->used - 1);
2299- }
2300- else {
2301- lua_pushlstring(L, "", 0);
2302- }
2303+ lua_pushlstring(L, CONST_BUF_LEN(du->key));
2304 switch (du->type) {
2305 case TYPE_STRING:
2306 ds = (data_string *)du;
2307- if (ds->value && ds->value->used) {
2308- lua_pushlstring(L, ds->value->ptr, ds->value->used - 1);
2309+ if (!buffer_is_empty(ds->value)) {
2310+ lua_pushlstring(L, CONST_BUF_LEN(ds->value));
2311 } else {
2312 lua_pushnil(L);
2313 }
2314@@ -252,8 +247,9 @@ static int magnet_stat(lua_State *L) {
2315 const char *s = luaL_checkstring(L, 1);
2316 server *srv;
2317 connection *con;
2318- buffer sb;
2319+ buffer *sb;
2320 stat_cache_entry *sce = NULL;
2321+ handler_t res;
2322
2323 lua_pushstring(L, "lighty.srv");
2324 lua_gettable(L, LUA_REGISTRYINDEX);
2325@@ -265,12 +261,12 @@ static int magnet_stat(lua_State *L) {
2326 con = lua_touserdata(L, -1);
2327 lua_pop(L, 1);
2328
2329- sb.ptr = (char *)s;
2330- sb.used = sb.size = strlen(s) + 1;
2331-
2332- if (HANDLER_GO_ON != stat_cache_get_entry(srv, con, &sb, &sce)) {
2333- lua_pushnil(L);
2334+ sb = buffer_init_string(s);
2335+ res = stat_cache_get_entry(srv, con, sb, &sce);
2336+ buffer_free(sb);
2337
2338+ if (HANDLER_GO_ON != res) {
2339+ lua_pushnil(L);
2340 return 1;
2341 }
2342
2343@@ -324,7 +320,7 @@ static int magnet_stat(lua_State *L) {
2344 buffer *b = buffer_init();
2345 etag_mutate(b, sce->etag);
2346
2347- lua_pushlstring(L, b->ptr, b->used - 1);
2348+ lua_pushlstring(L, CONST_BUF_LEN(b));
2349 buffer_free(b);
2350 } else {
2351 lua_pushnil(L);
2352@@ -332,7 +328,7 @@ static int magnet_stat(lua_State *L) {
2353 lua_setfield(L, -2, "etag");
2354
2355 if (!buffer_string_is_empty(sce->content_type)) {
2356- lua_pushlstring(L, sce->content_type->ptr, sce->content_type->used - 1);
2357+ lua_pushlstring(L, CONST_BUF_LEN(sce->content_type));
2358 } else {
2359 lua_pushnil(L);
2360 }
2361@@ -369,8 +365,8 @@ static int magnet_reqhdr_get(lua_State *L) {
2362 lua_pop(L, 1);
2363
2364 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, key))) {
2365- if (ds->value->used) {
2366- lua_pushlstring(L, ds->value->ptr, ds->value->used - 1);
2367+ if (!buffer_is_empty(ds->value)) {
2368+ lua_pushlstring(L, CONST_BUF_LEN(ds->value));
2369 } else {
2370 lua_pushnil(L);
2371 }
2372@@ -555,8 +551,8 @@ static int magnet_env_get(lua_State *L) {
2373
2374 dest = magnet_env_get_buffer(srv, con, key);
2375
2376- if (dest && dest->used) {
2377- lua_pushlstring(L, dest->ptr, dest->used - 1);
2378+ if (!buffer_is_empty(dest)) {
2379+ lua_pushlstring(L, CONST_BUF_LEN(dest));
2380 } else {
2381 lua_pushnil(L);
2382 }
2383@@ -617,8 +613,8 @@ static int magnet_env_next(lua_State *L) {
2384 lua_pushstring(L, magnet_env[pos].name);
2385
2386 dest = magnet_env_get_buffer_by_id(srv, con, magnet_env[pos].type);
2387- if (dest && dest->used) {
2388- lua_pushlstring(L, dest->ptr, dest->used - 1);
2389+ if (!buffer_is_empty(dest)) {
2390+ lua_pushlstring(L, CONST_BUF_LEN(dest));
2391 } else {
2392 lua_pushnil(L);
2393 }
2394@@ -649,7 +645,8 @@ static int magnet_cgi_get(lua_State *L) {
2395 con = lua_touserdata(L, -1);
2396 lua_pop(L, 1);
2397
2398- if (NULL != (ds = (data_string *)array_get_element(con->environment, key)) && ds->value->used)
2399+ ds = (data_string *)array_get_element(con->environment, key);
2400+ if (!buffer_is_empty(ds->value))
2401 lua_pushlstring(L, CONST_BUF_LEN(ds->value));
2402 else
2403 lua_pushnil(L);
2404diff --git a/src/mod_mysql_vhost.c b/src/mod_mysql_vhost.c
2405index 7d679fb..21260d5 100644
2406--- a/src/mod_mysql_vhost.c
2407+++ b/src/mod_mysql_vhost.c
2408@@ -25,10 +25,6 @@
2409 * for domain to directory lookups,
2410 * i.e virtual hosts (vhosts).
2411 *
2412- * Optionally sets fcgi_offset and fcgi_arg
2413- * in preparation for fcgi.c to handle
2414- * per-user fcgi chroot jails.
2415- *
2416 * /ada@riksnet.se 2004-12-06
2417 */
2418
2419@@ -63,8 +59,6 @@ typedef struct {
2420 typedef struct {
2421 buffer *server_name;
2422 buffer *document_root;
2423- buffer *fcgi_arg;
2424- unsigned fcgi_offset;
2425 } plugin_connection_data;
2426
2427 /* init the plugin data */
2428@@ -136,8 +130,6 @@ static void* mod_mysql_vhost_connection_data(server *srv, connection *con, void
2429
2430 c->server_name = buffer_init();
2431 c->document_root = buffer_init();
2432- c->fcgi_arg = buffer_init();
2433- c->fcgi_offset = 0;
2434
2435 return con->plugin_ctx[p->id] = c;
2436 }
2437@@ -158,8 +150,6 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_connection_close) {
2438
2439 buffer_free(c->server_name);
2440 buffer_free(c->document_root);
2441- buffer_free(c->fcgi_arg);
2442- c->fcgi_offset = 0;
2443
2444 free(c);
2445
2446@@ -222,7 +212,7 @@ SERVER_FUNC(mod_mysql_vhost_set_defaults) {
2447 s->mysql_pre = buffer_init();
2448 s->mysql_post = buffer_init();
2449
2450- if (sel->used && (qmark = strchr(sel->ptr, '?'))) {
2451+ if (!buffer_string_is_empty(sel) && (qmark = strchr(sel->ptr, '?'))) {
2452 *qmark = '\0';
2453 buffer_copy_string(s->mysql_pre, sel->ptr);
2454 buffer_copy_string(s->mysql_post, qmark+1);
2455@@ -258,7 +248,7 @@ SERVER_FUNC(mod_mysql_vhost_set_defaults) {
2456 mysql_options(s->mysql, MYSQL_OPT_RECONNECT, &reconnect);
2457 #endif
2458
2459-#define FOO(x) (s->x->used ? s->x->ptr : NULL)
2460+#define FOO(x) (buffer_string_is_empty(s->x) ? NULL : s->x->ptr)
2461
2462 #if MYSQL_VERSION_ID >= 40100
2463 /* CLIENT_MULTI_STATEMENTS first appeared in 4.1 */
2464@@ -334,37 +324,35 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
2465 MYSQL_RES *result = NULL;
2466
2467 /* no host specified? */
2468- if (!con->uri.authority->used) return HANDLER_GO_ON;
2469+ if (buffer_string_is_empty(con->uri.authority)) return HANDLER_GO_ON;
2470
2471 mod_mysql_vhost_patch_connection(srv, con, p);
2472
2473 if (!p->conf.mysql) return HANDLER_GO_ON;
2474- if (0 == p->conf.mysql_pre->used) return HANDLER_GO_ON;
2475+ if (buffer_string_is_empty(p->conf.mysql_pre)) return HANDLER_GO_ON;
2476
2477 /* sets up connection data if not done yet */
2478 c = mod_mysql_vhost_connection_data(srv, con, p_d);
2479
2480 /* check if cached this connection */
2481- if (c->server_name->used && /* con->uri.authority->used && */
2482- buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON;
2483+ if (buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON;
2484
2485 /* build and run SQL query */
2486 buffer_copy_buffer(p->tmp_buf, p->conf.mysql_pre);
2487- if (p->conf.mysql_post->used) {
2488+ if (!buffer_is_empty(p->conf.mysql_post)) {
2489 /* escape the uri.authority */
2490 unsigned long to_len;
2491
2492- /* 'to' has to be 'from_len * 2 + 1' */
2493- buffer_string_prepare_append(p->tmp_buf, (con->uri.authority->used - 1) * 2 + 1);
2494+ buffer_string_prepare_append(p->tmp_buf, buffer_string_length(con->uri.authority) * 2);
2495
2496 to_len = mysql_real_escape_string(p->conf.mysql,
2497- p->tmp_buf->ptr + p->tmp_buf->used - 1,
2498- con->uri.authority->ptr, con->uri.authority->used - 1);
2499- p->tmp_buf->used += to_len;
2500+ p->tmp_buf->ptr + buffer_string_length(p->tmp_buf),
2501+ CONST_BUF_LEN(con->uri.authority));
2502+ buffer_commit(p->tmp_buf, to_len);
2503
2504 buffer_append_string_buffer(p->tmp_buf, p->conf.mysql_post);
2505 }
2506- if (mysql_real_query(p->conf.mysql, p->tmp_buf->ptr, p->tmp_buf->used - 1)) {
2507+ if (mysql_real_query(p->conf.mysql, CONST_BUF_LEN(p->tmp_buf))) {
2508 log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(p->conf.mysql));
2509 goto ERR500;
2510 }
2511@@ -397,18 +385,6 @@ CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
2512 buffer_copy_buffer(c->server_name, con->uri.authority);
2513 buffer_copy_buffer(c->document_root, p->tmp_buf);
2514
2515- /* fcgi_offset and fcgi_arg are optional */
2516- if (cols > 1 && row[1]) {
2517- c->fcgi_offset = atoi(row[1]);
2518-
2519- if (cols > 2 && row[2]) {
2520- buffer_copy_string(c->fcgi_arg, row[2]);
2521- } else {
2522- c->fcgi_arg->used = 0;
2523- }
2524- } else {
2525- c->fcgi_offset = c->fcgi_arg->used = 0;
2526- }
2527 mysql_free_result(result);
2528 #if MYSQL_VERSION_ID >= 40100
2529 while (mysql_next_result(p->conf.mysql) == 0);
2530@@ -420,10 +396,9 @@ GO_ON:
2531 buffer_copy_buffer(con->physical.doc_root, c->document_root);
2532
2533 #ifdef DEBUG
2534- log_error_write(srv, __FILE__, __LINE__, "sbbdb",
2535+ log_error_write(srv, __FILE__, __LINE__, "sbb",
2536 result ? "NOT CACHED" : "cached",
2537- con->server_name, con->physical.doc_root,
2538- c->fcgi_offset, c->fcgi_arg);
2539+ con->server_name, con->physical.doc_root);
2540 #endif
2541 return HANDLER_GO_ON;
2542
2543diff --git a/src/mod_proxy.c b/src/mod_proxy.c
2544index fc2ca1a..dfdc636 100644
2545--- a/src/mod_proxy.c
2546+++ b/src/mod_proxy.c
2547@@ -472,7 +472,7 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
2548
2549 ds = (data_string *)con->request.headers->data[i];
2550
2551- if (ds->value->used && ds->key->used) {
2552+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
2553 if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
2554 if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Proxy-Connection"))) continue;
2555
2556@@ -485,7 +485,7 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
2557
2558 buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
2559
2560- hctx->wb->bytes_in += b->used - 1;
2561+ hctx->wb->bytes_in += buffer_string_length(b);
2562 chunkqueue_append_buffer(hctx->wb, b);
2563 buffer_free(b);
2564
2565@@ -620,7 +620,7 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
2566
2567 if (p->conf.debug) {
2568 log_error_write(srv, __FILE__, __LINE__, "sd",
2569- "proxy - have to read:", b);
2570+ "proxy - have to read:", b);
2571 }
2572
2573 if (b > 0) {
2574@@ -637,8 +637,7 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
2575 /* this should be catched by the b > 0 above */
2576 force_assert(r);
2577
2578- hctx->response->used += r;
2579- hctx->response->ptr[hctx->response->used - 1] = '\0';
2580+ buffer_commit(hctx->response, r);
2581
2582 #if 0
2583 log_error_write(srv, __FILE__, __LINE__, "sdsbs",
2584@@ -656,7 +655,7 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
2585 /* search for the \r\n\r\n in the string */
2586 if (NULL != (c = buffer_search_string_len(hctx->response, CONST_STR_LEN("\r\n\r\n")))) {
2587 size_t hlen = c - hctx->response->ptr + 4;
2588- size_t blen = hctx->response->used - hlen - 1;
2589+ size_t blen = buffer_string_length(hctx->response) - hlen;
2590 /* found */
2591
2592 buffer_append_string_len(hctx->response_header, hctx->response->ptr, hlen);
2593@@ -674,13 +673,13 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
2594
2595 con->file_started = 1;
2596 if (blen > 0) http_chunk_append_mem(srv, con, c + 4, blen);
2597- hctx->response->used = 0;
2598+ buffer_reset(hctx->response);
2599 joblist_append(srv, con);
2600 }
2601 } else {
2602 http_chunk_append_buffer(srv, con, hctx->response);
2603 joblist_append(srv, con);
2604- hctx->response->used = 0;
2605+ buffer_reset(hctx->response);
2606 }
2607
2608 } else {
2609@@ -703,8 +702,7 @@ static handler_t proxy_write_request(server *srv, handler_ctx *hctx) {
2610
2611 int ret;
2612
2613- if (!host ||
2614- (!host->host->used || !host->port)) return -1;
2615+ if (!host || buffer_string_is_empty(host->host) || !host->port) return -1;
2616
2617 switch(hctx->state) {
2618 case PROXY_STATE_CONNECT:
2619@@ -721,17 +719,17 @@ static handler_t proxy_write_request(server *srv, handler_ctx *hctx) {
2620 case PROXY_STATE_INIT:
2621 #if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
2622 if (strstr(host->host->ptr,":")) {
2623- if (-1 == (hctx->fd = socket(AF_INET6, SOCK_STREAM, 0))) {
2624- log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
2625- return HANDLER_ERROR;
2626- }
2627+ if (-1 == (hctx->fd = socket(AF_INET6, SOCK_STREAM, 0))) {
2628+ log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
2629+ return HANDLER_ERROR;
2630+ }
2631 } else
2632 #endif
2633 {
2634- if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
2635- log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
2636- return HANDLER_ERROR;
2637- }
2638+ if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
2639+ log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
2640+ return HANDLER_ERROR;
2641+ }
2642 }
2643 hctx->fde_ndx = -1;
2644
2645@@ -1078,13 +1076,8 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
2646 mod_proxy_patch_connection(srv, con, p);
2647
2648 fn = con->uri.path;
2649-
2650- if (fn->used == 0) {
2651- return HANDLER_ERROR;
2652- }
2653-
2654- s_len = fn->used - 1;
2655-
2656+ if (buffer_string_is_empty(fn)) return HANDLER_ERROR;
2657+ s_len = buffer_string_length(fn);
2658
2659 path_info_offset = 0;
2660
2661@@ -1099,9 +1092,9 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
2662
2663 ext = (data_array *)p->conf.extensions->data[k];
2664
2665- if (ext->key->used == 0) continue;
2666+ if (buffer_is_empty(ext->key)) continue;
2667
2668- ct_len = ext->key->used - 1;
2669+ ct_len = buffer_string_length(ext->key);
2670
2671 if (s_len < ct_len) continue;
2672
2673diff --git a/src/mod_redirect.c b/src/mod_redirect.c
2674index 93cecb7..615c7db 100644
2675--- a/src/mod_redirect.c
2676+++ b/src/mod_redirect.c
2677@@ -198,9 +198,9 @@ static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_
2678 match = kv->key;
2679 extra = kv->key_extra;
2680 pattern = kv->value->ptr;
2681- pattern_len = kv->value->used - 1;
2682+ pattern_len = buffer_string_length(kv->value);
2683
2684- if ((n = pcre_exec(match, extra, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
2685+ if ((n = pcre_exec(match, extra, CONST_BUF_LEN(p->match_buf), 0, 0, ovec, 3 * N)) < 0) {
2686 if (n != PCRE_ERROR_NOMATCH) {
2687 log_error_write(srv, __FILE__, __LINE__, "sd",
2688 "execution error while matching: ", n);
2689diff --git a/src/mod_rewrite.c b/src/mod_rewrite.c
2690index 48c0987..5191a64 100644
2691--- a/src/mod_rewrite.c
2692+++ b/src/mod_rewrite.c
2693@@ -372,9 +372,9 @@ static int process_rewrite_rules(server *srv, connection *con, plugin_data *p, r
2694
2695 match = rule->key;
2696 pattern = rule->value->ptr;
2697- pattern_len = rule->value->used - 1;
2698+ pattern_len = buffer_string_length(rule->value);
2699
2700- if ((n = pcre_exec(match, NULL, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
2701+ if ((n = pcre_exec(match, NULL, CONST_BUF_LEN(p->match_buf), 0, 0, ovec, 3 * N)) < 0) {
2702 if (n != PCRE_ERROR_NOMATCH) {
2703 log_error_write(srv, __FILE__, __LINE__, "sd",
2704 "execution error while matching: ", n);
2705diff --git a/src/mod_rrdtool.c b/src/mod_rrdtool.c
2706index 5eb0d9d..0532e4d 100644
2707--- a/src/mod_rrdtool.c
2708+++ b/src/mod_rrdtool.c
2709@@ -264,7 +264,7 @@ static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s)
2710 "RRA:MIN:0.5:24:775 "
2711 "RRA:MIN:0.5:288:797\n"));
2712
2713- if (-1 == (safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
2714+ if (-1 == (safe_write(p->write_fd, CONST_BUF_LEN(p->cmd)))) {
2715 log_error_write(srv, __FILE__, __LINE__, "ss",
2716 "rrdtool-write: failed", strerror(errno));
2717
2718@@ -279,8 +279,7 @@ static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s)
2719 return HANDLER_ERROR;
2720 }
2721
2722- p->resp->used = r;
2723- p->resp->ptr[p->resp->used++] = '\0';
2724+ buffer_commit(p->resp, r);
2725
2726 if (p->resp->ptr[0] != 'O' ||
2727 p->resp->ptr[1] != 'K') {
2728@@ -426,7 +425,7 @@ TRIGGER_FUNC(mod_rrd_trigger) {
2729 buffer_append_int(p->cmd, s->requests);
2730 buffer_append_string_len(p->cmd, CONST_STR_LEN("\n"));
2731
2732- if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
2733+ if (-1 == (r = safe_write(p->write_fd, CONST_BUF_LEN(p->cmd)))) {
2734 p->rrdtool_running = 0;
2735
2736 log_error_write(srv, __FILE__, __LINE__, "ss",
2737@@ -435,7 +434,7 @@ TRIGGER_FUNC(mod_rrd_trigger) {
2738 return HANDLER_ERROR;
2739 }
2740
2741- buffer_string_prepare_copy(p->resp, 4096);
2742+ buffer_string_prepare_copy(p->resp, 4095);
2743 if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size - 1))) {
2744 p->rrdtool_running = 0;
2745
2746@@ -445,8 +444,7 @@ TRIGGER_FUNC(mod_rrd_trigger) {
2747 return HANDLER_ERROR;
2748 }
2749
2750- p->resp->used = r;
2751- p->resp->ptr[p->resp->used++] = '\0';
2752+ buffer_commit(p->resp, r);
2753
2754 if (p->resp->ptr[0] != 'O' ||
2755 p->resp->ptr[1] != 'K') {
2756diff --git a/src/mod_scgi.c b/src/mod_scgi.c
2757index 9ea16a4..9e88de3 100644
2758--- a/src/mod_scgi.c
2759+++ b/src/mod_scgi.c
2760@@ -664,19 +664,19 @@ static int scgi_spawn_connection(server *srv,
2761
2762 #ifdef HAVE_SYS_UN_H
2763 scgi_addr_un.sun_family = AF_UNIX;
2764- if (proc->socket->used > sizeof(scgi_addr_un.sun_path)) {
2765+ if (buffer_string_length(proc->socket) + 1 > sizeof(scgi_addr_un.sun_path)) {
2766 log_error_write(srv, __FILE__, __LINE__, "sB",
2767 "ERROR: Unix Domain socket filename too long:",
2768 proc->socket);
2769 return -1;
2770 }
2771- memcpy(scgi_addr_un.sun_path, proc->socket->ptr, proc->socket->used);
2772+ memcpy(scgi_addr_un.sun_path, proc->socket->ptr, buffer_string_length(proc->socket) + 1);
2773
2774 #ifdef SUN_LEN
2775 servlen = SUN_LEN(&scgi_addr_un);
2776 #else
2777 /* stevens says: */
2778- servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
2779+ servlen = buffer_string_length(proc->socket) + 1 + sizeof(scgi_addr_un.sun_family);
2780 #endif
2781 socket_type = AF_UNIX;
2782 scgi_addr = (struct sockaddr *) &scgi_addr_un;
2783@@ -1072,7 +1072,7 @@ SETDEFAULTS_FUNC(mod_scgi_set_defaults) {
2784 /* unix domain socket */
2785 struct sockaddr_un un;
2786
2787- if (df->unixsocket->used > sizeof(un.sun_path) - 2) {
2788+ if (buffer_string_length(df->unixsocket) + 1 > sizeof(un.sun_path) - 2) {
2789 log_error_write(srv, __FILE__, __LINE__, "s",
2790 "path of the unixdomain socket is too large");
2791 goto error;
2792@@ -1338,19 +1338,19 @@ static int scgi_establish_connection(server *srv, handler_ctx *hctx) {
2793 #ifdef HAVE_SYS_UN_H
2794 /* use the unix domain socket */
2795 scgi_addr_un.sun_family = AF_UNIX;
2796- if (proc->socket->used > sizeof(scgi_addr_un.sun_path)) {
2797+ if (buffer_string_length(proc->socket) + 1 > sizeof(scgi_addr_un.sun_path)) {
2798 log_error_write(srv, __FILE__, __LINE__, "sB",
2799 "ERROR: Unix Domain socket filename too long:",
2800 proc->socket);
2801 return -1;
2802 }
2803- memcpy(scgi_addr_un.sun_path, proc->socket->ptr, proc->socket->used);
2804+ memcpy(scgi_addr_un.sun_path, proc->socket->ptr, buffer_string_length(proc->socket) + 1);
2805
2806 #ifdef SUN_LEN
2807 servlen = SUN_LEN(&scgi_addr_un);
2808 #else
2809 /* stevens says: */
2810- servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
2811+ servlen = buffer_string_length(proc->socket) + 1 + sizeof(scgi_addr_un.sun_family);
2812 #endif
2813 scgi_addr = (struct sockaddr *) &scgi_addr_un;
2814 #else
2815@@ -1416,7 +1416,7 @@ static int scgi_env_add_request_headers(server *srv, connection *con, plugin_dat
2816
2817 ds = (data_string *)con->request.headers->data[i];
2818
2819- if (ds->value->used && ds->key->used) {
2820+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
2821 buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 1);
2822
2823 scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
2824@@ -1428,7 +1428,7 @@ static int scgi_env_add_request_headers(server *srv, connection *con, plugin_dat
2825
2826 ds = (data_string *)con->environment->data[i];
2827
2828- if (ds->value->used && ds->key->used) {
2829+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
2830 buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 0);
2831
2832 scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
2833@@ -1471,8 +1471,8 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
2834 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag));
2835 }
2836
2837- if (con->server_name->used) {
2838- size_t len = con->server_name->used - 1;
2839+ if (!buffer_is_empty(con->server_name)) {
2840+ size_t len = buffer_string_length(con->server_name);
2841
2842 if (con->server_name->ptr[0] == '[') {
2843 const char *colon = strstr(con->server_name->ptr, "]:");
2844@@ -1611,7 +1611,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
2845 buffer_append_string_buffer(b, p->scgi_env);
2846 buffer_append_string_len(b, CONST_STR_LEN(","));
2847
2848- hctx->wb->bytes_in += b->used - 1;
2849+ hctx->wb->bytes_in += buffer_string_length(b);
2850 chunkqueue_append_buffer(hctx->wb, b);
2851 buffer_free(b);
2852
2853@@ -1757,8 +1757,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
2854 return 1;
2855 }
2856
2857- hctx->response->ptr[n] = '\0';
2858- hctx->response->used = n+1;
2859+ buffer_commit(hctx->response, n);
2860
2861 /* split header from body */
2862
2863@@ -1776,7 +1775,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
2864 if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
2865
2866 /* search for the \r\n\r\n or \n\n in the string */
2867- for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
2868+ for (c = hctx->response_header->ptr, cp = 0, used = buffer_string_length(hctx->response_header); used; c++, cp++, used--) {
2869 if (*c == ':') in_header = 1;
2870 else if (*c == '\n') {
2871 if (in_header == 0) {
2872@@ -1832,11 +1831,10 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
2873 http_chunk_append_buffer(srv, con, hctx->response_header);
2874 joblist_append(srv, con);
2875 } else {
2876- size_t blen = hctx->response_header->used - hlen - 1;
2877+ size_t blen = buffer_string_length(hctx->response_header) - hlen;
2878
2879 /* a small hack: terminate after at the second \r */
2880- hctx->response_header->used = hlen;
2881- hctx->response_header->ptr[hlen - 1] = '\0';
2882+ buffer_string_set_length(hctx->response_header, hlen - 1);
2883
2884 /* parse the response header */
2885 scgi_response_parse(srv, con, p, hctx->response_header, eol);
2886@@ -1847,7 +1845,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
2887 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
2888 }
2889
2890- if ((hctx->response->used != hlen) && blen > 0) {
2891+ if (blen > 0) {
2892 http_chunk_append_mem(srv, con, hctx->response_header->ptr + hlen, blen);
2893 joblist_append(srv, con);
2894 }
2895@@ -2110,20 +2108,20 @@ static handler_t scgi_write_request(server *srv, handler_ctx *hctx) {
2896 log_error_write(srv, __FILE__, __LINE__, "s", "fatal error: host = NULL");
2897 return HANDLER_ERROR;
2898 }
2899- if (((!host->host->used || !host->port) && !host->unixsocket->used)) {
2900+ if (((buffer_string_is_empty(host->host) || !host->port) && buffer_string_is_empty(host->unixsocket))) {
2901 log_error_write(srv, __FILE__, __LINE__, "sxddd",
2902 "write-req: error",
2903 host,
2904- host->host->used,
2905+ buffer_string_length(host->host),
2906 host->port,
2907- host->unixsocket->used);
2908+ buffer_string_length(host->unixsocket));
2909 return HANDLER_ERROR;
2910 }
2911
2912
2913 switch(hctx->state) {
2914 case FCGI_STATE_INIT:
2915- ret = host->unixsocket->used ? AF_UNIX : AF_INET;
2916+ ret = buffer_string_is_empty(host->unixsocket) ? AF_INET : AF_UNIX;
2917
2918 if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
2919 if (errno == EMFILE ||
2920@@ -2653,7 +2651,7 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
2921
2922 if (buffer_string_is_empty(fn)) return HANDLER_GO_ON;
2923
2924- s_len = fn->used - 1;
2925+ s_len = buffer_string_length(fn);
2926
2927 scgi_patch_connection(srv, con, p);
2928
2929@@ -2662,9 +2660,9 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
2930 size_t ct_len;
2931 scgi_extension *ext = p->conf.exts->exts[k];
2932
2933- if (ext->key->used == 0) continue;
2934+ if (buffer_is_empty(ext->key)) continue;
2935
2936- ct_len = ext->key->used - 1;
2937+ ct_len = buffer_string_length(ext->key);
2938
2939 if (s_len < ct_len) continue;
2940
2941@@ -2778,17 +2776,14 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
2942 /* the rewrite is only done for /prefix/? matches */
2943 if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
2944 buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
2945- con->uri.path->used = 1;
2946- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
2947+ buffer_string_set_length(con->uri.path, 0);
2948 } else if (extension->key->ptr[0] == '/' &&
2949- con->uri.path->used > extension->key->used &&
2950- NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
2951+ buffer_string_length(con->uri.path) > buffer_string_length(extension->key) &&
2952+ NULL != (pathinfo = strchr(con->uri.path->ptr + buffer_string_length(extension->key), '/'))) {
2953 /* rewrite uri.path and pathinfo */
2954
2955 buffer_copy_string(con->request.pathinfo, pathinfo);
2956-
2957- con->uri.path->used -= con->request.pathinfo->used - 1;
2958- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
2959+ buffer_string_set_length(con->uri.path, buffer_string_length(con->uri.path) - buffer_string_length(con->request.pathinfo));
2960 }
2961 }
2962 } else {
2963diff --git a/src/mod_secure_download.c b/src/mod_secure_download.c
2964index d94482e..da98b61 100644
2965--- a/src/mod_secure_download.c
2966+++ b/src/mod_secure_download.c
2967@@ -198,7 +198,7 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
2968
2969 if (con->mode != DIRECT) return HANDLER_GO_ON;
2970
2971- if (con->uri.path->used == 0) return HANDLER_GO_ON;
2972+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
2973
2974 mod_secdownload_patch_connection(srv, con, p);
2975
2976@@ -220,9 +220,9 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
2977 * /<uri-prefix>[a-f0-9]{32}/[a-f0-9]{8}/<rel-path>
2978 */
2979
2980- if (0 != strncmp(con->uri.path->ptr, p->conf.uri_prefix->ptr, p->conf.uri_prefix->used - 1)) return HANDLER_GO_ON;
2981+ if (0 != strncmp(con->uri.path->ptr, p->conf.uri_prefix->ptr, buffer_string_length(p->conf.uri_prefix))) return HANDLER_GO_ON;
2982
2983- md5_str = con->uri.path->ptr + p->conf.uri_prefix->used - 1;
2984+ md5_str = con->uri.path->ptr + buffer_string_length(p->conf.uri_prefix);
2985
2986 if (!is_hex_len(md5_str, 32)) return HANDLER_GO_ON;
2987 if (*(md5_str + 32) != '/') return HANDLER_GO_ON;
2988@@ -255,10 +255,9 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
2989 buffer_copy_buffer(p->md5, p->conf.secret);
2990 buffer_append_string(p->md5, rel_uri);
2991 buffer_append_string_len(p->md5, ts_str, 8);
2992- force_assert(p->md5->used > 0);
2993
2994 li_MD5_Init(&Md5Ctx);
2995- li_MD5_Update(&Md5Ctx, (unsigned char *)p->md5->ptr, p->md5->used - 1);
2996+ li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(p->md5));
2997 li_MD5_Final(HA1, &Md5Ctx);
2998
2999 buffer_copy_string_hex(p->md5, (char *)HA1, 16);
3000diff --git a/src/mod_simple_vhost.c b/src/mod_simple_vhost.c
3001index 6bb850f..fec8d54 100644
3002--- a/src/mod_simple_vhost.c
3003+++ b/src/mod_simple_vhost.c
3004@@ -124,12 +124,12 @@ SETDEFAULTS_FUNC(mod_simple_vhost_set_defaults) {
3005
3006 static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *out, buffer *host) {
3007 stat_cache_entry *sce = NULL;
3008- force_assert(p->conf.server_root->used > 1);
3009+ force_assert(!buffer_string_is_empty(p->conf.server_root));
3010
3011 buffer_string_prepare_copy(out, 127);
3012 buffer_copy_buffer(out, p->conf.server_root);
3013
3014- if (host->used) {
3015+ if (!buffer_string_is_empty(host)) {
3016 /* a hostname has to start with a alpha-numerical character
3017 * and must not contain a slash "/"
3018 */
3019@@ -145,8 +145,8 @@ static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *
3020 }
3021 buffer_append_slash(out);
3022
3023- if (p->conf.document_root->used > 2 && p->conf.document_root->ptr[0] == '/') {
3024- buffer_append_string_len(out, p->conf.document_root->ptr + 1, p->conf.document_root->used - 2);
3025+ if (buffer_string_length(p->conf.document_root) > 1 && p->conf.document_root->ptr[0] == '/') {
3026+ buffer_append_string_len(out, p->conf.document_root->ptr + 1, buffer_string_length(p->conf.document_root) - 1);
3027 } else {
3028 buffer_append_string_buffer(out, p->conf.document_root);
3029 buffer_append_slash(out);
3030@@ -227,17 +227,17 @@ static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_
3031 /* build_doc_root() requires a server_root; skip module if simple-vhost.server-root is not set
3032 * or set to an empty string (especially don't cache any results!)
3033 */
3034- if (p->conf.server_root->used < 2) return HANDLER_GO_ON;
3035+ if (buffer_string_is_empty(p->conf.server_root)) return HANDLER_GO_ON;
3036
3037- if (p->conf.docroot_cache_key->used &&
3038- con->uri.authority->used &&
3039+ if (!buffer_string_is_empty(p->conf.docroot_cache_key) &&
3040+ !buffer_string_is_empty(con->uri.authority) &&
3041 buffer_is_equal(p->conf.docroot_cache_key, con->uri.authority)) {
3042 /* cache hit */
3043 buffer_copy_buffer(con->server_name, p->conf.docroot_cache_servername);
3044 buffer_copy_buffer(con->physical.doc_root, p->conf.docroot_cache_value);
3045 } else {
3046 /* build document-root */
3047- if ((con->uri.authority->used == 0) ||
3048+ if (buffer_string_is_empty(con->uri.authority) ||
3049 build_doc_root(srv, con, p, p->doc_root, con->uri.authority)) {
3050 /* not found, fallback the default-host */
3051 if (0 == build_doc_root(srv, con, p,
3052diff --git a/src/mod_ssi.c b/src/mod_ssi.c
3053index 981fd76..ed3b75c 100644
3054--- a/src/mod_ssi.c
3055+++ b/src/mod_ssi.c
3056@@ -172,7 +172,7 @@ static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data
3057
3058 ds = (data_string *)con->request.headers->data[i];
3059
3060- if (ds->value->used && ds->key->used) {
3061+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
3062 /* don't forward the Authorization: Header */
3063 if (0 == strcasecmp(ds->key->ptr, "AUTHORIZATION")) {
3064 continue;
3065@@ -189,7 +189,7 @@ static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data
3066
3067 ds = (data_string *)con->environment->data[i];
3068
3069- if (ds->value->used && ds->key->used) {
3070+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) {
3071 buffer_copy_string_encoded_cgi_varnames(srv->tmp_buf, CONST_BUF_LEN(ds->key), 0);
3072
3073 ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
3074@@ -264,7 +264,7 @@ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
3075 * parameter.
3076 */
3077
3078- if (con->request.pathinfo->used) {
3079+ if (!buffer_string_is_empty(con->request.pathinfo)) {
3080 ssi_env_add(p->ssi_cgi_env, CONST_STRING("PATH_INFO"), con->request.pathinfo->ptr);
3081 }
3082
3083@@ -272,7 +272,7 @@ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
3084 ssi_env_add(p->ssi_cgi_env, CONST_STRING("DOCUMENT_ROOT"), con->physical.doc_root->ptr);
3085
3086 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_URI"), con->request.uri->ptr);
3087- ssi_env_add(p->ssi_cgi_env, CONST_STRING("QUERY_STRING"), con->uri.query->used ? con->uri.query->ptr : "");
3088+ ssi_env_add(p->ssi_cgi_env, CONST_STRING("QUERY_STRING"), buffer_is_empty(con->uri.query) ? "" : con->uri.query->ptr);
3089 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_METHOD"), get_http_method_name(con->request.http_method));
3090 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REDIRECT_STATUS"), "200");
3091 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PROTOCOL"), get_http_version_name(con->request.http_version));
3092@@ -1029,7 +1029,7 @@ static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p)
3093 con->file_finished = 1;
3094 con->mode = p->id;
3095
3096- if (p->conf.content_type->used <= 1) {
3097+ if (buffer_string_is_empty(p->conf.content_type)) {
3098 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
3099 } else {
3100 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->conf.content_type));
3101@@ -1100,16 +1100,16 @@ URIHANDLER_FUNC(mod_ssi_physical_path) {
3102
3103 if (con->mode != DIRECT) return HANDLER_GO_ON;
3104
3105- if (con->physical.path->used == 0) return HANDLER_GO_ON;
3106+ if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
3107
3108 mod_ssi_patch_connection(srv, con, p);
3109
3110 for (k = 0; k < p->conf.ssi_extension->used; k++) {
3111 data_string *ds = (data_string *)p->conf.ssi_extension->data[k];
3112
3113- if (ds->value->used == 0) continue;
3114+ if (buffer_is_empty(ds->value)) continue;
3115
3116- if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) {
3117+ if (buffer_is_equal_right_len(con->physical.path, ds->value, buffer_string_length(ds->value))) {
3118 /* handle ssi-request */
3119
3120 if (mod_ssi_handle_request(srv, con, p)) {
3121diff --git a/src/mod_ssi_expr.c b/src/mod_ssi_expr.c
3122index 140d086..489fde4 100644
3123--- a/src/mod_ssi_expr.c
3124+++ b/src/mod_ssi_expr.c
3125@@ -35,7 +35,7 @@ void ssi_val_free(ssi_val_t *s) {
3126
3127 int ssi_val_tobool(ssi_val_t *B) {
3128 if (B->type == SSI_TYPE_STRING) {
3129- return B->str->used > 1 ? 1 : 0;
3130+ return !buffer_string_is_empty(B->str);
3131 } else {
3132 return B->bo;
3133 }
3134diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c
3135index e36c697..d40aa31 100644
3136--- a/src/mod_staticfile.c
3137+++ b/src/mod_staticfile.c
3138@@ -304,7 +304,7 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
3139 /* write END-OF-HEADER */
3140 buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n"));
3141
3142- con->response.content_length += b->used - 1;
3143+ con->response.content_length += buffer_string_length(b);
3144 chunkqueue_append_buffer(con->write_queue, b);
3145 buffer_free(b);
3146 }
3147@@ -325,7 +325,7 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
3148 buffer_append_string(b, boundary);
3149 buffer_append_string_len(b, "--\r\n", 4);
3150
3151- con->response.content_length += b->used - 1;
3152+ con->response.content_length += buffer_string_length(b);
3153 chunkqueue_append_buffer(con->write_queue, b);
3154 buffer_free(b);
3155
3156@@ -363,8 +363,8 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
3157
3158 /* someone else has done a decision for us */
3159 if (con->http_status != 0) return HANDLER_GO_ON;
3160- if (con->uri.path->used == 0) return HANDLER_GO_ON;
3161- if (con->physical.path->used == 0) return HANDLER_GO_ON;
3162+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
3163+ if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
3164
3165 /* someone else has handled this request */
3166 if (con->mode != DIRECT) return HANDLER_GO_ON;
3167@@ -381,7 +381,7 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
3168
3169 mod_staticfile_patch_connection(srv, con, p);
3170
3171- if (p->conf.disable_pathinfo && 0 != con->request.pathinfo->used) {
3172+ if (p->conf.disable_pathinfo && !buffer_string_is_empty(con->request.pathinfo)) {
3173 if (con->conf.log_request_handling) {
3174 log_error_write(srv, __FILE__, __LINE__, "s", "-- NOT handling file as static file, pathinfo forbidden");
3175 }
3176@@ -392,9 +392,9 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
3177 for (k = 0; k < p->conf.exclude_ext->used; k++) {
3178 ds = (data_string *)p->conf.exclude_ext->data[k];
3179
3180- if (ds->value->used == 0) continue;
3181+ if (buffer_is_empty(ds->value)) continue;
3182
3183- if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) {
3184+ if (buffer_is_equal_right_len(con->physical.path, ds->value, buffer_string_length(ds->value))) {
3185 if (con->conf.log_request_handling) {
3186 log_error_write(srv, __FILE__, __LINE__, "s", "-- NOT handling file as static file, extension forbidden");
3187 }
3188diff --git a/src/mod_status.c b/src/mod_status.c
3189index 99b332a..daecb08 100644
3190--- a/src/mod_status.c
3191+++ b/src/mod_status.c
3192@@ -449,7 +449,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
3193 connection *c = srv->conns->ptr[j];
3194 const char *state;
3195
3196- if (CON_STATE_READ == c->state && c->request.orig_uri->used > 0) {
3197+ if (CON_STATE_READ == c->state && !buffer_string_is_empty(c->request.orig_uri)) {
3198 state = "k";
3199 } else {
3200 state = connection_get_short_state(c->state);
3201@@ -501,7 +501,7 @@ static handler_t mod_status_handle_server_status_html(server *srv, connection *c
3202
3203 buffer_append_string_len(b, CONST_STR_LEN("</td><td class=\"string\">"));
3204
3205- if (CON_STATE_READ == c->state && c->request.orig_uri->used > 0) {
3206+ if (CON_STATE_READ == c->state && !buffer_string_is_empty(c->request.orig_uri)) {
3207 buffer_append_string_len(b, CONST_STR_LEN("keep-alive"));
3208 } else {
3209 buffer_append_string(b, connection_get_state(c->state));
3210diff --git a/src/mod_trigger_b4_dl.c b/src/mod_trigger_b4_dl.c
3211index cff125c..e1fa993 100644
3212--- a/src/mod_trigger_b4_dl.c
3213+++ b/src/mod_trigger_b4_dl.c
3214@@ -320,7 +320,7 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
3215
3216 if (con->mode != DIRECT) return HANDLER_GO_ON;
3217
3218- if (con->uri.path->used == 0) return HANDLER_GO_ON;
3219+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
3220
3221 mod_trigger_b4_dl_patch_connection(srv, con, p);
3222
3223@@ -356,7 +356,7 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
3224 }
3225
3226 /* check if URL is a trigger -> insert IP into DB */
3227- if ((n = pcre_exec(p->conf.trigger_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) {
3228+ if ((n = pcre_exec(p->conf.trigger_regex, NULL, CONST_BUF_LEN(con->uri.path), 0, 0, ovec, 3 * N)) < 0) {
3229 if (n != PCRE_ERROR_NOMATCH) {
3230 log_error_write(srv, __FILE__, __LINE__, "sd",
3231 "execution error while matching:", n);
3232@@ -383,11 +383,12 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
3233 # endif
3234 # if defined(HAVE_MEMCACHE_H)
3235 if (p->conf.mc) {
3236- size_t i;
3237+ size_t i, len;
3238 buffer_copy_buffer(p->tmp_buf, p->conf.mc_namespace);
3239 buffer_append_string(p->tmp_buf, remote_ip);
3240
3241- for (i = 0; i < p->tmp_buf->used - 1; i++) {
3242+ len = buffer_string_length(p->tmp_buf);
3243+ for (i = 0; i < len; i++) {
3244 if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-';
3245 }
3246
3247@@ -407,7 +408,7 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
3248 }
3249
3250 /* check if URL is a download -> check IP in DB, update timestamp */
3251- if ((n = pcre_exec(p->conf.download_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) {
3252+ if ((n = pcre_exec(p->conf.download_regex, NULL, CONST_BUF_LEN(con->uri.path), 0, 0, ovec, 3 * N)) < 0) {
3253 if (n != PCRE_ERROR_NOMATCH) {
3254 log_error_write(srv, __FILE__, __LINE__, "sd",
3255 "execution error while matching: ", n);
3256@@ -469,12 +470,13 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
3257 # if defined(HAVE_MEMCACHE_H)
3258 if (p->conf.mc) {
3259 void *r;
3260- size_t i;
3261+ size_t i, len;
3262
3263 buffer_copy_buffer(p->tmp_buf, p->conf.mc_namespace);
3264 buffer_append_string(p->tmp_buf, remote_ip);
3265
3266- for (i = 0; i < p->tmp_buf->used - 1; i++) {
3267+ len = buffer_string_length(p->tmp_buf);
3268+ for (i = 0; i < len; i++) {
3269 if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-';
3270 }
3271
3272diff --git a/src/mod_userdir.c b/src/mod_userdir.c
3273index 392f4b2..682f950 100644
3274--- a/src/mod_userdir.c
3275+++ b/src/mod_userdir.c
3276@@ -181,14 +181,14 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
3277 struct passwd *pwd = NULL;
3278 #endif
3279
3280- if (con->uri.path->used == 0) return HANDLER_GO_ON;
3281+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
3282
3283 mod_userdir_patch_connection(srv, con, p);
3284
3285 /* enforce the userdir.path to be set in the config, ugly fix for #1587;
3286 * should be replaced with a clean .enabled option in 1.5
3287 */
3288- if (!p->conf.active || p->conf.path->used == 0) return HANDLER_GO_ON;
3289+ if (!p->conf.active || buffer_is_empty(p->conf.path)) return HANDLER_GO_ON;
3290
3291 /* /~user/foo.html -> /home/user/public_html/foo.html */
3292
3293diff --git a/src/mod_usertrack.c b/src/mod_usertrack.c
3294index 29e9fdf..11aad95 100644
3295--- a/src/mod_usertrack.c
3296+++ b/src/mod_usertrack.c
3297@@ -101,8 +101,8 @@ SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
3298 if (buffer_string_is_empty(s->cookie_name)) {
3299 buffer_copy_string_len(s->cookie_name, CONST_STR_LEN("TRACKID"));
3300 } else {
3301- size_t j;
3302- for (j = 0; j < s->cookie_name->used - 1; j++) {
3303+ size_t j, len = buffer_string_length(s->cookie_name);
3304+ for (j = 0; j < len; j++) {
3305 char c = s->cookie_name->ptr[j] | 32;
3306 if (c < 'a' || c > 'z') {
3307 log_error_write(srv, __FILE__, __LINE__, "sb",
3308@@ -115,8 +115,8 @@ SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
3309 }
3310
3311 if (!buffer_string_is_empty(s->cookie_domain)) {
3312- size_t j;
3313- for (j = 0; j < s->cookie_domain->used - 1; j++) {
3314+ size_t j, len = buffer_string_length(s->cookie_domain);
3315+ for (j = 0; j < len; j++) {
3316 char c = s->cookie_domain->ptr[j];
3317 if (c <= 32 || c >= 127 || c == '"' || c == '\\') {
3318 log_error_write(srv, __FILE__, __LINE__, "sb",
3319@@ -175,7 +175,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
3320 li_MD5_CTX Md5Ctx;
3321 char hh[LI_ITOSTRING_LENGTH];
3322
3323- if (con->uri.path->used == 0) return HANDLER_GO_ON;
3324+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
3325
3326 mod_usertrack_patch_connection(srv, con, p);
3327
3328@@ -193,7 +193,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
3329 char *nc;
3330
3331 /* skip WS */
3332- for (nc = g + p->conf.cookie_name->used-1; *nc == ' ' || *nc == '\t'; nc++);
3333+ for (nc = g + buffer_string_length(p->conf.cookie_name); *nc == ' ' || *nc == '\t'; nc++);
3334
3335 if (*nc == '=') {
3336 /* ok, found the key of our own cookie */
3337@@ -219,8 +219,8 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
3338
3339 /* generate shared-secret */
3340 li_MD5_Init(&Md5Ctx);
3341- li_MD5_Update(&Md5Ctx, (unsigned char *)con->uri.path->ptr, con->uri.path->used - 1);
3342- li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
3343+ li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(con->uri.path));
3344+ li_MD5_Update(&Md5Ctx, CONST_STR_LEN("+"));
3345
3346 /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
3347 li_itostr(hh, srv->cur_ts);
3348diff --git a/src/mod_webdav.c b/src/mod_webdav.c
3349index 433b904..654108a 100644
3350--- a/src/mod_webdav.c
3351+++ b/src/mod_webdav.c
3352@@ -446,7 +446,7 @@ URIHANDLER_FUNC(mod_webdav_uri_handler) {
3353
3354 UNUSED(srv);
3355
3356- if (con->uri.path->used == 0) return HANDLER_GO_ON;
3357+ if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
3358
3359 mod_webdav_patch_connection(srv, con, p);
3360
3361@@ -558,9 +558,8 @@ static int webdav_delete_file(server *srv, connection *con, plugin_data *p, phys
3362 /* bind the values to the insert */
3363
3364 sqlite3_bind_text(stmt, 1,
3365- dst->rel_path->ptr,
3366- dst->rel_path->used - 1,
3367- SQLITE_TRANSIENT);
3368+ CONST_BUF_LEN(dst->rel_path),
3369+ SQLITE_TRANSIENT);
3370
3371 if (SQLITE_DONE != sqlite3_step(stmt)) {
3372 /* */
3373@@ -590,7 +589,7 @@ static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physi
3374 int status = 0;
3375
3376 if ((de->d_name[0] == '.' && de->d_name[1] == '\0') ||
3377- (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
3378+ (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
3379 continue;
3380 /* ignore the parent dir */
3381 }
3382@@ -636,9 +635,8 @@ static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physi
3383 /* bind the values to the insert */
3384
3385 sqlite3_bind_text(stmt, 1,
3386- d.rel_path->ptr,
3387- d.rel_path->used - 1,
3388- SQLITE_TRANSIENT);
3389+ CONST_BUF_LEN(d.rel_path),
3390+ SQLITE_TRANSIENT);
3391
3392 if (SQLITE_DONE != sqlite3_step(stmt)) {
3393 /* */
3394@@ -714,14 +712,12 @@ static int webdav_copy_file(server *srv, connection *con, plugin_data *p, physic
3395
3396 /* bind the values to the insert */
3397 sqlite3_bind_text(stmt, 1,
3398- dst->rel_path->ptr,
3399- dst->rel_path->used - 1,
3400- SQLITE_TRANSIENT);
3401+ CONST_BUF_LEN(dst->rel_path),
3402+ SQLITE_TRANSIENT);
3403
3404 sqlite3_bind_text(stmt, 2,
3405- src->rel_path->ptr,
3406- src->rel_path->used - 1,
3407- SQLITE_TRANSIENT);
3408+ CONST_BUF_LEN(src->rel_path),
3409+ SQLITE_TRANSIENT);
3410
3411 if (SQLITE_DONE != sqlite3_step(stmt)) {
3412 /* */
3413@@ -751,8 +747,8 @@ static int webdav_copy_dir(server *srv, connection *con, plugin_data *p, physica
3414 while (NULL != (de = readdir(srcdir))) {
3415 struct stat st;
3416
3417- if ((de->d_name[0] == '.' && de->d_name[1] == '\0') ||
3418- (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
3419+ if ((de->d_name[0] == '.' && de->d_name[1] == '\0')
3420+ || (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
3421 continue;
3422 }
3423
3424@@ -793,14 +789,12 @@ static int webdav_copy_dir(server *srv, connection *con, plugin_data *p, physica
3425
3426 /* bind the values to the insert */
3427 sqlite3_bind_text(stmt, 1,
3428- dst->rel_path->ptr,
3429- dst->rel_path->used - 1,
3430- SQLITE_TRANSIENT);
3431+ CONST_BUF_LEN(dst->rel_path),
3432+ SQLITE_TRANSIENT);
3433
3434 sqlite3_bind_text(stmt, 2,
3435- src->rel_path->ptr,
3436- src->rel_path->used - 1,
3437- SQLITE_TRANSIENT);
3438+ CONST_BUF_LEN(src->rel_path),
3439+ SQLITE_TRANSIENT);
3440
3441 if (SQLITE_DONE != sqlite3_step(stmt)) {
3442 /* */
3443@@ -851,9 +845,9 @@ static int webdav_get_live_property(server *srv, connection *con, plugin_data *p
3444 for (k = 0; k < con->conf.mimetypes->used; k++) {
3445 data_string *ds = (data_string *)con->conf.mimetypes->data[k];
3446
3447- if (ds->key->used == 0) continue;
3448+ if (buffer_is_empty(ds->key)) continue;
3449
3450- if (buffer_is_equal_right_len(dst->path, ds->key, ds->key->used - 1)) {
3451+ if (buffer_is_equal_right_len(dst->path, ds->key, buffer_string_length(ds->key))) {
3452 buffer_append_string_len(b,CONST_STR_LEN("<D:getcontenttype>"));
3453 buffer_append_string_buffer(b, ds->value);
3454 buffer_append_string_len(b, CONST_STR_LEN("</D:getcontenttype>"));
3455@@ -907,17 +901,16 @@ static int webdav_get_property(server *srv, connection *con, plugin_data *p, phy
3456 /* bind the values to the insert */
3457
3458 sqlite3_bind_text(stmt, 1,
3459- dst->rel_path->ptr,
3460- dst->rel_path->used - 1,
3461- SQLITE_TRANSIENT);
3462+ CONST_BUF_LEN(dst->rel_path),
3463+ SQLITE_TRANSIENT);
3464 sqlite3_bind_text(stmt, 2,
3465- prop_name,
3466- strlen(prop_name),
3467- SQLITE_TRANSIENT);
3468+ prop_name,
3469+ strlen(prop_name),
3470+ SQLITE_TRANSIENT);
3471 sqlite3_bind_text(stmt, 3,
3472- prop_ns,
3473- strlen(prop_ns),
3474- SQLITE_TRANSIENT);
3475+ prop_ns,
3476+ strlen(prop_ns),
3477+ SQLITE_TRANSIENT);
3478
3479 /* it is the PK */
3480 while (SQLITE_ROW == sqlite3_step(stmt)) {
3481@@ -1046,7 +1039,7 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
3482 break;
3483 case MEM_CHUNK:
3484 /* append to the buffer */
3485- weHave = c->mem->used - 1 - c->offset;
3486+ weHave = buffer_string_length(c->mem) - c->offset;
3487
3488 if (weHave > weWant) weHave = weWant;
3489
3490@@ -1190,8 +1183,8 @@ static int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer
3491 sqlite3_reset(stmt);
3492
3493 sqlite3_bind_text(stmt, 1,
3494- CONST_BUF_LEN(uri),
3495- SQLITE_TRANSIENT);
3496+ CONST_BUF_LEN(uri),
3497+ SQLITE_TRANSIENT);
3498
3499 while (SQLITE_ROW == sqlite3_step(stmt)) {
3500 has_lock = 0;
3501@@ -1223,7 +1216,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3502
3503 if (!p->conf.enabled) return HANDLER_GO_ON;
3504 /* physical path is setup */
3505- if (con->physical.path->used == 0) return HANDLER_GO_ON;
3506+ if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
3507
3508 /* PROPFIND need them */
3509 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Depth"))) {
3510@@ -1274,7 +1267,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3511 if (prop->type == XML_TEXT_NODE) continue; /* ignore WS */
3512
3513 if (prop->ns &&
3514- (0 == xmlStrcmp(prop->ns->href, BAD_CAST "")) &&
3515+ (0 == xmlStrcmp(prop->ns->href, BAD_CAST "")) &&
3516 (0 != xmlStrcmp(prop->ns->prefix, BAD_CAST ""))) {
3517 size_t i;
3518 log_error_write(srv, __FILE__, __LINE__, "ss",
3519@@ -1318,9 +1311,8 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3520 /* bind the values to the insert */
3521
3522 sqlite3_bind_text(stmt, 1,
3523- con->uri.path->ptr,
3524- con->uri.path->used - 1,
3525- SQLITE_TRANSIENT);
3526+ CONST_BUF_LEN(con->uri.path),
3527+ SQLITE_TRANSIENT);
3528
3529 if (SQLITE_DONE != sqlite3_step(stmt)) {
3530 }
3531@@ -1757,7 +1749,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3532 }
3533 break;
3534 case MEM_CHUNK:
3535- if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
3536+ if ((r = write(fd, c->mem->ptr + c->offset, buffer_string_length(c->mem) - c->offset)) < 0) {
3537 switch(errno) {
3538 case ENOSPC:
3539 con->http_status = 507;
3540@@ -1810,7 +1802,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3541 }
3542
3543 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Overwrite"))) {
3544- if (ds->value->used != 2 ||
3545+ if (buffer_string_length(ds->value) != 1 ||
3546 (ds->value->ptr[0] != 'F' &&
3547 ds->value->ptr[0] != 'T') ) {
3548 con->http_status = 400;
3549@@ -1884,7 +1876,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3550
3551 /* don't add a second / */
3552 if (p->physical.rel_path->ptr[0] == '/') {
3553- buffer_append_string_len(p->physical.path, p->physical.rel_path->ptr + 1, p->physical.rel_path->used - 2);
3554+ buffer_append_string_len(p->physical.path, p->physical.rel_path->ptr + 1, buffer_string_length(p->physical.rel_path) - 1);
3555 } else {
3556 buffer_append_string_buffer(p->physical.path, p->physical.rel_path);
3557 }
3558@@ -1993,9 +1985,8 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3559
3560 /* bind the values to the insert */
3561 sqlite3_bind_text(stmt, 1,
3562- con->uri.path->ptr,
3563- con->uri.path->used - 1,
3564- SQLITE_TRANSIENT);
3565+ CONST_BUF_LEN(con->uri.path),
3566+ SQLITE_TRANSIENT);
3567
3568 if (SQLITE_DONE != sqlite3_step(stmt)) {
3569 log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move(delete old) failed:", sqlite3_errmsg(p->conf.sql));
3570@@ -2009,14 +2000,12 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3571
3572 /* bind the values to the insert */
3573 sqlite3_bind_text(stmt, 1,
3574- p->uri.path->ptr,
3575- p->uri.path->used - 1,
3576- SQLITE_TRANSIENT);
3577+ CONST_BUF_LEN(p->uri.path),
3578+ SQLITE_TRANSIENT);
3579
3580 sqlite3_bind_text(stmt, 2,
3581- con->uri.path->ptr,
3582- con->uri.path->used - 1,
3583- SQLITE_TRANSIENT);
3584+ CONST_BUF_LEN(con->uri.path),
3585+ SQLITE_TRANSIENT);
3586
3587 if (SQLITE_DONE != sqlite3_step(stmt)) {
3588 log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move failed:", sqlite3_errmsg(p->conf.sql));
3589@@ -2121,29 +2110,28 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
3590 /* bind the values to the insert */
3591
3592 sqlite3_bind_text(stmt, 1,
3593- con->uri.path->ptr,
3594- con->uri.path->used - 1,
3595- SQLITE_TRANSIENT);
3596+ CONST_BUF_LEN(con->uri.path),
3597+ SQLITE_TRANSIENT);
3598 sqlite3_bind_text(stmt, 2,
3599- (char *)prop->name,
3600- strlen((char *)prop->name),
3601- SQLITE_TRANSIENT);
3602+ (char *)prop->name,
3603+ strlen((char *)prop->name),
3604+ SQLITE_TRANSIENT);
3605 if (prop->ns) {
3606 sqlite3_bind_text(stmt, 3,
3607- (char *)prop->ns->href,
3608- strlen((char *)prop->ns->href),
3609- SQLITE_TRANSIENT);
3610+ (char *)prop->ns->href,
3611+ strlen((char *)prop->ns->href),
3612+ SQLITE_TRANSIENT);
3613 } else {
3614 sqlite3_bind_text(stmt, 3,
3615- "",
3616- 0,
3617- SQLITE_TRANSIENT);
3618+ "",
3619+ 0,
3620+ SQLITE_TRANSIENT);
3621 }
3622 if (stmt == p->conf.stmt_update_prop) {
3623 sqlite3_bind_text(stmt, 4,
3624- (char *)xmlNodeGetContent(prop),
3625- strlen((char *)xmlNodeGetContent(prop)),
3626- SQLITE_TRANSIENT);
3627+ (char *)xmlNodeGetContent(prop),
3628+ strlen((char *)xmlNodeGetContent(prop)),
3629+ SQLITE_TRANSIENT);
3630 }
3631
3632 if (SQLITE_DONE != (r = sqlite3_step(stmt))) {
3633@@ -2290,9 +2278,8 @@ propmatch_cleanup:
3634 sqlite3_reset(stmt);
3635
3636 sqlite3_bind_text(stmt, 1,
3637- p->uri.path->ptr,
3638- p->uri.path->used - 1,
3639- SQLITE_TRANSIENT);
3640+ CONST_BUF_LEN(p->uri.path),
3641+ SQLITE_TRANSIENT);
3642
3643 /* it is the PK */
3644 while (SQLITE_ROW == sqlite3_step(stmt)) {
3645@@ -2339,32 +2326,32 @@ propmatch_cleanup:
3646 sqlite3_reset(stmt);
3647
3648 sqlite3_bind_text(stmt, 1,
3649- CONST_BUF_LEN(p->tmp_buf),
3650- SQLITE_TRANSIENT);
3651+ CONST_BUF_LEN(p->tmp_buf),
3652+ SQLITE_TRANSIENT);
3653
3654 sqlite3_bind_text(stmt, 2,
3655- CONST_BUF_LEN(con->uri.path),
3656- SQLITE_TRANSIENT);
3657+ CONST_BUF_LEN(con->uri.path),
3658+ SQLITE_TRANSIENT);
3659
3660 sqlite3_bind_text(stmt, 3,
3661- (const char *)lockscope,
3662- xmlStrlen(lockscope),
3663- SQLITE_TRANSIENT);
3664+ (const char *)lockscope,
3665+ xmlStrlen(lockscope),
3666+ SQLITE_TRANSIENT);
3667
3668 sqlite3_bind_text(stmt, 4,
3669- (const char *)locktype,
3670- xmlStrlen(locktype),
3671- SQLITE_TRANSIENT);
3672+ (const char *)locktype,
3673+ xmlStrlen(locktype),
3674+ SQLITE_TRANSIENT);
3675
3676 /* owner */
3677 sqlite3_bind_text(stmt, 5,
3678- "",
3679- 0,
3680- SQLITE_TRANSIENT);
3681+ "",
3682+ 0,
3683+ SQLITE_TRANSIENT);
3684
3685 /* depth */
3686 sqlite3_bind_int(stmt, 6,
3687- depth);
3688+ depth);
3689
3690
3691 if (SQLITE_DONE != sqlite3_step(stmt)) {
3692@@ -2394,19 +2381,19 @@ propmatch_cleanup:
3693 sqlite3_stmt *stmt = p->conf.stmt_refresh_lock;
3694
3695 /* remove the < > around the token */
3696- if (locktoken->used < 6) {
3697+ if (buffer_string_length(locktoken) < 5) {
3698 con->http_status = 400;
3699
3700 return HANDLER_FINISHED;
3701 }
3702
3703- buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, locktoken->used - 5);
3704+ buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, buffer_string_length(locktoken) - 4);
3705
3706 sqlite3_reset(stmt);
3707
3708 sqlite3_bind_text(stmt, 1,
3709- CONST_BUF_LEN(p->tmp_buf),
3710- SQLITE_TRANSIENT);
3711+ CONST_BUF_LEN(p->tmp_buf),
3712+ SQLITE_TRANSIENT);
3713
3714 if (SQLITE_DONE != sqlite3_step(stmt)) {
3715 log_error_write(srv, __FILE__, __LINE__, "ss",
3716@@ -2437,7 +2424,7 @@ propmatch_cleanup:
3717 sqlite3_stmt *stmt = p->conf.stmt_remove_lock;
3718
3719 /* remove the < > around the token */
3720- if (locktoken->used < 4) {
3721+ if (buffer_string_length(locktoken) < 3) {
3722 con->http_status = 400;
3723
3724 return HANDLER_FINISHED;
3725@@ -2453,17 +2440,17 @@ propmatch_cleanup:
3726 * - 412
3727 * */
3728
3729- buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, locktoken->used - 3);
3730+ buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, buffer_string_length(locktoken) - 2);
3731
3732 sqlite3_reset(stmt);
3733
3734 sqlite3_bind_text(stmt, 1,
3735- CONST_BUF_LEN(p->tmp_buf),
3736- SQLITE_TRANSIENT);
3737+ CONST_BUF_LEN(p->tmp_buf),
3738+ SQLITE_TRANSIENT);
3739
3740 sqlite3_bind_text(stmt, 2,
3741- CONST_BUF_LEN(con->uri.path),
3742- SQLITE_TRANSIENT);
3743+ CONST_BUF_LEN(con->uri.path),
3744+ SQLITE_TRANSIENT);
3745
3746 if (SQLITE_DONE != sqlite3_step(stmt)) {
3747 log_error_write(srv, __FILE__, __LINE__, "ss",
3748diff --git a/src/network_linux_sendfile.c b/src/network_linux_sendfile.c
3749index 8d7598a..b967f3c 100644
3750--- a/src/network_linux_sendfile.c
3751+++ b/src/network_linux_sendfile.c
3752@@ -54,12 +54,12 @@ int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd,
3753 tc = tc->next, num_chunks++);
3754
3755 for (tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
3756- if (tc->mem->used == 0) {
3757+ if (buffer_string_is_empty(tc->mem)) {
3758 chunks[i].iov_base = tc->mem->ptr;
3759 chunks[i].iov_len = 0;
3760 } else {
3761 offset = tc->mem->ptr + tc->offset;
3762- toSend = tc->mem->used - 1 - tc->offset;
3763+ toSend = buffer_string_length(tc->mem) - tc->offset;
3764
3765 chunks[i].iov_base = offset;
3766
3767diff --git a/src/network_openssl.c b/src/network_openssl.c
3768index 04c29c0..d9ae33c 100644
3769--- a/src/network_openssl.c
3770+++ b/src/network_openssl.c
3771@@ -67,13 +67,13 @@ int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chu
3772 off_t toSend;
3773 ssize_t r;
3774
3775- if (c->mem->used == 0 || c->mem->used == 1) {
3776+ if (buffer_string_is_empty(c->mem)) {
3777 chunk_finished = 1;
3778 break;
3779 }
3780
3781 offset = c->mem->ptr + c->offset;
3782- toSend = c->mem->used - 1 - c->offset;
3783+ toSend = buffer_string_length(c->mem) - c->offset;
3784 if (toSend > max_bytes) toSend = max_bytes;
3785
3786 /**
3787@@ -149,7 +149,7 @@ int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chu
3788 max_bytes -= r;
3789 }
3790
3791- if (c->offset == (off_t)c->mem->used - 1) {
3792+ if (c->offset == (off_t)buffer_string_length(c->mem)) {
3793 chunk_finished = 1;
3794 }
3795
3796diff --git a/src/network_write.c b/src/network_write.c
3797index d46649b..6a89b50 100644
3798--- a/src/network_write.c
3799+++ b/src/network_write.c
3800@@ -36,13 +36,13 @@ int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqu
3801 off_t toSend;
3802 ssize_t r;
3803
3804- if (c->mem->used == 0) {
3805+ if (buffer_string_is_empty(c->mem)) {
3806 chunk_finished = 1;
3807 break;
3808 }
3809
3810 offset = c->mem->ptr + c->offset;
3811- toSend = c->mem->used - 1 - c->offset;
3812+ toSend = buffer_string_length(c->mem) - c->offset;
3813 if (toSend > max_bytes) toSend = max_bytes;
3814
3815 #ifdef __WIN32
3816@@ -75,7 +75,7 @@ int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqu
3817 cq->bytes_out += r;
3818 max_bytes -= r;
3819
3820- if (c->offset == (off_t)c->mem->used - 1) {
3821+ if (c->offset == (off_t)buffer_string_length(c->mem)) {
3822 chunk_finished = 1;
3823 }
3824
3825diff --git a/src/network_writev.c b/src/network_writev.c
3826index 1b93547..895336c 100644
3827--- a/src/network_writev.c
3828+++ b/src/network_writev.c
3829@@ -69,12 +69,12 @@ int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkq
3830 chunks = calloc(num_chunks, sizeof(*chunks));
3831
3832 for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
3833- if (tc->mem->used == 0) {
3834+ if (buffer_string_is_empty(tc->mem)) {
3835 chunks[i].iov_base = tc->mem->ptr;
3836 chunks[i].iov_len = 0;
3837 } else {
3838 offset = tc->mem->ptr + tc->offset;
3839- toSend = tc->mem->used - 1 - tc->offset;
3840+ toSend = buffer_string_length(tc->mem) - tc->offset;
3841
3842 chunks[i].iov_base = offset;
3843
3844diff --git a/src/proc_open.c b/src/proc_open.c
3845index c29b9c6..167027a 100644
3846--- a/src/proc_open.c
3847+++ b/src/proc_open.c
3848@@ -284,8 +284,7 @@ static void proc_read_fd_to_buffer(int fd, buffer *b) {
3849 if ((s = read(fd, (void *)(b->ptr + buffer_string_length(b)), buffer_string_space(b))) <= 0) {
3850 break;
3851 }
3852- b->used += s;
3853- b->ptr[b->used-1] = '\0';
3854+ buffer_commit(b, s);
3855 }
3856 }
3857 /* }}} */
3858@@ -298,7 +297,7 @@ int proc_open_buffer(const char *command, buffer *in, buffer *out, buffer *err)
3859 }
3860
3861 if (in) {
3862- if (write(proc.in.fd, (void *)in->ptr, in->used) < 0) {
3863+ if (write(proc.in.fd, CONST_BUF_LEN(in)) < 0) {
3864 perror("error writing pipe");
3865 return -1;
3866 }
3867@@ -315,7 +314,7 @@ int proc_open_buffer(const char *command, buffer *in, buffer *out, buffer *err)
3868 } else {
3869 buffer *tmp = buffer_init();
3870 proc_read_fd_to_buffer(proc.err.fd, tmp);
3871- if (tmp->used > 0 && write(2, (void*)tmp->ptr, tmp->used) < 0) {
3872+ if (!buffer_string_is_empty(tmp) && write(2, CONST_BUF_LEN(tmp)) < 0) {
3873 perror("error writing pipe");
3874 buffer_free(tmp);
3875 return -1;
3876diff --git a/src/request.c b/src/request.c
3877index 65d0a0e..993cb28 100644
3878--- a/src/request.c
3879+++ b/src/request.c
3880@@ -34,9 +34,9 @@ static int request_check_hostname(server *srv, connection *con, buffer *host) {
3881 */
3882
3883 /* no Host: */
3884- if (!host || host->used == 0) return 0;
3885+ if (buffer_is_empty(host)) return 0;
3886
3887- host_len = host->used - 1;
3888+ host_len = buffer_string_length(host);
3889
3890 /* IPv6 adress */
3891 if (host->ptr[0] == '[') {
3892@@ -92,10 +92,9 @@ static int request_check_hostname(server *srv, connection *con, buffer *host) {
3893 /* if the hostname ends in a "." strip it */
3894 if (host->ptr[host_len-1] == '.') {
3895 /* shift port info one left */
3896- if (NULL != colon) memmove(colon-1, colon, host->used - host_len);
3897- else host->ptr[host_len-1] = '\0';
3898+ if (NULL != colon) memmove(colon-1, colon, buffer_string_length(host) - host_len);
3899+ buffer_string_set_length(host, buffer_string_length(host) - 1);
3900 host_len -= 1;
3901- host->used -= 1;
3902 }
3903
3904 if (host_len == 0) return -1;
3905@@ -213,7 +212,7 @@ static int request_check_hostname(server *srv, connection *con, buffer *host) {
3906 #endif
3907
3908 static int http_request_split_value(array *vals, buffer *b) {
3909- size_t i;
3910+ size_t i, len;
3911 int state = 0;
3912
3913 const char *current;
3914@@ -226,10 +225,11 @@ static int http_request_split_value(array *vals, buffer *b) {
3915 * into a array (more or less a explode() incl. striping of whitespaces
3916 */
3917
3918- if (b->used == 0) return 0;
3919+ if (buffer_string_is_empty(b)) return 0;
3920
3921 current = b->ptr;
3922- for (i = 0; i < b->used; ++i, ++current) {
3923+ len = buffer_string_length(b);
3924+ for (i = 0; i <= len; ++i, ++current) {
3925 data_string *ds;
3926
3927 switch (state) {
3928@@ -297,7 +297,7 @@ int http_request_parse(server *srv, connection *con) {
3929 int line = 0;
3930
3931 int request_line_stage = 0;
3932- size_t i, first;
3933+ size_t i, first, ilen;
3934
3935 int done = 0;
3936
3937@@ -310,7 +310,7 @@ int http_request_parse(server *srv, connection *con) {
3938 if (con->conf.log_request_header) {
3939 log_error_write(srv, __FILE__, __LINE__, "sdsdSb",
3940 "fd:", con->fd,
3941- "request-len:", con->request.request->used,
3942+ "request-len:", buffer_string_length(con->request.request),
3943 "\n", con->request.request);
3944 }
3945
3946@@ -319,7 +319,7 @@ int http_request_parse(server *srv, connection *con) {
3947 con->request.request->ptr[1] == '\n') {
3948 /* we are in keep-alive and might get \r\n after a previous POST request.*/
3949
3950- buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, con->request.request->used - 1 - 2);
3951+ buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, buffer_string_length(con->request.request) - 2);
3952 } else {
3953 /* fill the local request buffer */
3954 buffer_copy_buffer(con->parse_request, con->request.request);
3955@@ -334,15 +334,14 @@ int http_request_parse(server *srv, connection *con) {
3956 *
3957 * <method> <uri> <protocol>\r\n
3958 * */
3959- for (i = 0, first = 0; i < con->parse_request->used && line == 0; i++) {
3960- char *cur = con->parse_request->ptr + i;
3961-
3962- switch(*cur) {
3963+ ilen = buffer_string_length(con->parse_request);
3964+ for (i = 0, first = 0; i < ilen && line == 0; i++) {
3965+ switch(con->parse_request->ptr[i]) {
3966 case '\r':
3967 if (con->parse_request->ptr[i+1] == '\n') {
3968 http_method_t r;
3969 char *nuri = NULL;
3970- size_t j;
3971+ size_t j, jlen;
3972
3973 /* \r\n -> \0\0 */
3974 con->parse_request->ptr[i] = '\0';
3975@@ -476,7 +475,8 @@ int http_request_parse(server *srv, connection *con) {
3976 }
3977
3978 /* check uri for invalid characters */
3979- for (j = 0; j < con->request.uri->used - 1; j++) {
3980+ jlen = buffer_string_length(con->request.uri);
3981+ for (j = 0; j < jlen; j++) {
3982 if (!request_uri_is_valid_char(con->request.uri->ptr[j])) {
3983 unsigned char buf[2];
3984 con->http_status = 400;
3985@@ -551,7 +551,7 @@ int http_request_parse(server *srv, connection *con) {
3986
3987 in_folding = 0;
3988
3989- if (con->request.uri->used == 1) {
3990+ if (buffer_string_is_empty(con->request.uri)) {
3991 con->http_status = 400;
3992 con->response.keep_alive = 0;
3993 con->keep_alive = 0;
3994@@ -579,7 +579,7 @@ int http_request_parse(server *srv, connection *con) {
3995 con->request.http_host = ds->value;
3996 }
3997
3998- for (; i < con->parse_request->used && !done; i++) {
3999+ for (; i <= ilen && !done; i++) {
4000 char *cur = con->parse_request->ptr + i;
4001
4002 if (is_key) {
4003@@ -825,7 +825,7 @@ int http_request_parse(server *srv, connection *con) {
4004 } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) {
4005 char *err;
4006 unsigned long int r;
4007- size_t j;
4008+ size_t j, jlen;
4009
4010 if (con_length_set) {
4011 con->http_status = 400;
4012@@ -842,9 +842,8 @@ int http_request_parse(server *srv, connection *con) {
4013 return 0;
4014 }
4015
4016- if (ds->value->used == 0) SEGFAULT();
4017-
4018- for (j = 0; j < ds->value->used - 1; j++) {
4019+ jlen = buffer_string_length(ds->value);
4020+ for (j = 0; j < jlen; j++) {
4021 char c = ds->value->ptr[j];
4022 if (!isdigit((unsigned char)c)) {
4023 log_error_write(srv, __FILE__, __LINE__, "sbs",
4024@@ -1177,9 +1176,9 @@ int http_request_parse(server *srv, connection *con) {
4025 int http_request_header_finished(server *srv, connection *con) {
4026 UNUSED(srv);
4027
4028- if (con->request.request->used < 5) return 0;
4029+ if (buffer_string_length(con->request.request) < 4) return 0;
4030
4031- if (0 == memcmp(con->request.request->ptr + con->request.request->used - 5, "\r\n\r\n", 4)) return 1;
4032+ if (0 == memcmp(con->request.request->ptr + buffer_string_length(con->request.request) - 4, CONST_STR_LEN("\r\n\r\n"))) return 1;
4033 if (NULL != strstr(con->request.request->ptr, "\r\n\r\n")) return 1;
4034
4035 return 0;
4036diff --git a/src/response.c b/src/response.c
4037index 5072d05..357f43b 100644
4038--- a/src/response.c
4039+++ b/src/response.c
4040@@ -70,7 +70,7 @@ int http_response_write_header(server *srv, connection *con) {
4041
4042 ds = (data_string *)con->response.headers->data[i];
4043
4044- if (ds->value->used && ds->key->used &&
4045+ if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key) &&
4046 0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-LIGHTTPD-")) &&
4047 0 != strncasecmp(ds->key->ptr, CONST_STR_LEN("X-Sendfile"))) {
4048 if (0 == strcasecmp(ds->key->ptr, "Date")) have_date = 1;
4049@@ -99,10 +99,7 @@ int http_response_write_header(server *srv, connection *con) {
4050 if (srv->cur_ts != srv->last_generated_date_ts) {
4051 buffer_string_prepare_copy(srv->ts_date_str, 255);
4052
4053- strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
4054- "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
4055-
4056- srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1;
4057+ buffer_append_strftime(srv->ts_date_str, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
4058
4059 srv->last_generated_date_ts = srv->cur_ts;
4060 }
4061@@ -113,7 +110,7 @@ int http_response_write_header(server *srv, connection *con) {
4062 if (!have_server) {
4063 if (buffer_is_empty(con->conf.server_tag)) {
4064 buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_DESC));
4065- } else if (con->conf.server_tag->used > 1) {
4066+ } else if (!buffer_string_is_empty(con->conf.server_tag)) {
4067 buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: "));
4068 buffer_append_string_encoded(b, CONST_BUF_LEN(con->conf.server_tag), ENCODING_HTTP_HEADER);
4069 }
4070@@ -121,7 +118,7 @@ int http_response_write_header(server *srv, connection *con) {
4071
4072 buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n"));
4073
4074- con->bytes_header = b->used - 1;
4075+ con->bytes_header = buffer_string_length(b);
4076
4077 if (con->conf.log_response_header) {
4078 log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b);
4079@@ -204,8 +201,7 @@ static void https_add_ssl_entries(connection *con) {
4080 buffer_string_prepare_copy(envds->value, n);
4081 BIO_read(bio, envds->value->ptr, n);
4082 BIO_free(bio);
4083- envds->value->ptr[n] = '\0';
4084- envds->value->used = n+1;
4085+ buffer_commit(envds->value, n);
4086 array_insert_unique(con->environment, (data_unset *)envds);
4087 }
4088 }
4089@@ -229,7 +225,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
4090 }
4091
4092 /* no decision yet, build conf->filename */
4093- if (con->mode == DIRECT && con->physical.path->used == 0) {
4094+ if (con->mode == DIRECT && buffer_is_empty(con->physical.path)) {
4095 char *qstr;
4096
4097 /* we only come here when we have the parse the full request again
4098@@ -294,8 +290,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
4099
4100 /** their might be a fragment which has to be cut away */
4101 if (NULL != (qstr = strchr(con->request.uri->ptr, '#'))) {
4102- con->request.uri->used = qstr - con->request.uri->ptr;
4103- con->request.uri->ptr[con->request.uri->used++] = '\0';
4104+ buffer_string_set_length(con->request.uri, qstr - con->request.uri->ptr);
4105 }
4106
4107 /** extract query string from request.uri */
4108@@ -451,23 +446,18 @@ handler_t http_response_prepare(server *srv, connection *con) {
4109
4110 if (con->physical.rel_path->used > 1) {
4111 buffer *b = con->physical.rel_path;
4112+ size_t len = buffer_string_length(b);
4113 size_t i;
4114
4115- if (b->used > 2 &&
4116- b->ptr[b->used-2] == '/' &&
4117- (b->ptr[b->used-3] == ' ' ||
4118- b->ptr[b->used-3] == '.')) {
4119- b->ptr[b->used--] = '\0';
4120- }
4121-
4122- for (i = b->used - 2; b->used > 1; i--) {
4123- if (b->ptr[i] == ' ' ||
4124- b->ptr[i] == '.') {
4125- b->ptr[b->used--] = '\0';
4126- } else {
4127- break;
4128- }
4129+ /* strip trailing " /" or "./" once */
4130+ if (len > 1 &&
4131+ b->ptr[len - 1] == '/' &&
4132+ (b->ptr[len - 2] == ' ' || b->ptr[len - 2] == '.')) {
4133+ len -= 2;
4134 }
4135+ /* strip all trailing " " and "." */
4136+ while (len > 0 && ( ' ' == b->ptr[len-1] || '.' == b->ptr[len-1] ) ) --len;
4137+ buffer_string_set_length(b, len);
4138 }
4139 #endif
4140
4141@@ -515,9 +505,9 @@ handler_t http_response_prepare(server *srv, connection *con) {
4142 buffer_copy_buffer(con->physical.basedir, con->physical.doc_root);
4143 buffer_copy_buffer(con->physical.path, con->physical.doc_root);
4144 buffer_append_slash(con->physical.path);
4145- if (con->physical.rel_path->used &&
4146+ if (!buffer_string_is_empty(con->physical.rel_path) &&
4147 con->physical.rel_path->ptr[0] == '/') {
4148- buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
4149+ buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, buffer_string_length(con->physical.rel_path) - 1);
4150 } else {
4151 buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
4152 }
4153@@ -589,7 +579,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
4154 };
4155 #endif
4156 if (S_ISDIR(sce->st.st_mode)) {
4157- if (con->uri.path->ptr[con->uri.path->used - 2] != '/') {
4158+ if (con->uri.path->ptr[buffer_string_length(con->uri.path) - 1] != '/') {
4159 /* redirect to .../ */
4160
4161 http_response_redirect_to_directory(srv, con);
4162@@ -672,7 +662,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
4163 }
4164
4165 if (slash) pathinfo = slash;
4166- } while ((found == 0) && (slash != NULL) && ((size_t)(slash - srv->tmp_buf->ptr) > (con->physical.basedir->used - 2)));
4167+ } while ((found == 0) && (slash != NULL) && ((size_t)(slash - srv->tmp_buf->ptr) > (buffer_string_length(con->physical.basedir) - 1)));
4168
4169 if (found == 0) {
4170 /* no it really doesn't exists */
4171@@ -711,8 +701,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
4172 * shorten uri.path
4173 */
4174
4175- con->uri.path->used -= strlen(pathinfo);
4176- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
4177+ buffer_string_set_length(con->uri.path, buffer_string_length(con->uri.path) - strlen(pathinfo));
4178 }
4179
4180 if (con->conf.log_request_handling) {
4181diff --git a/src/server.c b/src/server.c
4182index 71d3538..5089375 100644
4183--- a/src/server.c
4184+++ b/src/server.c
4185@@ -666,7 +666,7 @@ int main (int argc, char **argv) {
4186 #endif
4187
4188 /* check document-root */
4189- if (srv->config_storage[0]->document_root->used <= 1) {
4190+ if (buffer_string_is_empty(srv->config_storage[0]->document_root)) {
4191 log_error_write(srv, __FILE__, __LINE__, "s",
4192 "document-root is not set\n");
4193
4194@@ -686,7 +686,7 @@ int main (int argc, char **argv) {
4195 }
4196
4197 /* open pid file BEFORE chroot */
4198- if (srv->srvconf.pid_file->used) {
4199+ if (!buffer_string_is_empty(srv->srvconf.pid_file)) {
4200 if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
4201 struct stat st;
4202 if (errno != EEXIST) {
4203@@ -780,7 +780,7 @@ int main (int argc, char **argv) {
4204
4205 #ifdef HAVE_PWD_H
4206 /* set user and group */
4207- if (srv->srvconf.username->used) {
4208+ if (!buffer_string_is_empty(srv->srvconf.username)) {
4209 if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
4210 log_error_write(srv, __FILE__, __LINE__, "sb",
4211 "can't find username", srv->srvconf.username);
4212@@ -794,7 +794,7 @@ int main (int argc, char **argv) {
4213 }
4214 }
4215
4216- if (srv->srvconf.groupname->used) {
4217+ if (!buffer_string_is_empty(srv->srvconf.groupname)) {
4218 if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
4219 log_error_write(srv, __FILE__, __LINE__, "sb",
4220 "can't find groupname", srv->srvconf.groupname);
4221@@ -828,13 +828,13 @@ int main (int argc, char **argv) {
4222 log_error_write(srv, __FILE__, __LINE__, "ss", "setgroups failed: ", strerror(errno));
4223 return -1;
4224 }
4225- if (srv->srvconf.username->used) {
4226+ if (!buffer_string_is_empty(srv->srvconf.username)) {
4227 initgroups(srv->srvconf.username->ptr, grp->gr_gid);
4228 }
4229 }
4230 #endif
4231 #ifdef HAVE_CHROOT
4232- if (srv->srvconf.changeroot->used) {
4233+ if (!buffer_string_is_empty(srv->srvconf.changeroot)) {
4234 tzset();
4235
4236 if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
4237@@ -1001,8 +1001,7 @@ int main (int argc, char **argv) {
4238 if (pid_fd != -1) {
4239 buffer_copy_int(srv->tmp_buf, getpid());
4240 buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
4241- force_assert(srv->tmp_buf->used > 0);
4242- write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
4243+ write(pid_fd, CONST_BUF_LEN(srv->tmp_buf));
4244 close(pid_fd);
4245 pid_fd = -1;
4246 }
4247@@ -1425,8 +1424,8 @@ int main (int argc, char **argv) {
4248
4249 /* network_close() will cleanup after us */
4250
4251- if (srv->srvconf.pid_file->used &&
4252- srv->srvconf.changeroot->used == 0) {
4253+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
4254+ buffer_string_is_empty(srv->srvconf.changeroot)) {
4255 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
4256 if (errno != EACCES && errno != EPERM) {
4257 log_error_write(srv, __FILE__, __LINE__, "sbds",
4258@@ -1542,8 +1541,8 @@ int main (int argc, char **argv) {
4259 srv->joblist->used = 0;
4260 }
4261
4262- if (srv->srvconf.pid_file->used &&
4263- srv->srvconf.changeroot->used == 0 &&
4264+ if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
4265+ buffer_string_is_empty(srv->srvconf.changeroot) &&
4266 0 == graceful_shutdown) {
4267 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
4268 if (errno != EACCES && errno != EPERM) {
4269diff --git a/src/stat_cache.c b/src/stat_cache.c
4270index b63140e..dedea4b 100644
4271--- a/src/stat_cache.c
4272+++ b/src/stat_cache.c
4273@@ -222,8 +222,7 @@ static int stat_cache_attr_get(buffer *buf, char *name) {
4274 buffer_string_prepare_copy(buf, 1023);
4275 attrlen = buf->size - 1;
4276 if(0 == (ret = attr_get(name, "Content-Type", buf->ptr, &attrlen, 0))) {
4277- buf->used = attrlen + 1;
4278- buf->ptr[attrlen] = '\0';
4279+ buffer_commit(buf, attrlen);
4280 }
4281 return ret;
4282 }
4283@@ -332,7 +331,7 @@ static int buffer_copy_dirname(buffer *dst, buffer *file) {
4284
4285 if (buffer_string_is_empty(file)) return -1;
4286
4287- for (i = file->used - 1; i+1 > 0; i--) {
4288+ for (i = buffer_string_length(file); i > 0; i--) {
4289 if (file->ptr[i] == '/') {
4290 buffer_copy_string_len(dst, file->ptr, i);
4291 return 0;
4292@@ -499,7 +498,7 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
4293
4294 if (S_ISREG(st.st_mode)) {
4295 /* fix broken stat/open for symlinks to reg files with appended slash on freebsd,osx */
4296- if (name->ptr[name->used-2] == '/') {
4297+ if (name->ptr[buffer_string_length(name) - 1] == '/') {
4298 errno = ENOTDIR;
4299 return HANDLER_ERROR;
4300 }
4301@@ -571,16 +570,15 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
4302 * we assume "/" can not be symlink, so
4303 * skip the symlink stuff if our path is /
4304 **/
4305- else if ((name->used > 2)) {
4306+ else if (buffer_string_length(name) > 1) {
4307 buffer *dname;
4308 char *s_cur;
4309
4310 dname = buffer_init();
4311 buffer_copy_buffer(dname, name);
4312
4313- while ((s_cur = strrchr(dname->ptr,'/'))) {
4314- *s_cur = '\0';
4315- dname->used = s_cur - dname->ptr + 1;
4316+ while ((s_cur = strrchr(dname->ptr, '/'))) {
4317+ buffer_string_set_length(dname, s_cur - dname->ptr);
4318 if (dname->ptr == s_cur) {
4319 #ifdef DEBUG_STAT_CACHE
4320 log_error_write(srv, __FILE__, __LINE__, "s", "reached /");
4321@@ -615,16 +613,19 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
4322 #endif
4323 /* xattr did not set a content-type. ask the config */
4324 if (buffer_string_is_empty(sce->content_type)) {
4325+ size_t namelen = buffer_string_length(name);
4326+
4327 for (k = 0; k < con->conf.mimetypes->used; k++) {
4328 data_string *ds = (data_string *)con->conf.mimetypes->data[k];
4329 buffer *type = ds->key;
4330+ size_t typelen = buffer_string_length(type);
4331
4332- if (type->used == 0) continue;
4333+ if (buffer_is_empty(type)) continue;
4334
4335 /* check if the right side is the same */
4336- if (type->used > name->used) continue;
4337+ if (typelen > namelen) continue;
4338
4339- if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
4340+ if (0 == strncasecmp(name->ptr + namelen - typelen, type->ptr, typelen)) {
4341 buffer_copy_buffer(sce->content_type, ds->value);
4342 break;
4343 }
4344--
43452.4.5
4346
diff --git a/main/lighttpd/0020-rename-buffer_append_long_hex-to-buffer_append_uint_.patch b/main/lighttpd/0020-rename-buffer_append_long_hex-to-buffer_append_uint_.patch
new file mode 100644
index 0000000000..16441ace75
--- /dev/null
+++ b/main/lighttpd/0020-rename-buffer_append_long_hex-to-buffer_append_uint_.patch
@@ -0,0 +1,117 @@
1From 91a9a6b3910df8be3936ed0a70b0ac6cbdc10079 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:46 +0000
4Subject: [PATCH 20/29] rename buffer_append_long_hex to buffer_append_uint_hex
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9* takes uintmax_t now
10* use in http_chunk_append_len
11
12From: Stefan Bühler <stbuehler@web.de>
13
14git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2980 152afb58-edef-0310-8abb-c4023f1b3aa9
15---
16 src/buffer.c | 4 ++--
17 src/buffer.h | 2 +-
18 src/http_chunk.c | 22 +++-------------------
19 src/log.c | 4 ++--
20 4 files changed, 8 insertions(+), 24 deletions(-)
21
22diff --git a/src/buffer.c b/src/buffer.c
23index d343731..425d700 100644
24--- a/src/buffer.c
25+++ b/src/buffer.c
26@@ -234,12 +234,12 @@ void buffer_append_string_buffer(buffer *b, const buffer *src) {
27 }
28 }
29
30-void buffer_append_long_hex(buffer *b, unsigned long value) {
31+void buffer_append_uint_hex(buffer *b, uintmax_t value) {
32 char *buf;
33 int shift = 0;
34
35 {
36- unsigned long copy = value;
37+ uintmax_t copy = value;
38 do {
39 copy >>= 8;
40 shift += 2; /* counting nibbles (4 bits) */
41diff --git a/src/buffer.h b/src/buffer.h
42index e2ac778..f5d0224 100644
43--- a/src/buffer.h
44+++ b/src/buffer.h
45@@ -89,7 +89,7 @@ void buffer_append_string(buffer *b, const char *s);
46 void buffer_append_string_len(buffer *b, const char *s, size_t s_len);
47 void buffer_append_string_buffer(buffer *b, const buffer *src);
48
49-void buffer_append_long_hex(buffer *b, unsigned long len);
50+void buffer_append_uint_hex(buffer *b, uintmax_t len);
51 void buffer_append_int(buffer *b, intmax_t val);
52 void buffer_copy_int(buffer *b, intmax_t val);
53
54diff --git a/src/http_chunk.c b/src/http_chunk.c
55index 79e4586..45db56c 100644
56--- a/src/http_chunk.c
57+++ b/src/http_chunk.c
58@@ -21,31 +21,15 @@
59 #include <string.h>
60
61 static void http_chunk_append_len(server *srv, connection *con, size_t len) {
62- size_t i, olen = len, j;
63 buffer *b;
64
65 force_assert(NULL != srv);
66
67 b = srv->tmp_chunk_len;
68
69- if (len == 0) {
70- buffer_copy_string_len(b, CONST_STR_LEN("0\r\n"));
71- } else {
72- for (i = 0; i < 8 && len; i++) {
73- len >>= 4;
74- }
75-
76- /* i is the number of hex digits we have, + \r\n */
77- buffer_string_prepare_copy(b, i + 2);
78-
79- for (j = i-1, len = olen; j+1 > 0; j--) {
80- b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
81- len >>= 4;
82- }
83- buffer_commit(b, i);
84-
85- buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
86- }
87+ buffer_string_set_length(b, 0);
88+ buffer_append_uint_hex(b, len);
89+ buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
90
91 chunkqueue_append_buffer(con->write_queue, b);
92 }
93diff --git a/src/log.c b/src/log.c
94index 6c9c38d..9322d2c 100644
95--- a/src/log.c
96+++ b/src/log.c
97@@ -288,7 +288,7 @@ static void log_buffer_append_printf(buffer *out, const char *fmt, va_list ap) {
98 case 'x': /* int (hex) */
99 d = va_arg(ap, int);
100 buffer_append_string_len(out, CONST_STR_LEN("0x"));
101- buffer_append_long_hex(out, d);
102+ buffer_append_uint_hex(out, d);
103 buffer_append_string_len(out, CONST_STR_LEN(" "));
104 break;
105 case 'S': /* string */
106@@ -310,7 +310,7 @@ static void log_buffer_append_printf(buffer *out, const char *fmt, va_list ap) {
107 case 'X': /* int (hex) */
108 d = va_arg(ap, int);
109 buffer_append_string_len(out, CONST_STR_LEN("0x"));
110- buffer_append_long_hex(out, d);
111+ buffer_append_uint_hex(out, d);
112 break;
113 case '(':
114 case ')':
115--
1162.4.5
117
diff --git a/main/lighttpd/0021-buffer-constify-some-parameters.patch b/main/lighttpd/0021-buffer-constify-some-parameters.patch
new file mode 100644
index 0000000000..d99e114906
--- /dev/null
+++ b/main/lighttpd/0021-buffer-constify-some-parameters.patch
@@ -0,0 +1,98 @@
1From 66ad587f2f9e9d9ce44437c1e185a961cfc13290 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:49 +0000
4Subject: [PATCH 21/29] [buffer] constify some parameters
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2981 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 src/buffer.c | 12 ++++++------
14 src/buffer.h | 12 ++++++------
15 2 files changed, 12 insertions(+), 12 deletions(-)
16
17diff --git a/src/buffer.c b/src/buffer.c
18index 425d700..57c1613 100644
19--- a/src/buffer.c
20+++ b/src/buffer.c
21@@ -409,11 +409,11 @@ char * buffer_search_string_len(buffer *b, const char *needle, size_t len) {
22 return NULL;
23 }
24
25-int buffer_is_empty(buffer *b) {
26+int buffer_is_empty(const buffer *b) {
27 return NULL == b || 0 == b->used;
28 }
29
30-int buffer_string_is_empty(buffer *b) {
31+int buffer_string_is_empty(const buffer *b) {
32 return 0 == buffer_string_length(b);
33 }
34
35@@ -424,7 +424,7 @@ int buffer_string_is_empty(buffer *b) {
36 * alignment properly.
37 */
38
39-int buffer_is_equal(buffer *a, buffer *b) {
40+int buffer_is_equal(const buffer *a, const buffer *b) {
41 force_assert(NULL != a && NULL != b);
42
43 if (a->used != b->used) return 0;
44@@ -433,7 +433,7 @@ int buffer_is_equal(buffer *a, buffer *b) {
45 return (0 == memcmp(a->ptr, b->ptr, a->used));
46 }
47
48-int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
49+int buffer_is_equal_string(const buffer *a, const char *s, size_t b_len) {
50 force_assert(NULL != a && NULL != s);
51 force_assert(b_len + 1 > b_len);
52
53@@ -445,7 +445,7 @@ int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
54 }
55
56 /* buffer_is_equal_caseless_string(b, CONST_STR_LEN("value")) */
57-int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len) {
58+int buffer_is_equal_caseless_string(const buffer *a, const char *s, size_t b_len) {
59 force_assert(NULL != a);
60 if (a->used != b_len + 1) return 0;
61 force_assert('\0' == a->ptr[a->used - 1]);
62@@ -472,7 +472,7 @@ int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b
63 return a_len < b_len ? -1 : 1;
64 }
65
66-int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
67+int buffer_is_equal_right_len(const buffer *b1, const buffer *b2, size_t len) {
68 /* no len -> equal */
69 if (len == 0) return 1;
70
71diff --git a/src/buffer.h b/src/buffer.h
72index f5d0224..b6065d4 100644
73--- a/src/buffer.h
74+++ b/src/buffer.h
75@@ -112,14 +112,14 @@ char * buffer_search_string_len(buffer *b, const char *needle, size_t len);
76 * unset "string" (buffer) config options are initialized to used == 0,
77 * while setting an empty string leads to used == 1
78 */
79-int buffer_is_empty(buffer *b);
80+int buffer_is_empty(const buffer *b);
81 /* NULL buffer, empty buffer (used == 0) or empty string (used == 1) */
82-int buffer_string_is_empty(buffer *b);
83+int buffer_string_is_empty(const buffer *b);
84
85-int buffer_is_equal(buffer *a, buffer *b);
86-int buffer_is_equal_right_len(buffer *a, buffer *b, size_t len);
87-int buffer_is_equal_string(buffer *a, const char *s, size_t b_len);
88-int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len);
89+int buffer_is_equal(const buffer *a, const buffer *b);
90+int buffer_is_equal_right_len(const buffer *a, const buffer *b, size_t len);
91+int buffer_is_equal_string(const buffer *a, const char *s, size_t b_len);
92+int buffer_is_equal_caseless_string(const buffer *a, const char *s, size_t b_len);
93 int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len);
94
95 typedef enum {
96--
972.4.5
98
diff --git a/main/lighttpd/0022-bitset-unused-remove.patch b/main/lighttpd/0022-bitset-unused-remove.patch
new file mode 100644
index 0000000000..572f7a5e25
--- /dev/null
+++ b/main/lighttpd/0022-bitset-unused-remove.patch
@@ -0,0 +1,170 @@
1From bfce99aacc99d962a9855fbbae61c309728122fe Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:51 +0000
4Subject: [PATCH 22/29] [bitset] unused -> remove
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2982 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 src/CMakeLists.txt | 2 +-
14 src/Makefile.am | 4 ++--
15 src/SConscript | 2 +-
16 src/bitset.c | 67 ------------------------------------------------------
17 src/bitset.h | 19 ----------------
18 src/fdevent.h | 1 -
19 6 files changed, 4 insertions(+), 91 deletions(-)
20 delete mode 100644 src/bitset.c
21 delete mode 100644 src/bitset.h
22
23diff --git a/src/Makefile.am b/src/Makefile.am
24index a5471ff..a4ada19 100644
25--- a/src/Makefile.am
26+++ b/src/Makefile.am
27@@ -66,7 +66,7 @@ common_src=buffer.c log.c \
28 fdevent_poll.c fdevent_linux_sysepoll.c \
29 fdevent_solaris_devpoll.c fdevent_solaris_port.c \
30 fdevent_freebsd_kqueue.c \
31- data_config.c bitset.c \
32+ data_config.c \
33 inet_ntop_cache.c crc32.c \
34 connections-glue.c \
35 configfile-glue.c \
36@@ -273,7 +273,7 @@ hdr = server.h buffer.h network.h log.h keyvalue.h \
37 fdevent.h connections.h base.h stat_cache.h \
38 plugin.h mod_auth.h \
39 etag.h joblist.h array.h crc32.h \
40- network_backends.h configfile.h bitset.h \
41+ network_backends.h configfile.h \
42 mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
43 configparser.h mod_ssi_exprparser.h \
44 sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
45diff --git a/src/SConscript b/src/SConscript
46index 7565094..bb507a5 100644
47--- a/src/SConscript
48+++ b/src/SConscript
49@@ -14,7 +14,7 @@ common_src = Split("buffer.c log.c \
50 fdevent_poll.c fdevent_linux_sysepoll.c \
51 fdevent_solaris_devpoll.c fdevent_solaris_port.c \
52 fdevent_freebsd_kqueue.c \
53- data_config.c bitset.c \
54+ data_config.c \
55 inet_ntop_cache.c crc32.c \
56 connections-glue.c \
57 configfile-glue.c \
58diff --git a/src/bitset.c b/src/bitset.c
59deleted file mode 100644
60index 27c93a8..0000000
61--- a/src/bitset.c
62+++ /dev/null
63@@ -1,67 +0,0 @@
64-#include "buffer.h"
65-#include "bitset.h"
66-
67-#include <limits.h>
68-#include <stdlib.h>
69-#include <string.h>
70-#include <stdio.h>
71-#include <assert.h>
72-
73-#define BITSET_BITS \
74- ( CHAR_BIT * sizeof(size_t) )
75-
76-#define BITSET_MASK(pos) \
77- ( ((size_t)1) << ((pos) % BITSET_BITS) )
78-
79-#define BITSET_WORD(set, pos) \
80- ( (set)->bits[(pos) / BITSET_BITS] )
81-
82-#define BITSET_USED(nbits) \
83- ( ((nbits) + (BITSET_BITS - 1)) / BITSET_BITS )
84-
85-bitset *bitset_init(size_t nbits) {
86- bitset *set;
87-
88- set = malloc(sizeof(*set));
89- force_assert(set);
90-
91- set->bits = calloc(BITSET_USED(nbits), sizeof(*set->bits));
92- set->nbits = nbits;
93-
94- force_assert(set->bits);
95-
96- return set;
97-}
98-
99-void bitset_reset(bitset *set) {
100- memset(set->bits, 0, BITSET_USED(set->nbits) * sizeof(*set->bits));
101-}
102-
103-void bitset_free(bitset *set) {
104- free(set->bits);
105- free(set);
106-}
107-
108-void bitset_clear_bit(bitset *set, size_t pos) {
109- if (pos >= set->nbits) {
110- SEGFAULT();
111- }
112-
113- BITSET_WORD(set, pos) &= ~BITSET_MASK(pos);
114-}
115-
116-void bitset_set_bit(bitset *set, size_t pos) {
117- if (pos >= set->nbits) {
118- SEGFAULT();
119- }
120-
121- BITSET_WORD(set, pos) |= BITSET_MASK(pos);
122-}
123-
124-int bitset_test_bit(bitset *set, size_t pos) {
125- if (pos >= set->nbits) {
126- SEGFAULT();
127- }
128-
129- return (BITSET_WORD(set, pos) & BITSET_MASK(pos)) != 0;
130-}
131diff --git a/src/bitset.h b/src/bitset.h
132deleted file mode 100644
133index 467e13f..0000000
134--- a/src/bitset.h
135+++ /dev/null
136@@ -1,19 +0,0 @@
137-#ifndef _BITSET_H_
138-#define _BITSET_H_
139-
140-#include <stddef.h>
141-
142-typedef struct {
143- size_t *bits;
144- size_t nbits;
145-} bitset;
146-
147-bitset *bitset_init(size_t nbits);
148-void bitset_reset(bitset *set);
149-void bitset_free(bitset *set);
150-
151-void bitset_clear_bit(bitset *set, size_t pos);
152-void bitset_set_bit(bitset *set, size_t pos);
153-int bitset_test_bit(bitset *set, size_t pos);
154-
155-#endif
156diff --git a/src/fdevent.h b/src/fdevent.h
157index 5147baa..235d68b 100644
158--- a/src/fdevent.h
159+++ b/src/fdevent.h
160@@ -6,7 +6,6 @@
161 #endif
162
163 #include "settings.h"
164-#include "bitset.h"
165
166 #if defined HAVE_STDINT_H
167 # include <stdint.h>
168--
1692.4.5
170
diff --git a/main/lighttpd/0023-remove-unused-stuff-from-server.h.patch b/main/lighttpd/0023-remove-unused-stuff-from-server.h.patch
new file mode 100644
index 0000000000..178cba4c40
--- /dev/null
+++ b/main/lighttpd/0023-remove-unused-stuff-from-server.h.patch
@@ -0,0 +1,38 @@
1From 68add2602b15638f2bb8cb7710a0dd60e95c6ac3 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:53 +0000
4Subject: [PATCH 23/29] remove unused stuff from server.h
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2983 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 src/server.h | 8 --------
14 1 file changed, 8 deletions(-)
15
16diff --git a/src/server.h b/src/server.h
17index bca2d52..67d4e7c 100644
18--- a/src/server.h
19+++ b/src/server.h
20@@ -3,15 +3,7 @@
21
22 #include "base.h"
23
24-typedef struct {
25- char *key;
26- char *value;
27-} two_strings;
28-
29-typedef enum { CONFIG_UNSET, CONFIG_DOCUMENT_ROOT } config_var_t;
30-
31 int config_read(server *srv, const char *fn);
32 int config_set_defaults(server *srv);
33-buffer *config_get_value_buffer(server *srv, connection *con, config_var_t field);
34
35 #endif
36--
372.4.5
38
diff --git a/main/lighttpd/0024-crc32-fix-method-signature-const-pointer.patch b/main/lighttpd/0024-crc32-fix-method-signature-const-pointer.patch
new file mode 100644
index 0000000000..f53cc5b2cf
--- /dev/null
+++ b/main/lighttpd/0024-crc32-fix-method-signature-const-pointer.patch
@@ -0,0 +1,44 @@
1From deceae78c9584350d17a9b5b9a5d2fef3def5e45 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:56 +0000
4Subject: [PATCH 24/29] [crc32] fix method signature (const pointer)
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2984 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 src/crc32.c | 2 +-
14 src/crc32.h | 2 +-
15 2 files changed, 2 insertions(+), 2 deletions(-)
16
17diff --git a/src/crc32.c b/src/crc32.c
18index cdad7bc..b19bec5 100644
19--- a/src/crc32.c
20+++ b/src/crc32.c
21@@ -70,7 +70,7 @@ static const unsigned int crc_c[256] = {
22 };
23
24
25-uint32_t generate_crc32c(char *buffer, size_t length) {
26+uint32_t generate_crc32c(const char *buffer, size_t length) {
27 size_t i;
28 uint32_t crc32 = ~0L;
29
30diff --git a/src/crc32.h b/src/crc32.h
31index c5b4245..10e0e90 100644
32--- a/src/crc32.h
33+++ b/src/crc32.h
34@@ -13,6 +13,6 @@
35 # include <inttypes.h>
36 #endif
37
38-uint32_t generate_crc32c(char *string, size_t length);
39+uint32_t generate_crc32c(const char *string, size_t length);
40
41 #endif
42--
432.4.5
44
diff --git a/main/lighttpd/0025-tests-fix-undefined-index-warning-in-sendfile.php.patch b/main/lighttpd/0025-tests-fix-undefined-index-warning-in-sendfile.php.patch
new file mode 100644
index 0000000000..f37b98cdba
--- /dev/null
+++ b/main/lighttpd/0025-tests-fix-undefined-index-warning-in-sendfile.php.patch
@@ -0,0 +1,31 @@
1From 673923daf839fda59e4dc1e5f95f5b265a65e802 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Sun, 8 Feb 2015 19:10:58 +0000
4Subject: [PATCH 25/29] [tests] fix undefined index warning in sendfile.php
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2985 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 tests/docroot/www/sendfile.php | 2 +-
14 1 file changed, 1 insertion(+), 1 deletion(-)
15
16diff --git a/tests/docroot/www/sendfile.php b/tests/docroot/www/sendfile.php
17index 0aa8786..e460220 100644
18--- a/tests/docroot/www/sendfile.php
19+++ b/tests/docroot/www/sendfile.php
20@@ -6,7 +6,7 @@ function pathencode($path) {
21
22 $val = "X-Sendfile2: " . pathencode(getcwd() . "/index.txt") . " " . $_GET["range"];
23
24-if ($_GET["range2"]) $val .= ", " . pathencode(getcwd() . "/index.txt") . " " . $_GET["range2"];
25+if (isset($_GET["range2"])) $val .= ", " . pathencode(getcwd() . "/index.txt") . " " . $_GET["range2"];
26
27 header($val);
28
29--
302.4.5
31
diff --git a/main/lighttpd/0026-mod_auth-use-crypt_r-instead-of-crypt-if-available.patch b/main/lighttpd/0026-mod_auth-use-crypt_r-instead-of-crypt-if-available.patch
new file mode 100644
index 0000000000..8fbefeb99e
--- /dev/null
+++ b/main/lighttpd/0026-mod_auth-use-crypt_r-instead-of-crypt-if-available.patch
@@ -0,0 +1,102 @@
1From c92496720d21ea7888187a8ae305c392d4fe824a Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Thu, 12 Feb 2015 06:39:39 +0000
4Subject: [PATCH 26/29] [mod_auth] use crypt_r instead of crypt if available
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9From: Stefan Bühler <stbuehler@web.de>
10
11git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2986 152afb58-edef-0310-8abb-c4023f1b3aa9
12---
13 NEWS | 1 +
14 configure.ac | 22 +++++++++++++++-------
15 src/CMakeLists.txt | 12 +++++++++---
16 src/config.h.cmake | 3 ++-
17 src/http_auth.c | 10 +++++++++-
18 5 files changed, 36 insertions(+), 12 deletions(-)
19
20diff --git a/NEWS b/NEWS
21index ddb370d..59fd4f6 100644
22--- a/NEWS
23+++ b/NEWS
24@@ -16,6 +16,7 @@ NEWS
25 * [connections] fix bug in connection state handling
26 * print backtrace in assert logging with libunwind
27 * major refactoring of internal buffer/chunk handling
28+ * [mod_auth] use crypt_r instead of crypt if available
29
30 - 1.4.35 - 2014-03-12
31 * [network/ssl] fix build error if TLSEXT is disabled
32diff --git a/configure.ac b/configure.ac
33index c846d1a..16e66d6 100644
34--- a/configure.ac
35+++ b/configure.ac
36@@ -528,19 +528,27 @@ if test "$WITH_LUA" != "no"; then
37 AC_SUBST(LUA_LIBS)
38 fi
39
40+dnl search for crypt_r and (fallback) for crypt
41 save_LIBS=$LIBS
42-AC_SEARCH_LIBS(crypt,crypt,[
43+LIBS=
44+AC_SEARCH_LIBS([crypt_r],[crypt],[
45+ AC_DEFINE([HAVE_CRYPT_R], [1], [crypt_r])
46 AC_CHECK_HEADERS([crypt.h],[
47- AC_DEFINE([HAVE_CRYPT_H], [1])
48+ AC_DEFINE([HAVE_CRYPT_H], [1], [crypt.h])
49 ])
50
51- AC_DEFINE([HAVE_LIBCRYPT], [1], [libcrypt])
52- if test "$ac_cv_search_crypt" != no; then
53- test "$ac_cv_search_crypt" = "none required" || CRYPT_LIB="$ac_cv_search_crypt"
54- fi
55+ CRYPT_LIB=$LIBS
56+],[
57+ AC_SEARCH_LIBS([crypt],[crypt],[
58+ AC_CHECK_HEADERS([crypt.h],[
59+ AC_DEFINE([HAVE_CRYPT_H], [1], [crypt.h])
60+ ])
61+
62+ CRYPT_LIB=$LIBS
63+ ])
64 ])
65 LIBS=$save_LIBS
66-AC_SUBST(CRYPT_LIB)
67+AC_SUBST([CRYPT_LIB])
68
69 save_LIBS=$LIBS
70 AC_SEARCH_LIBS(sendfilev,sendfile,[
71diff --git a/src/http_auth.c b/src/http_auth.c
72index a98ea62..dacf70a 100644
73--- a/src/http_auth.c
74+++ b/src/http_auth.c
75@@ -669,15 +669,23 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
76 return (strcmp(sample, password->ptr) == 0) ? 0 : 1;
77 #endif
78 } else {
79-#ifdef HAVE_CRYPT
80+#if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT)
81 char *crypted;
82+#if defined(HAVE_CRYPT_R)
83+ struct crypt_data crypt_tmp_data;
84+ crypt_tmp_data.initialized = 0;
85+#endif
86
87 /* a simple DES password is 2 + 11 characters. everything else should be longer. */
88 if (buffer_string_length(password) < 13) {
89 return -1;
90 }
91
92+#if defined(HAVE_CRYPT_R)
93+ if (0 == (crypted = crypt_r(pw, password->ptr, &crypt_tmp_data))) {
94+#else
95 if (0 == (crypted = crypt(pw, password->ptr))) {
96+#endif
97 /* crypt failed. */
98 return -1;
99 }
100--
1012.4.5
102
diff --git a/main/lighttpd/0027-fix-error-message-for-T_CONFIG_ARRAY-config-values-i.patch b/main/lighttpd/0027-fix-error-message-for-T_CONFIG_ARRAY-config-values-i.patch
new file mode 100644
index 0000000000..c11a695e72
--- /dev/null
+++ b/main/lighttpd/0027-fix-error-message-for-T_CONFIG_ARRAY-config-values-i.patch
@@ -0,0 +1,49 @@
1From df87b3ef98711b6a4ca4cefb1fceec022ddcdc13 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Thu, 14 May 2015 09:38:30 +0000
4Subject: [PATCH 27/29] fix error message for T_CONFIG_ARRAY config values if
5 an entry value is not a string
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10From: Stefan Bühler <stbuehler@web.de>
11
12git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2987 152afb58-edef-0310-8abb-c4023f1b3aa9
13---
14 NEWS | 1 +
15 src/configfile-glue.c | 6 +++---
16 2 files changed, 4 insertions(+), 3 deletions(-)
17
18diff --git a/NEWS b/NEWS
19index 59fd4f6..4d19144 100644
20--- a/NEWS
21+++ b/NEWS
22@@ -17,6 +17,7 @@ NEWS
23 * print backtrace in assert logging with libunwind
24 * major refactoring of internal buffer/chunk handling
25 * [mod_auth] use crypt_r instead of crypt if available
26+ * fix error message for T_CONFIG_ARRAY config values if an entry value is not a string
27
28 - 1.4.35 - 2014-03-12
29 * [network/ssl] fix build error if TLSEXT is disabled
30diff --git a/src/configfile-glue.c b/src/configfile-glue.c
31index f411d72..807e307 100644
32--- a/src/configfile-glue.c
33+++ b/src/configfile-glue.c
34@@ -56,9 +56,9 @@ int config_insert_values_internal(server *srv, array *ca, const config_values_t
35
36 array_insert_unique(cv[i].destination, (data_unset *)ds);
37 } else {
38- log_error_write(srv, __FILE__, __LINE__, "sssd",
39- "the key of an array can only be a string or a integer, variable:",
40- cv[i].key, "type:", da->value->data[j]->type);
41+ log_error_write(srv, __FILE__, __LINE__, "sssbsd",
42+ "the value of an array can only be a string, variable:",
43+ cv[i].key, "[", da->value->data[j]->key, "], type:", da->value->data[j]->type);
44
45 return -1;
46 }
47--
482.4.5
49
diff --git a/main/lighttpd/0028-fix-segfaults-in-many-plugins-if-they-failed-configu.patch b/main/lighttpd/0028-fix-segfaults-in-many-plugins-if-they-failed-configu.patch
new file mode 100644
index 0000000000..d35b478424
--- /dev/null
+++ b/main/lighttpd/0028-fix-segfaults-in-many-plugins-if-they-failed-configu.patch
@@ -0,0 +1,447 @@
1From 33cebeb0f778d437e1a6070504f588b2531fa291 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Thu, 14 May 2015 09:38:33 +0000
4Subject: [PATCH 28/29] fix segfaults in many plugins if they failed
5 configuration
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10From: Stefan Bühler <stbuehler@web.de>
11
12git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2988 152afb58-edef-0310-8abb-c4023f1b3aa9
13---
14 NEWS | 1 +
15 src/mod_access.c | 2 ++
16 src/mod_accesslog.c | 2 +-
17 src/mod_alias.c | 2 +-
18 src/mod_auth.c | 2 +-
19 src/mod_cgi.c | 2 ++
20 src/mod_cml.c | 2 ++
21 src/mod_compress.c | 2 +-
22 src/mod_evasive.c | 2 ++
23 src/mod_evhost.c | 2 +-
24 src/mod_expire.c | 3 ++-
25 src/mod_extforward.c | 2 +-
26 src/mod_fastcgi.c | 2 +-
27 src/mod_flv_streaming.c | 2 +-
28 src/mod_indexfile.c | 2 +-
29 src/mod_magnet.c | 2 +-
30 src/mod_proxy.c | 7 +++----
31 src/mod_redirect.c | 2 ++
32 src/mod_rewrite.c | 3 +++
33 src/mod_rrdtool.c | 2 ++
34 src/mod_scgi.c | 2 +-
35 src/mod_secure_download.c | 2 ++
36 src/mod_setenv.c | 2 ++
37 src/mod_skeleton.c | 2 +-
38 src/mod_ssi.c | 2 ++
39 src/mod_staticfile.c | 2 ++
40 src/mod_trigger_b4_dl.c | 2 +-
41 src/mod_uploadprogress.c | 2 ++
42 src/mod_userdir.c | 2 ++
43 src/mod_usertrack.c | 2 ++
44 src/mod_webdav.c | 2 +-
45 31 files changed, 49 insertions(+), 19 deletions(-)
46
47diff --git a/NEWS b/NEWS
48index 4d19144..dd2d1b8 100644
49--- a/NEWS
50+++ b/NEWS
51@@ -18,6 +18,7 @@ NEWS
52 * major refactoring of internal buffer/chunk handling
53 * [mod_auth] use crypt_r instead of crypt if available
54 * fix error message for T_CONFIG_ARRAY config values if an entry value is not a string
55+ * fix segfaults in many plugins if they failed configuration
56
57 - 1.4.35 - 2014-03-12
58 * [network/ssl] fix build error if TLSEXT is disabled
59diff --git a/src/mod_access.c b/src/mod_access.c
60index a6c25a4..e6a9a14 100644
61--- a/src/mod_access.c
62+++ b/src/mod_access.c
63@@ -40,6 +40,8 @@ FREE_FUNC(mod_access_free) {
64 for (i = 0; i < srv->config_context->used; i++) {
65 plugin_config *s = p->config_storage[i];
66
67+ if (NULL == s) continue;
68+
69 array_free(s->access_deny);
70
71 free(s);
72diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
73index 9bb3fe2..f5be7d2 100644
74--- a/src/mod_accesslog.c
75+++ b/src/mod_accesslog.c
76@@ -414,7 +414,7 @@ FREE_FUNC(mod_accesslog_free) {
77 for (i = 0; i < srv->config_context->used; i++) {
78 plugin_config *s = p->config_storage[i];
79
80- if (!s) continue;
81+ if (NULL == s) continue;
82
83 if (!buffer_string_is_empty(s->access_logbuffer)) {
84 if (s->log_access_fd != -1) {
85diff --git a/src/mod_alias.c b/src/mod_alias.c
86index 4625973..f9d7b51 100644
87--- a/src/mod_alias.c
88+++ b/src/mod_alias.c
89@@ -45,7 +45,7 @@ FREE_FUNC(mod_alias_free) {
90 for (i = 0; i < srv->config_context->used; i++) {
91 plugin_config *s = p->config_storage[i];
92
93- if(!s) continue;
94+ if (NULL == s) continue;
95
96 array_free(s->alias);
97
98diff --git a/src/mod_auth.c b/src/mod_auth.c
99index 1870893..edddaa8 100644
100--- a/src/mod_auth.c
101+++ b/src/mod_auth.c
102@@ -60,7 +60,7 @@ FREE_FUNC(mod_auth_free) {
103 for (i = 0; i < srv->config_context->used; i++) {
104 mod_auth_plugin_config *s = p->config_storage[i];
105
106- if (!s) continue;
107+ if (NULL == s) continue;
108
109 array_free(s->auth_require);
110 buffer_free(s->auth_plain_groupfile);
111diff --git a/src/mod_cgi.c b/src/mod_cgi.c
112index 8a7cc2b..01b1877 100644
113--- a/src/mod_cgi.c
114+++ b/src/mod_cgi.c
115@@ -127,6 +127,8 @@ FREE_FUNC(mod_cgi_free) {
116 for (i = 0; i < srv->config_context->used; i++) {
117 plugin_config *s = p->config_storage[i];
118
119+ if (NULL == s) continue;
120+
121 array_free(s->cgi);
122
123 free(s);
124diff --git a/src/mod_cml.c b/src/mod_cml.c
125index baa23b3..98f8d77 100644
126--- a/src/mod_cml.c
127+++ b/src/mod_cml.c
128@@ -43,6 +43,8 @@ FREE_FUNC(mod_cml_free) {
129 for (i = 0; i < srv->config_context->used; i++) {
130 plugin_config *s = p->config_storage[i];
131
132+ if (NULL == s) continue;
133+
134 buffer_free(s->ext);
135
136 buffer_free(s->mc_namespace);
137diff --git a/src/mod_compress.c b/src/mod_compress.c
138index f0ffa1c..29d5ab5 100644
139--- a/src/mod_compress.c
140+++ b/src/mod_compress.c
141@@ -90,7 +90,7 @@ FREE_FUNC(mod_compress_free) {
142 for (i = 0; i < srv->config_context->used; i++) {
143 plugin_config *s = p->config_storage[i];
144
145- if (!s) continue;
146+ if (NULL == s) continue;
147
148 array_free(s->compress);
149 buffer_free(s->compress_cache_dir);
150diff --git a/src/mod_evasive.c b/src/mod_evasive.c
151index d9b8732..da45c9a 100644
152--- a/src/mod_evasive.c
153+++ b/src/mod_evasive.c
154@@ -58,6 +58,8 @@ FREE_FUNC(mod_evasive_free) {
155 for (i = 0; i < srv->config_context->used; i++) {
156 plugin_config *s = p->config_storage[i];
157
158+ if (NULL == s) continue;
159+
160 free(s);
161 }
162 free(p->config_storage);
163diff --git a/src/mod_evhost.c b/src/mod_evhost.c
164index e728551..3c49adf 100644
165--- a/src/mod_evhost.c
166+++ b/src/mod_evhost.c
167@@ -46,7 +46,7 @@ FREE_FUNC(mod_evhost_free) {
168 for (i = 0; i < srv->config_context->used; i++) {
169 plugin_config *s = p->config_storage[i];
170
171- if (!s) continue;
172+ if (NULL == s) continue;
173
174 if(s->path_pieces) {
175 size_t j;
176diff --git a/src/mod_expire.c b/src/mod_expire.c
177index e26c3c6..0794c15 100644
178--- a/src/mod_expire.c
179+++ b/src/mod_expire.c
180@@ -62,7 +62,8 @@ FREE_FUNC(mod_expire_free) {
181 size_t i;
182 for (i = 0; i < srv->config_context->used; i++) {
183 plugin_config *s = p->config_storage[i];
184- if (!s) continue;
185+
186+ if (NULL == s) continue;
187
188 array_free(s->expire_url);
189 free(s);
190diff --git a/src/mod_extforward.c b/src/mod_extforward.c
191index 7f77982..557c505 100644
192--- a/src/mod_extforward.c
193+++ b/src/mod_extforward.c
194@@ -135,7 +135,7 @@ FREE_FUNC(mod_extforward_free) {
195 for (i = 0; i < srv->config_context->used; i++) {
196 plugin_config *s = p->config_storage[i];
197
198- if (!s) continue;
199+ if (NULL == s) continue;
200
201 array_free(s->forwarder);
202 array_free(s->headers);
203diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
204index d16306c..5be73df 100644
205--- a/src/mod_fastcgi.c
206+++ b/src/mod_fastcgi.c
207@@ -693,7 +693,7 @@ FREE_FUNC(mod_fastcgi_free) {
208 plugin_config *s = p->config_storage[i];
209 fcgi_exts *exts;
210
211- if (!s) continue;
212+ if (NULL == s) continue;
213
214 exts = s->exts;
215
216diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c
217index db041e2..6e92c74 100644
218--- a/src/mod_flv_streaming.c
219+++ b/src/mod_flv_streaming.c
220@@ -54,7 +54,7 @@ FREE_FUNC(mod_flv_streaming_free) {
221 for (i = 0; i < srv->config_context->used; i++) {
222 plugin_config *s = p->config_storage[i];
223
224- if (!s) continue;
225+ if (NULL == s) continue;
226
227 array_free(s->extensions);
228
229diff --git a/src/mod_indexfile.c b/src/mod_indexfile.c
230index 13d18e2..3c57256 100644
231--- a/src/mod_indexfile.c
232+++ b/src/mod_indexfile.c
233@@ -51,7 +51,7 @@ FREE_FUNC(mod_indexfile_free) {
234 for (i = 0; i < srv->config_context->used; i++) {
235 plugin_config *s = p->config_storage[i];
236
237- if (!s) continue;
238+ if (NULL == s) continue;
239
240 array_free(s->indexfiles);
241
242diff --git a/src/mod_magnet.c b/src/mod_magnet.c
243index 8f89d4e..0d99fdf 100644
244--- a/src/mod_magnet.c
245+++ b/src/mod_magnet.c
246@@ -71,7 +71,7 @@ FREE_FUNC(mod_magnet_free) {
247 for (i = 0; i < srv->config_context->used; i++) {
248 plugin_config *s = p->config_storage[i];
249
250- if (!s) continue;
251+ if (NULL == s) continue;
252
253 array_free(s->url_raw);
254 array_free(s->physical_path);
255diff --git a/src/mod_proxy.c b/src/mod_proxy.c
256index dfdc636..7821072 100644
257--- a/src/mod_proxy.c
258+++ b/src/mod_proxy.c
259@@ -167,12 +167,11 @@ FREE_FUNC(mod_proxy_free) {
260 for (i = 0; i < srv->config_context->used; i++) {
261 plugin_config *s = p->config_storage[i];
262
263- if (s) {
264+ if (NULL == s) continue;
265
266- array_free(s->extensions);
267+ array_free(s->extensions);
268
269- free(s);
270- }
271+ free(s);
272 }
273 free(p->config_storage);
274 }
275diff --git a/src/mod_redirect.c b/src/mod_redirect.c
276index 615c7db..769c8c8 100644
277--- a/src/mod_redirect.c
278+++ b/src/mod_redirect.c
279@@ -47,6 +47,8 @@ FREE_FUNC(mod_redirect_free) {
280 for (i = 0; i < srv->config_context->used; i++) {
281 plugin_config *s = p->config_storage[i];
282
283+ if (NULL == s) continue;
284+
285 pcre_keyvalue_buffer_free(s->redirect);
286
287 free(s);
288diff --git a/src/mod_rewrite.c b/src/mod_rewrite.c
289index 5191a64..113cc54 100644
290--- a/src/mod_rewrite.c
291+++ b/src/mod_rewrite.c
292@@ -146,6 +146,9 @@ FREE_FUNC(mod_rewrite_free) {
293 size_t i;
294 for (i = 0; i < srv->config_context->used; i++) {
295 plugin_config *s = p->config_storage[i];
296+
297+ if (NULL == s) continue;
298+
299 rewrite_rule_buffer_free(s->rewrite);
300 rewrite_rule_buffer_free(s->rewrite_NF);
301
302diff --git a/src/mod_rrdtool.c b/src/mod_rrdtool.c
303index 0532e4d..6b8cdae 100644
304--- a/src/mod_rrdtool.c
305+++ b/src/mod_rrdtool.c
306@@ -65,6 +65,8 @@ FREE_FUNC(mod_rrd_free) {
307 for (i = 0; i < srv->config_context->used; i++) {
308 plugin_config *s = p->config_storage[i];
309
310+ if (NULL == s) continue;
311+
312 buffer_free(s->path_rrdtool_bin);
313 buffer_free(s->path_rrd);
314
315diff --git a/src/mod_scgi.c b/src/mod_scgi.c
316index 9e88de3..733b51c 100644
317--- a/src/mod_scgi.c
318+++ b/src/mod_scgi.c
319@@ -554,7 +554,7 @@ FREE_FUNC(mod_scgi_free) {
320 plugin_config *s = p->config_storage[i];
321 scgi_exts *exts;
322
323- if (!s) continue;
324+ if (NULL == s) continue;
325
326 exts = s->exts;
327
328diff --git a/src/mod_secure_download.c b/src/mod_secure_download.c
329index da98b61..d85872d 100644
330--- a/src/mod_secure_download.c
331+++ b/src/mod_secure_download.c
332@@ -65,6 +65,8 @@ FREE_FUNC(mod_secdownload_free) {
333 for (i = 0; i < srv->config_context->used; i++) {
334 plugin_config *s = p->config_storage[i];
335
336+ if (NULL == s) continue;
337+
338 buffer_free(s->secret);
339 buffer_free(s->doc_root);
340 buffer_free(s->uri_prefix);
341diff --git a/src/mod_setenv.c b/src/mod_setenv.c
342index 60e9b55..34075c1 100644
343--- a/src/mod_setenv.c
344+++ b/src/mod_setenv.c
345@@ -67,6 +67,8 @@ FREE_FUNC(mod_setenv_free) {
346 for (i = 0; i < srv->config_context->used; i++) {
347 plugin_config *s = p->config_storage[i];
348
349+ if (NULL == s) continue;
350+
351 array_free(s->request_header);
352 array_free(s->response_header);
353 array_free(s->environment);
354diff --git a/src/mod_skeleton.c b/src/mod_skeleton.c
355index 68d272d..8461279 100644
356--- a/src/mod_skeleton.c
357+++ b/src/mod_skeleton.c
358@@ -79,7 +79,7 @@ FREE_FUNC(mod_skeleton_free) {
359 for (i = 0; i < srv->config_context->used; i++) {
360 plugin_config *s = p->config_storage[i];
361
362- if (!s) continue;
363+ if (NULL == s) continue;
364
365 array_free(s->match);
366
367diff --git a/src/mod_ssi.c b/src/mod_ssi.c
368index ed3b75c..07b695d 100644
369--- a/src/mod_ssi.c
370+++ b/src/mod_ssi.c
371@@ -69,6 +69,8 @@ FREE_FUNC(mod_ssi_free) {
372 for (i = 0; i < srv->config_context->used; i++) {
373 plugin_config *s = p->config_storage[i];
374
375+ if (NULL == s) continue;
376+
377 array_free(s->ssi_extension);
378 buffer_free(s->content_type);
379
380diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c
381index d40aa31..22929bb 100644
382--- a/src/mod_staticfile.c
383+++ b/src/mod_staticfile.c
384@@ -63,6 +63,8 @@ FREE_FUNC(mod_staticfile_free) {
385 for (i = 0; i < srv->config_context->used; i++) {
386 plugin_config *s = p->config_storage[i];
387
388+ if (NULL == s) continue;
389+
390 array_free(s->exclude_ext);
391
392 free(s);
393diff --git a/src/mod_trigger_b4_dl.c b/src/mod_trigger_b4_dl.c
394index e1fa993..4a3eac2 100644
395--- a/src/mod_trigger_b4_dl.c
396+++ b/src/mod_trigger_b4_dl.c
397@@ -89,7 +89,7 @@ FREE_FUNC(mod_trigger_b4_dl_free) {
398 for (i = 0; i < srv->config_context->used; i++) {
399 plugin_config *s = p->config_storage[i];
400
401- if (!s) continue;
402+ if (NULL == s) continue;
403
404 buffer_free(s->db_filename);
405 buffer_free(s->download_url);
406diff --git a/src/mod_userdir.c b/src/mod_userdir.c
407index 682f950..f6f1d8a 100644
408--- a/src/mod_userdir.c
409+++ b/src/mod_userdir.c
410@@ -60,6 +60,8 @@ FREE_FUNC(mod_userdir_free) {
411 for (i = 0; i < srv->config_context->used; i++) {
412 plugin_config *s = p->config_storage[i];
413
414+ if (NULL == s) continue;
415+
416 array_free(s->include_user);
417 array_free(s->exclude_user);
418 buffer_free(s->path);
419diff --git a/src/mod_usertrack.c b/src/mod_usertrack.c
420index 11aad95..3adedcf 100644
421--- a/src/mod_usertrack.c
422+++ b/src/mod_usertrack.c
423@@ -48,6 +48,8 @@ FREE_FUNC(mod_usertrack_free) {
424 for (i = 0; i < srv->config_context->used; i++) {
425 plugin_config *s = p->config_storage[i];
426
427+ if (NULL == s) continue;
428+
429 buffer_free(s->cookie_name);
430 buffer_free(s->cookie_domain);
431
432diff --git a/src/mod_webdav.c b/src/mod_webdav.c
433index 654108a..2fff8c3 100644
434--- a/src/mod_webdav.c
435+++ b/src/mod_webdav.c
436@@ -120,7 +120,7 @@ FREE_FUNC(mod_webdav_free) {
437 for (i = 0; i < srv->config_context->used; i++) {
438 plugin_config *s = p->config_storage[i];
439
440- if (!s) continue;
441+ if (NULL == s) continue;
442
443 buffer_free(s->sqlite_db_name);
444 #ifdef USE_PROPPATCH
445--
4462.4.5
447
diff --git a/main/lighttpd/0029-escape-all-strings-for-logging-fixes-2646-log-file-i.patch b/main/lighttpd/0029-escape-all-strings-for-logging-fixes-2646-log-file-i.patch
new file mode 100644
index 0000000000..20307fb204
--- /dev/null
+++ b/main/lighttpd/0029-escape-all-strings-for-logging-fixes-2646-log-file-i.patch
@@ -0,0 +1,174 @@
1From 427120b41a141626dbb40a752c848f199fc9f7a8 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
3Date: Thu, 28 May 2015 15:47:14 +0000
4Subject: [PATCH 29/29] =?UTF-8?q?escape=20all=20strings=20for=20logging=20?=
5 =?UTF-8?q?(fixes=20#2646=20log=20file=20injection,=20reported=20by=20Jaan?=
6 =?UTF-8?q?us=20K=C3=A4=C3=A4p)?=
7MIME-Version: 1.0
8Content-Type: text/plain; charset=UTF-8
9Content-Transfer-Encoding: 8bit
10
11From: Stefan Bühler <stbuehler@web.de>
12
13git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2989 152afb58-edef-0310-8abb-c4023f1b3aa9
14---
15 NEWS | 5 +++--
16 src/buffer.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17 src/buffer.h | 5 ++++-
18 src/log.c | 8 ++++----
19 4 files changed, 70 insertions(+), 7 deletions(-)
20
21diff --git a/NEWS b/NEWS
22index dd2d1b8..18007fc 100644
23--- a/NEWS
24+++ b/NEWS
25@@ -19,6 +19,7 @@ NEWS
26 * [mod_auth] use crypt_r instead of crypt if available
27 * fix error message for T_CONFIG_ARRAY config values if an entry value is not a string
28 * fix segfaults in many plugins if they failed configuration
29+ * escape all strings for logging (fixes #2646 log file injection, reported by Jaanus Kääp)
30
31 - 1.4.35 - 2014-03-12
32 * [network/ssl] fix build error if TLSEXT is disabled
33@@ -557,10 +558,10 @@ NEWS
34 * ignore empty packets from STDERR stream. #998
35 * fix a crash for files with an mtime of 0 reported by cubiq on irc [1519]
36 CVE-2007-1870
37- * allow empty passwords with ldap (Jörg Sonnenberger) [1516]
38+ * allow empty passwords with ldap (Jörg Sonnenberger) [1516]
39 * mod_scgi.c segfault fix #964 [1501]
40 * Added round-robin support to mod_fastcgi [1500]
41- * Handle DragonFlyBSD the same way as Freebsd (Jörg Sonnenberger) [1492,1676]
42+ * Handle DragonFlyBSD the same way as Freebsd (Jörg Sonnenberger) [1492,1676]
43 * added now and weeks support to mod_expire. #943
44 * fix cpu hog in certain requests [1473] CVE-2007-1869
45 * fix for handling hostnames with trailing dot [1406]
46diff --git a/src/buffer.c b/src/buffer.c
47index 57c1613..36995a0 100644
48--- a/src/buffer.c
49+++ b/src/buffer.c
50@@ -731,6 +731,65 @@ void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer
51 }
52 }
53
54+void buffer_append_string_c_escaped(buffer *b, const char *s, size_t s_len) {
55+ unsigned char *ds, *d;
56+ size_t d_len, ndx;
57+
58+ force_assert(NULL != b);
59+ force_assert(NULL != s || 0 == s_len);
60+
61+ if (0 == s_len) return;
62+
63+ /* count to-be-encoded-characters */
64+ for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
65+ if ((*ds < 0x20) /* control character */
66+ || (*ds >= 0x7f)) { /* DEL + non-ASCII characters */
67+ switch (*ds) {
68+ case '\t':
69+ case '\r':
70+ case '\n':
71+ d_len += 2;
72+ break;
73+ default:
74+ d_len += 4; /* \xCC */
75+ break;
76+ }
77+ } else {
78+ d_len++;
79+ }
80+ }
81+
82+ d = (unsigned char*) buffer_string_prepare_append(b, d_len);
83+ buffer_commit(b, d_len); /* fill below */
84+ force_assert('\0' == *d);
85+
86+ for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
87+ if ((*ds < 0x20) /* control character */
88+ || (*ds >= 0x7f)) { /* DEL + non-ASCII characters */
89+ d[d_len++] = '\\';
90+ switch (*ds) {
91+ case '\t':
92+ d[d_len++] = 't';
93+ break;
94+ case '\r':
95+ d[d_len++] = 'r';
96+ break;
97+ case '\n':
98+ d[d_len++] = 'n';
99+ break;
100+ default:
101+ d[d_len++] = 'x';
102+ d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F];
103+ d[d_len++] = hex_chars[(*ds) & 0x0F];
104+ break;
105+ }
106+ } else {
107+ d[d_len++] = *ds;
108+ }
109+ }
110+}
111+
112+
113 void buffer_copy_string_encoded_cgi_varnames(buffer *b, const char *s, size_t s_len, int is_http_header) {
114 size_t i, j;
115
116diff --git a/src/buffer.h b/src/buffer.h
117index b6065d4..5f659df 100644
118--- a/src/buffer.h
119+++ b/src/buffer.h
120@@ -133,6 +133,9 @@ typedef enum {
121
122 void buffer_append_string_encoded(buffer *b, const char *s, size_t s_len, buffer_encoding_t encoding);
123
124+/* escape non-printable characters; simple escapes for \t, \r, \n; fallback to \xCC */
125+void buffer_append_string_c_escaped(buffer *b, const char *s, size_t s_len);
126+
127 /* to upper case, replace non alpha-numerics with '_'; if is_http_header prefix with "HTTP_" unless s is "content-type" */
128 void buffer_copy_string_encoded_cgi_varnames(buffer *b, const char *s, size_t s_len, int is_http_header);
129
130@@ -164,7 +167,7 @@ static inline void buffer_append_slash(buffer *b); /* append '/' no non-empty st
131 buffer_copy_string_len(x, y, sizeof(y) - 1)
132
133 #define CONST_STR_LEN(x) x, (x) ? sizeof(x) - 1 : 0
134-#define CONST_BUF_LEN(x) (x)->ptr, buffer_string_length(x)
135+#define CONST_BUF_LEN(x) ((x) ? (x)->ptr : NULL), buffer_string_length(x)
136
137
138 #define UNUSED(x) ( (void)(x) )
139diff --git a/src/log.c b/src/log.c
140index 9322d2c..94f4710 100644
141--- a/src/log.c
142+++ b/src/log.c
143@@ -267,12 +267,12 @@ static void log_buffer_append_printf(buffer *out, const char *fmt, va_list ap) {
144 switch(*fmt) {
145 case 's': /* string */
146 s = va_arg(ap, char *);
147- buffer_append_string(out, s);
148+ buffer_append_string_c_escaped(out, s, (NULL != s) ? strlen(s) : 0);
149 buffer_append_string_len(out, CONST_STR_LEN(" "));
150 break;
151 case 'b': /* buffer */
152 b = va_arg(ap, buffer *);
153- buffer_append_string_buffer(out, b);
154+ buffer_append_string_c_escaped(out, CONST_BUF_LEN(b));
155 buffer_append_string_len(out, CONST_STR_LEN(" "));
156 break;
157 case 'd': /* int */
158@@ -293,11 +293,11 @@ static void log_buffer_append_printf(buffer *out, const char *fmt, va_list ap) {
159 break;
160 case 'S': /* string */
161 s = va_arg(ap, char *);
162- buffer_append_string(out, s);
163+ buffer_append_string_c_escaped(out, s, (NULL != s) ? strlen(s) : 0);
164 break;
165 case 'B': /* buffer */
166 b = va_arg(ap, buffer *);
167- buffer_append_string_buffer(out, b);
168+ buffer_append_string_c_escaped(out, CONST_BUF_LEN(b));
169 break;
170 case 'D': /* int */
171 d = va_arg(ap, int);
172--
1732.4.5
174
diff --git a/main/lighttpd/APKBUILD b/main/lighttpd/APKBUILD
index b959f48f2c..e3a7d7cc12 100644
--- a/main/lighttpd/APKBUILD
+++ b/main/lighttpd/APKBUILD
@@ -2,7 +2,7 @@
2pkgname=lighttpd 2pkgname=lighttpd
3pkgver=1.4.35 3pkgver=1.4.35
4_streamver=2.2.0 4_streamver=2.2.0
5pkgrel=3 5pkgrel=4
6pkgdesc="a secure, fast, compliant and very flexible web-server" 6pkgdesc="a secure, fast, compliant and very flexible web-server"
7url="http://www.lighttpd.net/" 7url="http://www.lighttpd.net/"
8arch="all" 8arch="all"
@@ -16,6 +16,36 @@ makedepends="flex pcre-dev openssl-dev zlib-dev bzip2-dev lua-dev
16source="http://download.lighttpd.net/lighttpd/releases-1.4.x/$pkgname-$pkgver.tar.bz2 16source="http://download.lighttpd.net/lighttpd/releases-1.4.x/$pkgname-$pkgver.tar.bz2
17 http://h264.code-shop.com/download/lighttpd-1.4.18_mod_h264_streaming-$_streamver.tar.gz 17 http://h264.code-shop.com/download/lighttpd-1.4.18_mod_h264_streaming-$_streamver.tar.gz
18 18
19 0001-next-is-1.4.36.patch
20 0002-use-keep-alive-timeout-while-waiting-for-HTTP-header.patch
21 0003-fix-bad-shift-in-conditional-netmask-.-0-handling.patch
22 0004-add-more-mime-types-and-a-script-to-generate-mime.co.patch
23 0005-fix-typo-in-NEWS-entry-for-2579.patch
24 0006-add-support-for-Free-BSD-extended-attributes.patch
25 0007-build-use-fortify-flags-with-extra-warnings.patch
26 0008-mod_dirlisting-mod_redirect-mod_rewrite-abort-config.patch
27 0009-ssl-disable-SSL3.0-by-default.patch
28 0010-Fixed-typo-found-by-openSUSE-user-boo-907709.patch
29 0011-add-NEWS-entry-for-previous-commit.patch
30 0012-network-fix-compile-break-in-calculation-of-sockaddr.patch
31 0013-connections-fix-bug-in-connection-state-handling.patch
32 0014-print-backtrace-in-assert-logging-with-libunwind.patch
33 0015-fix-buffer-chunk-and-http_chunk-API.patch
34 0016-Remove-chunkqueue_get_-append-prepend-API.patch
35 0017-Remove-buffer_prepare_copy-and-buffer_prepare_append.patch
36 0018-tests-improve-valgrind-and-strace-TRACEME-disable-co.patch
37 0019-Use-buffer-API-to-read-and-modify-used-member.patch
38 0020-rename-buffer_append_long_hex-to-buffer_append_uint_.patch
39 0021-buffer-constify-some-parameters.patch
40 0022-bitset-unused-remove.patch
41 0023-remove-unused-stuff-from-server.h.patch
42 0024-crc32-fix-method-signature-const-pointer.patch
43 0025-tests-fix-undefined-index-warning-in-sendfile.php.patch
44 0026-mod_auth-use-crypt_r-instead-of-crypt-if-available.patch
45 0027-fix-error-message-for-T_CONFIG_ARRAY-config-values-i.patch
46 0028-fix-segfaults-in-many-plugins-if-they-failed-configu.patch
47 0029-escape-all-strings-for-logging-fixes-2646-log-file-i.patch
48
19 $pkgname.initd 49 $pkgname.initd
20 $pkgname.confd 50 $pkgname.confd
21 $pkgname.logrotate 51 $pkgname.logrotate
@@ -134,6 +164,35 @@ mod_webdav() {
134 164
135md5sums="f7a88130ee9984b421ad8aa80629750a lighttpd-1.4.35.tar.bz2 165md5sums="f7a88130ee9984b421ad8aa80629750a lighttpd-1.4.35.tar.bz2
136ac37885c881a058194405232e7737a7a lighttpd-1.4.18_mod_h264_streaming-2.2.0.tar.gz 166ac37885c881a058194405232e7737a7a lighttpd-1.4.18_mod_h264_streaming-2.2.0.tar.gz
16700ee47ed4f38b4feede5bc015466966f 0001-next-is-1.4.36.patch
168bd2d1fba09c4ccee295a3c2dcafe8257 0002-use-keep-alive-timeout-while-waiting-for-HTTP-header.patch
169dd6668db0b13257cbf63e6964e14edc3 0003-fix-bad-shift-in-conditional-netmask-.-0-handling.patch
1700fb4734ad0d3a669e29593a3bee8cb19 0004-add-more-mime-types-and-a-script-to-generate-mime.co.patch
1710f3bf205dfa4bc26c27e6d91bae5a77d 0005-fix-typo-in-NEWS-entry-for-2579.patch
172148470359b1c253d926929cbf4a3df6e 0006-add-support-for-Free-BSD-extended-attributes.patch
1737a295bd597977549912a995cac4c16d2 0007-build-use-fortify-flags-with-extra-warnings.patch
174f7eae7225e3bbb176c805c4781c20fdd 0008-mod_dirlisting-mod_redirect-mod_rewrite-abort-config.patch
17571745edff2b66f6e3764008f265922cf 0009-ssl-disable-SSL3.0-by-default.patch
1763dfd329eba6cbe2d5561a4a86be41d41 0010-Fixed-typo-found-by-openSUSE-user-boo-907709.patch
177d3701826b4d2e62eb915e2add340ab64 0011-add-NEWS-entry-for-previous-commit.patch
1780fb5b2d1047abf714072ac1d5e4d8e9d 0012-network-fix-compile-break-in-calculation-of-sockaddr.patch
179719ea46ccbd435b4e0a5b7679f6e6619 0013-connections-fix-bug-in-connection-state-handling.patch
180ab768bf719f1c80bcfec3921f597e9ce 0014-print-backtrace-in-assert-logging-with-libunwind.patch
181b45c3022b16bac36ed542e7761d1fc8d 0015-fix-buffer-chunk-and-http_chunk-API.patch
1824cae316e303cc74e6ceba6d9bb31b118 0016-Remove-chunkqueue_get_-append-prepend-API.patch
1835fdc9ba9824c47e92e35a87ed77cf673 0017-Remove-buffer_prepare_copy-and-buffer_prepare_append.patch
184bb6293085a26d2585fd1a9027ee163df 0018-tests-improve-valgrind-and-strace-TRACEME-disable-co.patch
1851df70c6be883619b1c0e0b225e8a76d9 0019-Use-buffer-API-to-read-and-modify-used-member.patch
1868cbc257ca7cb41933ed19bd096d63953 0020-rename-buffer_append_long_hex-to-buffer_append_uint_.patch
187abaa48bc0376b5bc2266159c81b386fd 0021-buffer-constify-some-parameters.patch
1880d2b7108b95bf4a26830e45337da57a9 0022-bitset-unused-remove.patch
1895f7c377944b94ae35e4360296241eab1 0023-remove-unused-stuff-from-server.h.patch
1907ab10c7e1f8ccb260289ab55d3588110 0024-crc32-fix-method-signature-const-pointer.patch
191ef60f4c3935b3b1a70e3ea0159208d7e 0025-tests-fix-undefined-index-warning-in-sendfile.php.patch
19224efc5f5dc32f35b34935cb69f7ff064 0026-mod_auth-use-crypt_r-instead-of-crypt-if-available.patch
193f4d7686b793434bba88c03cbbc783440 0027-fix-error-message-for-T_CONFIG_ARRAY-config-values-i.patch
194d7b916dab3c4440e0f5cee327f6e3993 0028-fix-segfaults-in-many-plugins-if-they-failed-configu.patch
19592a0c1b87737ac0f845ac10fefcf724a 0029-escape-all-strings-for-logging-fixes-2646-log-file-i.patch
137b3f7106fa5dcdadf3b0e1bb98bba5e3a lighttpd.initd 196b3f7106fa5dcdadf3b0e1bb98bba5e3a lighttpd.initd
1380dede109282bfe685bdec6b35f0e4b6b lighttpd.confd 1970dede109282bfe685bdec6b35f0e4b6b lighttpd.confd
139ad091c9157134890499f26d170352c9f lighttpd.logrotate 198ad091c9157134890499f26d170352c9f lighttpd.logrotate
@@ -144,6 +203,35 @@ f3363e39832f1b6678468b482d121afb mod_fastcgi.conf
144aee5947a1abf380b0685a534ca384b42 mod_fastcgi_fpm.conf" 203aee5947a1abf380b0685a534ca384b42 mod_fastcgi_fpm.conf"
145sha256sums="4a71c1f6d8af41ed894b507720c4c17184dc320590013881d5170ca7f15c5bf7 lighttpd-1.4.35.tar.bz2 204sha256sums="4a71c1f6d8af41ed894b507720c4c17184dc320590013881d5170ca7f15c5bf7 lighttpd-1.4.35.tar.bz2
146732cf98d823f2c7ddc96a3130a3c88d588b02ed20a0e7f8c9be25a265fbea2d6 lighttpd-1.4.18_mod_h264_streaming-2.2.0.tar.gz 205732cf98d823f2c7ddc96a3130a3c88d588b02ed20a0e7f8c9be25a265fbea2d6 lighttpd-1.4.18_mod_h264_streaming-2.2.0.tar.gz
206c879dbe0d41e2b5e9d79e94c621bcb6498170a9949aa9944009aebf7266f6574 0001-next-is-1.4.36.patch
207ea90697199e2dafb483942e44558bb73727b3ba2e2afe9017735a92db5a92b9e 0002-use-keep-alive-timeout-while-waiting-for-HTTP-header.patch
2082de1193ee68715de6f92654a439c09254500c6d371fd979400265af1c31e2f64 0003-fix-bad-shift-in-conditional-netmask-.-0-handling.patch
2091708a734bb0bd9a6e5ff4357da82bf5dffc15bbb89e3fb369e4ed21408431081 0004-add-more-mime-types-and-a-script-to-generate-mime.co.patch
21069b6b9986c6dd69ea77b60d61da8c984869a34d2e48928d774678392e9e0b377 0005-fix-typo-in-NEWS-entry-for-2579.patch
211959120d7c256733292aaeb6595c55e9b703968d3de3093ec3c65163f86859058 0006-add-support-for-Free-BSD-extended-attributes.patch
212e6e5984fb33ed89d7961e39ea75467a644a8f70ab931ff886545ee271b3e4079 0007-build-use-fortify-flags-with-extra-warnings.patch
2135a59ef2bf5efd77770a02421451372ec08b00a2e27cd4ce1312301ea94be58af 0008-mod_dirlisting-mod_redirect-mod_rewrite-abort-config.patch
214b204c4bf8572f41cd31d4de34529ab65ec42a0d32eb4bcd4b77d42afd3858ff5 0009-ssl-disable-SSL3.0-by-default.patch
215c25c136143f597a557df676bb80dc549d44b4216de2bbec578b02e474532b7f5 0010-Fixed-typo-found-by-openSUSE-user-boo-907709.patch
216f0759a4fd37e43abb4901ecc53cfa64bc24ffcc52d425d1057b63d5e696ccddc 0011-add-NEWS-entry-for-previous-commit.patch
21791cc0d32a195178d78923749e0d9f49cba3806e988f3ec30ec1011bb5f10c888 0012-network-fix-compile-break-in-calculation-of-sockaddr.patch
2183c1ec290a581afb0c11d5743ecdffbee4bb2caec790e9c174fce2ce7501dcc96 0013-connections-fix-bug-in-connection-state-handling.patch
219afdfe2f60b91367eecc00b63d6e7f5bad221c9d719f4f827aef2b5fd35fecdaa 0014-print-backtrace-in-assert-logging-with-libunwind.patch
220fff02538e63edb68e4c070f0c5f518a43630addd7b4ce33b321caa9071f05357 0015-fix-buffer-chunk-and-http_chunk-API.patch
221c72d9b344ba4784cb1db1d9fca4fc88c86dca25ec1cfc91688424474da22e5f9 0016-Remove-chunkqueue_get_-append-prepend-API.patch
222600a3698a6d8882bf1f91a0f1e636395736f479d3fa2dda0b0ab099dbe648e73 0017-Remove-buffer_prepare_copy-and-buffer_prepare_append.patch
22320b759bf8f4c7c79862f919fce2dc1b3348695993ba1033449df9558dbe01a6d 0018-tests-improve-valgrind-and-strace-TRACEME-disable-co.patch
2244b5538e7428ac2d625655b35f46afcdf794f9cf7fab11d2fb2f626d9c0684dd9 0019-Use-buffer-API-to-read-and-modify-used-member.patch
22517b240483cd3b326e67c6dc38b53a9041623b9aec664e883c81f4ce525a36108 0020-rename-buffer_append_long_hex-to-buffer_append_uint_.patch
22658b7afa5a8e98a700c8856174586d4f458019308313864fcddcb974cf94650b2 0021-buffer-constify-some-parameters.patch
227d98d8bc7ddd107bca0b7653a7c9ac7f6874b986864f00c4a359a71892dda9da7 0022-bitset-unused-remove.patch
2283f4524142df2db012c5a8f0ab0dac2bdc53d5a253d18b842e4ba0649e37ac435 0023-remove-unused-stuff-from-server.h.patch
22945ae49ec62907750b5741d726942bc5171397a88cf676ff7750d54a89f94e8a8 0024-crc32-fix-method-signature-const-pointer.patch
2307adefe15856cb965f6ab102d8e655513b229c475951003766ea15d60e0f95536 0025-tests-fix-undefined-index-warning-in-sendfile.php.patch
231e46917c0731eff62ee5d73ecbdd6d4276674893936132a050c855c419d1dc8e6 0026-mod_auth-use-crypt_r-instead-of-crypt-if-available.patch
232a1c8b496be35065ea72a115462c3a23c78995b953ce15b806d2ef6b6b6758523 0027-fix-error-message-for-T_CONFIG_ARRAY-config-values-i.patch
23342192c43bd917a6b196e8b3fb52cfc76b9165f0b3de08bd30d0fab08b3ce2444 0028-fix-segfaults-in-many-plugins-if-they-failed-configu.patch
234dca7509a720ce26488685ce7acca041e83e1e1f2eb195adc36338ef4031b90fc 0029-escape-all-strings-for-logging-fixes-2646-log-file-i.patch
147097a4df1a6470e2e9fd2097c7c1daa7b1ee6341faddc35a65e975af019beaebd lighttpd.initd 235097a4df1a6470e2e9fd2097c7c1daa7b1ee6341faddc35a65e975af019beaebd lighttpd.initd
14894f69a173dc26610a43532474230537b9bc31ec846fb9f94cb72765f125edf87 lighttpd.confd 23694f69a173dc26610a43532474230537b9bc31ec846fb9f94cb72765f125edf87 lighttpd.confd
149503ee1cd454e2c0f9a212ef60dc8321893eda06ccf721ecbe94d189a09e0bc6c lighttpd.logrotate 237503ee1cd454e2c0f9a212ef60dc8321893eda06ccf721ecbe94d189a09e0bc6c lighttpd.logrotate
@@ -154,6 +242,35 @@ d1adc1358b5d9e85353caa2e706bfa231d145dd59c075cdcb3f818b3cb5d722e mod_fastcgi.co
154e7eb047360e09d1a2b693f08d4a912b99954090c5bdea706f46a33554e867043 mod_fastcgi_fpm.conf" 242e7eb047360e09d1a2b693f08d4a912b99954090c5bdea706f46a33554e867043 mod_fastcgi_fpm.conf"
155sha512sums="13f8562fb735964fe7ef1b127a15c43907f34be70b6bd2dd4ba61b59275d7c2a8d9a7947ff1a4d7cc5fd7efd309fc66b7de6d954b59424f814ea2eb98fd876b9 lighttpd-1.4.35.tar.bz2 243sha512sums="13f8562fb735964fe7ef1b127a15c43907f34be70b6bd2dd4ba61b59275d7c2a8d9a7947ff1a4d7cc5fd7efd309fc66b7de6d954b59424f814ea2eb98fd876b9 lighttpd-1.4.35.tar.bz2
15612e1b7c8146cccfa78678ce56cd2f704423559b23b90996dff00602634f110512146386086ac234293a3c28900a06c2bec1c97e680e7eed5173372f88177b351 lighttpd-1.4.18_mod_h264_streaming-2.2.0.tar.gz 24412e1b7c8146cccfa78678ce56cd2f704423559b23b90996dff00602634f110512146386086ac234293a3c28900a06c2bec1c97e680e7eed5173372f88177b351 lighttpd-1.4.18_mod_h264_streaming-2.2.0.tar.gz
245622314eae65e08866dd55efbbf0a3c9b84818e4f5f5e4c4a602883c0123cf448edbfd1dd1c69a288fae923c730be213a4cf358aa6334caf57c62b54330fa2765 0001-next-is-1.4.36.patch
24623a9f56e402fc24cea33e2d4d84ed7c4c0473b4c28bab9837294756ea27b5f6682393871188ec9b3744591aa01c75804a3373999842f3e44935c87e7b0f214de 0002-use-keep-alive-timeout-while-waiting-for-HTTP-header.patch
2477ebe0117493bcea361e1dc60a394e57fb52b6d83c284af246179af58e41c2b2a95255f257fd8706c31dddf67559c8f807db1c959fd39777f5ec1d31bc48ed1c2 0003-fix-bad-shift-in-conditional-netmask-.-0-handling.patch
24885ad87b3632ad145812a1cf1bcaf321d98a000a0e50fdbbdbacf1b3a3e53e3081044da070ce41e2d2a234a82f4bfb7938ce09d8db289e5c469254d2b6cd6f487 0004-add-more-mime-types-and-a-script-to-generate-mime.co.patch
24964a75d212a8f4388be909d4f6b341f5567a028469b91db49df9ef018248ad78d6468d945c582090f762ea2f778568aedfb572e5493927cab25476966d11ef479 0005-fix-typo-in-NEWS-entry-for-2579.patch
25009d3722fa79423bb0bfc7c1fc5fd1b2a8022127b40b8a1055ac26aec369861b27b8be2394bfcf2dd0f33adc1063e7ba1d3bac3ced9e6d4d74c824c870aede879 0006-add-support-for-Free-BSD-extended-attributes.patch
2511df20ff4c5b48e60fdd8b4c37d47016667b7ad6c74ea8d4d8bb53b84bd0f90e9905fdc500df319a5288e92761500e8ddd6a15e5b946e34c819628bef6c501610 0007-build-use-fortify-flags-with-extra-warnings.patch
2529fb01cec49962a47db026befd73a13026df06b7ee16d4870394ce5c3dd3ff4c671b53425a1066a43482854dca7f4dad234100c0dc71e7647dc70202d61053a61 0008-mod_dirlisting-mod_redirect-mod_rewrite-abort-config.patch
253cb94bfb83ddbe1f2aaccf844ab262139f111dbc8cd522cfe3621e235b5e058fdf960d9245f154c0da17f5c52d1c2f56f37d473fdbb5c71ca584ce408ae9affca 0009-ssl-disable-SSL3.0-by-default.patch
254385db7d9879584e76ddd1e01a1d30bd8488a440ddc9ab014de5db72f001d6370007b0e96dd83f5875b154dd34ad289c7ed4d93b42c8143d81b0598dfbee38674 0010-Fixed-typo-found-by-openSUSE-user-boo-907709.patch
2553409867e77a2a7dfbd429e1ea8b5c45573c75c8574edd71fb206a3fc76a230f98b1232bfc3e7a77c59008c4c32155e360c972dd7ebcb42baf9671af2b388df2a 0011-add-NEWS-entry-for-previous-commit.patch
256cf5fbcc8742757bed684e23a8c2ca3fe66184fd5d5e153f54a24108a8ddde2062f4adb300211c56759a3401ae24c1b1e6313e8bb07e9688cc25a3fe83fae29e5 0012-network-fix-compile-break-in-calculation-of-sockaddr.patch
257836703b795bcb9601b6212c8b7e1be50a681e50697dc564749f1a5cc3795ecc16de4e86be98037b6fca98ba728835f3a5f7261e9b39e4ebe3824e3d58fcd7559 0013-connections-fix-bug-in-connection-state-handling.patch
258aca54c61898d26e6e729be421e96e595929646f4361dd905c22dc4aed6ba795c33c233f76961f2b6401ad60104c0fdfce263c1240aeeed29e3fc7bd7e7ed67a1 0014-print-backtrace-in-assert-logging-with-libunwind.patch
259d97bb6832e85923454ed3ff5c2d739c7f70b0141f08fe6c1326ca86eb55a75f5a4bf7e761b2d73402c0552bb76faefff2b442030d76891fade51197b34719839 0015-fix-buffer-chunk-and-http_chunk-API.patch
260f9a1c772a3a8cdc3d0e5dd6430d3ac5651cda2bb1f6dc156474477c6c9509ff98fcfe76bf89d9761970ccd8ae56c8585d51b81757b46ded356a55f8247efb248 0016-Remove-chunkqueue_get_-append-prepend-API.patch
261500ede5ad01476afe0e65d1cef22f0c89df3b91d330479cd23071aa594276560bf045de9531a61e5a15821ba5389e616fbdf6532caf25882d9ec86ec0c882a53 0017-Remove-buffer_prepare_copy-and-buffer_prepare_append.patch
262c22dad92b15655cb071c0e96f43bd1f6af55f1f4c468279814aa5643ec601d5e0ba5d0829470d6125a7da979fed7c79689af453e5b127310d7c5cfb77e0479ad 0018-tests-improve-valgrind-and-strace-TRACEME-disable-co.patch
2637d3133bd31cd413eef55cff57a4deeeb553db1c23cc17eb1655a0c02b70aa4f11ef069b47979966c1e0e6512a9b74a5bfcc50b4c91c55115b55d4861d3b95581 0019-Use-buffer-API-to-read-and-modify-used-member.patch
2640b37401c1acbf5b7bb633758024c2a09fe22a54731175fe5475217952691059fac1b757bf2a651c2f91ce2b71c010ad05b2015523954062cae5d88103f1eb783 0020-rename-buffer_append_long_hex-to-buffer_append_uint_.patch
265558a8333f509a3cbd7a4c04b745ab407e7d846a01fbd400e873dc9a18e90b8042bb46e34c0475dbfa203fe39ba201145d06384f5c1f42a2dc0894c43cc984dac 0021-buffer-constify-some-parameters.patch
26649c6c3d032b69740e1b9ae9f2c0b09d13a34a4e2aed890c12af78bfd2a2266319d282b0a2a63dab214189bcd9b4596226818dfca44dfed0f44d7494976f98b2c 0022-bitset-unused-remove.patch
267b1299b16f14feaf848344d27dd6b6529543d49b8ec26bf03de3e2fe7551254cc00eec1b3309f73b8e6541b730b047425feabb8f5c6a822757b7934825d79bbbc 0023-remove-unused-stuff-from-server.h.patch
26840f6436720ecf43370a32081da1529a9df1faee15e29056ec8832456beacfff2ea19e73b9c6377f1942d7852eaad2ea88cc1b4e49c0a317768f3b4a7cfb97cc1 0024-crc32-fix-method-signature-const-pointer.patch
2697c9772483e7d32cbc80dd9133661bf8a7542e2c571ecc9745d926de78f6879067cfd0feb7725235f23fa715febb5b810bcb352170cb8e6e09ce861961f937db4 0025-tests-fix-undefined-index-warning-in-sendfile.php.patch
270f01032d73b5a0f7b339fa4ea863767acf39a4ae84ab90eeac702eac029982017e659afc3da21198919c63a739412f12a31756cfa8ad1bcd8cc651cbd70d00b7d 0026-mod_auth-use-crypt_r-instead-of-crypt-if-available.patch
271bedd3fa6a02e315e11109ec0b5dd3ef2c3a8a250d45fdd673254cce20059165b1c96227725e01ac5e9b85fe93da2ac89770d5b2fe414bbf66063b5fe7d3ee38b 0027-fix-error-message-for-T_CONFIG_ARRAY-config-values-i.patch
272974ac318ad22aa164b860bf9273f0ccb10b08f43642bcd90008e31844d65329b89ff7100538971d068a1f42ea451639c5345dd94fe303a936e4ebd6212e431a6 0028-fix-segfaults-in-many-plugins-if-they-failed-configu.patch
2738fb56b604c89129ba84fd2d34dc38ea31eb07b377b69f8551c831d65d0076cfc7f0d9219bda4b0ad122e12102aecf29a84c6111a8bfc232f97652efc5f14e600 0029-escape-all-strings-for-logging-fixes-2646-log-file-i.patch
15769b7574a8d4384bcbbca587aa643aeb55c2b237e726093d1443982d8ec1d085b15c3891a273f7901a9554df4d0842a586d59cc6062b8347e72dad8c6c37bc39a lighttpd.initd 27469b7574a8d4384bcbbca587aa643aeb55c2b237e726093d1443982d8ec1d085b15c3891a273f7901a9554df4d0842a586d59cc6062b8347e72dad8c6c37bc39a lighttpd.initd
15893a05dddab14ba6355a0345f1da2fe900c8b55fed8f98506295dc12d96c7cef803c4aca77f016b8acea7bbde485be1e09a57d31fdca6f91023fbeb4db9a90a8b lighttpd.confd 27593a05dddab14ba6355a0345f1da2fe900c8b55fed8f98506295dc12d96c7cef803c4aca77f016b8acea7bbde485be1e09a57d31fdca6f91023fbeb4db9a90a8b lighttpd.confd
159e1284fe9ab4b9a53c21b40a5ac3e77e66343e187321b8a2f7464db64747f3a99f7e17a9e7c0e298db84a24fa1286cfe344dbff182eddd9de5c0605f5397a6972 lighttpd.logrotate 276e1284fe9ab4b9a53c21b40a5ac3e77e66343e187321b8a2f7464db64747f3a99f7e17a9e7c0e298db84a24fa1286cfe344dbff182eddd9de5c0605f5397a6972 lighttpd.logrotate