1 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/Makefile.in lighttpd-1.4.12/Makefile.in
2 --- lighttpd-1.4.11/Makefile.in 2006-03-07 14:21:08.000000000 +0200
3 +++ lighttpd-1.4.12/Makefile.in 2006-07-11 21:48:16.000000000 +0300
5 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
6 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
9 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
11 $(srcdir)/distribute.sh.in $(srcdir)/lighttpd.spec.in \
12 $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
13 compile config.guess config.sub depcomp install-sh ltmain.sh \
14 - missing mkinstalldirs
17 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
18 am__aclocal_m4_deps = $(top_srcdir)/configure.in
21 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
22 configure.lineno configure.status.lineno
23 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
24 +mkinstalldirs = $(install_sh) -d
25 CONFIG_HEADER = config.h
26 CONFIG_CLEAN_FILES = lighttpd.spec distribute.sh
31 LTLIBOBJS = @LTLIBOBJS@
32 -LUACONFIG = @LUACONFIG@
33 LUA_CFLAGS = @LUA_CFLAGS@
37 ac_ct_F77 = @ac_ct_F77@
38 ac_ct_RANLIB = @ac_ct_RANLIB@
39 ac_ct_STRIP = @ac_ct_STRIP@
40 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
41 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
42 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
43 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
44 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/NEWS lighttpd-1.4.12/NEWS
45 --- lighttpd-1.4.11/NEWS 2006-03-09 19:34:33.000000000 +0200
46 +++ lighttpd-1.4.12/NEWS 2006-07-11 21:23:42.000000000 +0300
51 +- 1.4.12 - 2006-..-..
53 + * added handling of Content-Range to PUT requests in mod_webdav
54 + * added handling of ETag and If-Modified-Since to mod_compress if
55 + cache-dir is not set
56 + * added experimental LOCK support for mod_webdav
57 + * added support for X-Sendfile as addition to X-LIGHTTPD-send-file.
58 + This allows compatibility with mod_xsendfile for apache
59 + (http://celebnamer.celebworld.ws/stuff/mod_xsendfile/)
60 + * fixed handling of If-Modified-Since if Etag is not set
61 + * fixed hanging fastcgi connections
62 + * fixed stalling SSL POST requests
63 + * fixed round-robin load-balancing in mod_proxy
64 + * TODO: add fail-over to mod-proxy
65 + * TODO: fix CACHE_HIT/MISS in mod_cml
66 + * TODO: finish LOCK/UNLOCK in mod_webdav
70 * added ability to specify which ip address spawn-fci listens on
71 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/configure.in lighttpd-1.4.12/configure.in
72 --- lighttpd-1.4.11/configure.in 2006-03-04 16:32:38.000000000 +0200
73 +++ lighttpd-1.4.12/configure.in 2006-07-11 21:23:42.000000000 +0300
76 # Process this file with autoconf to produce a configure script.
78 -AC_INIT(lighttpd, 1.4.11, jan@kneschke.de)
79 +AC_INIT(lighttpd, 1.4.12, jan@kneschke.de)
80 AC_CONFIG_SRCDIR([src/server.c])
87 -AC_CHECK_MEMBER(struct tm.tm_gmtoff,AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm]),,[#include <time.h>])
88 +AC_CHECK_MEMBER(struct tm.tm_gmtoff,[AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm])],,[#include <time.h>])
89 AC_CHECK_TYPES(struct sockaddr_storage,,,[#include <sys/socket.h>])
90 AC_CHECK_TYPES(socklen_t,,,[#include <sys/types.h>
91 #include <sys/socket.h>])
93 AC_DEFINE([HAVE_SQLITE3], [1], [libsqlite3])
94 AC_DEFINE([HAVE_SQLITE3_H], [1], [sqlite3.h])
97 + AC_MSG_CHECKING(for locks in mod_webdav)
98 + AC_ARG_WITH(webdav-locks, AC_HELP_STRING([--with-webdav-locks],[locks in mod_webdav]),
99 + [WITH_WEBDAV_LOCKS=$withval],[WITH_WEBDAV_LOCKS=no])
100 + AC_MSG_RESULT([$WITH_WEBDAV_LOCKS])
102 + if test "$WITH_WEBDAV_LOCKS" != "no"; then
103 + AC_CHECK_LIB(uuid, uuid_unparse, [
104 + AC_CHECK_HEADERS([uuid/uuid.h],[
106 + AC_DEFINE([HAVE_UUID], [1], [libuuid])
107 + AC_DEFINE([HAVE_UUID_H], [1], [uuid/uuid.h is available])
115 @@ -381,30 +397,11 @@
117 AC_MSG_RESULT($WITH_LUA)
118 if test "$WITH_LUA" != "no"; then
119 - AC_PATH_PROG(LUACONFIG, lua-config)
121 - if test x"$LUACONFIG" != x; then
122 - LUA_CFLAGS=`$LUACONFIG --include`
123 - LUA_LIBS=`$LUACONFIG --libs --extralibs`
125 + PKG_CHECK_MODULES(LUA, lua >= 5.1, [
126 AC_DEFINE([HAVE_LUA], [1], [liblua])
127 AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
129 - AC_CHECK_LIB(lua, lua_open, [
130 - AC_CHECK_HEADERS([lua.h],[
131 - LUA_LIBS="-llua -llualib"
132 - AC_DEFINE([HAVE_LUA], [1], [liblua])
133 - AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
138 - if test x"$LUA_LIBS" = x; then
140 - PKG_CHECK_MODULES(LUA, lua, [
141 - AC_DEFINE([HAVE_LUA], [1], [liblua])
142 - AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
152 AC_CHECK_FUNCS([dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \
153 - strdup strerror strstr strtol sendfile getopt socket \
154 + strdup strerror strstr strtol sendfile getopt socket lstat \
155 gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot \
156 getuid select signal pathconf madvise posix_fadvise posix_madvise \
157 writev sigaction sendfile64 send_file kqueue port_create localtime_r])
162 -do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi"
163 +do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming"
165 plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl"
166 features="regex-conditionals"
168 disable_feature="$disable_feature $features"
171 +features="webdav-locks"
172 +if test "x$UUID_LIB" \!= x; then
173 + enable_feature="$enable_feature $features"
175 + disable_feature="$disable_feature $features"
182 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/cygwin/Makefile.in lighttpd-1.4.12/cygwin/Makefile.in
183 --- lighttpd-1.4.11/cygwin/Makefile.in 2006-03-07 14:20:57.000000000 +0200
184 +++ lighttpd-1.4.12/cygwin/Makefile.in 2006-07-11 21:48:12.000000000 +0300
186 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
187 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
190 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
192 am__aclocal_m4_deps = $(top_srcdir)/configure.in
193 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
195 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
196 +mkinstalldirs = $(install_sh) -d
197 CONFIG_HEADER = $(top_builddir)/config.h
198 CONFIG_CLEAN_FILES = lighttpd.README
203 LTLIBOBJS = @LTLIBOBJS@
204 -LUACONFIG = @LUACONFIG@
205 LUA_CFLAGS = @LUA_CFLAGS@
206 LUA_LIBS = @LUA_LIBS@
209 ac_ct_F77 = @ac_ct_F77@
210 ac_ct_RANLIB = @ac_ct_RANLIB@
211 ac_ct_STRIP = @ac_ct_STRIP@
212 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
213 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
214 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
215 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
216 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/cygwin/lighttpd.README lighttpd-1.4.12/cygwin/lighttpd.README
217 --- lighttpd-1.4.11/cygwin/lighttpd.README 2006-03-07 14:22:19.000000000 +0200
218 +++ lighttpd-1.4.12/cygwin/lighttpd.README 2006-07-11 21:49:09.000000000 +0300
221 -------------------------------------------
\r
222 -A fast, secure and flexible webserver
\r
224 -Runtime requirements:
\r
225 - cygwin-1.5.10 or newer
\r
226 - crypt-1.1 or newer
\r
227 - libbz2_1-1.0.2 or newer
\r
228 - libpcre0-4.5 or newer
\r
229 - openssl-0.9.7d or newer
\r
230 - zlib-1.2.1 or newer
\r
232 -Build requirements:
\r
233 - cygwin-1.5.10 or newer
\r
234 - gcc-3.3.1-3 or newer
\r
235 - binutils-20030901-1 or newer
\r
244 -Canonical homepage:
\r
245 - http://jan.kneschke.de/projects/lighttpd/
\r
247 -Canonical download:
\r
248 - http://jan.kneschke.de/projects/lighttpd/download
\r
250 -------------------------------------
\r
252 -Build instructions:
\r
253 - unpack lighttpd-1.4.11-<REL>-src.tar.bz2
\r
254 - if you use setup to install this src package, it will be
\r
255 - unpacked under /usr/src automatically
\r
257 - ./lighttpd-1.4.11-<REL>.sh all
\r
260 - /usr/src/lighttpd-1.4.11-<REL>.tar.bz2
\r
261 - /usr/src/lighttpd-1.4.11-<REL>-src.tar.bz2
\r
263 -Or use './lighttpd-1.4.11-<REL>.sh prep' to get a patched source directory
\r
265 --------------------------------------------
\r
267 -Files included in the binary distribution:
\r
269 - /etc/lighttpd/lighttpd.conf.default
\r
270 - /usr/lib/cyglightcomp.dll
\r
271 - /usr/lib/lighttpd/mod_access.dll
\r
272 - /usr/lib/lighttpd/mod_accesslog.dll
\r
273 - /usr/lib/lighttpd/mod_auth.dll
\r
274 - /usr/lib/lighttpd/mod_cgi.dll
\r
275 - /usr/lib/lighttpd/mod_compress.dll
\r
276 - /usr/lib/lighttpd/mod_evhost.dll
\r
277 - /usr/lib/lighttpd/mod_expire.dll
\r
278 - /usr/lib/lighttpd/mod_fastcgi.dll
\r
279 - /usr/lib/lighttpd/mod_httptls.dll
\r
280 - /usr/lib/lighttpd/mod_maps.dll
\r
281 - /usr/lib/lighttpd/mod_proxy.dll
\r
282 - /usr/lib/lighttpd/mod_redirect.dll
\r
283 - /usr/lib/lighttpd/mod_rewrite.dll
\r
284 - /usr/lib/lighttpd/mod_rrdtool.dll
\r
285 - /usr/lib/lighttpd/mod_secdownload.dll
\r
286 - /usr/lib/lighttpd/mod_simple_vhost.dll
\r
287 - /usr/lib/lighttpd/mod_ssi.dll
\r
288 - /usr/lib/lighttpd/mod_status.dll
\r
289 - /usr/lib/lighttpd/mod_usertrack.dll
\r
290 - /usr/sbin/lighttpd.exe
\r
291 - /usr/share/doc/Cygwin/lighttpd-1.3.0.README
\r
292 - /usr/share/doc/lighttpd-1.3.0/accesslog.txt
\r
293 - /usr/share/doc/lighttpd-1.3.0/authentification.txt
\r
294 - /usr/share/doc/lighttpd-1.3.0/AUTHORS
\r
295 - /usr/share/doc/lighttpd-1.3.0/cgi.txt
\r
296 - /usr/share/doc/lighttpd-1.3.0/ChangeLog
\r
297 - /usr/share/doc/lighttpd-1.3.0/compress.txt
\r
298 - /usr/share/doc/lighttpd-1.3.0/configuration.txt
\r
299 - /usr/share/doc/lighttpd-1.3.0/COPYING
\r
300 - /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt
\r
301 - /usr/share/doc/lighttpd-1.3.0/fastcgi.txt
\r
302 - /usr/share/doc/lighttpd-1.3.0/features.txt
\r
303 - /usr/share/doc/lighttpd-1.3.0/INSTALL
\r
304 - /usr/share/doc/lighttpd-1.3.0/NEWS
\r
305 - /usr/share/doc/lighttpd-1.3.0/performance.txt
\r
306 - /usr/share/doc/lighttpd-1.3.0/plugins.txt
\r
307 - /usr/share/doc/lighttpd-1.3.0/proxy.txt
\r
308 - /usr/share/doc/lighttpd-1.3.0/README
\r
309 - /usr/share/doc/lighttpd-1.3.0/redirect.txt
\r
310 - /usr/share/doc/lighttpd-1.3.0/rewrite.txt
\r
311 - /usr/share/doc/lighttpd-1.3.0/rrdtool.txt
\r
312 - /usr/share/doc/lighttpd-1.3.0/secdownload.txt
\r
313 - /usr/share/doc/lighttpd-1.3.0/security.txt
\r
314 - /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt
\r
315 - /usr/share/doc/lighttpd-1.3.0/skeleton.txt
\r
316 - /usr/share/doc/lighttpd-1.3.0/ssi.txt
\r
317 - /usr/share/doc/lighttpd-1.3.0/state.txt
\r
318 - /usr/share/man/man1/lighttpd.1.gz
\r
320 -------------------
\r
324 ----------- lighttpd-1.3.1-1 -----------
\r
328 ----------- lighttpd-1.3.0-1 -----------
\r
331 -Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>
\r
332 -Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
\r
335 +------------------------------------------
336 +A fast, secure and flexible webserver
338 +Runtime requirements:
339 + cygwin-1.5.10 or newer
341 + libbz2_1-1.0.2 or newer
342 + libpcre0-4.5 or newer
343 + openssl-0.9.7d or newer
344 + zlib-1.2.1 or newer
347 + cygwin-1.5.10 or newer
348 + gcc-3.3.1-3 or newer
349 + binutils-20030901-1 or newer
359 + http://jan.kneschke.de/projects/lighttpd/
362 + http://jan.kneschke.de/projects/lighttpd/download
364 +------------------------------------
367 + unpack lighttpd-1.4.12-<REL>-src.tar.bz2
368 + if you use setup to install this src package, it will be
369 + unpacked under /usr/src automatically
371 + ./lighttpd-1.4.12-<REL>.sh all
374 + /usr/src/lighttpd-1.4.12-<REL>.tar.bz2
375 + /usr/src/lighttpd-1.4.12-<REL>-src.tar.bz2
377 +Or use './lighttpd-1.4.12-<REL>.sh prep' to get a patched source directory
379 +-------------------------------------------
381 +Files included in the binary distribution:
383 + /etc/lighttpd/lighttpd.conf.default
384 + /usr/lib/cyglightcomp.dll
385 + /usr/lib/lighttpd/mod_access.dll
386 + /usr/lib/lighttpd/mod_accesslog.dll
387 + /usr/lib/lighttpd/mod_auth.dll
388 + /usr/lib/lighttpd/mod_cgi.dll
389 + /usr/lib/lighttpd/mod_compress.dll
390 + /usr/lib/lighttpd/mod_evhost.dll
391 + /usr/lib/lighttpd/mod_expire.dll
392 + /usr/lib/lighttpd/mod_fastcgi.dll
393 + /usr/lib/lighttpd/mod_httptls.dll
394 + /usr/lib/lighttpd/mod_maps.dll
395 + /usr/lib/lighttpd/mod_proxy.dll
396 + /usr/lib/lighttpd/mod_redirect.dll
397 + /usr/lib/lighttpd/mod_rewrite.dll
398 + /usr/lib/lighttpd/mod_rrdtool.dll
399 + /usr/lib/lighttpd/mod_secdownload.dll
400 + /usr/lib/lighttpd/mod_simple_vhost.dll
401 + /usr/lib/lighttpd/mod_ssi.dll
402 + /usr/lib/lighttpd/mod_status.dll
403 + /usr/lib/lighttpd/mod_usertrack.dll
404 + /usr/sbin/lighttpd.exe
405 + /usr/share/doc/Cygwin/lighttpd-1.3.0.README
406 + /usr/share/doc/lighttpd-1.3.0/accesslog.txt
407 + /usr/share/doc/lighttpd-1.3.0/authentification.txt
408 + /usr/share/doc/lighttpd-1.3.0/AUTHORS
409 + /usr/share/doc/lighttpd-1.3.0/cgi.txt
410 + /usr/share/doc/lighttpd-1.3.0/ChangeLog
411 + /usr/share/doc/lighttpd-1.3.0/compress.txt
412 + /usr/share/doc/lighttpd-1.3.0/configuration.txt
413 + /usr/share/doc/lighttpd-1.3.0/COPYING
414 + /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt
415 + /usr/share/doc/lighttpd-1.3.0/fastcgi.txt
416 + /usr/share/doc/lighttpd-1.3.0/features.txt
417 + /usr/share/doc/lighttpd-1.3.0/INSTALL
418 + /usr/share/doc/lighttpd-1.3.0/NEWS
419 + /usr/share/doc/lighttpd-1.3.0/performance.txt
420 + /usr/share/doc/lighttpd-1.3.0/plugins.txt
421 + /usr/share/doc/lighttpd-1.3.0/proxy.txt
422 + /usr/share/doc/lighttpd-1.3.0/README
423 + /usr/share/doc/lighttpd-1.3.0/redirect.txt
424 + /usr/share/doc/lighttpd-1.3.0/rewrite.txt
425 + /usr/share/doc/lighttpd-1.3.0/rrdtool.txt
426 + /usr/share/doc/lighttpd-1.3.0/secdownload.txt
427 + /usr/share/doc/lighttpd-1.3.0/security.txt
428 + /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt
429 + /usr/share/doc/lighttpd-1.3.0/skeleton.txt
430 + /usr/share/doc/lighttpd-1.3.0/ssi.txt
431 + /usr/share/doc/lighttpd-1.3.0/state.txt
432 + /usr/share/man/man1/lighttpd.1.gz
438 +---------- lighttpd-1.3.1-1 -----------
442 +---------- lighttpd-1.3.0-1 -----------
445 +Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>
446 +Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
448 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/cygwin/lighttpd.README.in lighttpd-1.4.12/cygwin/lighttpd.README.in
449 --- lighttpd-1.4.11/cygwin/lighttpd.README.in 2005-08-11 01:26:59.000000000 +0300
450 +++ lighttpd-1.4.12/cygwin/lighttpd.README.in 2006-07-11 21:23:40.000000000 +0300
453 -------------------------------------------
\r
454 -A fast, secure and flexible webserver
\r
456 -Runtime requirements:
\r
457 - cygwin-1.5.10 or newer
\r
458 - crypt-1.1 or newer
\r
459 - libbz2_1-1.0.2 or newer
\r
460 - libpcre0-4.5 or newer
\r
461 - openssl-0.9.7d or newer
\r
462 - zlib-1.2.1 or newer
\r
464 -Build requirements:
\r
465 - cygwin-1.5.10 or newer
\r
466 - gcc-3.3.1-3 or newer
\r
467 - binutils-20030901-1 or newer
\r
476 -Canonical homepage:
\r
477 - http://jan.kneschke.de/projects/lighttpd/
\r
479 -Canonical download:
\r
480 - http://jan.kneschke.de/projects/lighttpd/download
\r
482 -------------------------------------
\r
484 -Build instructions:
\r
485 - unpack lighttpd-@VERSION@-<REL>-src.tar.bz2
\r
486 - if you use setup to install this src package, it will be
\r
487 - unpacked under /usr/src automatically
\r
489 - ./lighttpd-@VERSION@-<REL>.sh all
\r
492 - /usr/src/lighttpd-@VERSION@-<REL>.tar.bz2
\r
493 - /usr/src/lighttpd-@VERSION@-<REL>-src.tar.bz2
\r
495 -Or use './lighttpd-@VERSION@-<REL>.sh prep' to get a patched source directory
\r
497 --------------------------------------------
\r
499 -Files included in the binary distribution:
\r
501 - /etc/lighttpd/lighttpd.conf.default
\r
502 - /usr/lib/cyglightcomp.dll
\r
503 - /usr/lib/lighttpd/mod_access.dll
\r
504 - /usr/lib/lighttpd/mod_accesslog.dll
\r
505 - /usr/lib/lighttpd/mod_auth.dll
\r
506 - /usr/lib/lighttpd/mod_cgi.dll
\r
507 - /usr/lib/lighttpd/mod_compress.dll
\r
508 - /usr/lib/lighttpd/mod_evhost.dll
\r
509 - /usr/lib/lighttpd/mod_expire.dll
\r
510 - /usr/lib/lighttpd/mod_fastcgi.dll
\r
511 - /usr/lib/lighttpd/mod_httptls.dll
\r
512 - /usr/lib/lighttpd/mod_maps.dll
\r
513 - /usr/lib/lighttpd/mod_proxy.dll
\r
514 - /usr/lib/lighttpd/mod_redirect.dll
\r
515 - /usr/lib/lighttpd/mod_rewrite.dll
\r
516 - /usr/lib/lighttpd/mod_rrdtool.dll
\r
517 - /usr/lib/lighttpd/mod_secdownload.dll
\r
518 - /usr/lib/lighttpd/mod_simple_vhost.dll
\r
519 - /usr/lib/lighttpd/mod_ssi.dll
\r
520 - /usr/lib/lighttpd/mod_status.dll
\r
521 - /usr/lib/lighttpd/mod_usertrack.dll
\r
522 - /usr/sbin/lighttpd.exe
\r
523 - /usr/share/doc/Cygwin/lighttpd-1.3.0.README
\r
524 - /usr/share/doc/lighttpd-1.3.0/accesslog.txt
\r
525 - /usr/share/doc/lighttpd-1.3.0/authentification.txt
\r
526 - /usr/share/doc/lighttpd-1.3.0/AUTHORS
\r
527 - /usr/share/doc/lighttpd-1.3.0/cgi.txt
\r
528 - /usr/share/doc/lighttpd-1.3.0/ChangeLog
\r
529 - /usr/share/doc/lighttpd-1.3.0/compress.txt
\r
530 - /usr/share/doc/lighttpd-1.3.0/configuration.txt
\r
531 - /usr/share/doc/lighttpd-1.3.0/COPYING
\r
532 - /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt
\r
533 - /usr/share/doc/lighttpd-1.3.0/fastcgi.txt
\r
534 - /usr/share/doc/lighttpd-1.3.0/features.txt
\r
535 - /usr/share/doc/lighttpd-1.3.0/INSTALL
\r
536 - /usr/share/doc/lighttpd-1.3.0/NEWS
\r
537 - /usr/share/doc/lighttpd-1.3.0/performance.txt
\r
538 - /usr/share/doc/lighttpd-1.3.0/plugins.txt
\r
539 - /usr/share/doc/lighttpd-1.3.0/proxy.txt
\r
540 - /usr/share/doc/lighttpd-1.3.0/README
\r
541 - /usr/share/doc/lighttpd-1.3.0/redirect.txt
\r
542 - /usr/share/doc/lighttpd-1.3.0/rewrite.txt
\r
543 - /usr/share/doc/lighttpd-1.3.0/rrdtool.txt
\r
544 - /usr/share/doc/lighttpd-1.3.0/secdownload.txt
\r
545 - /usr/share/doc/lighttpd-1.3.0/security.txt
\r
546 - /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt
\r
547 - /usr/share/doc/lighttpd-1.3.0/skeleton.txt
\r
548 - /usr/share/doc/lighttpd-1.3.0/ssi.txt
\r
549 - /usr/share/doc/lighttpd-1.3.0/state.txt
\r
550 - /usr/share/man/man1/lighttpd.1.gz
\r
552 -------------------
\r
556 ----------- lighttpd-1.3.1-1 -----------
\r
560 ----------- lighttpd-1.3.0-1 -----------
\r
563 -Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>
\r
564 -Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
\r
567 +------------------------------------------
568 +A fast, secure and flexible webserver
570 +Runtime requirements:
571 + cygwin-1.5.10 or newer
573 + libbz2_1-1.0.2 or newer
574 + libpcre0-4.5 or newer
575 + openssl-0.9.7d or newer
576 + zlib-1.2.1 or newer
579 + cygwin-1.5.10 or newer
580 + gcc-3.3.1-3 or newer
581 + binutils-20030901-1 or newer
591 + http://jan.kneschke.de/projects/lighttpd/
594 + http://jan.kneschke.de/projects/lighttpd/download
596 +------------------------------------
599 + unpack lighttpd-@VERSION@-<REL>-src.tar.bz2
600 + if you use setup to install this src package, it will be
601 + unpacked under /usr/src automatically
603 + ./lighttpd-@VERSION@-<REL>.sh all
606 + /usr/src/lighttpd-@VERSION@-<REL>.tar.bz2
607 + /usr/src/lighttpd-@VERSION@-<REL>-src.tar.bz2
609 +Or use './lighttpd-@VERSION@-<REL>.sh prep' to get a patched source directory
611 +-------------------------------------------
613 +Files included in the binary distribution:
615 + /etc/lighttpd/lighttpd.conf.default
616 + /usr/lib/cyglightcomp.dll
617 + /usr/lib/lighttpd/mod_access.dll
618 + /usr/lib/lighttpd/mod_accesslog.dll
619 + /usr/lib/lighttpd/mod_auth.dll
620 + /usr/lib/lighttpd/mod_cgi.dll
621 + /usr/lib/lighttpd/mod_compress.dll
622 + /usr/lib/lighttpd/mod_evhost.dll
623 + /usr/lib/lighttpd/mod_expire.dll
624 + /usr/lib/lighttpd/mod_fastcgi.dll
625 + /usr/lib/lighttpd/mod_httptls.dll
626 + /usr/lib/lighttpd/mod_maps.dll
627 + /usr/lib/lighttpd/mod_proxy.dll
628 + /usr/lib/lighttpd/mod_redirect.dll
629 + /usr/lib/lighttpd/mod_rewrite.dll
630 + /usr/lib/lighttpd/mod_rrdtool.dll
631 + /usr/lib/lighttpd/mod_secdownload.dll
632 + /usr/lib/lighttpd/mod_simple_vhost.dll
633 + /usr/lib/lighttpd/mod_ssi.dll
634 + /usr/lib/lighttpd/mod_status.dll
635 + /usr/lib/lighttpd/mod_usertrack.dll
636 + /usr/sbin/lighttpd.exe
637 + /usr/share/doc/Cygwin/lighttpd-1.3.0.README
638 + /usr/share/doc/lighttpd-1.3.0/accesslog.txt
639 + /usr/share/doc/lighttpd-1.3.0/authentification.txt
640 + /usr/share/doc/lighttpd-1.3.0/AUTHORS
641 + /usr/share/doc/lighttpd-1.3.0/cgi.txt
642 + /usr/share/doc/lighttpd-1.3.0/ChangeLog
643 + /usr/share/doc/lighttpd-1.3.0/compress.txt
644 + /usr/share/doc/lighttpd-1.3.0/configuration.txt
645 + /usr/share/doc/lighttpd-1.3.0/COPYING
646 + /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt
647 + /usr/share/doc/lighttpd-1.3.0/fastcgi.txt
648 + /usr/share/doc/lighttpd-1.3.0/features.txt
649 + /usr/share/doc/lighttpd-1.3.0/INSTALL
650 + /usr/share/doc/lighttpd-1.3.0/NEWS
651 + /usr/share/doc/lighttpd-1.3.0/performance.txt
652 + /usr/share/doc/lighttpd-1.3.0/plugins.txt
653 + /usr/share/doc/lighttpd-1.3.0/proxy.txt
654 + /usr/share/doc/lighttpd-1.3.0/README
655 + /usr/share/doc/lighttpd-1.3.0/redirect.txt
656 + /usr/share/doc/lighttpd-1.3.0/rewrite.txt
657 + /usr/share/doc/lighttpd-1.3.0/rrdtool.txt
658 + /usr/share/doc/lighttpd-1.3.0/secdownload.txt
659 + /usr/share/doc/lighttpd-1.3.0/security.txt
660 + /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt
661 + /usr/share/doc/lighttpd-1.3.0/skeleton.txt
662 + /usr/share/doc/lighttpd-1.3.0/ssi.txt
663 + /usr/share/doc/lighttpd-1.3.0/state.txt
664 + /usr/share/man/man1/lighttpd.1.gz
670 +---------- lighttpd-1.3.1-1 -----------
674 +---------- lighttpd-1.3.0-1 -----------
677 +Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>
678 +Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
680 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/Makefile.in lighttpd-1.4.12/doc/Makefile.in
681 --- lighttpd-1.4.11/doc/Makefile.in 2006-03-07 14:20:57.000000000 +0200
682 +++ lighttpd-1.4.12/doc/Makefile.in 2006-07-11 21:48:12.000000000 +0300
684 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
685 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
688 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
690 am__aclocal_m4_deps = $(top_srcdir)/configure.in
691 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
693 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
694 +mkinstalldirs = $(install_sh) -d
695 CONFIG_HEADER = $(top_builddir)/config.h
701 LTLIBOBJS = @LTLIBOBJS@
702 -LUACONFIG = @LUACONFIG@
703 LUA_CFLAGS = @LUA_CFLAGS@
704 LUA_LIBS = @LUA_LIBS@
707 ac_ct_F77 = @ac_ct_F77@
708 ac_ct_RANLIB = @ac_ct_RANLIB@
709 ac_ct_STRIP = @ac_ct_STRIP@
710 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
711 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
712 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
713 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
714 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/authentication.txt lighttpd-1.4.12/doc/authentication.txt
715 --- lighttpd-1.4.11/doc/authentication.txt 2006-01-12 20:34:26.000000000 +0200
716 +++ lighttpd-1.4.12/doc/authentication.txt 2006-07-11 21:23:42.000000000 +0300
720 :Author: Jan Kneschke
722 -:Revision: $Revision$
724 +:Revision: $Revision$
727 The auth module provides ...
728 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/compress.txt lighttpd-1.4.12/doc/compress.txt
729 --- lighttpd-1.4.11/doc/compress.txt 2005-08-11 01:26:16.000000000 +0300
730 +++ lighttpd-1.4.12/doc/compress.txt 2006-07-11 21:23:42.000000000 +0300
734 Output compression reduces the network load and can improve the overall
735 -throughput of the webserver.
736 +throughput of the webserver. All major http-clients support compression by
737 +announcing it in the Accept-Encoding header. This is used to negotiate the
738 +most suitable compression method. We support deflate, gzip and bzip2.
740 -Only static content is supported up to now.
741 +deflate (RFC1950, RFC1951) and gzip (RFC1952) depend on zlib while bzip2
742 +depends on libbzip2. bzip2 is only supported by lynx and some other console
745 -The server negotiates automaticly which compression method is used.
746 -Supported are gzip, deflate, bzip.
747 +Currently we limit to compression support to static files.
752 +mod_compress can stored compressed files on disk to optimized the compression
753 +on a second request away. As soon as compress.cache-dir is set the files are
756 +The names of the cache files are made of the filename, the compression method
757 +and the etag associated to the file.
759 +Cleaning the cache is left to the user. A cron job deleting files older than
760 +10 days should do fine.
765 +The module limits the compression of files to files larger than 128 Byte and
766 +smaller than 128 MByte.
768 +The lower limit is set as small files tend to become larger by compressing due
769 +to the compression headers, the upper limit is set to work sensable with
770 +memory and cpu-time.
775 Default: not set, compress the file for every request
778 - mimetypes where might get compressed
779 + mimetypes which might get compressed
783 compress.filetype = ("text/plain", "text/html")
785 + Keep in mind that compressed JavaScript and CSS files are broken in some
790 +compress.max-file-size
791 + maximum size of the original file to be compressed kBytes.
793 + This is meant to protect the server against DoSing as compressing large
794 + (let's say 1Gbyte) takes a lot of time and would delay the whole operation
797 + There is a hard upper limit of 128Mbyte.
799 + Default: unlimited (== hard-limit of 128MByte)
801 Compressing Dynamic Content
802 ===========================
804 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/configuration.txt lighttpd-1.4.12/doc/configuration.txt
805 --- lighttpd-1.4.11/doc/configuration.txt 2006-03-09 02:10:40.000000000 +0200
806 +++ lighttpd-1.4.12/doc/configuration.txt 2006-07-11 21:23:42.000000000 +0300
810 :Author: Jan Kneschke
812 -:Revision: $Revision$
814 +:Revision: $Revision$
817 the layout of the configuration file
820 debug.log-request-handling
823 +debug.log-condition-handling
826 +debug.log-condition-cache-handling
827 + for developers only
829 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/fastcgi.txt lighttpd-1.4.12/doc/fastcgi.txt
830 --- lighttpd-1.4.11/doc/fastcgi.txt 2006-02-16 17:03:52.000000000 +0200
831 +++ lighttpd-1.4.12/doc/fastcgi.txt 2006-07-11 21:23:42.000000000 +0300
833 PHP can extract PATH_INFO from it (default: disabled)
834 :"disable-time": time to wait before a disabled backend is checked
836 - :"allow-x-send-file": controls if X-LIGHTTPD-send-file headers
838 + :"allow-x-send-file": controls if X-LIGHTTPD-send-file and X-Sendfile
839 + headers are allowed
843 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/lighttpd.conf lighttpd-1.4.12/doc/lighttpd.conf
844 --- lighttpd-1.4.11/doc/lighttpd.conf 2006-03-04 14:41:12.000000000 +0200
845 +++ lighttpd-1.4.12/doc/lighttpd.conf 2006-07-11 21:23:42.000000000 +0300
846 @@ -172,10 +172,11 @@
847 #dir-listing.activate = "enable"
850 -#debug.log-request-header = "enable"
851 -#debug.log-response-header = "enable"
852 -#debug.log-request-handling = "enable"
853 -#debug.log-file-not-found = "enable"
854 +#debug.log-request-header = "enable"
855 +#debug.log-response-header = "enable"
856 +#debug.log-request-handling = "enable"
857 +#debug.log-file-not-found = "enable"
858 +#debug.log-condition-handling = "enable"
860 ### only root can use these options
862 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/performance.txt lighttpd-1.4.12/doc/performance.txt
863 --- lighttpd-1.4.11/doc/performance.txt 2006-02-02 13:01:08.000000000 +0200
864 +++ lighttpd-1.4.12/doc/performance.txt 2006-07-11 21:23:42.000000000 +0300
867 server.stat-cache-engine = "fam" # either fam, simple or disabled
869 +See http://oss.sgi.com/projects/fam/faq.html for information about FAM.
870 +See http://www.gnome.org/~veillard/gamin/overview.html for information about gamin.
872 Platform-Specific Notes
873 =======================
874 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/doc/secdownload.txt lighttpd-1.4.12/doc/secdownload.txt
875 --- lighttpd-1.4.11/doc/secdownload.txt 2005-12-20 15:58:58.000000000 +0200
876 +++ lighttpd-1.4.12/doc/secdownload.txt 2006-07-11 21:23:42.000000000 +0300
878 $secret = "verysecret";
879 $uri_prefix = "/dl/";
882 + # filename, make sure it's started with a "/" or you'll get 404 in the browser
883 $f = "/secret-file.txt";
886 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/lighttpd.spec lighttpd-1.4.12/lighttpd.spec
887 --- lighttpd-1.4.11/lighttpd.spec 2006-03-07 14:22:18.000000000 +0200
888 +++ lighttpd-1.4.12/lighttpd.spec 2006-07-11 21:49:09.000000000 +0300
890 Summary: A fast webserver with minimal memory-footprint (lighttpd)
895 Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-%version.tar.gz
896 Packager: Jan Kneschke <jan@kneschke.de>
897 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/openwrt/Makefile.in lighttpd-1.4.12/openwrt/Makefile.in
898 --- lighttpd-1.4.11/openwrt/Makefile.in 2006-03-07 14:20:58.000000000 +0200
899 +++ lighttpd-1.4.12/openwrt/Makefile.in 2006-07-11 21:48:12.000000000 +0300
901 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
902 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
905 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
907 am__aclocal_m4_deps = $(top_srcdir)/configure.in
908 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
910 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
911 +mkinstalldirs = $(install_sh) -d
912 CONFIG_HEADER = $(top_builddir)/config.h
913 CONFIG_CLEAN_FILES = control lighttpd.mk
918 LTLIBOBJS = @LTLIBOBJS@
919 -LUACONFIG = @LUACONFIG@
920 LUA_CFLAGS = @LUA_CFLAGS@
921 LUA_LIBS = @LUA_LIBS@
924 ac_ct_F77 = @ac_ct_F77@
925 ac_ct_RANLIB = @ac_ct_RANLIB@
926 ac_ct_STRIP = @ac_ct_STRIP@
927 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
928 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
929 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
930 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
931 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/openwrt/control lighttpd-1.4.12/openwrt/control
932 --- lighttpd-1.4.11/openwrt/control 2006-03-07 14:22:19.000000000 +0200
933 +++ lighttpd-1.4.12/openwrt/control 2006-07-11 21:49:10.000000000 +0300
939 Maintainer: Jan Kneschke <jan@kneschke.de>
940 -Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.11.tar.gz
941 +Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.12.tar.gz
945 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/openwrt/lighttpd.mk lighttpd-1.4.12/openwrt/lighttpd.mk
946 --- lighttpd-1.4.11/openwrt/lighttpd.mk 2006-03-07 14:22:19.000000000 +0200
947 +++ lighttpd-1.4.12/openwrt/lighttpd.mk 2006-07-11 21:49:10.000000000 +0300
950 # For this example we'll use a fairly simple package that compiles easily
951 # and has sources available for download at sourceforge
952 -LIGHTTPD=lighttpd-1.4.11
953 +LIGHTTPD=lighttpd-1.4.12
954 LIGHTTPD_TARGET=.built
955 LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD)
956 LIGHTTPD_IPK=$(BUILD_DIR)/$(LIGHTTPD)_mipsel.ipk
957 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/Makefile.am lighttpd-1.4.12/src/Makefile.am
958 --- lighttpd-1.4.11/src/Makefile.am 2006-03-07 14:20:20.000000000 +0200
959 +++ lighttpd-1.4.12/src/Makefile.am 2006-07-11 21:23:40.000000000 +0300
962 configparser.y: lemon
963 mod_ssi_exprparser.y: lemon
964 +http_resp_parser.y: lemon
966 configparser.c configparser.h: configparser.y
968 - $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c
969 + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
971 +http_resp_parser.c http_resp_parser.h: http_resp_parser.y
972 + rm -f http_resp_parser.h
973 + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
975 mod_ssi_exprparser.c mod_ssi_exprparser.h: mod_ssi_exprparser.y
976 rm -f mod_ssi_exprparser.h
977 - $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
978 + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
981 configfile.c: configparser.h
983 network_write.c network_linux_sendfile.c \
984 network_freebsd_sendfile.c network_writev.c \
985 network_solaris_sendfilev.c network_openssl.c \
987 + splaytree.c http_resp.c http_resp_parser.c
989 src = server.c response.c connections.c network.c \
990 configfile.c configparser.c request.c proc_open.c
993 lib_LTLIBRARIES += mod_webdav.la
994 mod_webdav_la_SOURCES = mod_webdav.c
995 -mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS)
996 +mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS)
997 mod_webdav_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
998 -mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS)
999 +mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) $(UUID_LIB)
1001 lib_LTLIBRARIES += mod_cml.la
1002 mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c
1003 @@ -103,6 +108,11 @@
1004 mod_mysql_vhost_la_LIBADD = $(MYSQL_LIBS) $(common_libadd)
1005 mod_mysql_vhost_la_CPPFLAGS = $(MYSQL_INCLUDE)
1007 +lib_LTLIBRARIES += mod_sql_vhost_core.la
1008 +mod_sql_vhost_core_la_SOURCES = mod_sql_vhost_core.c
1009 +mod_sql_vhost_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
1010 +mod_sql_vhost_core_la_LIBADD = $(common_libadd)
1012 lib_LTLIBRARIES += mod_cgi.la
1013 mod_cgi_la_SOURCES = mod_cgi.c
1014 mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
1016 mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
1017 configparser.h mod_ssi_exprparser.h \
1018 sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
1019 - splaytree.h proc_open.h
1020 + splaytree.h proc_open.h http_resp.h mod_sql_vhost_core.h
1022 DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\""
1024 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/Makefile.in lighttpd-1.4.12/src/Makefile.in
1025 --- lighttpd-1.4.11/src/Makefile.in 2006-03-07 14:21:02.000000000 +0200
1026 +++ lighttpd-1.4.12/src/Makefile.in 2006-07-11 21:48:14.000000000 +0300
1028 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
1029 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
1032 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
1037 -SOURCES = $(liblightcomp_la_SOURCES) $(mod_access_la_SOURCES) $(mod_accesslog_la_SOURCES) $(mod_alias_la_SOURCES) $(mod_auth_la_SOURCES) $(mod_cgi_la_SOURCES) $(mod_cml_la_SOURCES) $(mod_compress_la_SOURCES) $(mod_dirlisting_la_SOURCES) $(mod_evasive_la_SOURCES) $(mod_evhost_la_SOURCES) $(mod_expire_la_SOURCES) $(mod_fastcgi_la_SOURCES) $(mod_flv_streaming_la_SOURCES) $(mod_indexfile_la_SOURCES) $(mod_mysql_vhost_la_SOURCES) $(mod_proxy_la_SOURCES) $(mod_redirect_la_SOURCES) $(mod_rewrite_la_SOURCES) $(mod_rrdtool_la_SOURCES) $(mod_scgi_la_SOURCES) $(mod_secdownload_la_SOURCES) $(mod_setenv_la_SOURCES) $(mod_simple_vhost_la_SOURCES) $(mod_ssi_la_SOURCES) $(mod_staticfile_la_SOURCES) $(mod_status_la_SOURCES) $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) $(lemon_SOURCES) $(lighttpd_SOURCES) $(proc_open_SOURCES) $(spawn_fcgi_SOURCES)
1040 top_srcdir = @top_srcdir@
1043 am__aclocal_m4_deps = $(top_srcdir)/configure.in
1044 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
1046 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
1047 +mkinstalldirs = $(install_sh) -d
1048 CONFIG_HEADER = $(top_builddir)/config.h
1049 CONFIG_CLEAN_FILES =
1050 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
1052 inet_ntop_cache.c crc32.c connections-glue.c configfile-glue.c \
1053 http-header-glue.c network_write.c network_linux_sendfile.c \
1054 network_freebsd_sendfile.c network_writev.c \
1055 - network_solaris_sendfilev.c network_openssl.c splaytree.c
1056 + network_solaris_sendfilev.c network_openssl.c splaytree.c \
1057 + http_resp.c http_resp_parser.c
1058 am__objects_1 = liblightcomp_la-buffer.lo liblightcomp_la-log.lo \
1059 liblightcomp_la-keyvalue.lo liblightcomp_la-chunk.lo \
1060 liblightcomp_la-http_chunk.lo liblightcomp_la-stream.lo \
1062 liblightcomp_la-network_writev.lo \
1063 liblightcomp_la-network_solaris_sendfilev.lo \
1064 liblightcomp_la-network_openssl.lo \
1065 - liblightcomp_la-splaytree.lo
1066 + liblightcomp_la-splaytree.lo liblightcomp_la-http_resp.lo \
1067 + liblightcomp_la-http_resp_parser.lo
1068 @NO_RDYNAMIC_TRUE@am_liblightcomp_la_OBJECTS = $(am__objects_1)
1069 liblightcomp_la_OBJECTS = $(am_liblightcomp_la_OBJECTS)
1070 @NO_RDYNAMIC_TRUE@am_liblightcomp_la_rpath = -rpath $(libdir)
1072 mod_simple_vhost_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
1073 am_mod_simple_vhost_la_OBJECTS = mod_simple_vhost.lo
1074 mod_simple_vhost_la_OBJECTS = $(am_mod_simple_vhost_la_OBJECTS)
1075 +mod_sql_vhost_core_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
1076 +am_mod_sql_vhost_core_la_OBJECTS = mod_sql_vhost_core.lo
1077 +mod_sql_vhost_core_la_OBJECTS = $(am_mod_sql_vhost_core_la_OBJECTS)
1078 mod_ssi_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
1079 am_mod_ssi_la_OBJECTS = mod_ssi_exprparser.lo mod_ssi_expr.lo \
1082 connections-glue.c configfile-glue.c http-header-glue.c \
1083 network_write.c network_linux_sendfile.c \
1084 network_freebsd_sendfile.c network_writev.c \
1085 - network_solaris_sendfilev.c network_openssl.c splaytree.c
1086 + network_solaris_sendfilev.c network_openssl.c splaytree.c \
1087 + http_resp.c http_resp_parser.c
1088 am__objects_2 = buffer.$(OBJEXT) log.$(OBJEXT) keyvalue.$(OBJEXT) \
1089 chunk.$(OBJEXT) http_chunk.$(OBJEXT) stream.$(OBJEXT) \
1090 fdevent.$(OBJEXT) stat_cache.$(OBJEXT) plugin.$(OBJEXT) \
1092 network_linux_sendfile.$(OBJEXT) \
1093 network_freebsd_sendfile.$(OBJEXT) network_writev.$(OBJEXT) \
1094 network_solaris_sendfilev.$(OBJEXT) network_openssl.$(OBJEXT) \
1095 - splaytree.$(OBJEXT)
1096 + splaytree.$(OBJEXT) http_resp.$(OBJEXT) \
1097 + http_resp_parser.$(OBJEXT)
1098 @NO_RDYNAMIC_FALSE@am__objects_3 = $(am__objects_2)
1099 am__objects_4 = server.$(OBJEXT) response.$(OBJEXT) \
1100 connections.$(OBJEXT) network.$(OBJEXT) configfile.$(OBJEXT) \
1102 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
1103 $(AM_CFLAGS) $(CFLAGS)
1105 -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
1106 - $(AM_LDFLAGS) $(LDFLAGS) -o $@
1107 +LINK = $(LIBTOOL) --tag=CC --mode=link "$(CCLD)" $(AM_CFLAGS) \
1108 + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
1109 SOURCES = $(liblightcomp_la_SOURCES) $(mod_access_la_SOURCES) \
1110 $(mod_accesslog_la_SOURCES) $(mod_alias_la_SOURCES) \
1111 $(mod_auth_la_SOURCES) $(mod_cgi_la_SOURCES) \
1112 @@ -296,11 +301,12 @@
1113 $(mod_rewrite_la_SOURCES) $(mod_rrdtool_la_SOURCES) \
1114 $(mod_scgi_la_SOURCES) $(mod_secdownload_la_SOURCES) \
1115 $(mod_setenv_la_SOURCES) $(mod_simple_vhost_la_SOURCES) \
1116 - $(mod_ssi_la_SOURCES) $(mod_staticfile_la_SOURCES) \
1117 - $(mod_status_la_SOURCES) $(mod_trigger_b4_dl_la_SOURCES) \
1118 - $(mod_userdir_la_SOURCES) $(mod_usertrack_la_SOURCES) \
1119 - $(mod_webdav_la_SOURCES) $(lemon_SOURCES) $(lighttpd_SOURCES) \
1120 - $(proc_open_SOURCES) $(spawn_fcgi_SOURCES)
1121 + $(mod_sql_vhost_core_la_SOURCES) $(mod_ssi_la_SOURCES) \
1122 + $(mod_staticfile_la_SOURCES) $(mod_status_la_SOURCES) \
1123 + $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) \
1124 + $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) \
1125 + $(lemon_SOURCES) $(lighttpd_SOURCES) $(proc_open_SOURCES) \
1126 + $(spawn_fcgi_SOURCES)
1127 DIST_SOURCES = $(am__liblightcomp_la_SOURCES_DIST) \
1128 $(mod_access_la_SOURCES) $(mod_accesslog_la_SOURCES) \
1129 $(mod_alias_la_SOURCES) $(mod_auth_la_SOURCES) \
1131 $(mod_redirect_la_SOURCES) $(mod_rewrite_la_SOURCES) \
1132 $(mod_rrdtool_la_SOURCES) $(mod_scgi_la_SOURCES) \
1133 $(mod_secdownload_la_SOURCES) $(mod_setenv_la_SOURCES) \
1134 - $(mod_simple_vhost_la_SOURCES) $(mod_ssi_la_SOURCES) \
1135 + $(mod_simple_vhost_la_SOURCES) \
1136 + $(mod_sql_vhost_core_la_SOURCES) $(mod_ssi_la_SOURCES) \
1137 $(mod_staticfile_la_SOURCES) $(mod_status_la_SOURCES) \
1138 $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) \
1139 $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) \
1143 LTLIBOBJS = @LTLIBOBJS@
1144 -LUACONFIG = @LUACONFIG@
1145 LUA_CFLAGS = @LUA_CFLAGS@
1146 LUA_LIBS = @LUA_LIBS@
1149 ac_ct_F77 = @ac_ct_F77@
1150 ac_ct_RANLIB = @ac_ct_RANLIB@
1151 ac_ct_STRIP = @ac_ct_STRIP@
1152 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
1153 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
1154 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
1155 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
1157 network_write.c network_linux_sendfile.c \
1158 network_freebsd_sendfile.c network_writev.c \
1159 network_solaris_sendfilev.c network_openssl.c \
1161 + splaytree.c http_resp.c http_resp_parser.c
1163 src = server.c response.c connections.c network.c configfile.c \
1164 configparser.c request.c proc_open.c $(am__append_2)
1165 @@ -491,10 +498,11 @@
1166 #mod_httptls_la_LIBADD = $(common_libadd)
1167 lib_LTLIBRARIES = $(am__append_1) mod_flv_streaming.la mod_evasive.la \
1168 mod_webdav.la mod_cml.la mod_trigger_b4_dl.la \
1169 - mod_mysql_vhost.la mod_cgi.la mod_scgi.la mod_staticfile.la \
1170 - mod_dirlisting.la mod_indexfile.la mod_setenv.la mod_alias.la \
1171 - mod_userdir.la mod_rrdtool.la mod_usertrack.la mod_proxy.la \
1172 - mod_ssi.la mod_secdownload.la mod_expire.la mod_evhost.la \
1173 + mod_mysql_vhost.la mod_sql_vhost_core.la mod_cgi.la \
1174 + mod_scgi.la mod_staticfile.la mod_dirlisting.la \
1175 + mod_indexfile.la mod_setenv.la mod_alias.la mod_userdir.la \
1176 + mod_rrdtool.la mod_usertrack.la mod_proxy.la mod_ssi.la \
1177 + mod_secdownload.la mod_expire.la mod_evhost.la \
1178 mod_simple_vhost.la mod_fastcgi.la mod_access.la \
1179 mod_compress.la mod_auth.la mod_rewrite.la mod_redirect.la \
1180 mod_status.la mod_accesslog.la
1182 mod_evasive_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
1183 mod_evasive_la_LIBADD = $(common_libadd)
1184 mod_webdav_la_SOURCES = mod_webdav.c
1185 -mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS)
1186 +mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS)
1187 mod_webdav_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
1188 -mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS)
1189 +mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) $(UUID_LIB)
1190 mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c
1191 mod_cml_la_CFLAGS = $(AM_CFLAGS) $(LUA_CFLAGS)
1192 mod_cml_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
1194 mod_mysql_vhost_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
1195 mod_mysql_vhost_la_LIBADD = $(MYSQL_LIBS) $(common_libadd)
1196 mod_mysql_vhost_la_CPPFLAGS = $(MYSQL_INCLUDE)
1197 +mod_sql_vhost_core_la_SOURCES = mod_sql_vhost_core.c
1198 +mod_sql_vhost_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
1199 +mod_sql_vhost_core_la_LIBADD = $(common_libadd)
1200 mod_cgi_la_SOURCES = mod_cgi.c
1201 mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
1202 mod_cgi_la_LIBADD = $(common_libadd)
1204 mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
1205 configparser.h mod_ssi_exprparser.h \
1206 sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
1207 - splaytree.h proc_open.h
1208 + splaytree.h proc_open.h http_resp.h mod_sql_vhost_core.h
1210 lighttpd_SOURCES = $(src)
1211 lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) $(ATTR_LIB) $(common_libadd) $(SSL_LIB) $(FAM_LIBS)
1213 $(LINK) -rpath $(libdir) $(mod_setenv_la_LDFLAGS) $(mod_setenv_la_OBJECTS) $(mod_setenv_la_LIBADD) $(LIBS)
1214 mod_simple_vhost.la: $(mod_simple_vhost_la_OBJECTS) $(mod_simple_vhost_la_DEPENDENCIES)
1215 $(LINK) -rpath $(libdir) $(mod_simple_vhost_la_LDFLAGS) $(mod_simple_vhost_la_OBJECTS) $(mod_simple_vhost_la_LIBADD) $(LIBS)
1216 +mod_sql_vhost_core.la: $(mod_sql_vhost_core_la_OBJECTS) $(mod_sql_vhost_core_la_DEPENDENCIES)
1217 + $(LINK) -rpath $(libdir) $(mod_sql_vhost_core_la_LDFLAGS) $(mod_sql_vhost_core_la_OBJECTS) $(mod_sql_vhost_core_la_LIBADD) $(LIBS)
1218 mod_ssi.la: $(mod_ssi_la_OBJECTS) $(mod_ssi_la_DEPENDENCIES)
1219 $(LINK) -rpath $(libdir) $(mod_ssi_la_LDFLAGS) $(mod_ssi_la_OBJECTS) $(mod_ssi_la_LIBADD) $(LIBS)
1220 mod_staticfile.la: $(mod_staticfile_la_OBJECTS) $(mod_staticfile_la_DEPENDENCIES)
1222 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_auth.Plo@am__quote@
1223 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_auth_digest.Plo@am__quote@
1224 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_chunk.Po@am__quote@
1225 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_resp.Po@am__quote@
1226 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http_resp_parser.Po@am__quote@
1227 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet_ntop_cache.Po@am__quote@
1228 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/joblist.Po@am__quote@
1229 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keyvalue.Po@am__quote@
1231 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-fdevent_solaris_devpoll.Plo@am__quote@
1232 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-http-header-glue.Plo@am__quote@
1233 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-http_chunk.Plo@am__quote@
1234 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-http_resp.Plo@am__quote@
1235 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-http_resp_parser.Plo@am__quote@
1236 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-inet_ntop_cache.Plo@am__quote@
1237 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-joblist.Plo@am__quote@
1238 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-keyvalue.Plo@am__quote@
1240 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_secure_download.Plo@am__quote@
1241 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_setenv.Plo@am__quote@
1242 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_simple_vhost.Plo@am__quote@
1243 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_sql_vhost_core.Plo@am__quote@
1244 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_ssi.Plo@am__quote@
1245 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_ssi_expr.Plo@am__quote@
1246 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_ssi_exprparser.Plo@am__quote@
1247 @@ -1247,6 +1265,20 @@
1248 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1249 @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -c -o liblightcomp_la-splaytree.lo `test -f 'splaytree.c' || echo '$(srcdir)/'`splaytree.c
1251 +liblightcomp_la-http_resp.lo: http_resp.c
1252 +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -MT liblightcomp_la-http_resp.lo -MD -MP -MF "$(DEPDIR)/liblightcomp_la-http_resp.Tpo" -c -o liblightcomp_la-http_resp.lo `test -f 'http_resp.c' || echo '$(srcdir)/'`http_resp.c; \
1253 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/liblightcomp_la-http_resp.Tpo" "$(DEPDIR)/liblightcomp_la-http_resp.Plo"; else rm -f "$(DEPDIR)/liblightcomp_la-http_resp.Tpo"; exit 1; fi
1254 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='http_resp.c' object='liblightcomp_la-http_resp.lo' libtool=yes @AMDEPBACKSLASH@
1255 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1256 +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -c -o liblightcomp_la-http_resp.lo `test -f 'http_resp.c' || echo '$(srcdir)/'`http_resp.c
1258 +liblightcomp_la-http_resp_parser.lo: http_resp_parser.c
1259 +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -MT liblightcomp_la-http_resp_parser.lo -MD -MP -MF "$(DEPDIR)/liblightcomp_la-http_resp_parser.Tpo" -c -o liblightcomp_la-http_resp_parser.lo `test -f 'http_resp_parser.c' || echo '$(srcdir)/'`http_resp_parser.c; \
1260 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/liblightcomp_la-http_resp_parser.Tpo" "$(DEPDIR)/liblightcomp_la-http_resp_parser.Plo"; else rm -f "$(DEPDIR)/liblightcomp_la-http_resp_parser.Tpo"; exit 1; fi
1261 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='http_resp_parser.c' object='liblightcomp_la-http_resp_parser.lo' libtool=yes @AMDEPBACKSLASH@
1262 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1263 +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblightcomp_la_CFLAGS) $(CFLAGS) -c -o liblightcomp_la-http_resp_parser.lo `test -f 'http_resp_parser.c' || echo '$(srcdir)/'`http_resp_parser.c
1265 mod_cml_la-mod_cml.lo: mod_cml.c
1266 @am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_cml_la_CFLAGS) $(CFLAGS) -MT mod_cml_la-mod_cml.lo -MD -MP -MF "$(DEPDIR)/mod_cml_la-mod_cml.Tpo" -c -o mod_cml_la-mod_cml.lo `test -f 'mod_cml.c' || echo '$(srcdir)/'`mod_cml.c; \
1267 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/mod_cml_la-mod_cml.Tpo" "$(DEPDIR)/mod_cml_la-mod_cml.Plo"; else rm -f "$(DEPDIR)/mod_cml_la-mod_cml.Tpo"; exit 1; fi
1268 @@ -1506,14 +1538,19 @@
1269 @CROSS_COMPILING_TRUE@mod_ssi_exprparser.c mod_ssi_exprparser.h:
1270 @CROSS_COMPILING_FALSE@configparser.y: lemon
1271 @CROSS_COMPILING_FALSE@mod_ssi_exprparser.y: lemon
1272 +@CROSS_COMPILING_FALSE@http_resp_parser.y: lemon
1274 @CROSS_COMPILING_FALSE@configparser.c configparser.h: configparser.y
1275 @CROSS_COMPILING_FALSE@ rm -f configparser.h
1276 -@CROSS_COMPILING_FALSE@ $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c
1277 +@CROSS_COMPILING_FALSE@ $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
1279 +@CROSS_COMPILING_FALSE@http_resp_parser.c http_resp_parser.h: http_resp_parser.y
1280 +@CROSS_COMPILING_FALSE@ rm -f http_resp_parser.h
1281 +@CROSS_COMPILING_FALSE@ $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
1283 @CROSS_COMPILING_FALSE@mod_ssi_exprparser.c mod_ssi_exprparser.h: mod_ssi_exprparser.y
1284 @CROSS_COMPILING_FALSE@ rm -f mod_ssi_exprparser.h
1285 -@CROSS_COMPILING_FALSE@ $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
1286 +@CROSS_COMPILING_FALSE@ $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
1288 configfile.c: configparser.h
1289 mod_ssi_expr.c: mod_ssi_exprparser.h
1290 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/array.c lighttpd-1.4.12/src/array.c
1291 --- lighttpd-1.4.11/src/array.c 2005-11-18 13:58:32.000000000 +0200
1292 +++ lighttpd-1.4.12/src/array.c 2006-07-11 21:23:39.000000000 +0300
1295 array *array_init(void) {
1299 a = calloc(1, sizeof(*a));
1303 a->next_power_of_2 = 1;
1310 void array_free(array *a) {
1315 if (!a->is_weakref) {
1316 for (i = 0; i < a->size; i++) {
1317 if (a->data[i]) a->data[i]->free(a->data[i]);
1322 if (a->data) free(a->data);
1323 if (a->sorted) free(a->sorted);
1329 void array_reset(array *a) {
1334 if (!a->is_weakref) {
1335 for (i = 0; i < a->used; i++) {
1336 a->data[i]->reset(a->data[i]);
1345 static int array_get_index(array *a, const char *key, size_t keylen, int *rndx) {
1350 if (key == NULL) return -1;
1353 /* try to find the string */
1354 for (i = pos = a->next_power_of_2 / 2; ; i >>= 1) {
1360 } else if (pos >= (int)a->used) {
1363 cmp = buffer_caseless_compare(key, keylen, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used);
1368 ndx = a->sorted[pos];
1369 @@ -110,46 +110,46 @@
1375 if (rndx) *rndx = pos;
1381 data_unset *array_get_element(array *a, const char *key) {
1385 if (-1 != (ndx = array_get_index(a, key, strlen(key) + 1, NULL))) {
1386 /* found, leave here */
1389 return a->data[ndx];
1397 data_unset *array_get_unused_element(array *a, data_type_t t) {
1398 data_unset *ds = NULL;
1403 if (a->size == 0) return NULL;
1406 if (a->used == a->size) return NULL;
1408 if (a->data[a->used]) {
1409 ds = a->data[a->used];
1412 a->data[a->used] = NULL;
1419 /* replace or insert data, return the old one with the same key */
1420 data_unset *array_replace(array *a, data_unset *du) {
1424 if (-1 == (ndx = array_get_index(a, du->key->ptr, du->key->used, NULL))) {
1425 array_insert_unique(a, du);
1427 @@ -164,13 +164,13 @@
1432 - /* generate unique index if neccesary */
1434 + /* generate unique index if necessary */
1435 if (str->key->used == 0 || str->is_index_key) {
1436 buffer_copy_long(str->key, a->unique_ndx++);
1437 str->is_index_key = 1;
1441 /* try to find the string */
1442 if (-1 != (ndx = array_get_index(a, str->key->ptr, str->key->used, &pos))) {
1443 /* found, leave here */
1444 @@ -181,14 +181,14 @@
1453 if (a->used+1 > INT_MAX) {
1454 /* we can't handle more then INT_MAX entries: see array_get_index() */
1461 a->data = malloc(sizeof(*a->data) * a->size);
1462 @@ -204,27 +204,27 @@
1464 for (j = a->used; j < a->size; j++) a->data[j] = NULL;
1468 ndx = (int) a->used;
1471 a->data[a->used++] = str;
1477 buffer_caseless_compare(str->key->ptr, str->key->used, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used) > 0)) {
1481 - /* move everything on step to the right */
1484 + /* move everything one step to the right */
1486 memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted));
1491 a->sorted[pos] = ndx;
1494 if (a->next_power_of_2 == (size_t)ndx) a->next_power_of_2 <<= 1;
1511 array_print_indent(depth);
1512 fprintf(stderr, ")");
1518 @@ -323,47 +323,47 @@
1530 ds = data_string_init();
1531 buffer_copy_string(ds->key, "abc");
1532 buffer_copy_string(ds->value, "alfrag");
1535 array_insert_unique(a, (data_unset *)ds);
1538 ds = data_string_init();
1539 buffer_copy_string(ds->key, "abc");
1540 buffer_copy_string(ds->value, "hameplman");
1543 array_insert_unique(a, (data_unset *)ds);
1546 ds = data_string_init();
1547 buffer_copy_string(ds->key, "123");
1548 buffer_copy_string(ds->value, "alfrag");
1551 array_insert_unique(a, (data_unset *)ds);
1554 dc = data_count_init();
1555 buffer_copy_string(dc->key, "def");
1558 array_insert_unique(a, (data_unset *)dc);
1561 dc = data_count_init();
1562 buffer_copy_string(dc->key, "def");
1565 array_insert_unique(a, (data_unset *)dc);
1574 fprintf(stderr, "%d\n",
1575 buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type")));
1581 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/array.h lighttpd-1.4.12/src/array.h
1582 --- lighttpd-1.4.11/src/array.h 2005-09-23 21:24:18.000000000 +0300
1583 +++ lighttpd-1.4.12/src/array.h 2006-07-11 21:23:39.000000000 +0300
1585 #define DATA_UNSET \
1588 - int is_index_key; /* 1 if key is a array index (autogenerated keys) */ \
1589 + int is_index_key; /* 1 if key is an array index (auto-generated keys) */ \
1590 struct data_unset *(*copy)(const struct data_unset *src); \
1591 void (* free)(struct data_unset *p); \
1592 void (* reset)(struct data_unset *p); \
1609 size_t next_power_of_2;
1610 int is_weakref; /* data is weakref, don't bother the data */
1639 COMP_SERVER_SOCKET, COMP_HTTP_URL, COMP_HTTP_HOST, COMP_HTTP_REFERER, COMP_HTTP_USERAGENT, COMP_HTTP_COOKIE, COMP_HTTP_REMOTEIP
1642 -/* $HTTP["host"] == "incremental.home.kneschke.de" { ... }
1643 +/* $HTTP["host"] == "incremental.home.kneschke.de" { ... }
1644 * for print: comp_key op string
1645 * for compare: comp cond string/regex
1648 typedef struct _data_config data_config;
1649 struct _data_config {
1664 int context_ndx; /* more or less like an id */
1668 /* for chaining only */
1685 @@ -120,13 +120,13 @@
1691 unsigned short port;
1698 int usage; /* fair-balancing needs the no. of connections active on this host */
1699 int last_used_ndx; /* round robin */
1701 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/base.h lighttpd-1.4.12/src/base.h
1702 --- lighttpd-1.4.11/src/base.h 2006-01-11 16:51:04.000000000 +0200
1703 +++ lighttpd-1.4.12/src/base.h 2006-07-11 21:23:39.000000000 +0300
1707 #include <sys/types.h>
1708 -#include <sys/time.h>
1709 #include <sys/stat.h>
1711 #ifdef HAVE_CONFIG_H
1713 #include "sys-socket.h"
1714 #include "splaytree.h"
1717 #if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
1718 # define USE_OPENSSL
1719 -# include <openssl/ssl.h>
1720 +# include <openssl/ssl.h>
1728 -#ifndef O_LARGEFILE
1729 -# define O_LARGEFILE 0
1734 # define SIZE_MAX SIZE_T_MAX
1737 /* solaris and NetBSD 1.3.x again */
1738 #if (!defined(HAVE_STDINT_H)) && (!defined(HAVE_INTTYPES_H)) && (!defined(uint32_t))
1739 -# define uint32_t u_int32_t
1740 +/* # define uint32_t u_int32_t */
1741 +typedef unsigned __int32 uint32_t;
1747 #include "settings.h"
1749 -typedef enum { T_CONFIG_UNSET,
1755 +typedef enum { T_CONFIG_UNSET,
1762 } config_values_type_t;
1764 -typedef enum { T_CONFIG_SCOPE_UNSET,
1765 - T_CONFIG_SCOPE_SERVER,
1766 +typedef enum { T_CONFIG_SCOPE_UNSET,
1767 + T_CONFIG_SCOPE_SERVER,
1768 T_CONFIG_SCOPE_CONNECTION
1769 } config_scope_type_t;
1776 config_values_type_t type;
1777 config_scope_type_t scope;
1779 @@ -142,40 +137,40 @@
1780 /* the request-line */
1788 http_method_t http_method;
1789 http_version_t http_version;
1792 buffer *request_line;
1795 /* strings to the header */
1796 buffer *http_host; /* not alloced */
1797 const char *http_range;
1798 const char *http_content_type;
1799 const char *http_if_modified_since;
1800 const char *http_if_none_match;
1807 size_t content_length; /* returned by strtoul() */
1810 /* internal representation */
1811 int accept_encoding;
1819 off_t content_length;
1820 - int keep_alive; /* used by the subrequests in proxy, cgi and fcgi to say the subrequest was keep-alive or not */
1822 + int keep_alive; /* used by the subrequests in proxy, cgi and fcgi to say whether the subrequest was keep-alive or not */
1829 HTTP_TRANSFER_ENCODING_IDENTITY, HTTP_TRANSFER_ENCODING_CHUNKED
1830 } transfer_encoding;
1832 @@ -191,21 +186,21 @@
1835 buffer *basedir; /* path = "(basedir)(.*)" */
1838 buffer *doc_root; /* path = doc_root + rel_path */
1863 - splay_tree *files; /* the nodes of the tree are stat_cache_entry's */
1865 + splay_tree *files; /* the nodes of the tree are stat_cache_entries */
1867 buffer *dir_name; /* for building the dirname from the filename */
1869 splay_tree *dirs; /* the nodes of the tree are fam_dir_entry */
1876 /* virtual-servers */
1877 buffer *document_root;
1878 buffer *server_name;
1881 buffer *dirlist_encoding;
1882 buffer *errorfile_prefix;
1885 unsigned short max_keep_alive_requests;
1886 unsigned short max_keep_alive_idle;
1887 unsigned short max_read_idle;
1888 @@ -244,16 +239,17 @@
1889 unsigned short use_xattr;
1890 unsigned short follow_symlink;
1891 unsigned short range_requests;
1897 unsigned short log_file_not_found;
1898 unsigned short log_request_header;
1899 unsigned short log_request_handling;
1900 unsigned short log_response_header;
1901 unsigned short log_condition_handling;
1904 + unsigned short log_condition_cache_handling;
1908 buffer *ssl_pemfile;
1909 buffer *ssl_ca_file;
1910 @@ -268,22 +264,22 @@
1912 unsigned short global_kbytes_per_second; /* */
1914 - off_t global_bytes_per_second_cnt;
1915 + off_t global_bytes_per_second_cnt;
1916 /* server-wide traffic-shaper
1919 * each context has the counter which is inited once
1920 - * a second by the global_kbytes_per_second config-var
1921 + * per second by the global_kbytes_per_second config-var
1923 * as soon as global_kbytes_per_second gets below 0
1924 * the connected conns are "offline" a little bit
1927 - * we somehow have to loose our "we are writable" signal
1928 + * we somehow have to lose our "we are writable" signal
1933 off_t *global_bytes_per_second_cnt_ptr; /* */
1939 @@ -291,18 +287,18 @@
1941 /* the order of the items should be the same as they are processed
1942 * read before write as we use this later */
1944 - CON_STATE_CONNECT,
1945 - CON_STATE_REQUEST_START,
1947 - CON_STATE_REQUEST_END,
1948 - CON_STATE_READ_POST,
1949 - CON_STATE_HANDLE_REQUEST,
1950 - CON_STATE_RESPONSE_START,
1952 - CON_STATE_RESPONSE_END,
1956 + CON_STATE_CONNECT,
1957 + CON_STATE_REQUEST_START,
1959 + CON_STATE_REQUEST_END,
1960 + CON_STATE_READ_POST,
1961 + CON_STATE_HANDLE_REQUEST,
1962 + CON_STATE_RESPONSE_START,
1964 + CON_STATE_RESPONSE_END,
1967 } connection_state_t;
1969 typedef enum { COND_RESULT_UNSET, COND_RESULT_FALSE, COND_RESULT_TRUE } cond_result_t;
1970 @@ -315,88 +311,88 @@
1973 connection_state_t state;
1977 time_t read_idle_ts;
1978 time_t close_timeout_ts;
1979 time_t write_request_ts;
1982 time_t connection_start;
1983 time_t request_start;
1986 struct timeval start_tv;
1989 size_t request_count; /* number of requests handled in this connection */
1990 size_t loops_per_request; /* to catch endless loops in a single request
1993 * used by mod_rewrite, mod_fastcgi, ... and others
1994 * this is self-protection
1998 int fd; /* the FD for this connection */
1999 int fde_ndx; /* index for the fdevent-handler */
2000 int ndx; /* reverse mapping to server->connection[ndx] */
2007 - int keep_alive; /* only request.c can enable it, all other just disable */
2010 + int keep_alive; /* only request.c can enable it, all others just disable */
2016 chunkqueue *write_queue; /* a large queue for low-level write ( HTTP response ) [ file, mem ] */
2017 chunkqueue *read_queue; /* a small queue for low-level read ( HTTP request ) [ mem ] */
2018 chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/
2021 int traffic_limit_reached;
2024 off_t bytes_written; /* used by mod_accesslog, mod_rrd */
2025 off_t bytes_written_cur_second; /* used by mod_accesslog, mod_rrd */
2026 off_t bytes_read; /* used by mod_accesslog, mod_rrd */
2034 buffer *dst_addr_buf;
2037 buffer *parse_request;
2038 unsigned int parsed_response; /* bitfield which contains the important header-fields of the parsed response header */
2043 - physical physical;
2044 + physical physical;
2051 buffer *authed_user;
2052 array *environment; /* used to pass lighttpd internal stuff to the FastCGI/CGI apps, setenv does that */
2062 connection_type mode;
2065 void **plugin_ctx; /* plugin connection specific config */
2068 specific_config conf; /* global connection specific config */
2069 cond_cache_t *cond_cache;
2072 buffer *server_name;
2076 buffer *error_handler;
2077 int error_handler_saved_status;
2078 int in_error_handler;
2081 void *srv_socket; /* reference to the server-socket (typecast to server_socket) */
2087 @@ -439,39 +435,48 @@
2092 + NETWORK_STATUS_UNSET,
2093 + NETWORK_STATUS_SUCCESS,
2094 + NETWORK_STATUS_FATAL_ERROR,
2095 + NETWORK_STATUS_CONNECTION_CLOSE,
2096 + NETWORK_STATUS_WAIT_FOR_EVENT,
2097 + NETWORK_STATUS_INTERRUPTED
2098 +} network_status_t;
2101 unsigned short port;
2105 buffer *errorlog_file;
2106 unsigned short errorlog_use_syslog;
2109 unsigned short dont_daemonize;
2118 buffer *event_handler;
2121 buffer *modules_dir;
2122 buffer *network_backend;
2124 array *upload_tempdirs;
2127 unsigned short max_worker;
2128 unsigned short max_fds;
2129 unsigned short max_conns;
2130 unsigned short max_request_size;
2133 unsigned short log_request_header_on_error;
2134 unsigned short log_state_handling;
2136 - enum { STAT_CACHE_ENGINE_UNSET,
2137 - STAT_CACHE_ENGINE_NONE,
2138 - STAT_CACHE_ENGINE_SIMPLE,
2139 - STAT_CACHE_ENGINE_FAM
2141 + enum { STAT_CACHE_ENGINE_UNSET,
2142 + STAT_CACHE_ENGINE_NONE,
2143 + STAT_CACHE_ENGINE_SIMPLE,
2144 + STAT_CACHE_ENGINE_FAM
2145 } stat_cache_engine;
2146 unsigned short enable_cores;
2148 @@ -480,14 +485,14 @@
2154 buffer *ssl_pemfile;
2155 buffer *ssl_ca_file;
2156 unsigned short use_ipv6;
2157 unsigned short is_ssl;
2166 @@ -495,37 +500,37 @@
2169 server_socket **ptr;
2174 } server_socket_array;
2176 typedef struct server {
2177 server_socket_array srv_sockets;
2182 enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode;
2183 buffer *errorlog_buf;
2186 fdevents *ev, *ev_ins;
2189 buffer_plugin plugins;
2203 int max_fds; /* max possible fds */
2204 int cur_fds; /* currently used fds */
2205 int want_fds; /* waiting fds */
2206 int sockets_disabled;
2212 @@ -533,13 +538,13 @@
2213 buffer *response_header;
2214 buffer *response_range;
2218 buffer *tmp_chunk_len;
2221 buffer *empty_string; /* is necessary for cond_match */
2223 buffer *cond_check_buf;
2228 inet_ntop_cache_type inet_ntop_cache[INET_NTOP_CACHE_MAX];
2229 @@ -547,31 +552,31 @@
2230 mtime_cache_type mtime_cache[FILE_CACHE_MAX];
2237 time_t last_generated_date_ts;
2238 time_t last_generated_debug_ts;
2242 buffer *ts_debug_str;
2243 buffer *ts_date_str;
2248 array *config_touched;
2251 array *config_context;
2252 specific_config **config_storage;
2255 server_config srvconf;
2258 int config_deprecated;
2262 connections *joblist;
2263 connections *fdwaitqueue;
2266 stat_cache *stat_cache;
2269 @@ -588,18 +593,20 @@
2270 * fastcgi.backend.<key>.disconnects = ...
2275 fdevent_handler_t event_handler;
2277 - int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
2278 - int (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
2279 + network_status_t (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
2280 + network_status_t (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
2282 - int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
2283 - int (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
2284 + network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
2285 + network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
2295 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/buffer.c lighttpd-1.4.12/src/buffer.c
2296 --- lighttpd-1.4.11/src/buffer.c 2006-01-13 00:00:45.000000000 +0200
2297 +++ lighttpd-1.4.12/src/buffer.c 2006-07-11 21:23:40.000000000 +0300
2308 buffer* buffer_init(void) {
2312 b = malloc(sizeof(*b));
2334 void buffer_free(buffer *b) {
2337 void buffer_reset(buffer *b) {
2341 /* limit don't reuse buffer larger than ... bytes */
2342 if (b->size > BUFFER_MAX_REUSE_SIZE) {
2355 - * allocate (if neccessary) enough space for 'size' bytes and
2357 + * allocate (if necessary) enough space for 'size' bytes and
2358 * set the 'used' counter to 0
2363 #define BUFFER_PIECE_SIZE 64
2365 int buffer_prepare_copy(buffer *b, size_t size) {
2368 - if ((0 == b->size) ||
2370 + if ((0 == b->size) ||
2372 if (b->size) free(b->ptr);
2377 - /* always allocate a multiply of BUFFER_PIECE_SIZE */
2379 + /* always allocate a multiple of BUFFER_PIECE_SIZE */
2380 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
2383 b->ptr = malloc(b->size);
2391 - * increase the internal buffer (if neccessary) to append another 'size' byte
2393 + * increase the internal buffer (if necessary) to append another 'size' byte
2394 * ->used isn't changed
2399 int buffer_prepare_append(buffer *b, size_t size) {
2406 - /* always allocate a multiply of BUFFER_PIECE_SIZE */
2408 + /* always allocate a multiple of BUFFER_PIECE_SIZE */
2409 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
2412 b->ptr = malloc(b->size);
2415 } else if (b->used + size > b->size) {
2418 - /* always allocate a multiply of BUFFER_PIECE_SIZE */
2420 + /* always allocate a multiple of BUFFER_PIECE_SIZE */
2421 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
2424 b->ptr = realloc(b->ptr, b->size);
2429 int buffer_copy_string(buffer *b, const char *s) {
2433 if (!s || !b) return -1;
2435 s_len = strlen(s) + 1;
2436 @@ -136,26 +136,26 @@
2438 int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
2439 if (!s || !b) return -1;
2441 - /* removed optimization as we have to keep the empty string
2443 + /* removed optimization as we have to keep the empty string
2444 * in some cases for the config handling
2447 * url.access-deny = ( "" )
2449 if (s_len == 0) return 0;
2452 buffer_prepare_copy(b, s_len + 1);
2455 memcpy(b->ptr, s, s_len);
2456 b->ptr[s_len] = '\0';
2457 b->used = s_len + 1;
2463 int buffer_copy_string_buffer(buffer *b, const buffer *src) {
2464 if (!src) return -1;
2467 if (src->used == 0) {
2470 @@ -201,10 +201,10 @@
2473 * append a string to the end of the buffer
2475 - * the resulting buffer is terminated with a '\0'
2476 - * s is treated as a un-terminated string (a \0 is handled a normal character)
2479 + * the resulting buffer is terminated with a '\0'
2480 + * s is treated as an un-terminated string (a \0 is handled as a normal character)
2483 * @param s the string
2484 * @param s_len size of the string (without the terminating \0)
2486 int buffer_append_string_buffer(buffer *b, const buffer *src) {
2487 if (!src) return -1;
2488 if (src->used == 0) return 0;
2491 return buffer_append_string_len(b, src->ptr, src->used - 1);
2496 int buffer_copy_memory(buffer *b, const char *s, size_t s_len) {
2497 if (!s || !b) return -1;
2503 return buffer_append_memory(b, s, s_len);
2506 @@ -402,46 +402,115 @@
2512 + * init the ptr buffer
2515 +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer)
2517 + buffer_ptr *l = calloc(1, sizeof(buffer_ptr));
2524 + * free the buffer_array
2527 +void buffer_ptr_free(buffer_ptr *l)
2530 + buffer_ptr_clear(l);
2535 +void buffer_ptr_clear(buffer_ptr *l)
2537 + assert(NULL != l);
2539 + if (l->free && l->used) {
2541 + for (i = 0; i < l->used; i ++) {
2542 + l->free(l->ptr[i]);
2554 +void buffer_ptr_append(buffer_ptr* l, void *item)
2556 + assert(NULL != l);
2557 + if (l->ptr == NULL) {
2559 + l->ptr = (void **)malloc(sizeof(void *) * l->size);
2561 + else if (l->used == l->size) {
2563 + l->ptr = realloc(l->ptr, sizeof(void *) * l->size);
2565 + l->ptr[l->used++] = item;
2568 +void *buffer_ptr_pop(buffer_ptr* l)
2570 + assert(NULL != l && l->used > 0);
2571 + return l->ptr[--l->used];
2574 +void *buffer_ptr_top(buffer_ptr* l)
2576 + assert(NULL != l && l->used > 0);
2577 + return l->ptr[l->used-1];
2585 buffer_array* buffer_array_init(void) {
2589 b = malloc(sizeof(*b));
2601 void buffer_array_reset(buffer_array *b) {
2608 /* if they are too large, reduce them */
2609 for (i = 0; i < b->used; i++) {
2610 buffer_reset(b->ptr[i]);
2619 - * free the buffer_array
2621 + * free the buffer_array
2625 void buffer_array_free(buffer_array *b) {
2630 for (i = 0; i < b->size; i++) {
2631 if (b->ptr[i]) buffer_free(b->ptr[i]);
2635 buffer *buffer_array_append_get_buffer(buffer_array *b) {
2641 b->ptr = malloc(sizeof(*b->ptr) * b->size);
2642 @@ -467,13 +536,13 @@
2648 if (b->ptr[b->used] == NULL) {
2649 b->ptr[b->used] = buffer_init();
2653 b->ptr[b->used]->used = 0;
2656 return b->ptr[b->used++];
2659 @@ -482,23 +551,23 @@
2661 if (len == 0) return NULL;
2662 if (needle == NULL) return NULL;
2665 if (b->used < len) return NULL;
2668 for(i = 0; i < b->used - len; i++) {
2669 if (0 == memcmp(b->ptr + i, needle, len)) {
2678 buffer *buffer_init_string(const char *str) {
2679 buffer *b = buffer_init();
2682 buffer_copy_string(b, str);
2692 - * check if two buffer contain the same data
2694 + * check if two buffers contain the same data
2696 * HISTORY: this function was pretty much optimized, but didn't handled
2697 * alignment properly.
2699 @@ -522,100 +591,100 @@
2701 int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
2709 return buffer_is_equal(a, &b);
2712 /* simple-assumption:
2714 - * most parts are equal and doing a case conversion needs time
2717 + * most parts are equal and doing a case conversion takes time
2720 int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {
2721 size_t ndx = 0, max_ndx;
2723 size_t mask = sizeof(*al) - 1;
2729 - /* is the alignment correct ? */
2731 + /* is the alignment correct? */
2732 if ( ((size_t)al & mask) == 0 &&
2733 ((size_t)bl & mask) == 0 ) {
2736 max_ndx = ((a_len < b_len) ? a_len : b_len) & ~mask;
2739 for (; ndx < max_ndx; ndx += sizeof(*al)) {
2740 if (*al != *bl) break;
2754 max_ndx = ((a_len < b_len) ? a_len : b_len);
2757 for (; ndx < max_ndx; ndx++) {
2758 char a1 = *a++, b1 = *b++;
2762 if ((a1 >= 'A' && a1 <= 'Z') && (b1 >= 'a' && b1 <= 'z'))
2764 else if ((a1 >= 'a' && a1 <= 'z') && (b1 >= 'A' && b1 <= 'Z'))
2766 if ((a1 - b1) != 0) return (a1 - b1);
2778 * check if the rightmost bytes of the string are equal.
2785 int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
2786 /* no, len -> equal */
2787 if (len == 0) return 1;
2790 /* len > 0, but empty buffers -> not equal */
2791 if (b1->used == 0 || b2->used == 0) return 0;
2794 /* buffers too small -> not equal */
2795 - if (b1->used - 1 < len || b1->used - 1 < len) return 0;
2797 - if (0 == strncmp(b1->ptr + b1->used - 1 - len,
2798 + if (b1->used - 1 < len || b2->used - 1 < len) return 0;
2800 + if (0 == strncmp(b1->ptr + b1->used - 1 - len,
2801 b2->ptr + b2->used - 1 - len, len)) {
2809 int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
2814 if (in_len * 2 < in_len) return -1;
2817 buffer_prepare_copy(b, in_len * 2 + 1);
2820 for (i = 0; i < in_len; i++) {
2821 b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
2822 b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
2824 b->ptr[b->used++] = '\0';
2831 0 1 2 3 4 5 6 7 8 9 A B C D E F
2833 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
2834 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2835 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2836 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, /* 20 - 2F space " # $ % & ' + , / */
2837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */
2838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
2840 0 1 2 3 4 5 6 7 8 9 A B C D E F
2842 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
2843 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2844 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2845 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, /* 20 - 2F space " # $ % & ' + , / */
2846 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */
2847 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
2849 0 1 2 3 4 5 6 7 8 9 A B C D E F
2851 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
2852 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2853 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2854 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */
2855 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */
2856 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
2858 0 1 2 3 4 5 6 7 8 9 A B C D E F
2860 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
2861 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2862 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2863 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */
2864 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */
2865 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */
2866 @@ -712,12 +781,12 @@
2867 0 1 2 3 4 5 6 7 8 9 A B C D E F
2869 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */
2870 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2871 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
2872 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */
2873 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
2874 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
2875 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
2876 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
2877 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
2878 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */
2879 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
2880 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
2881 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
2882 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70 - 7F */
2883 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
2884 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
2885 @@ -734,13 +803,13 @@
2886 unsigned char *ds, *d;
2888 const char *map = NULL;
2891 if (!s || !b) return -1;
2894 if (b->ptr[b->used - 1] != '\0') {
2899 if (s_len == 0) return 0;
2902 @@ -760,12 +829,12 @@
2903 map = encoded_chars_hex;
2905 case ENCODING_UNSET:
2907 + return buffer_append_string_len(b, s, s_len);
2910 assert(map != NULL);
2912 - /* count to-be-encoded-characters */
2914 + /* count to-be-encoded characters */
2915 for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
2924 buffer_prepare_append(b, d_len);
2927 for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
2930 @@ -820,16 +889,16 @@
2934 - /* terminate buffer and calculate new length */
2935 + /* terminate buffer and calculate new length */
2936 b->ptr[b->used + d_len - 1] = '\0';
2945 -/* decodes url-special-chars inplace.
2946 +/* decodes url-special chars in-place.
2947 * replaces non-printable characters with '_'
2950 @@ -854,10 +923,10 @@
2951 low = hex2int(*(src + 2));
2953 high = (high << 4) | low;
2955 - /* map control-characters out */
2957 + /* map out control characters */
2958 if (high < 32 || high == 127) high = '_';
2965 * /abc/./xyz gets /abc/xyz
2966 * /abc//xyz gets /abc/xyz
2968 - * NOTE: src and dest can point to the same buffer, in which case,
2969 + * NOTE: src and dest can point to the same buffer, in which case
2970 * the operation is performed in-place.
2973 @@ -979,7 +1048,7 @@
2975 int light_isxdigit(int c) {
2976 if (light_isdigit(c)) return 1;
2980 return (c >= 'a' && c <= 'f');
2982 @@ -993,31 +1062,56 @@
2983 return light_isdigit(c) || light_isalpha(c);
2986 +#undef BUFFER_CTYPE_FUNC
2987 +#define BUFFER_CTYPE_FUNC(type) \
2988 + int buffer_is##type(buffer *b) { \
2990 + if (b->used < 2) return 0; \
2992 + len = b->used - 1; \
2993 + /* c-string only */ \
2994 + if (b->ptr[len] != '\0') { \
2997 + /* check on the whole string */ \
2998 + for (i = 0; i < len; i ++) { \
2999 + if (!light_is##type(b->ptr[i])) { \
3006 +BUFFER_CTYPE_FUNC(digit)
3007 +BUFFER_CTYPE_FUNC(xdigit)
3008 +BUFFER_CTYPE_FUNC(alpha)
3009 +BUFFER_CTYPE_FUNC(alnum)
3011 int buffer_to_lower(buffer *b) {
3015 if (b->used == 0) return 0;
3018 for (c = b->ptr; *c; c++) {
3019 if (*c >= 'A' && *c <= 'Z') {
3029 int buffer_to_upper(buffer *b) {
3033 if (b->used == 0) return 0;
3036 for (c = b->ptr; *c; c++) {
3037 if (*c >= 'a' && *c <= 'z') {
3045 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/buffer.h lighttpd-1.4.12/src/buffer.h
3046 --- lighttpd-1.4.11/src/buffer.h 2006-01-13 00:00:45.000000000 +0200
3047 +++ lighttpd-1.4.12/src/buffer.h 2006-07-11 21:23:40.000000000 +0300
3059 +typedef void (*buffer_ptr_free_t)(void *p);
3065 + buffer_ptr_free_t free;
3079 - size_t offset; /* input-pointer */
3081 - size_t used; /* output-pointer */
3083 + size_t offset; /* input pointer */
3085 + size_t used; /* output pointer */
3089 +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer);
3090 +void buffer_ptr_free(buffer_ptr *b);
3091 +void buffer_ptr_clear(buffer_ptr *b);
3092 +void buffer_ptr_append(buffer_ptr *b, void *item);
3093 +void *buffer_ptr_pop(buffer_ptr *b);
3094 +void *buffer_ptr_top(buffer_ptr *b);
3096 buffer_array* buffer_array_init(void);
3097 void buffer_array_free(buffer_array *b);
3098 void buffer_array_reset(buffer_array *b);
3100 buffer* buffer_init_string(const char *str);
3101 void buffer_free(buffer *b);
3102 void buffer_reset(buffer *b);
3105 int buffer_prepare_copy(buffer *b, size_t size);
3106 int buffer_prepare_append(buffer *b, size_t size);
3112 - ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
3113 - ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */
3114 - ENCODING_HTML, /* & becomes & and so on */
3115 + ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of an href */
3116 + ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus encoding "/" as "%2F" */
3117 + ENCODING_HTML, /* "&" becomes "&" and so on */
3118 ENCODING_MINIMAL_XML, /* minimal encoding for xml */
3119 ENCODING_HEX /* encode string as hex */
3120 } buffer_encoding_t;
3121 @@ -111,19 +128,21 @@
3122 int light_isalpha(int c);
3123 int light_isalnum(int c);
3125 +#define BUFFER_CTYPE_FUNC(type) int buffer_is##type(buffer *b);
3126 +BUFFER_CTYPE_FUNC(digit)
3127 +BUFFER_CTYPE_FUNC(xdigit)
3128 +BUFFER_CTYPE_FUNC(alpha)
3129 +BUFFER_CTYPE_FUNC(alnum)
3131 #define BUFFER_APPEND_STRING_CONST(x, y) \
3132 buffer_append_string_len(x, y, sizeof(y) - 1)
3134 #define BUFFER_COPY_STRING_CONST(x, y) \
3135 buffer_copy_string_len(x, y, sizeof(y) - 1)
3137 -#define BUFFER_APPEND_SLASH(x) \
3138 - if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); }
3140 #define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
3141 #define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
3144 #define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0)
3145 #define UNUSED(x) ( (void)(x) )
3147 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/chunk.c lighttpd-1.4.12/src/chunk.c
3148 --- lighttpd-1.4.11/src/chunk.c 2005-11-18 15:18:19.000000000 +0200
3149 +++ lighttpd-1.4.12/src/chunk.c 2006-07-11 21:23:39.000000000 +0300
3152 * the network chunk-API
3159 #include <sys/types.h>
3160 #include <sys/stat.h>
3161 -#include <sys/mman.h>
3165 -#include <unistd.h>
3173 +#include "sys-mmap.h"
3174 +#include "sys-files.h"
3176 chunkqueue *chunkqueue_init(void) {
3180 cq = calloc(1, sizeof(*cq));
3193 static chunk *chunk_init(void) {
3197 c = calloc(1, sizeof(*c));
3200 c->mem = buffer_init();
3201 c->file.name = buffer_init();
3203 c->file.mmap.start = MAP_FAILED;
3210 static void chunk_free(chunk *c) {
3214 buffer_free(c->mem);
3215 buffer_free(c->file.name);
3219 static void chunk_reset(chunk *c) {
3223 buffer_reset(c->mem);
3225 if (c->file.is_temp && !buffer_is_empty(c->file.name)) {
3226 unlink(c->file.name->ptr);
3230 buffer_reset(c->file.name);
3232 if (c->file.fd != -1) {
3235 void chunkqueue_free(chunkqueue *cq) {
3242 for (c = cq->first; c; ) {
3249 for (c = cq->unused; c; ) {
3259 static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) {
3262 - /* check if we have a unused chunk */
3264 + /* check if we have an unused chunk */
3268 @@ -109,18 +110,18 @@
3270 cq->unused_chunks--;
3277 static int chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) {
3278 c->next = cq->first;
3282 if (cq->last == NULL) {
3290 @@ -129,19 +130,19 @@
3296 if (cq->first == NULL) {
3304 void chunkqueue_reset(chunkqueue *cq) {
3306 /* move everything to the unused queue */
3308 - /* mark all read written */
3310 + /* mark all read written */
3311 for (c = cq->first; c; c = c->next) {
3316 c->offset = c->file.length;
3323 @@ -162,93 +163,93 @@
3325 int chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) {
3329 if (len == 0) return 0;
3332 c = chunkqueue_get_unused_chunk(cq);
3335 c->type = FILE_CHUNK;
3338 buffer_copy_string_buffer(c->file.name, fn);
3339 c->file.start = offset;
3340 c->file.length = len;
3344 chunkqueue_append_chunk(cq, c);
3350 int chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) {
3354 if (mem->used == 0) return 0;
3357 c = chunkqueue_get_unused_chunk(cq);
3358 c->type = MEM_CHUNK;
3360 buffer_copy_string_buffer(c->mem, mem);
3363 chunkqueue_append_chunk(cq, c);
3369 int chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) {
3373 if (mem->used == 0) return 0;
3376 c = chunkqueue_get_unused_chunk(cq);
3377 c->type = MEM_CHUNK;
3379 buffer_copy_string_buffer(c->mem, mem);
3382 chunkqueue_prepend_chunk(cq, c);
3388 int chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
3392 if (len == 0) return 0;
3395 c = chunkqueue_get_unused_chunk(cq);
3396 c->type = MEM_CHUNK;
3398 buffer_copy_string_len(c->mem, mem, len - 1);
3401 chunkqueue_append_chunk(cq, c);
3407 buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) {
3411 c = chunkqueue_get_unused_chunk(cq);
3414 c->type = MEM_CHUNK;
3416 buffer_reset(c->mem);
3419 chunkqueue_prepend_chunk(cq, c);
3425 buffer *chunkqueue_get_append_buffer(chunkqueue *cq) {
3429 c = chunkqueue_get_unused_chunk(cq);
3432 c->type = MEM_CHUNK;
3434 buffer_reset(c->mem);
3437 chunkqueue_append_chunk(cq, c);
3444 chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
3446 buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX");
3449 c = chunkqueue_get_unused_chunk(cq);
3451 c->type = FILE_CHUNK;
3452 @@ -273,12 +274,12 @@
3455 /* we have several tempdirs, only if all of them fail we jump out */
3458 for (i = 0; i < cq->tempdirs->used; i++) {
3459 data_string *ds = (data_string *)cq->tempdirs->data[i];
3461 buffer_copy_string_buffer(template, ds->value);
3462 - BUFFER_APPEND_SLASH(template);
3463 + PATHNAME_APPEND_SLASH(template);
3464 BUFFER_APPEND_STRING_CONST(template, "lighttpd-upload-XXXXXX");
3466 if (-1 != (c->file.fd = mkstemp(template->ptr))) {
3468 chunkqueue_append_chunk(cq, c);
3470 buffer_free(template);
3477 off_t chunkqueue_length(chunkqueue *cq) {
3482 for (c = cq->first; c; c = c->next) {
3485 @@ -321,14 +322,14 @@
3494 off_t chunkqueue_written(chunkqueue *cq) {
3499 for (c = cq->first; c; c = c->next) {
3512 if (c->offset == (off_t)c->mem->used - 1) is_finished = 1;
3515 - if (c->offset == c->file.length) is_finished = 1;
3516 + if (c->offset == c->file.length) is_finished = 1;
3523 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/chunk.h lighttpd-1.4.12/src/chunk.h
3524 --- lighttpd-1.4.11/src/chunk.h 2005-11-01 09:32:21.000000000 +0200
3525 +++ lighttpd-1.4.12/src/chunk.h 2006-07-11 21:23:40.000000000 +0300
3528 typedef struct chunk {
3529 enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type;
3532 buffer *mem; /* either the storage of the mem-chunk or the read-ahead buffer */
3536 off_t length; /* octets to send from the starting offset */
3541 char *start; /* the start pointer of the mmap'ed area */
3542 size_t length; /* size of the mmap'ed area */
3543 - off_t offset; /* start is <n> octet away from the start of the file */
3544 + off_t offset; /* start is <n> octets away from the start of the file */
3547 - int is_temp; /* file is temporary and will be deleted if on cleanup */
3548 + int is_temp; /* file is temporary and will be deleted on cleanup */
3551 - off_t offset; /* octets sent from this chunk
3552 - the size of the chunk is either
3554 + off_t offset; /* octets sent from this chunk
3555 + the size of the chunk is either
3556 - mem-chunk: mem->used - 1
3557 - file-chunk: file.length
3570 size_t unused_chunks;
3572 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configfile-glue.c lighttpd-1.4.12/src/configfile-glue.c
3573 --- lighttpd-1.4.11/src/configfile-glue.c 2006-03-03 20:14:56.000000000 +0200
3574 +++ lighttpd-1.4.12/src/configfile-glue.c 2006-07-11 21:23:39.000000000 +0300
3582 * are the external interface of lighttpd. The functions
3583 * are used by the server itself and the plugins.
3585 - * The main-goal is to have a small library in the end
3586 - * which is linked against both and which will define
3587 + * The main-goal is to have a small library in the end
3588 + * which is linked against both and which will define
3589 * the interface itself in the end.
3596 int config_insert_values_internal(server *srv, array *ca, const config_values_t cv[]) {
3601 for (i = 0; cv[i].key; i++) {
3604 if (NULL == (du = array_get_element(ca, cv[i].key))) {
3612 switch (cv[i].type) {
3613 case T_CONFIG_ARRAY:
3614 if (du->type == TYPE_ARRAY) {
3616 data_array *da = (data_array *)du;
3619 for (j = 0; j < da->value->used; j++) {
3620 if (da->value->data[j]->type == TYPE_STRING) {
3621 data_string *ds = data_string_init();
3624 buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
3625 if (!da->is_index_key) {
3626 /* the id's were generated automaticly, as we copy now we might have to renumber them
3627 - * this is used to prepend server.modules by mod_indexfiles as it has to be loaded
3628 + * this is used to prepend server.modules by mod_indexfiles as it has to be loaded
3629 * before mod_fastcgi and friends */
3630 buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
3634 array_insert_unique(cv[i].destination, (data_unset *)ds);
3636 - log_error_write(srv, __FILE__, __LINE__, "sssd",
3637 - "the key of and array can only be a string or a integer, variable:",
3638 - cv[i].key, "type:", da->value->data[j]->type);
3640 + log_error_write(srv, __FILE__, __LINE__, "sssd",
3641 + "the key of and array can only be a string or a integer, variable:",
3642 + cv[i].key, "type:", da->value->data[j]->type);
3648 log_error_write(srv, __FILE__, __LINE__, "sss", "unexpected type for key: ", cv[i].key, "array of strings");
3654 case T_CONFIG_STRING:
3655 if (du->type == TYPE_STRING) {
3656 data_string *ds = (data_string *)du;
3659 buffer_copy_string_buffer(cv[i].destination, ds->value);
3660 + } else if (du->type == TYPE_INTEGER) {
3661 + data_integer *di = (data_integer *)du;
3663 + buffer_copy_long(cv[i].destination, di->value);
3665 log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\"");
3673 case TYPE_INTEGER: {
3674 data_integer *di = (data_integer *)du;
3677 *((unsigned short *)(cv[i].destination)) = di->value;
3681 data_string *ds = (data_string *)du;
3684 + if (buffer_isdigit(ds->value)) {
3685 + *((unsigned short *)(cv[i].destination)) = strtol(ds->value->ptr, NULL, 10);
3689 log_error_write(srv, __FILE__, __LINE__, "ssb", "get a string but expected a short:", cv[i].key, ds->value);
3695 @@ -100,19 +110,19 @@
3696 case T_CONFIG_BOOLEAN:
3697 if (du->type == TYPE_STRING) {
3698 data_string *ds = (data_string *)du;
3701 if (buffer_is_equal_string(ds->value, CONST_STR_LEN("enable"))) {
3702 *((unsigned short *)(cv[i].destination)) = 1;
3703 } else if (buffer_is_equal_string(ds->value, CONST_STR_LEN("disable"))) {
3704 *((unsigned short *)(cv[i].destination)) = 0;
3706 log_error_write(srv, __FILE__, __LINE__, "ssbs", "ERROR: unexpected value for key:", cv[i].key, ds->value, "(enable|disable)");
3712 log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: unexpected type for key:", cv[i].key, "(string)", "\"(enable|disable)\"");
3720 case T_CONFIG_DEPRECATED:
3721 log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found deprecated key:", cv[i].key, "-", (char *)(cv[i].destination));
3724 srv->config_deprecated = 1;
3730 @@ -133,25 +143,25 @@
3731 int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) {
3736 for (i = 0; cv[i].key; i++) {
3737 data_string *touched;
3740 if (NULL == (du = array_get_element(ca, cv[i].key))) {
3749 touched = data_string_init();
3752 buffer_copy_string(touched->value, "");
3753 buffer_copy_string_buffer(touched->key, du->key);
3756 array_insert_unique(srv->config_touched, (data_unset *)touched);
3760 return config_insert_values_internal(srv, ca, cv);
3763 @@ -191,25 +201,25 @@
3766 /* pass the rules */
3770 case COMP_HTTP_HOST: {
3771 char *ck_colon = NULL, *val_colon = NULL;
3774 if (!buffer_is_empty(con->uri.authority)) {
3779 * append server-port to the HTTP_POST if necessary
3783 l = con->uri.authority;
3787 case CONFIG_COND_NE:
3788 case CONFIG_COND_EQ:
3789 ck_colon = strchr(dc->string->ptr, ':');
3790 val_colon = strchr(l->ptr, ':');
3793 if (ck_colon == val_colon) {
3794 /* nothing to do with it */
3796 @@ -230,21 +240,21 @@
3801 + l = srv->empty_string;
3805 case COMP_HTTP_REMOTEIP: {
3807 - /* handle remoteip limitations
3809 + /* handle remoteip limitations
3811 * "10.0.0.1" is provided for all comparisions
3814 * only for == and != we support
3821 if ((dc->cond == CONFIG_COND_EQ ||
3822 dc->cond == CONFIG_COND_NE) &&
3823 (con->dst_addr.plain.sa_family == AF_INET) &&
3824 @@ -253,41 +263,48 @@
3827 struct in_addr val_inp;
3830 + if (con->conf.log_condition_handling) {
3831 + l = srv->empty_string;
3833 + log_error_write(srv, __FILE__, __LINE__, "bsbsb", dc->comp_key,
3834 + "(", l, ") compare to", dc->string);
3837 if (*(nm_slash+1) == '\0') {
3838 log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string);
3841 return COND_RESULT_FALSE;
3845 nm_bits = strtol(nm_slash + 1, &err, 10);
3849 log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: non-digit found in netmask:", dc->string, *err);
3852 return COND_RESULT_FALSE;
3856 /* take IP convert to the native */
3857 buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr);
3860 if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) {
3861 log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
3864 return COND_RESULT_FALSE;
3868 if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) {
3869 log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
3872 return COND_RESULT_FALSE;
3878 nm = htonl(~((1 << (32 - nm_bits)) - 1));
3881 if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) {
3882 return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
3886 case COMP_HTTP_REFERER: {
3890 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) {
3895 return COND_RESULT_FALSE;
3900 if (con->conf.log_condition_handling) {
3901 log_error_write(srv, __FILE__, __LINE__, "bsbs", dc->comp_key,
3902 @@ -346,10 +363,10 @@
3904 return COND_RESULT_FALSE;
3908 if (con->conf.log_condition_handling) {
3909 log_error_write(srv, __FILE__, __LINE__, "bsbsb", dc->comp_key,
3910 - "(", l, ") compare to ", dc->string);
3911 + "(", l, ") compare to", dc->string);
3914 case CONFIG_COND_NE:
3915 @@ -365,13 +382,13 @@
3916 case CONFIG_COND_MATCH: {
3917 cond_cache_t *cache = &con->cond_cache[dc->context_ndx];
3922 #define elementsof(x) (sizeof(x) / sizeof(x[0]))
3924 n = pcre_exec(dc->regex, dc->regex_study, l->ptr, l->used - 1, 0, 0,
3925 cache->matches, elementsof(cache->matches));
3928 cache->patterncount = n;
3930 cache->comp_value = l;
3937 return COND_RESULT_FALSE;
3941 cond_cache_t *caches = con->cond_cache;
3943 if (COND_RESULT_UNSET == caches[dc->context_ndx].result) {
3944 + if (con->conf.log_condition_handling) {
3945 + log_error_write(srv, __FILE__, __LINE__, "sds", "=== start of", dc->context_ndx, "condition block ===");
3947 if (COND_RESULT_TRUE == (caches[dc->context_ndx].result = config_check_cond_nocache(srv, con, dc))) {
3950 @@ -409,11 +429,11 @@
3952 if (con->conf.log_condition_handling) {
3953 log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
3954 - "(uncached) result:",
3956 caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false");
3959 - if (con->conf.log_condition_handling) {
3960 + if (con->conf.log_condition_cache_handling) {
3961 log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
3963 caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false");
3967 int config_check_cond(server *srv, connection *con, data_config *dc) {
3968 - if (con->conf.log_condition_handling) {
3969 - log_error_write(srv, __FILE__, __LINE__, "s", "=== start of condition block ===");
3971 return (config_check_cond_cached(srv, con, dc) == COND_RESULT_TRUE);
3974 @@ -443,3 +460,85 @@
3978 +/* return <0 on error
3979 + * return 0-x if matched (and replaced)
3981 +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result)
3985 + pcre_extra *extra;
3986 + const char *pattern;
3987 + size_t pattern_len;
3990 + pcre_keyvalue *kv;
3994 + for (i = 0; i < kvb->used; i++) {
3998 + extra = kv->key_extra;
3999 + pattern = kv->value->ptr;
4000 + pattern_len = kv->value->used - 1;
4002 + if ((n = pcre_exec(match, extra, match_buf->ptr, match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
4003 + if (n != PCRE_ERROR_NOMATCH) {
4007 + const char **list;
4008 + size_t start, end;
4012 + pcre_get_substring_list(match_buf->ptr, ovec, n, &list);
4014 + /* search for $[0-9] */
4016 + buffer_reset(result);
4018 + start = 0; end = pattern_len;
4019 + for (k = 0; k < pattern_len; k++) {
4020 + if ((pattern[k] == '$' || pattern[k] == '%') &&
4021 + isdigit((unsigned char)pattern[k + 1])) {
4024 + size_t num = pattern[k + 1] - '0';
4028 + buffer_append_string_len(result, pattern + start, end - start);
4030 + if (pattern[k] == '$') {
4031 + /* n is always > 0 */
4032 + if (num < (size_t)n) {
4033 + buffer_append_string(result, list[num]);
4036 + config_append_cond_match_buffer(con, context, result, num);
4044 + buffer_append_string_len(result, pattern + start, pattern_len - start);
4052 + return PCRE_ERROR_NOMATCH;
4060 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configfile.c lighttpd-1.4.12/src/configfile.c
4061 --- lighttpd-1.4.11/src/configfile.c 2006-02-15 14:26:42.000000000 +0200
4062 +++ lighttpd-1.4.12/src/configfile.c 2006-07-11 21:23:39.000000000 +0300
4067 -#include <unistd.h>
4076 -#include "license.h"
4079 #include "configparser.h"
4080 #include "configfile.h"
4081 #include "proc_open.h"
4083 +#include "sys-files.h"
4084 +#include "sys-process.h"
4088 +#define PATH_MAX 64
4091 static int config_insert(server *srv) {
4094 buffer *stat_cache_string;
4096 - config_values_t cv[] = {
4098 + config_values_t cv[] = {
4099 { "server.bind", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 0 */
4100 { "server.errorlog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 1 */
4101 { "server.errorfile-prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 2 */
4103 { "server.tag", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
4104 { "server.use-ipv6", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
4105 { "server.modules", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 9 */
4108 { "server.event-handler", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 */
4109 { "server.pid-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 */
4110 { "server.max-request-size", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
4112 { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */
4113 { "server.name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 18 */
4114 { "server.max-keep-alive-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 19 */
4117 { "server.max-read-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 20 */
4118 { "server.max-write-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 21 */
4119 { "server.error-handler-404", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 22 */
4121 { "mimetype.use-xattr", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */
4122 { "mimetype.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 28 */
4123 { "ssl.pemfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 29 */
4126 { "ssl.engine", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 30 */
4129 { "debug.log-file-not-found", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 31 */
4130 { "debug.log-request-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 32 */
4131 { "debug.log-response-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 33 */
4132 { "debug.log-request-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 34 */
4135 { "server.protocol-http11", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 35 */
4136 { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 36 */
4137 { "debug.log-state-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */
4138 { "ssl.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 38 */
4141 { "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 39 */
4142 { "server.range-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 40 */
4143 { "server.stat-cache-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 41 */
4145 { "server.network-backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 43 */
4146 { "server.upload-dirs", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 44 */
4147 { "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */
4149 + { "debug.log-condition-cache-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 46 */
4151 { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
4152 { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
4153 { "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
4155 { "server.groupid", "use server.groupname instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
4156 { "server.use-keep-alive", "use server.max-keep-alive-requests = 0 instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
4157 { "server.force-lower-case-files", "use server.force-lowercase-filenames instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
4160 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
4166 cv[0].destination = srv->srvconf.bindhost;
4167 cv[1].destination = srv->srvconf.errorlog_file;
4168 @@ -102,33 +105,33 @@
4169 cv[4].destination = srv->srvconf.username;
4170 cv[5].destination = srv->srvconf.groupname;
4171 cv[6].destination = &(srv->srvconf.port);
4174 cv[9].destination = srv->srvconf.modules;
4175 cv[10].destination = srv->srvconf.event_handler;
4176 cv[11].destination = srv->srvconf.pid_file;
4179 cv[13].destination = &(srv->srvconf.max_worker);
4180 cv[23].destination = &(srv->srvconf.max_fds);
4181 cv[36].destination = &(srv->srvconf.log_request_header_on_error);
4182 cv[37].destination = &(srv->srvconf.log_state_handling);
4185 cv[39].destination = &(srv->srvconf.errorlog_use_syslog);
4188 stat_cache_string = buffer_init();
4189 cv[41].destination = stat_cache_string;
4190 cv[43].destination = srv->srvconf.network_backend;
4191 cv[44].destination = srv->srvconf.upload_tempdirs;
4192 cv[45].destination = &(srv->srvconf.enable_cores);
4195 cv[42].destination = &(srv->srvconf.max_conns);
4196 cv[12].destination = &(srv->srvconf.max_request_size);
4197 srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
4199 assert(srv->config_storage);
4202 for (i = 0; i < srv->config_context->used; i++) {
4206 s = calloc(1, sizeof(specific_config));
4208 s->document_root = buffer_init();
4209 @@ -154,17 +157,18 @@
4210 s->global_kbytes_per_second = 0;
4211 s->global_bytes_per_second_cnt = 0;
4212 s->global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
4215 cv[2].destination = s->errorfile_prefix;
4218 cv[7].destination = s->server_tag;
4219 cv[8].destination = &(s->use_ipv6);
4225 cv[14].destination = s->document_root;
4226 cv[15].destination = &(s->force_lowercase_filenames);
4227 cv[16].destination = &(s->log_condition_handling);
4228 + cv[46].destination = &(s->log_condition_cache_handling);
4229 cv[17].destination = &(s->max_keep_alive_requests);
4230 cv[18].destination = s->server_name;
4231 cv[19].destination = &(s->max_keep_alive_idle);
4232 @@ -179,23 +183,23 @@
4233 cv[28].destination = s->mimetypes;
4234 cv[29].destination = s->ssl_pemfile;
4235 cv[30].destination = &(s->is_ssl);
4238 cv[31].destination = &(s->log_file_not_found);
4239 cv[32].destination = &(s->log_request_handling);
4240 cv[33].destination = &(s->log_response_header);
4241 cv[34].destination = &(s->log_request_header);
4244 cv[35].destination = &(s->allow_http11);
4245 cv[38].destination = s->ssl_ca_file;
4246 cv[40].destination = &(s->range_requests);
4249 srv->config_storage[i] = s;
4252 if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) {
4258 if (buffer_is_empty(stat_cache_string)) {
4259 srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
4260 } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {
4261 @@ -205,22 +209,22 @@
4262 } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("disable"))) {
4263 srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_NONE;
4265 - log_error_write(srv, __FILE__, __LINE__, "sb",
4266 + log_error_write(srv, __FILE__, __LINE__, "sb",
4267 "server.stat-cache-engine can be one of \"disable\", \"simple\", \"fam\", but not:", stat_cache_string);
4268 ret = HANDLER_ERROR;
4272 buffer_free(stat_cache_string);
4281 -#define PATCH(x) con->conf.x = s->x
4283 + con->conf.x = s->x
4284 int config_setup_connection(server *srv, connection *con) {
4285 specific_config *s = srv->config_storage[0];
4288 PATCH(allow_http11);
4290 PATCH(document_root);
4291 @@ -236,20 +240,21 @@
4292 PATCH(kbytes_per_second);
4293 PATCH(global_kbytes_per_second);
4294 PATCH(global_bytes_per_second_cnt);
4297 con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
4298 buffer_copy_string_buffer(con->server_name, s->server_name);
4301 PATCH(log_request_header);
4302 PATCH(log_response_header);
4303 PATCH(log_request_handling);
4304 PATCH(log_condition_handling);
4305 + PATCH(log_condition_cache_handling);
4306 PATCH(log_file_not_found);
4309 PATCH(range_requests);
4310 PATCH(force_lowercase_filenames);
4317 @@ -257,22 +262,22 @@
4319 int config_patch_connection(server *srv, connection *con, comp_key_t comp) {
4323 /* skip the first, the global context */
4324 for (i = 1; i < srv->config_context->used; i++) {
4325 data_config *dc = (data_config *)srv->config_context->data[i];
4326 specific_config *s = srv->config_storage[i];
4330 if (comp != dc->comp) continue;
4333 /* condition didn't match */
4334 if (!config_check_cond(srv, con, dc)) continue;
4338 for (j = 0; j < dc->value->used; j++) {
4339 data_unset *du = dc->value->data[j];
4342 if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.document-root"))) {
4343 PATCH(document_root);
4344 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.range-requests"))) {
4345 @@ -315,11 +320,13 @@
4346 PATCH(log_response_header);
4347 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-handling"))) {
4348 PATCH(log_condition_handling);
4349 + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-cache-handling"))) {
4350 + PATCH(log_condition_cache_handling);
4351 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-file-not-found"))) {
4352 PATCH(log_file_not_found);
4353 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) {
4354 PATCH(allow_http11);
4355 - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {
4356 + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {
4357 PATCH(force_lowercase_filenames);
4358 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.kbytes-per-second"))) {
4359 PATCH(global_kbytes_per_second);
4369 @@ -336,15 +343,15 @@
4375 const buffer *source;
4391 if (0 != stream_open(&(t->s), t->file)) {
4392 - log_error_write(srv, __FILE__, __LINE__, "sbss",
4393 + log_error_write(srv, __FILE__, __LINE__, "sbss",
4394 "opening configfile ", t->file, "failed:", strerror(errno));
4395 buffer_free(t->file);
4398 t->size = t->s.size;
4407 static int config_skip_comment(tokenizer_t *t) {
4409 assert(t->input[t->offset] == '#');
4410 - for (i = 1; t->input[t->offset + i] &&
4411 + for (i = 1; t->input[t->offset + i] &&
4412 (t->input[t->offset + i] != '\n' && t->input[t->offset + i] != '\r');
4415 @@ -411,44 +418,44 @@
4416 static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer *token) {
4421 for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) {
4422 char c = t->input[t->offset];
4423 const char *start = NULL;
4430 if (t->input[t->offset + 1] == '>') {
4434 buffer_copy_string(token, "=>");
4437 tid = TK_ARRAY_ASSIGN;
4439 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4440 + log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4441 "source:", t->source,
4442 - "line:", t->line, "pos:", t->line_pos,
4443 + "line:", t->line, "pos:", t->line_pos,
4444 "use => for assignments in arrays");
4447 } else if (t->in_cond) {
4448 if (t->input[t->offset + 1] == '=') {
4452 buffer_copy_string(token, "==");
4456 } else if (t->input[t->offset + 1] == '~') {
4460 buffer_copy_string(token, "=~");
4465 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4466 + log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4467 "source:", t->source,
4468 - "line:", t->line, "pos:", t->line_pos,
4469 + "line:", t->line, "pos:", t->line_pos,
4470 "only =~ and == are allowed in the condition");
4473 @@ -456,51 +463,51 @@
4475 } else if (t->in_key) {
4479 buffer_copy_string_len(token, t->input + t->offset, 1);
4485 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4486 + log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4487 "source:", t->source,
4488 - "line:", t->line, "pos:", t->line_pos,
4489 + "line:", t->line, "pos:", t->line_pos,
4490 "unexpected equal-sign: =");
4499 if (t->input[t->offset + 1] == '=') {
4503 buffer_copy_string(token, "!=");
4507 } else if (t->input[t->offset + 1] == '~') {
4511 buffer_copy_string(token, "!~");
4516 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4517 + log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4518 "source:", t->source,
4519 - "line:", t->line, "pos:", t->line_pos,
4520 + "line:", t->line, "pos:", t->line_pos,
4521 "only !~ and != are allowed in the condition");
4527 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4528 + log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4529 "source:", t->source,
4530 - "line:", t->line, "pos:", t->line_pos,
4531 + "line:", t->line, "pos:", t->line_pos,
4532 "unexpected exclamation-marks: !");
4540 @@ -546,10 +553,10 @@
4542 if (t->in_brace > 0) {
4546 buffer_copy_string(token, "(COMMA)");
4553 @@ -557,70 +564,70 @@
4554 /* search for the terminating " */
4555 start = t->input + t->offset + 1;
4556 buffer_copy_string(token, "");
4559 for (i = 1; t->input[t->offset + i]; i++) {
4560 if (t->input[t->offset + i] == '\\' &&
4561 t->input[t->offset + i + 1] == '"') {
4564 buffer_append_string_len(token, start, t->input + t->offset + i - start);
4567 start = t->input + t->offset + i + 1;
4578 if (t->input[t->offset + i] == '"') {
4582 buffer_append_string_len(token, start, t->input + t->offset + i - start);
4589 if (t->input[t->offset + i] == '\0') {
4592 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4594 + log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4595 "source:", t->source,
4596 - "line:", t->line, "pos:", t->line_pos,
4597 + "line:", t->line, "pos:", t->line_pos,
4598 "missing closing quote");
4606 t->line_pos += i + 1;
4618 buffer_copy_string(token, "(");
4628 buffer_copy_string(token, ")");
4639 buffer_copy_string(token, "$");
4645 @@ -637,96 +644,88 @@
4654 buffer_copy_string(token, "{");
4667 buffer_copy_string(token, "}");
4679 buffer_copy_string(token, "[");
4692 buffer_copy_string(token, "]");
4697 t->line_pos += config_skip_comment(t);
4703 - for (i = 0; t->input[t->offset + i] &&
4704 + for (i = 0; t->input[t->offset + i] &&
4705 (isalpha((unsigned char)t->input[t->offset + i])
4709 if (i && t->input[t->offset + i]) {
4710 tid = TK_SRVVARNAME;
4711 buffer_copy_string_len(token, t->input + t->offset, i);
4718 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4719 + log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4720 "source:", t->source,
4721 - "line:", t->line, "pos:", t->line_pos,
4722 + "line:", t->line, "pos:", t->line_pos,
4723 "invalid character in condition");
4726 } else if (isdigit((unsigned char)c)) {
4727 /* take all digits */
4728 for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]); i++);
4731 /* was there it least a digit ? */
4732 - if (i && t->input[t->offset + i]) {
4737 buffer_copy_string_len(token, t->input + t->offset, i);
4744 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4745 - "source:", t->source,
4746 - "line:", t->line, "pos:", t->line_pos,
4747 - "unexpected EOF");
4752 /* the key might consist of [-.0-9a-z] */
4753 - for (i = 0; t->input[t->offset + i] &&
4754 - (isalnum((unsigned char)t->input[t->offset + i]) ||
4755 + for (i = 0; t->input[t->offset + i] &&
4756 + (isalnum((unsigned char)t->input[t->offset + i]) ||
4757 t->input[t->offset + i] == '.' ||
4758 t->input[t->offset + i] == '_' || /* for env.* */
4759 t->input[t->offset + i] == '-'
4763 if (i && t->input[t->offset + i]) {
4764 buffer_copy_string_len(token, t->input + t->offset, i);
4767 if (strcmp(token->ptr, "include") == 0) {
4769 } else if (strcmp(token->ptr, "include_shell") == 0) {
4770 @@ -738,14 +737,14 @@
4780 - log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4781 + log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
4782 "source:", t->source,
4783 - "line:", t->line, "pos:", t->line_pos,
4784 + "line:", t->line, "pos:", t->line_pos,
4785 "invalid character in variable name");
4788 @@ -753,16 +752,16 @@
4797 - log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd",
4798 + log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd",
4799 "source:", t->source,
4800 "line:", t->line, "pos:", t->line_pos,
4801 token, token->used - 1, tid);
4806 } else if (t->offset < t->size) {
4807 fprintf(stderr, "%s.%d: %d, %s\n",
4808 @@ -781,10 +780,11 @@
4809 pParser = configparserAlloc( malloc );
4810 lasttoken = buffer_init();
4811 token = buffer_init();
4813 while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) {
4814 buffer_copy_string_buffer(lasttoken, token);
4815 configparser(pParser, token_id, token, context);
4818 token = buffer_init();
4821 @@ -797,14 +797,14 @@
4824 configparserFree(pParser, free);
4828 - log_error_write(srv, __FILE__, __LINE__, "sb",
4829 + log_error_write(srv, __FILE__, __LINE__, "sb",
4830 "configfile parser failed:", lasttoken);
4831 } else if (context->ok == 0) {
4832 - log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb",
4833 + log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb",
4834 "source:", t->source,
4835 - "line:", t->line, "pos:", t->line_pos,
4836 + "line:", t->line, "pos:", t->line_pos,
4837 "parser failed somehow near here:", lasttoken);
4852 if (0 != stream_open(&s, filename)) {
4853 - log_error_write(srv, __FILE__, __LINE__, "sbss",
4854 + log_error_write(srv, __FILE__, __LINE__, "sbss",
4855 "opening configfile ", filename, "failed:", strerror(errno));
4859 char oldpwd[PATH_MAX];
4861 if (NULL == getcwd(oldpwd, sizeof(oldpwd))) {
4862 - log_error_write(srv, __FILE__, __LINE__, "s",
4863 + log_error_write(srv, __FILE__, __LINE__, "s",
4864 "cannot get cwd", strerror(errno));
4870 if (0 != proc_open_buffer(&proc, cmd, NULL, out, NULL)) {
4871 - log_error_write(srv, __FILE__, __LINE__, "sbss",
4872 + log_error_write(srv, __FILE__, __LINE__, "sbss",
4873 "opening", source, "failed:", strerror(errno));
4876 @@ -896,13 +896,12 @@
4877 static void context_init(server *srv, config_t *context) {
4880 - context->configs_stack = array_init();
4881 - context->configs_stack->is_weakref = 1;
4882 + context->configs_stack = buffer_ptr_init(NULL);
4883 context->basedir = buffer_init();
4886 static void context_free(config_t *context) {
4887 - array_free(context->configs_stack);
4888 + buffer_ptr_free(context->configs_stack);
4889 buffer_free(context->basedir);
4892 @@ -918,18 +917,15 @@
4893 context_init(srv, &context);
4894 context.all_configs = srv->config_context;
4903 + /* use the current dir as basedir for all other includes
4905 + pos = strrchr(fn, DIR_SEPERATOR);
4908 buffer_copy_string_len(context.basedir, fn, pos - fn + 1);
4913 dc = data_config_init();
4914 buffer_copy_string(dc->key, "global");
4917 dpid->value = getpid();
4918 buffer_copy_string(dpid->key, "var.PID");
4919 array_insert_unique(srv->config, (data_unset *)dpid);
4922 dcwd = data_string_init();
4923 buffer_prepare_copy(dcwd->value, 1024);
4924 if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) {
4931 if (NULL != (modules = (data_array *)array_get_element(srv->config, "server.modules"))) {
4933 data_array *prepends;
4934 @@ -1026,22 +1022,23 @@
4935 buffer_copy_string(modules->key, "server.modules");
4936 array_insert_unique(srv->config, (data_unset *)modules);
4941 if (0 != config_insert(srv)) {
4950 int config_set_defaults(server *srv) {
4952 specific_config *s = srv->config_storage[0];
4953 struct stat st1, st2;
4955 - struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
4958 + struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
4960 /* - poll is most reliable
4961 * - select works everywhere
4962 * - linux-* are experimental
4963 @@ -1067,20 +1064,21 @@
4965 { FDEVENT_HANDLER_UNSET, NULL }
4969 - if (buffer_is_empty(s->document_root)) {
4970 - log_error_write(srv, __FILE__, __LINE__, "s",
4971 - "a default document-root has to be set");
4977 + if (buffer_is_empty(s->document_root)) {
4978 + log_error_write(srv, __FILE__, __LINE__, "s",
4979 + "a default document-root has to be set");
4984 if (buffer_is_empty(srv->srvconf.changeroot)) {
4985 - if (-1 == stat(s->document_root->ptr, &st1)) {
4986 - log_error_write(srv, __FILE__, __LINE__, "sb",
4987 + pathname_unix2local(s->document_root);
4988 + if (-1 == stat(s->document_root->ptr, &st1)) {
4989 + log_error_write(srv, __FILE__, __LINE__, "sbs",
4990 "base-docroot doesn't exist:",
4991 - s->document_root);
4992 + s->document_root, strerror(errno));
4996 @@ -1088,18 +1086,18 @@
4997 buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.changeroot);
4998 buffer_append_string_buffer(srv->tmp_buf, s->document_root);
5000 - if (-1 == stat(srv->tmp_buf->ptr, &st1)) {
5001 - log_error_write(srv, __FILE__, __LINE__, "sb",
5002 + if (-1 == stat(srv->tmp_buf->ptr, &st1)) {
5003 + log_error_write(srv, __FILE__, __LINE__, "sb",
5004 "base-docroot doesn't exist:",
5013 - buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
5015 - buffer_to_lower(srv->tmp_buf);
5016 + buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
5018 + buffer_to_lower(srv->tmp_buf);
5020 if (0 == stat(srv->tmp_buf->ptr, &st1)) {
5022 @@ -1107,68 +1105,68 @@
5023 is_lower = buffer_is_equal(srv->tmp_buf, s->document_root);
5025 /* lower-case existed, check upper-case */
5026 - buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
5027 + buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
5029 - buffer_to_upper(srv->tmp_buf);
5030 + buffer_to_upper(srv->tmp_buf);
5032 /* we have to handle the special case that upper and lower-casing results in the same filename
5033 * as in server.document-root = "/" or "/12345/" */
5035 if (is_lower && buffer_is_equal(srv->tmp_buf, s->document_root)) {
5036 - /* lower-casing and upper-casing didn't result in
5037 - * an other filename, no need to stat(),
5038 + /* lower-casing and upper-casing didn't result in
5039 + * an other filename, no need to stat(),
5040 * just assume it is case-sensitive. */
5042 s->force_lowercase_filenames = 0;
5043 - } else if (0 == stat(srv->tmp_buf->ptr, &st2)) {
5044 + } else if (0 == stat(srv->tmp_buf->ptr, &st2)) {
5046 + /* upper case exists too, doesn't the FS handle this ? */
5048 + /* upper and lower have the same inode -> case-insensitve FS */
5050 + if (st1.st_ino == st2.st_ino) {
5051 + /* upper and lower have the same inode -> case-insensitve FS */
5053 + s->force_lowercase_filenames = 1;
5058 - /* upper case exists too, doesn't the FS handle this ? */
5060 - /* upper and lower have the same inode -> case-insensitve FS */
5062 - if (st1.st_ino == st2.st_ino) {
5063 - /* upper and lower have the same inode -> case-insensitve FS */
5065 - s->force_lowercase_filenames = 1;
5070 if (srv->srvconf.port == 0) {
5071 srv->srvconf.port = s->is_ssl ? 443 : 80;
5075 if (srv->srvconf.event_handler->used == 0) {
5076 /* choose a good default
5078 - * the event_handler list is sorted by 'goodness'
5080 + * the event_handler list is sorted by 'goodness'
5081 * taking the first available should be the best solution
5083 srv->event_handler = event_handlers[0].et;
5086 if (FDEVENT_HANDLER_UNSET == srv->event_handler) {
5087 - log_error_write(srv, __FILE__, __LINE__, "s",
5088 + log_error_write(srv, __FILE__, __LINE__, "s",
5089 "sorry, there is no event handler for this system");
5100 for (i = 0; event_handlers[i].name; i++) {
5101 if (0 == strcmp(event_handlers[i].name, srv->srvconf.event_handler->ptr)) {
5102 srv->event_handler = event_handlers[i].et;
5108 if (FDEVENT_HANDLER_UNSET == srv->event_handler) {
5109 - log_error_write(srv, __FILE__, __LINE__, "sb",
5110 - "the selected event-handler in unknown or not supported:",
5111 + log_error_write(srv, __FILE__, __LINE__, "sb",
5112 + "the selected event-handler in unknown or not supported:",
5113 srv->srvconf.event_handler );
5119 @@ -1176,19 +1174,19 @@
5121 if (buffer_is_empty(s->ssl_pemfile)) {
5122 /* PEM file is require */
5124 - log_error_write(srv, __FILE__, __LINE__, "s",
5126 + log_error_write(srv, __FILE__, __LINE__, "s",
5127 "ssl.pemfile has to be set");
5133 - log_error_write(srv, __FILE__, __LINE__, "s",
5134 + log_error_write(srv, __FILE__, __LINE__, "s",
5135 "ssl support is missing, recompile with --with-openssl");
5145 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configfile.h lighttpd-1.4.12/src/configfile.h
5146 --- lighttpd-1.4.11/src/configfile.h 2005-08-23 17:36:12.000000000 +0300
5147 +++ lighttpd-1.4.12/src/configfile.h 2006-07-11 21:23:39.000000000 +0300
5152 - array *configs_stack; /* to parse nested block */
5153 + buffer_ptr *configs_stack; /* to parse nested block */
5154 data_config *current; /* current started with { */
5157 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configparser.c lighttpd-1.4.12/src/configparser.c
5158 --- lighttpd-1.4.11/src/configparser.c 2006-02-01 19:51:15.000000000 +0200
5159 +++ lighttpd-1.4.12/src/configparser.c 2006-07-11 21:49:18.000000000 +0300
5161 dc->parent = ctx->current;
5162 array_insert_unique(dc->parent->childs, (data_unset *)dc);
5164 - array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current);
5165 + buffer_ptr_append(ctx->configs_stack, (void *)ctx->current);
5169 static data_config *configparser_pop(config_t *ctx) {
5170 data_config *old = ctx->current;
5171 - ctx->current = (data_config *) array_pop(ctx->configs_stack);
5172 + ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack);
5176 /* return a copied variable */
5177 static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) {
5178 - if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) {
5181 - if (NULL != (env = getenv(key->ptr + 4))) {
5183 - ds = data_string_init();
5184 - buffer_append_string(ds->value, env);
5185 - return (data_unset *)ds;
5188 - fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4);
5199 - fprintf(stderr, "get var %s\n", key->ptr);
5200 + fprintf(stderr, "get var %s\n", key->ptr);
5202 - for (dc = ctx->current; dc; dc = dc->parent) {
5203 + for (dc = ctx->current; dc; dc = dc->parent) {
5205 - fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
5206 - array_print(dc->value, 0);
5207 + fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
5208 + array_print(dc->value, 0);
5210 - if (NULL != (du = array_get_element(dc->value, key->ptr))) {
5211 - return du->copy(du);
5213 + if (NULL != (du = array_get_element(dc->value, key->ptr))) {
5214 + return du->copy(du);
5216 - fprintf(stderr, "Undefined config variable: %s\n", key->ptr);
5223 /* op1 is to be eat/return by this function, op1->key is not cared
5224 @@ -124,14 +106,14 @@
5228 -#line 128 "configparser.c"
5229 +#line 110 "configparser.c"
5230 /* Next is all token values, in a form suitable for use by makeheaders.
5231 ** This section will be null unless lemon is run with the -m switch.
5235 ** These constants (all generated automatically by the parser generator)
5236 ** specify the various kinds of tokens (terminals) that the parser
5240 ** Each symbol here is a terminal symbol in the grammar.
5243 ** and nonterminals. "int" is used otherwise.
5244 ** YYNOCODE is a number of type YYCODETYPE which corresponds
5245 ** to no legal terminal or nonterminal number. This
5246 -** number is used to fill in empty slots of the hash
5247 +** number is used to fill in empty slots of the hash
5249 ** YYFALLBACK If defined, this indicates that one or more tokens
5250 ** have fall-back values which should be used if the
5252 ** and nonterminal numbers. "unsigned char" is
5253 ** used if there are fewer than 250 rules and
5254 ** states combined. "int" is used otherwise.
5255 -** configparserTOKENTYPE is the data type used for minor tokens given
5256 +** configparserTOKENTYPE is the data type used for minor tokens given
5257 ** directly to the parser from the tokenizer.
5258 ** YYMINORTYPE is the data type used for all minor tokens.
5259 ** This is typically a union of many types, one of
5261 #define configparserARG_PDECL ,config_t *ctx
5262 #define configparserARG_FETCH config_t *ctx = yypParser->ctx
5263 #define configparserARG_STORE yypParser->ctx = ctx
5264 -#define YYNSTATE 62
5266 +#define YYNSTATE 63
5268 #define YYERRORSYMBOL 26
5269 #define YYERRSYMDT yy95
5270 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
5272 /* Next are that tables used to determine what action to take based on the
5273 ** current state and lookahead token. These tables are used to implement
5274 ** functions that take a state number and lookahead value and return an
5278 ** Suppose the action integer is N. Then the action is determined as
5281 ** If the index value yy_shift_ofst[S]+X is out of range or if the value
5282 ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
5283 ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
5284 -** and that yy_default[S] should be used instead.
5285 +** and that yy_default[S] should be used instead.
5287 ** The formula above is for computing the action when the lookahead is
5288 ** a terminal symbol. If the lookahead is a non-terminal (as occurs after
5289 @@ -248,67 +230,69 @@
5290 ** yy_default[] Default action for each state.
5292 static YYACTIONTYPE yy_action[] = {
5293 - /* 0 */ 2, 3, 4, 5, 13, 14, 62, 15, 7, 44,
5294 - /* 10 */ 20, 86, 16, 45, 28, 48, 40, 10, 39, 25,
5295 - /* 20 */ 22, 49, 45, 8, 15, 102, 1, 20, 28, 18,
5296 - /* 30 */ 57, 59, 19, 25, 22, 39, 19, 61, 98, 45,
5297 - /* 40 */ 20, 6, 23, 24, 26, 28, 35, 57, 59, 12,
5298 - /* 50 */ 25, 22, 28, 27, 36, 87, 29, 25, 22, 33,
5299 - /* 60 */ 15, 30, 31, 20, 28, 38, 9, 17, 37, 25,
5300 - /* 70 */ 22, 39, 42, 43, 10, 45, 11, 53, 54, 55,
5301 - /* 80 */ 56, 28, 52, 57, 59, 34, 25, 22, 28, 27,
5302 - /* 90 */ 32, 88, 41, 25, 22, 33, 28, 48, 46, 28,
5303 - /* 100 */ 48, 25, 22, 58, 25, 22, 60, 21, 19, 47,
5304 - /* 110 */ 51, 50, 25, 22, 88, 88, 93,
5305 + /* 0 */ 2, 3, 4, 5, 13, 14, 63, 15, 7, 45,
5306 + /* 10 */ 20, 88, 16, 46, 28, 49, 41, 10, 40, 25,
5307 + /* 20 */ 22, 50, 46, 8, 15, 104, 1, 20, 28, 18,
5308 + /* 30 */ 58, 60, 6, 25, 22, 40, 47, 62, 11, 46,
5309 + /* 40 */ 20, 9, 23, 24, 26, 29, 89, 58, 60, 10,
5310 + /* 50 */ 17, 38, 28, 27, 37, 19, 30, 25, 22, 34,
5311 + /* 60 */ 15, 100, 20, 20, 23, 24, 26, 12, 19, 31,
5312 + /* 70 */ 32, 40, 19, 44, 43, 46, 95, 35, 90, 89,
5313 + /* 80 */ 28, 49, 42, 58, 60, 25, 22, 59, 28, 27,
5314 + /* 90 */ 33, 48, 52, 25, 22, 34, 28, 49, 51, 28,
5315 + /* 100 */ 36, 25, 22, 61, 25, 22, 89, 28, 39, 89,
5316 + /* 110 */ 89, 89, 25, 22, 54, 55, 56, 57, 89, 28,
5317 + /* 120 */ 53, 21, 89, 89, 25, 22, 25, 22,
5319 static YYCODETYPE yy_lookahead[] = {
5320 /* 0 */ 29, 30, 31, 32, 33, 34, 0, 1, 44, 38,
5321 /* 10 */ 4, 15, 41, 16, 35, 36, 45, 46, 12, 40,
5322 /* 20 */ 41, 42, 16, 15, 1, 27, 28, 4, 35, 36,
5323 - /* 30 */ 24, 25, 5, 40, 41, 12, 5, 14, 11, 16,
5324 - /* 40 */ 4, 1, 6, 7, 8, 35, 36, 24, 25, 28,
5325 - /* 50 */ 40, 41, 35, 36, 37, 15, 39, 40, 41, 42,
5326 - /* 60 */ 1, 9, 10, 4, 35, 36, 38, 2, 3, 40,
5327 - /* 70 */ 41, 12, 28, 14, 46, 16, 13, 20, 21, 22,
5328 - /* 80 */ 23, 35, 36, 24, 25, 11, 40, 41, 35, 36,
5329 - /* 90 */ 37, 13, 13, 40, 41, 42, 35, 36, 17, 35,
5330 - /* 100 */ 36, 40, 41, 42, 40, 41, 42, 35, 5, 18,
5331 - /* 110 */ 43, 19, 40, 41, 47, 47, 13,
5332 + /* 30 */ 24, 25, 1, 40, 41, 12, 17, 14, 13, 16,
5333 + /* 40 */ 4, 38, 6, 7, 8, 9, 15, 24, 25, 46,
5334 + /* 50 */ 2, 3, 35, 36, 37, 5, 39, 40, 41, 42,
5335 + /* 60 */ 1, 11, 4, 4, 6, 7, 8, 28, 5, 9,
5336 + /* 70 */ 10, 12, 5, 14, 28, 16, 13, 11, 13, 47,
5337 + /* 80 */ 35, 36, 13, 24, 25, 40, 41, 42, 35, 36,
5338 + /* 90 */ 37, 18, 43, 40, 41, 42, 35, 36, 19, 35,
5339 + /* 100 */ 36, 40, 41, 42, 40, 41, 47, 35, 36, 47,
5340 + /* 110 */ 47, 47, 40, 41, 20, 21, 22, 23, 47, 35,
5341 + /* 120 */ 36, 35, 47, 47, 40, 41, 40, 41,
5343 #define YY_SHIFT_USE_DFLT (-5)
5344 static signed char yy_shift_ofst[] = {
5345 - /* 0 */ -5, 6, -5, -5, -5, 40, -4, 8, -3, -5,
5346 - /* 10 */ 63, -5, 23, -5, -5, -5, 65, 36, 31, 36,
5347 - /* 20 */ -5, -5, -5, -5, -5, -5, 36, 27, -5, 52,
5348 - /* 30 */ -5, 36, -5, 74, 36, 31, -5, 36, 31, 78,
5349 - /* 40 */ 79, -5, 59, -5, -5, 81, 91, 36, 31, 92,
5350 - /* 50 */ 57, 36, 103, -5, -5, -5, -5, 36, -5, 36,
5352 + /* 0 */ -5, 6, -5, -5, -5, 31, -4, 8, -3, -5,
5353 + /* 10 */ 25, -5, 23, -5, -5, -5, 48, 58, 67, 58,
5354 + /* 20 */ -5, -5, -5, -5, -5, -5, 36, 50, -5, -5,
5355 + /* 30 */ 60, -5, 58, -5, 66, 58, 67, -5, 58, 67,
5356 + /* 40 */ 65, 69, -5, 59, -5, -5, 19, 73, 58, 67,
5357 + /* 50 */ 79, 94, 58, 63, -5, -5, -5, -5, 58, -5,
5358 + /* 60 */ 58, -5, -5,
5360 #define YY_REDUCE_USE_DFLT (-37)
5361 static signed char yy_reduce_ofst[] = {
5362 - /* 0 */ -2, -29, -37, -37, -37, -36, -37, -37, 28, -37,
5363 - /* 10 */ -37, 21, -29, -37, -37, -37, -37, -7, -37, 72,
5364 + /* 0 */ -2, -29, -37, -37, -37, -36, -37, -37, 3, -37,
5365 + /* 10 */ -37, 39, -29, -37, -37, -37, -37, -7, -37, 86,
5366 /* 20 */ -37, -37, -37, -37, -37, -37, 17, -37, -37, -37,
5367 - /* 30 */ -37, 53, -37, -37, 10, -37, -37, 29, -37, -37,
5368 - /* 40 */ -37, 44, -29, -37, -37, -37, -37, -21, -37, -37,
5369 - /* 50 */ 67, 46, -37, -37, -37, -37, -37, 61, -37, 64,
5370 - /* 60 */ -37, -37,
5371 + /* 30 */ -37, -37, 53, -37, -37, 64, -37, -37, 72, -37,
5372 + /* 40 */ -37, -37, 46, -29, -37, -37, -37, -37, -21, -37,
5373 + /* 50 */ -37, 49, 84, -37, -37, -37, -37, -37, 45, -37,
5374 + /* 60 */ 61, -37, -37,
5376 static YYACTIONTYPE yy_default[] = {
5377 - /* 0 */ 64, 101, 63, 65, 66, 101, 67, 101, 101, 90,
5378 - /* 10 */ 101, 64, 101, 68, 69, 70, 101, 101, 71, 101,
5379 - /* 20 */ 73, 74, 76, 77, 78, 79, 101, 84, 75, 101,
5380 - /* 30 */ 80, 82, 81, 101, 101, 85, 83, 101, 72, 101,
5381 - /* 40 */ 101, 64, 101, 89, 91, 101, 101, 101, 98, 101,
5382 - /* 50 */ 101, 101, 101, 94, 95, 96, 97, 101, 99, 101,
5384 + /* 0 */ 65, 103, 64, 66, 67, 103, 68, 103, 103, 92,
5385 + /* 10 */ 103, 65, 103, 69, 70, 71, 103, 103, 72, 103,
5386 + /* 20 */ 74, 75, 77, 78, 79, 80, 103, 86, 76, 81,
5387 + /* 30 */ 103, 82, 84, 83, 103, 103, 87, 85, 103, 73,
5388 + /* 40 */ 103, 103, 65, 103, 91, 93, 103, 103, 103, 100,
5389 + /* 50 */ 103, 103, 103, 103, 96, 97, 98, 99, 103, 101,
5390 + /* 60 */ 103, 102, 94,
5392 #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
5394 /* The next table maps tokens into fallback tokens. If a construct
5395 ** like the following:
5398 ** %fallback ID X Y Z.
5400 ** appears in the grammer, then ID becomes a fallback token for X, Y,
5401 @@ -359,10 +343,10 @@
5407 ** Turn parser tracing on by giving a stream to which to write the trace
5408 ** and a prompt to preface each trace message. Tracing is turned off
5409 -** by making either argument NULL
5410 +** by making either argument NULL
5416 /* For tracing shifts, the names of all terminals and nonterminals
5417 ** are required. The following table supplies these names */
5418 -static const char *yyTokenName[] = {
5419 +static const char *yyTokenName[] = {
5420 "$", "EOL", "ASSIGN", "APPEND",
5421 "LKEY", "PLUS", "STRING", "INTEGER",
5422 "LPARAN", "RPARAN", "COMMA", "ARRAY_ASSIGN",
5423 @@ -425,27 +409,28 @@
5424 /* 15 */ "value ::= STRING",
5425 /* 16 */ "value ::= INTEGER",
5426 /* 17 */ "value ::= array",
5427 - /* 18 */ "array ::= LPARAN aelements RPARAN",
5428 - /* 19 */ "aelements ::= aelements COMMA aelement",
5429 - /* 20 */ "aelements ::= aelements COMMA",
5430 - /* 21 */ "aelements ::= aelement",
5431 - /* 22 */ "aelement ::= expression",
5432 - /* 23 */ "aelement ::= stringop ARRAY_ASSIGN expression",
5433 - /* 24 */ "eols ::= EOL",
5434 - /* 25 */ "eols ::=",
5435 - /* 26 */ "globalstart ::= GLOBAL",
5436 - /* 27 */ "global ::= globalstart LCURLY metalines RCURLY",
5437 - /* 28 */ "condlines ::= condlines eols ELSE condline",
5438 - /* 29 */ "condlines ::= condline",
5439 - /* 30 */ "condline ::= context LCURLY metalines RCURLY",
5440 - /* 31 */ "context ::= DOLLAR SRVVARNAME LBRACKET stringop RBRACKET cond expression",
5441 - /* 32 */ "cond ::= EQ",
5442 - /* 33 */ "cond ::= MATCH",
5443 - /* 34 */ "cond ::= NE",
5444 - /* 35 */ "cond ::= NOMATCH",
5445 - /* 36 */ "stringop ::= expression",
5446 - /* 37 */ "include ::= INCLUDE stringop",
5447 - /* 38 */ "include_shell ::= INCLUDE_SHELL stringop",
5448 + /* 18 */ "array ::= LPARAN RPARAN",
5449 + /* 19 */ "array ::= LPARAN aelements RPARAN",
5450 + /* 20 */ "aelements ::= aelements COMMA aelement",
5451 + /* 21 */ "aelements ::= aelements COMMA",
5452 + /* 22 */ "aelements ::= aelement",
5453 + /* 23 */ "aelement ::= expression",
5454 + /* 24 */ "aelement ::= stringop ARRAY_ASSIGN expression",
5455 + /* 25 */ "eols ::= EOL",
5456 + /* 26 */ "eols ::=",
5457 + /* 27 */ "globalstart ::= GLOBAL",
5458 + /* 28 */ "global ::= globalstart LCURLY metalines RCURLY",
5459 + /* 29 */ "condlines ::= condlines eols ELSE condline",
5460 + /* 30 */ "condlines ::= condline",
5461 + /* 31 */ "condline ::= context LCURLY metalines RCURLY",
5462 + /* 32 */ "context ::= DOLLAR SRVVARNAME LBRACKET stringop RBRACKET cond expression",
5463 + /* 33 */ "cond ::= EQ",
5464 + /* 34 */ "cond ::= MATCH",
5465 + /* 35 */ "cond ::= NE",
5466 + /* 36 */ "cond ::= NOMATCH",
5467 + /* 37 */ "stringop ::= expression",
5468 + /* 38 */ "include ::= INCLUDE stringop",
5469 + /* 39 */ "include_shell ::= INCLUDE_SHELL stringop",
5479 ** This function allocates a new parser.
5480 ** The only argument is a pointer to a function which works like
5483 /* Here is inserted the actions which take place when a
5484 ** terminal or non-terminal is destroyed. This can happen
5485 ** when the symbol is popped from the stack during a
5486 - ** reduce or during error processing or when a parser is
5487 + ** reduce or during error processing or when a parser is
5488 ** being destroyed before it is finished parsing.
5490 ** Note: during a reduce, the only symbols destroyed are those
5491 @@ -528,44 +513,44 @@
5495 -#line 160 "./configparser.y"
5496 +#line 143 "./configparser.y"
5497 { buffer_free((yypminor->yy0)); }
5498 -#line 533 "configparser.c"
5499 +#line 518 "configparser.c"
5502 -#line 151 "./configparser.y"
5503 +#line 134 "./configparser.y"
5504 { (yypminor->yy41)->free((yypminor->yy41)); }
5505 -#line 538 "configparser.c"
5506 +#line 523 "configparser.c"
5509 -#line 152 "./configparser.y"
5510 +#line 135 "./configparser.y"
5511 { (yypminor->yy41)->free((yypminor->yy41)); }
5512 -#line 543 "configparser.c"
5513 +#line 528 "configparser.c"
5516 -#line 153 "./configparser.y"
5517 +#line 136 "./configparser.y"
5518 { (yypminor->yy41)->free((yypminor->yy41)); }
5519 -#line 548 "configparser.c"
5520 +#line 533 "configparser.c"
5523 -#line 154 "./configparser.y"
5524 +#line 137 "./configparser.y"
5525 { array_free((yypminor->yy40)); }
5526 -#line 553 "configparser.c"
5527 +#line 538 "configparser.c"
5530 -#line 155 "./configparser.y"
5531 +#line 138 "./configparser.y"
5532 { array_free((yypminor->yy40)); }
5533 -#line 558 "configparser.c"
5534 +#line 543 "configparser.c"
5537 -#line 156 "./configparser.y"
5538 +#line 139 "./configparser.y"
5539 { buffer_free((yypminor->yy43)); }
5540 -#line 563 "configparser.c"
5541 +#line 548 "configparser.c"
5544 -#line 157 "./configparser.y"
5545 +#line 140 "./configparser.y"
5546 { buffer_free((yypminor->yy43)); }
5547 -#line 568 "configparser.c"
5548 +#line 553 "configparser.c"
5550 default: break; /* If no destructor action specified: do nothing */
5558 ** Deallocate and destroy a parser. Destructors are all called for
5559 ** all stack elements before shutting the parser down.
5564 int stateno = pParser->yystack[pParser->yyidx].stateno;
5567 /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */
5568 i = yy_shift_ofst[stateno];
5569 if( i==YY_SHIFT_USE_DFLT ){
5573 int stateno = pParser->yystack[pParser->yyidx].stateno;
5576 i = yy_reduce_ofst[stateno];
5577 if( i==YY_REDUCE_USE_DFLT ){
5578 return yy_default[stateno];
5588 configparserARG_FETCH;
5589 yymsp = &yypParser->yystack[yypParser->yyidx];
5591 - if( yyTraceFILE && yyruleno>=0
5592 + if( yyTraceFILE && yyruleno>=0
5593 && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
5594 fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
5595 yyRuleName[yyruleno]);
5597 /* No destructor defined for global */
5600 -#line 134 "./configparser.y"
5601 +#line 116 "./configparser.y"
5602 { yymsp[-1].minor.yy78 = NULL; }
5603 -#line 837 "configparser.c"
5604 +#line 823 "configparser.c"
5605 yy_destructor(1,&yymsp[0].minor);
5608 @@ -847,10 +833,15 @@
5609 yy_destructor(1,&yymsp[0].minor);
5612 -#line 162 "./configparser.y"
5613 +#line 145 "./configparser.y"
5615 buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
5616 - if (NULL == array_get_element(ctx->current->value, yymsp[0].minor.yy41->key->ptr)) {
5617 + if (strncmp(yymsp[-2].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
5618 + fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
5619 + ctx->current->context_ndx,
5620 + ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
5622 + } else if (NULL == array_get_element(ctx->current->value, yymsp[0].minor.yy41->key->ptr)) {
5623 array_insert_unique(ctx->current->value, yymsp[0].minor.yy41);
5624 yymsp[0].minor.yy41 = NULL;
5626 @@ -864,16 +855,21 @@
5627 buffer_free(yymsp[-2].minor.yy43);
5628 yymsp[-2].minor.yy43 = NULL;
5630 -#line 867 "configparser.c"
5631 +#line 858 "configparser.c"
5632 yy_destructor(2,&yymsp[-1].minor);
5635 -#line 179 "./configparser.y"
5636 +#line 167 "./configparser.y"
5638 array *vars = ctx->current->value;
5641 - if (NULL != (du = array_get_element(vars, yymsp[-2].minor.yy43->ptr))) {
5642 + if (strncmp(yymsp[-2].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
5643 + fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n",
5644 + ctx->current->context_ndx,
5645 + ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
5647 + } else if (NULL != (du = array_get_element(vars, yymsp[-2].minor.yy43->ptr))) {
5648 /* exists in current block */
5649 du = configparser_merge_data(du, yymsp[0].minor.yy41);
5652 buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43);
5653 array_replace(vars, du);
5655 + yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
5656 } else if (NULL != (du = configparser_get_variable(ctx, yymsp[-2].minor.yy43))) {
5657 du = configparser_merge_data(du, yymsp[0].minor.yy41);
5659 @@ -892,22 +889,20 @@
5660 buffer_copy_string_buffer(du->key, yymsp[-2].minor.yy43);
5661 array_insert_unique(ctx->current->value, du);
5663 + yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
5665 - fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n",
5666 - ctx->current->context_ndx,
5667 - ctx->current->key->ptr, yymsp[-2].minor.yy43->ptr);
5669 + buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
5670 + array_insert_unique(ctx->current->value, yymsp[0].minor.yy41);
5672 buffer_free(yymsp[-2].minor.yy43);
5673 yymsp[-2].minor.yy43 = NULL;
5674 - yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
5675 yymsp[0].minor.yy41 = NULL;
5677 -#line 906 "configparser.c"
5678 +#line 901 "configparser.c"
5679 yy_destructor(3,&yymsp[-1].minor);
5682 -#line 214 "./configparser.y"
5683 +#line 206 "./configparser.y"
5685 if (strchr(yymsp[0].minor.yy0->ptr, '.') == NULL) {
5686 yygotominor.yy43 = buffer_init_string("var.");
5687 @@ -919,10 +914,10 @@
5688 yymsp[0].minor.yy0 = NULL;
5691 -#line 922 "configparser.c"
5692 +#line 917 "configparser.c"
5695 -#line 226 "./configparser.y"
5696 +#line 218 "./configparser.y"
5698 yygotominor.yy41 = configparser_merge_data(yymsp[-2].minor.yy41, yymsp[0].minor.yy41);
5699 if (NULL == yygotominor.yy41) {
5700 @@ -932,21 +927,38 @@
5701 yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
5702 yymsp[0].minor.yy41 = NULL;
5704 -#line 935 "configparser.c"
5705 +#line 930 "configparser.c"
5706 yy_destructor(5,&yymsp[-1].minor);
5709 -#line 236 "./configparser.y"
5710 +#line 228 "./configparser.y"
5712 yygotominor.yy41 = yymsp[0].minor.yy41;
5713 yymsp[0].minor.yy41 = NULL;
5715 -#line 944 "configparser.c"
5716 +#line 939 "configparser.c"
5719 -#line 241 "./configparser.y"
5720 +#line 233 "./configparser.y"
5722 - yygotominor.yy41 = configparser_get_variable(ctx, yymsp[0].minor.yy43);
5723 + if (strncmp(yymsp[0].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) {
5726 + if (NULL != (env = getenv(yymsp[0].minor.yy43->ptr + 4))) {
5728 + ds = data_string_init();
5729 + buffer_append_string(ds->value, env);
5730 + yygotominor.yy41 = (data_unset *)ds;
5733 + yygotominor.yy41 = NULL;
5734 + fprintf(stderr, "Undefined env variable: %s\n", yymsp[0].minor.yy43->ptr + 4);
5737 + } else if (NULL == (yygotominor.yy41 = configparser_get_variable(ctx, yymsp[0].minor.yy43))) {
5738 + fprintf(stderr, "Undefined config variable: %s\n", yymsp[0].minor.yy43->ptr);
5741 if (!yygotominor.yy41) {
5742 /* make a dummy so it won't crash */
5743 yygotominor.yy41 = (data_unset *)data_string_init();
5744 @@ -954,50 +966,59 @@
5745 buffer_free(yymsp[0].minor.yy43);
5746 yymsp[0].minor.yy43 = NULL;
5748 -#line 957 "configparser.c"
5749 +#line 969 "configparser.c"
5752 -#line 251 "./configparser.y"
5753 +#line 260 "./configparser.y"
5755 yygotominor.yy41 = (data_unset *)data_string_init();
5756 buffer_copy_string_buffer(((data_string *)(yygotominor.yy41))->value, yymsp[0].minor.yy0);
5757 buffer_free(yymsp[0].minor.yy0);
5758 yymsp[0].minor.yy0 = NULL;
5760 -#line 967 "configparser.c"
5761 +#line 979 "configparser.c"
5764 -#line 258 "./configparser.y"
5765 +#line 267 "./configparser.y"
5767 yygotominor.yy41 = (data_unset *)data_integer_init();
5768 ((data_integer *)(yygotominor.yy41))->value = strtol(yymsp[0].minor.yy0->ptr, NULL, 10);
5769 buffer_free(yymsp[0].minor.yy0);
5770 yymsp[0].minor.yy0 = NULL;
5772 -#line 977 "configparser.c"
5773 +#line 989 "configparser.c"
5776 -#line 264 "./configparser.y"
5777 +#line 273 "./configparser.y"
5779 yygotominor.yy41 = (data_unset *)data_array_init();
5780 array_free(((data_array *)(yygotominor.yy41))->value);
5781 ((data_array *)(yygotominor.yy41))->value = yymsp[0].minor.yy40;
5782 yymsp[0].minor.yy40 = NULL;
5784 -#line 987 "configparser.c"
5785 +#line 999 "configparser.c"
5788 -#line 270 "./configparser.y"
5789 +#line 279 "./configparser.y"
5791 + yygotominor.yy40 = array_init();
5793 +#line 1006 "configparser.c"
5794 + yy_destructor(8,&yymsp[-1].minor);
5795 + yy_destructor(9,&yymsp[0].minor);
5798 +#line 282 "./configparser.y"
5800 yygotominor.yy40 = yymsp[-1].minor.yy40;
5801 yymsp[-1].minor.yy40 = NULL;
5803 -#line 995 "configparser.c"
5804 +#line 1016 "configparser.c"
5805 yy_destructor(8,&yymsp[-2].minor);
5806 yy_destructor(9,&yymsp[0].minor);
5809 -#line 275 "./configparser.y"
5811 +#line 287 "./configparser.y"
5813 if (buffer_is_empty(yymsp[0].minor.yy41->key) ||
5814 NULL == array_get_element(yymsp[-2].minor.yy40, yymsp[0].minor.yy41->key->ptr)) {
5815 @@ -1014,37 +1035,37 @@
5816 yygotominor.yy40 = yymsp[-2].minor.yy40;
5817 yymsp[-2].minor.yy40 = NULL;
5819 -#line 1017 "configparser.c"
5820 +#line 1038 "configparser.c"
5821 yy_destructor(10,&yymsp[-1].minor);
5824 -#line 292 "./configparser.y"
5826 +#line 304 "./configparser.y"
5828 yygotominor.yy40 = yymsp[-1].minor.yy40;
5829 yymsp[-1].minor.yy40 = NULL;
5831 -#line 1026 "configparser.c"
5832 +#line 1047 "configparser.c"
5833 yy_destructor(10,&yymsp[0].minor);
5836 -#line 297 "./configparser.y"
5838 +#line 309 "./configparser.y"
5840 yygotominor.yy40 = array_init();
5841 array_insert_unique(yygotominor.yy40, yymsp[0].minor.yy41);
5842 yymsp[0].minor.yy41 = NULL;
5844 -#line 1036 "configparser.c"
5845 +#line 1057 "configparser.c"
5848 -#line 303 "./configparser.y"
5850 +#line 315 "./configparser.y"
5852 yygotominor.yy41 = yymsp[0].minor.yy41;
5853 yymsp[0].minor.yy41 = NULL;
5855 -#line 1044 "configparser.c"
5856 +#line 1065 "configparser.c"
5859 -#line 307 "./configparser.y"
5861 +#line 319 "./configparser.y"
5863 buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43);
5864 buffer_free(yymsp[-2].minor.yy43);
5865 @@ -1053,27 +1074,27 @@
5866 yygotominor.yy41 = yymsp[0].minor.yy41;
5867 yymsp[0].minor.yy41 = NULL;
5869 -#line 1056 "configparser.c"
5870 +#line 1077 "configparser.c"
5871 yy_destructor(11,&yymsp[-1].minor);
5874 - yy_destructor(1,&yymsp[0].minor);
5877 + yy_destructor(1,&yymsp[0].minor);
5880 -#line 319 "./configparser.y"
5883 +#line 331 "./configparser.y"
5886 dc = (data_config *)array_get_element(ctx->srv->config_context, "global");
5888 configparser_push(ctx, dc, 0);
5890 -#line 1072 "configparser.c"
5891 +#line 1093 "configparser.c"
5892 yy_destructor(12,&yymsp[0].minor);
5895 -#line 326 "./configparser.y"
5897 +#line 338 "./configparser.y"
5901 @@ -1082,16 +1103,16 @@
5903 assert(cur && ctx->current);
5905 - yygotominor.yy0 = cur;
5906 + yygotominor.yy78 = cur;
5908 -#line 1087 "configparser.c"
5909 +#line 1108 "configparser.c"
5910 /* No destructor defined for globalstart */
5911 yy_destructor(13,&yymsp[-2].minor);
5912 /* No destructor defined for metalines */
5913 yy_destructor(14,&yymsp[0].minor);
5916 -#line 337 "./configparser.y"
5918 +#line 349 "./configparser.y"
5920 assert(yymsp[-3].minor.yy78->context_ndx < yymsp[0].minor.yy78->context_ndx);
5921 yymsp[0].minor.yy78->prev = yymsp[-3].minor.yy78;
5922 @@ -1100,20 +1121,20 @@
5923 yymsp[-3].minor.yy78 = NULL;
5924 yymsp[0].minor.yy78 = NULL;
5926 -#line 1103 "configparser.c"
5927 +#line 1124 "configparser.c"
5928 /* No destructor defined for eols */
5929 yy_destructor(15,&yymsp[-1].minor);
5932 -#line 346 "./configparser.y"
5934 +#line 358 "./configparser.y"
5936 yygotominor.yy78 = yymsp[0].minor.yy78;
5937 yymsp[0].minor.yy78 = NULL;
5939 -#line 1113 "configparser.c"
5940 +#line 1134 "configparser.c"
5943 -#line 351 "./configparser.y"
5945 +#line 363 "./configparser.y"
5949 @@ -1124,14 +1145,14 @@
5951 yygotominor.yy78 = cur;
5953 -#line 1127 "configparser.c"
5954 +#line 1148 "configparser.c"
5955 /* No destructor defined for context */
5956 yy_destructor(13,&yymsp[-2].minor);
5957 /* No destructor defined for metalines */
5958 yy_destructor(14,&yymsp[0].minor);
5961 -#line 362 "./configparser.y"
5963 +#line 374 "./configparser.y"
5966 buffer *b, *rvalue, *op;
5967 @@ -1266,45 +1287,45 @@
5968 yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
5969 yymsp[0].minor.yy41 = NULL;
5971 -#line 1269 "configparser.c"
5972 +#line 1290 "configparser.c"
5973 yy_destructor(16,&yymsp[-6].minor);
5974 yy_destructor(18,&yymsp[-4].minor);
5975 yy_destructor(19,&yymsp[-2].minor);
5978 -#line 496 "./configparser.y"
5980 +#line 508 "./configparser.y"
5982 yygotominor.yy27 = CONFIG_COND_EQ;
5984 -#line 1279 "configparser.c"
5985 +#line 1300 "configparser.c"
5986 yy_destructor(20,&yymsp[0].minor);
5989 -#line 499 "./configparser.y"
5991 +#line 511 "./configparser.y"
5993 yygotominor.yy27 = CONFIG_COND_MATCH;
5995 -#line 1287 "configparser.c"
5996 +#line 1308 "configparser.c"
5997 yy_destructor(21,&yymsp[0].minor);
6000 -#line 502 "./configparser.y"
6002 +#line 514 "./configparser.y"
6004 yygotominor.yy27 = CONFIG_COND_NE;
6006 -#line 1295 "configparser.c"
6007 +#line 1316 "configparser.c"
6008 yy_destructor(22,&yymsp[0].minor);
6011 -#line 505 "./configparser.y"
6013 +#line 517 "./configparser.y"
6015 yygotominor.yy27 = CONFIG_COND_NOMATCH;
6017 -#line 1303 "configparser.c"
6018 +#line 1324 "configparser.c"
6019 yy_destructor(23,&yymsp[0].minor);
6022 -#line 509 "./configparser.y"
6024 +#line 521 "./configparser.y"
6026 yygotominor.yy43 = NULL;
6028 @@ -1321,10 +1342,10 @@
6029 yymsp[0].minor.yy41->free(yymsp[0].minor.yy41);
6030 yymsp[0].minor.yy41 = NULL;
6032 -#line 1324 "configparser.c"
6033 +#line 1345 "configparser.c"
6036 -#line 526 "./configparser.y"
6038 +#line 538 "./configparser.y"
6041 if (0 != config_parse_file(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) {
6042 @@ -1334,11 +1355,11 @@
6043 yymsp[0].minor.yy43 = NULL;
6046 -#line 1337 "configparser.c"
6047 +#line 1358 "configparser.c"
6048 yy_destructor(24,&yymsp[-1].minor);
6051 -#line 536 "./configparser.y"
6053 +#line 548 "./configparser.y"
6056 if (0 != config_parse_cmd(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) {
6057 @@ -1348,7 +1369,7 @@
6058 yymsp[0].minor.yy43 = NULL;
6061 -#line 1351 "configparser.c"
6062 +#line 1372 "configparser.c"
6063 yy_destructor(25,&yymsp[-1].minor);
6066 @@ -1378,11 +1399,11 @@
6067 while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
6068 /* Here code is inserted which will be executed whenever the
6070 -#line 125 "./configparser.y"
6071 +#line 107 "./configparser.y"
6075 -#line 1385 "configparser.c"
6076 +#line 1406 "configparser.c"
6077 configparserARG_STORE; /* Suppress warning about unused %extra_argument variable */
6080 @@ -1489,7 +1510,7 @@
6081 #ifdef YYERRORSYMBOL
6082 /* A syntax error has occurred.
6083 ** The response to an error depends upon whether or not the
6084 - ** grammar defines an error token "ERROR".
6085 + ** grammar defines an error token "ERROR".
6087 ** This is what we do if the grammar does define ERROR:
6089 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/configparser.y lighttpd-1.4.12/src/configparser.y
6090 --- lighttpd-1.4.11/src/configparser.y 2006-01-26 18:46:25.000000000 +0200
6091 +++ lighttpd-1.4.12/src/configparser.y 2006-07-11 21:23:40.000000000 +0300
6093 dc->parent = ctx->current;
6094 array_insert_unique(dc->parent->childs, (data_unset *)dc);
6096 - array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current);
6097 + buffer_ptr_append(ctx->configs_stack, (void *)ctx->current);
6101 static data_config *configparser_pop(config_t *ctx) {
6102 data_config *old = ctx->current;
6103 - ctx->current = (data_config *) array_pop(ctx->configs_stack);
6104 + ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack);
6108 /* return a copied variable */
6109 static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) {
6110 - if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) {
6113 - if (NULL != (env = getenv(key->ptr + 4))) {
6115 - ds = data_string_init();
6116 - buffer_append_string(ds->value, env);
6117 - return (data_unset *)ds;
6120 - fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4);
6131 - fprintf(stderr, "get var %s\n", key->ptr);
6132 + fprintf(stderr, "get var %s\n", key->ptr);
6134 - for (dc = ctx->current; dc; dc = dc->parent) {
6135 + for (dc = ctx->current; dc; dc = dc->parent) {
6137 - fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
6138 - array_print(dc->value, 0);
6139 + fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
6140 + array_print(dc->value, 0);
6142 - if (NULL != (du = array_get_element(dc->value, key->ptr))) {
6143 - return du->copy(du);
6145 + if (NULL != (du = array_get_element(dc->value, key->ptr))) {
6146 + return du->copy(du);
6148 - fprintf(stderr, "Undefined config variable: %s\n", key->ptr);
6155 /* op1 is to be eat/return by this function, op1->key is not cared
6157 %type aelement {data_unset *}
6158 %type condline {data_config *}
6159 %type condlines {data_config *}
6160 +%type global {data_config *}
6161 %type aelements {array *}
6162 %type array {array *}
6163 %type key {buffer *}
6164 @@ -161,7 +144,12 @@
6166 varline ::= key(A) ASSIGN expression(B). {
6167 buffer_copy_string_buffer(B->key, A);
6168 - if (NULL == array_get_element(ctx->current->value, B->key->ptr)) {
6169 + if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
6170 + fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
6171 + ctx->current->context_ndx,
6172 + ctx->current->key->ptr, A->ptr);
6174 + } else if (NULL == array_get_element(ctx->current->value, B->key->ptr)) {
6175 array_insert_unique(ctx->current->value, B);
6178 @@ -180,7 +168,12 @@
6179 array *vars = ctx->current->value;
6182 - if (NULL != (du = array_get_element(vars, A->ptr))) {
6183 + if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
6184 + fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n",
6185 + ctx->current->context_ndx,
6186 + ctx->current->key->ptr, A->ptr);
6188 + } else if (NULL != (du = array_get_element(vars, A->ptr))) {
6189 /* exists in current block */
6190 du = configparser_merge_data(du, B);
6193 buffer_copy_string_buffer(du->key, A);
6194 array_replace(vars, du);
6197 } else if (NULL != (du = configparser_get_variable(ctx, A))) {
6198 du = configparser_merge_data(du, B);
6200 @@ -199,15 +193,13 @@
6201 buffer_copy_string_buffer(du->key, A);
6202 array_insert_unique(ctx->current->value, du);
6206 - fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n",
6207 - ctx->current->context_ndx,
6208 - ctx->current->key->ptr, A->ptr);
6210 + buffer_copy_string_buffer(B->key, A);
6211 + array_insert_unique(ctx->current->value, B);
6219 @@ -239,7 +231,24 @@
6222 value(A) ::= key(B). {
6223 - A = configparser_get_variable(ctx, B);
6224 + if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) {
6227 + if (NULL != (env = getenv(B->ptr + 4))) {
6229 + ds = data_string_init();
6230 + buffer_append_string(ds->value, env);
6231 + A = (data_unset *)ds;
6235 + fprintf(stderr, "Undefined env variable: %s\n", B->ptr + 4);
6238 + } else if (NULL == (A = configparser_get_variable(ctx, B))) {
6239 + fprintf(stderr, "Undefined config variable: %s\n", B->ptr);
6243 /* make a dummy so it won't crash */
6244 A = (data_unset *)data_string_init();
6246 ((data_array *)(A))->value = B;
6249 +array(A) ::= LPARAN RPARAN. {
6252 array(A) ::= LPARAN aelements(B) RPARAN. {
6255 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/connections-glue.c lighttpd-1.4.12/src/connections-glue.c
6256 --- lighttpd-1.4.11/src/connections-glue.c 2005-09-12 10:04:23.000000000 +0300
6257 +++ lighttpd-1.4.12/src/connections-glue.c 2006-07-11 21:23:39.000000000 +0300
6259 case CON_STATE_REQUEST_END: return "req-end";
6260 case CON_STATE_RESPONSE_START: return "resp-start";
6261 case CON_STATE_RESPONSE_END: return "resp-end";
6262 - default: return "(unknown)";
6263 + default: return "(unknown)";
6268 case CON_STATE_REQUEST_END: return "Q";
6269 case CON_STATE_RESPONSE_START: return "s";
6270 case CON_STATE_RESPONSE_END: return "S";
6271 - default: return "x";
6272 + default: return "x";
6276 int connection_set_state(server *srv, connection *con, connection_state_t state) {
6286 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/connections.c lighttpd-1.4.12/src/connections.c
6287 --- lighttpd-1.4.11/src/connections.c 2006-03-05 22:14:53.000000000 +0200
6288 +++ lighttpd-1.4.12/src/connections.c 2006-07-11 21:23:39.000000000 +0300
6293 -#include <unistd.h>
6298 #include "inet_ntop_cache.h"
6301 -# include <openssl/ssl.h>
6302 -# include <openssl/err.h>
6303 +# include <openssl/ssl.h>
6304 +# include <openssl/err.h>
6307 #ifdef HAVE_SYS_FILIO_H
6311 #include "sys-socket.h"
6312 +#include "sys-files.h"
6317 static connection *connections_get_new_connection(server *srv) {
6318 connections *conns = srv->conns;
6322 if (conns->size == 0) {
6326 } else if (conns->size == conns->used) {
6328 conns->ptr = realloc(conns->ptr, sizeof(*conns->ptr) * conns->size);
6331 for (i = conns->used; i < conns->size; i++) {
6332 conns->ptr[i] = connection_init(srv);
6336 connection_reset(srv, conns->ptr[conns->used]);
6339 fprintf(stderr, "%s.%d: add: ", __FILE__, __LINE__);
6340 for (i = 0; i < conns->used + 1; i++) {
6341 fprintf(stderr, "%d ", conns->ptr[i]->fd);
6343 fprintf(stderr, "\n");
6348 conns->ptr[conns->used]->ndx = conns->used;
6349 return conns->ptr[conns->used++];
6353 connections *conns = srv->conns;
6357 if (con == NULL) return -1;
6360 if (-1 == con->ndx) return -1;
6366 /* not last element */
6369 if (i != conns->used - 1) {
6370 temp = conns->ptr[i];
6371 conns->ptr[i] = conns->ptr[conns->used - 1];
6372 conns->ptr[conns->used - 1] = temp;
6375 conns->ptr[i]->ndx = i;
6376 conns->ptr[conns->used - 1]->ndx = -1;
6385 fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used);
6386 @@ -104,25 +104,23 @@
6387 fprintf(stderr, "%d ", conns->ptr[i]->fd);
6389 fprintf(stderr, "\n");
6395 int connection_close(server *srv, connection *con) {
6397 server_socket *srv_sock = con->srv_socket;
6402 if (srv_sock->is_ssl) {
6403 if (con->ssl) SSL_free(con->ssl);
6409 fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
6410 fdevent_unregister(srv->ev, con->fd);
6413 if (closesocket(con->fd)) {
6414 log_error_write(srv, __FILE__, __LINE__, "sds",
6415 "(warning) close:", con->fd, strerror(errno));
6416 @@ -133,207 +131,96 @@
6417 "(warning) close:", con->fd, strerror(errno));
6424 log_error_write(srv, __FILE__, __LINE__, "sd",
6425 "closed()", con->fd);
6429 connection_del(srv, con);
6430 connection_set_state(srv, con, CON_STATE_CONNECT);
6437 static void dump_packet(const unsigned char *data, size_t len) {
6441 if (len == 0) return;
6444 for (i = 0; i < len; i++) {
6445 if (i % 16 == 0) fprintf(stderr, " ");
6448 fprintf(stderr, "%02x ", data[i]);
6451 if ((i + 1) % 16 == 0) {
6452 fprintf(stderr, " ");
6453 for (j = 0; j <= i % 16; j++) {
6457 if (i-15+j >= len) break;
6463 fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
6467 fprintf(stderr, "\n");
6472 if (len % 16 != 0) {
6473 for (j = i % 16; j < 16; j++) {
6474 fprintf(stderr, " ");
6478 fprintf(stderr, " ");
6479 for (j = i & ~0xf; j < len; j++) {
6484 fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
6486 fprintf(stderr, "\n");
6491 -static int connection_handle_read(server *srv, connection *con) {
6496 - server_socket *srv_sock = con->srv_socket;
6499 - b = chunkqueue_get_append_buffer(con->read_queue);
6500 - buffer_prepare_copy(b, 4096);
6501 +static network_status_t connection_handle_read(server *srv, connection *con) {
6502 + off_t oldlen, newlen;
6505 - if (srv_sock->is_ssl) {
6506 - len = SSL_read(con->ssl, b->ptr, b->size - 1);
6508 - if (ioctl(con->fd, FIONREAD, &toread)) {
6509 - log_error_write(srv, __FILE__, __LINE__, "sd",
6510 - "unexpected end-of-file:",
6514 - buffer_prepare_copy(b, toread);
6515 + oldlen = chunkqueue_length(con->read_queue);
6517 - len = read(con->fd, b->ptr, b->size - 1);
6519 -#elif defined(__WIN32)
6520 - len = recv(con->fd, b->ptr, b->size - 1, 0);
6522 - if (ioctl(con->fd, FIONREAD, &toread)) {
6523 - log_error_write(srv, __FILE__, __LINE__, "sd",
6524 - "unexpected end-of-file:",
6528 - buffer_prepare_copy(b, toread);
6530 - len = read(con->fd, b->ptr, b->size - 1);
6534 - con->is_readable = 0;
6537 - if (srv_sock->is_ssl) {
6540 - switch ((r = SSL_get_error(con->ssl, len))) {
6541 - case SSL_ERROR_WANT_READ:
6543 - case SSL_ERROR_SYSCALL:
6545 - * man SSL_get_error()
6547 - * SSL_ERROR_SYSCALL
6548 - * Some I/O error occurred. The OpenSSL error queue may contain more
6549 - * information on the error. If the error queue is empty (i.e.
6550 - * ERR_get_error() returns 0), ret can be used to find out more about
6551 - * the error: If ret == 0, an EOF was observed that violates the
6552 - * protocol. If ret == -1, the underlying BIO reported an I/O error
6553 - * (for socket I/O on Unix systems, consult errno for details).
6556 - while((ssl_err = ERR_get_error())) {
6557 - /* get all errors from the error-queue */
6558 - log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
6559 - r, ERR_error_string(ssl_err, NULL));
6561 + switch(network_read_chunkqueue(srv, con, con->read_queue)) {
6562 + case NETWORK_STATUS_SUCCESS:
6564 + case NETWORK_STATUS_WAIT_FOR_EVENT:
6565 + con->is_readable = 0;
6566 + return NETWORK_STATUS_WAIT_FOR_EVENT;
6567 + case NETWORK_STATUS_INTERRUPTED:
6568 + con->is_readable = 1;
6569 + return NETWORK_STATUS_WAIT_FOR_EVENT;
6570 + case NETWORK_STATUS_CONNECTION_CLOSE:
6572 + con->is_readable = 0;
6573 + return NETWORK_STATUS_CONNECTION_CLOSE;
6574 + case NETWORK_STATUS_FATAL_ERROR:
6575 + con->is_readable = 0;
6577 + connection_set_state(srv, con, CON_STATE_ERROR);
6578 + return NETWORK_STATUS_FATAL_ERROR;
6586 - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
6593 - case SSL_ERROR_ZERO_RETURN:
6594 - /* clean shutdown on the remote side */
6597 - /* FIXME: later */
6600 - /* fall thourgh */
6602 - while((ssl_err = ERR_get_error())) {
6603 - /* get all errors from the error-queue */
6604 - log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
6605 - r, ERR_error_string(ssl_err, NULL));
6610 - if (errno == EAGAIN) return 0;
6611 - if (errno == EINTR) {
6612 - /* we have been interrupted before we could read */
6613 - con->is_readable = 1;
6617 - if (errno != ECONNRESET) {
6618 - /* expected for keep-alive */
6619 - log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
6623 - if (errno == EAGAIN) return 0;
6624 - if (errno == EINTR) {
6625 - /* we have been interrupted before we could read */
6626 - con->is_readable = 1;
6630 - if (errno != ECONNRESET) {
6631 - /* expected for keep-alive */
6632 - log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
6635 - connection_set_state(srv, con, CON_STATE_ERROR);
6638 - } else if (len == 0) {
6639 - con->is_readable = 0;
6640 - /* the other end close the connection -> KEEP-ALIVE */
6645 - } else if ((size_t)len < b->size - 1) {
6646 - /* we got less then expected, wait for the next fd-event */
6648 - con->is_readable = 0;
6652 - b->ptr[b->used++] = '\0';
6654 - con->bytes_read += len;
6656 - dump_packet(b->ptr, len);
6660 + newlen = chunkqueue_length(con->read_queue);
6662 + con->bytes_read += (newlen - oldlen);
6664 + return NETWORK_STATUS_SUCCESS;
6667 static int connection_handle_write_prepare(server *srv, connection *con) {
6669 case HTTP_METHOD_GET:
6670 case HTTP_METHOD_POST:
6671 case HTTP_METHOD_HEAD:
6673 case HTTP_METHOD_PUT:
6674 case HTTP_METHOD_MKCOL:
6675 case HTTP_METHOD_DELETE:
6676 @@ -350,12 +238,14 @@
6677 case HTTP_METHOD_MOVE:
6678 case HTTP_METHOD_PROPFIND:
6679 case HTTP_METHOD_PROPPATCH:
6680 + case HTTP_METHOD_LOCK:
6681 + case HTTP_METHOD_UNLOCK:
6683 case HTTP_METHOD_OPTIONS:
6685 * 400 is coming from the request-parser BEFORE uri.path is set
6686 - * 403 is from the response handler when noone else catched it
6688 + * 403 is from the response handler when noone else catched it
6691 if (con->uri.path->used &&
6692 con->uri.path->ptr[0] != '*') {
6693 @@ -381,55 +271,58 @@
6699 if (con->http_status == 0) {
6700 con->http_status = 403;
6704 switch(con->http_status) {
6705 case 400: /* class: header + custom body */
6721 if (con->mode != DIRECT) break;
6724 con->file_finished = 0;
6727 buffer_reset(con->physical.path);
6730 /* try to send static errorfile */
6731 if (!buffer_is_empty(con->conf.errorfile_prefix)) {
6732 stat_cache_entry *sce = NULL;
6735 buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix);
6736 buffer_append_string(con->physical.path, get_http_status_body_name(con->http_status));
6739 if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
6740 con->file_finished = 1;
6743 http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size);
6744 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
6748 - if (!con->file_finished) {
6750 + if (!con->file_finished) {
6754 buffer_reset(con->physical.path);
6757 con->file_finished = 1;
6758 b = chunkqueue_get_append_buffer(con->write_queue);
6761 /* build default error-page */
6762 - buffer_copy_string(b,
6763 + buffer_copy_string(b,
6764 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
6765 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
6766 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
6768 buffer_append_long(b, con->http_status);
6769 buffer_append_string(b, " - ");
6770 buffer_append_string(b, get_http_status_name(con->http_status));
6773 buffer_append_string(b,
6776 @@ -448,12 +341,12 @@
6777 buffer_append_long(b, con->http_status);
6778 buffer_append_string(b, " - ");
6779 buffer_append_string(b, get_http_status_name(con->http_status));
6781 - buffer_append_string(b,"</h1>\n"
6783 + buffer_append_string(b,"</h1>\n"
6789 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
6792 @@ -463,10 +356,10 @@
6798 case 206: /* write_queue is already prepared */
6799 con->file_finished = 1;
6803 case 205: /* class: header only */
6805 @@ -474,19 +367,19 @@
6806 /* disable chunked encoding again as we have no body */
6807 con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
6808 chunkqueue_reset(con->write_queue);
6811 con->file_finished = 1;
6817 if (con->file_finished) {
6818 - /* we have all the content and chunked encoding is not used, set a content-length */
6820 - if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) &&
6821 + /* we have all the content and chunked encoding is not used, set a content-length */
6823 + if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) &&
6824 (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) {
6825 buffer_copy_off_t(srv->tmp_buf, chunkqueue_length(con->write_queue));
6828 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));
6831 @@ -495,74 +388,77 @@
6832 ((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0)) {
6833 con->keep_alive = 0;
6837 if (0 == (con->parsed_response & HTTP_CONNECTION)) {
6838 /* (f)cgi did'nt send Connection: header
6843 if (((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) &&
6844 (con->parsed_response & HTTP_CONTENT_LENGTH) == 0) {
6845 /* without content_length, no keep-alive */
6848 con->keep_alive = 0;
6851 /* a subrequest disable keep-alive although the client wanted it */
6852 if (con->keep_alive && !con->response.keep_alive) {
6853 con->keep_alive = 0;
6856 /* FIXME: we have to drop the Connection: Header from the subrequest */
6862 if (con->request.http_method == HTTP_METHOD_HEAD) {
6863 chunkqueue_reset(con->write_queue);
6866 http_response_write_header(srv, con);
6872 static int connection_handle_write(server *srv, connection *con) {
6873 - switch(network_write_chunkqueue(srv, con, con->write_queue)) {
6875 + switch(network_write_chunkqueue(srv, con, con->write_queue)) {
6876 + case NETWORK_STATUS_SUCCESS:
6877 if (con->file_finished) {
6878 connection_set_state(srv, con, CON_STATE_RESPONSE_END);
6879 joblist_append(srv, con);
6882 - case -1: /* error on our side */
6883 + case NETWORK_STATUS_FATAL_ERROR: /* error on our side */
6884 log_error_write(srv, __FILE__, __LINE__, "sd",
6885 "connection closed: write failed on fd", con->fd);
6886 connection_set_state(srv, con, CON_STATE_ERROR);
6887 joblist_append(srv, con);
6889 - case -2: /* remote close */
6890 + case NETWORK_STATUS_CONNECTION_CLOSE: /* remote close */
6891 connection_set_state(srv, con, CON_STATE_ERROR);
6892 joblist_append(srv, con);
6895 + case NETWORK_STATUS_WAIT_FOR_EVENT:
6896 con->is_writable = 0;
6899 /* not finished yet -> WRITE */
6901 + case NETWORK_STATUS_INTERRUPTED:
6902 + con->is_writable = 1;
6904 + case NETWORK_STATUS_UNSET:
6914 connection *connection_init(server *srv) {
6920 con = calloc(1, sizeof(*con));
6926 @@ -573,32 +469,32 @@
6929 con->x = buffer_init();
6933 CLEAN(request.request_line);
6934 CLEAN(request.request);
6935 CLEAN(request.pathinfo);
6938 CLEAN(request.orig_uri);
6942 CLEAN(uri.authority);
6944 CLEAN(uri.path_raw);
6948 CLEAN(physical.doc_root);
6949 CLEAN(physical.path);
6950 CLEAN(physical.basedir);
6951 CLEAN(physical.rel_path);
6952 CLEAN(physical.etag);
6953 CLEAN(parse_request);
6958 CLEAN(error_handler);
6959 CLEAN(dst_addr_buf);
6963 con->write_queue = chunkqueue_init();
6964 con->read_queue = chunkqueue_init();
6965 @@ -608,26 +504,26 @@
6966 con->request.headers = array_init();
6967 con->response.headers = array_init();
6968 con->environment = array_init();
6971 /* init plugin specific connection structures */
6974 con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *));
6977 con->cond_cache = calloc(srv->config_context->used, sizeof(cond_cache_t));
6978 config_setup_connection(srv, con);
6984 void connections_free(server *srv) {
6985 connections *conns = srv->conns;
6990 for (i = 0; i < conns->size; i++) {
6991 connection *con = conns->ptr[i];
6994 connection_reset(srv, con);
6997 chunkqueue_free(con->write_queue);
6998 chunkqueue_free(con->read_queue);
6999 chunkqueue_free(con->request_content_queue);
7000 @@ -637,27 +533,27 @@
7003 buffer_free(con->x);
7007 CLEAN(request.request_line);
7008 CLEAN(request.request);
7009 CLEAN(request.pathinfo);
7012 CLEAN(request.orig_uri);
7016 CLEAN(uri.authority);
7018 CLEAN(uri.path_raw);
7022 CLEAN(physical.doc_root);
7023 CLEAN(physical.path);
7024 CLEAN(physical.basedir);
7025 CLEAN(physical.etag);
7026 CLEAN(physical.rel_path);
7027 CLEAN(parse_request);
7032 CLEAN(error_handler);
7033 @@ -665,97 +561,97 @@
7035 free(con->plugin_ctx);
7036 free(con->cond_cache);
7047 int connection_reset(server *srv, connection *con) {
7051 plugins_call_connection_reset(srv, con);
7054 con->is_readable = 1;
7055 con->is_writable = 1;
7056 con->http_status = 0;
7057 con->file_finished = 0;
7058 con->file_started = 0;
7059 con->got_response = 0;
7062 con->parsed_response = 0;
7065 con->bytes_written = 0;
7066 con->bytes_written_cur_second = 0;
7067 con->bytes_read = 0;
7068 con->bytes_header = 0;
7069 con->loops_per_request = 0;
7072 con->request.http_method = HTTP_METHOD_UNSET;
7073 con->request.http_version = HTTP_VERSION_UNSET;
7076 con->request.http_if_modified_since = NULL;
7077 con->request.http_if_none_match = NULL;
7080 con->response.keep_alive = 0;
7081 con->response.content_length = -1;
7082 con->response.transfer_encoding = 0;
7089 if (con->x) buffer_reset(con->x);
7093 CLEAN(request.request_line);
7094 CLEAN(request.pathinfo);
7095 CLEAN(request.request);
7098 CLEAN(request.orig_uri);
7102 CLEAN(uri.authority);
7104 CLEAN(uri.path_raw);
7108 CLEAN(physical.doc_root);
7109 CLEAN(physical.path);
7110 CLEAN(physical.basedir);
7111 CLEAN(physical.rel_path);
7112 CLEAN(physical.etag);
7115 CLEAN(parse_request);
7120 CLEAN(error_handler);
7126 - if (con->x) con->x->used = 0;
7128 + if (con->x) con->x->used = 0;
7134 con->request.x = NULL;
7139 CLEAN(http_content_type);
7141 con->request.content_length = 0;
7144 array_reset(con->request.headers);
7145 array_reset(con->response.headers);
7146 array_reset(con->environment);
7149 chunkqueue_reset(con->write_queue);
7150 chunkqueue_reset(con->request_content_queue);
7152 - /* the plugins should cleanup themself */
7153 + /* the plugins should cleanup themself */
7154 for (i = 0; i < srv->plugins.used; i++) {
7155 plugin *p = ((plugin **)(srv->plugins.ptr))[i];
7156 plugin_data *pd = p->data;
7159 con->plugin_ctx[pd->id] = NULL;
7163 #if COND_RESULT_UNSET
7164 for (i = srv->config_context->used - 1; i >= 0; i --) {
7165 con->cond_cache[i].result = COND_RESULT_UNSET;
7166 @@ -777,56 +673,56 @@
7168 memset(con->cond_cache, 0, sizeof(cond_cache_t) * srv->config_context->used);
7172 con->header_len = 0;
7173 con->in_error_handler = 0;
7176 config_setup_connection(srv, con);
7184 - * search for \r\n\r\n
7187 + * search for \r\n\r\n
7189 * this is a special 32bit version which is using a sliding window for
7190 - * the comparisions
7192 + * the comparisions
7201 * cmpbuf: abcd != cdef
7202 * cmpbuf: bcde != cdef
7203 * cmpbuf: cdef == cdef -> return &c
7205 - * cmpbuf and rnrn are treated as 32bit uint and bit-ops are used to
7207 + * cmpbuf and rnrn are treated as 32bit uint and bit-ops are used to
7208 * maintain cmpbuf and rnrn
7213 char *buffer_search_rnrn(buffer *b) {
7214 uint32_t cmpbuf, rnrn;
7219 if (b->used < 4) return NULL;
7222 rnrn = ('\r' << 24) | ('\n' << 16) |
7223 ('\r' << 8) | ('\n' << 0);
7226 cmpbuf = (b->ptr[0] << 24) | (b->ptr[1] << 16) |
7227 (b->ptr[2] << 8) | (b->ptr[3] << 0);
7231 for (i = 0; i < b->used - 4; i++) {
7232 if (cmpbuf == rnrn) return cp - 4;
7235 cmpbuf = (cmpbuf << 8 | *(cp++)) & 0xffffffff;
7242 @@ -840,22 +736,25 @@
7244 chunkqueue *cq = con->read_queue;
7245 chunkqueue *dst_cq = con->request_content_queue;
7248 if (con->is_readable) {
7249 con->read_idle_ts = srv->cur_ts;
7252 switch(connection_handle_read(srv, con)) {
7254 + case NETWORK_STATUS_FATAL_ERROR:
7257 + case NETWORK_STATUS_CONNECTION_CLOSE:
7258 /* remote side closed the connection
7259 * if we still have content, handle it, if not leave here */
7261 if (cq->first == cq->last &&
7262 - cq->first->mem->used == 0) {
7263 + (NULL == cq->first ||
7264 + cq->first->mem->used == 0)) {
7266 /* conn-closed, leave here */
7267 connection_set_state(srv, con, CON_STATE_ERROR);
7273 @@ -891,14 +790,14 @@
7274 /* the last node was empty */
7275 if (c->next == NULL) {
7287 /* nothing to handle */
7288 if (cq->first == NULL) return 0;
7290 @@ -906,25 +805,26 @@
7291 case CON_STATE_READ:
7292 /* prepare con->request.request */
7296 /* check if we need the full package */
7297 if (con->request.request->used == 0) {
7301 b.ptr = c->mem->ptr + c->offset;
7302 b.used = c->mem->used - c->offset;
7305 if (NULL != (h_term = buffer_search_rnrn(&b))) {
7307 * - copy everything incl. the terminator to request.request
7310 - buffer_copy_string_len(con->request.request,
7313 + buffer_copy_string_len(con->request.request,
7315 h_term - b.ptr + 4);
7318 /* the buffer has been read up to the terminator */
7319 c->offset += h_term - b.ptr + 4;
7322 /* not found, copy everything */
7323 buffer_copy_string_len(con->request.request, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
7324 @@ -932,14 +832,14 @@
7327 /* have to take care of overlapping header terminators */
7330 size_t l = con->request.request->used - 2;
7331 char *s = con->request.request->ptr;
7335 b.ptr = c->mem->ptr + c->offset;
7336 b.used = c->mem->used - c->offset;
7339 if (con->request.request->used - 1 > 3 &&
7343 c->mem->ptr[0] == '\n') {
7344 buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 1);
7348 h_term = con->request.request->ptr;
7349 } else if (con->request.request->used - 1 > 2 &&
7352 c->mem->ptr[1] == '\n') {
7353 buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 2);
7357 h_term = con->request.request->ptr;
7358 } else if (con->request.request->used - 1 > 1 &&
7360 @@ -968,17 +868,17 @@
7361 c->mem->ptr[2] == '\n') {
7362 buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 3);
7366 h_term = con->request.request->ptr;
7367 } else if (NULL != (h_term = buffer_search_string_len(&b, "\r\n\r\n", 4))) {
7369 * - copy everything incl. the terminator to request.request
7372 - buffer_append_string_len(con->request.request,
7373 - c->mem->ptr + c->offset,
7375 + buffer_append_string_len(con->request.request,
7376 + c->mem->ptr + c->offset,
7377 c->offset + h_term - b.ptr + 4);
7380 /* the buffer has been read up to the terminator */
7381 c->offset += h_term - b.ptr + 4;
7383 @@ -999,16 +899,16 @@
7384 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
7387 - case CON_STATE_READ_POST:
7388 + case CON_STATE_READ_POST:
7389 for (c = cq->first; c && (dst_cq->bytes_in != (off_t)con->request.content_length); c = c->next) {
7390 off_t weWant, weHave, toRead;
7393 weWant = con->request.content_length - dst_cq->bytes_in;
7396 assert(c->mem->used);
7399 weHave = c->mem->used - c->offset - 1;
7402 toRead = weHave > weWant ? weWant : weHave;
7404 /* the new way, copy everything into a chunkqueue whcih might use tempfiles */
7405 @@ -1017,13 +917,13 @@
7406 /* copy everything to max 1Mb sized tempfiles */
7409 - * if the last chunk is
7410 + * if the last chunk is
7411 * - smaller than 1Mb (size < 1Mb)
7412 * - not read yet (offset == 0)
7415 - * -> create a new chunk
7417 + * -> create a new chunk
7422 @@ -1056,14 +956,14 @@
7423 /* we have a chunk, let's write to it */
7425 if (dst_c->file.fd == -1) {
7426 - /* we don't have file to write to,
7427 + /* we don't have file to write to,
7428 * EACCES might be one reason.
7430 * Instead of sending 500 we send 413 and say the request is too large
7433 log_error_write(srv, __FILE__, __LINE__, "sbs",
7434 - "denying upload as opening to temp-file for upload failed:",
7435 + "denying upload as opening to temp-file for upload failed:",
7436 dst_c->file.name, strerror(errno));
7438 con->http_status = 413; /* Request-Entity too large */
7439 @@ -1074,15 +974,15 @@
7442 if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
7443 - /* write failed for some reason ... disk full ? */
7444 + /* write failed for some reason ... disk full ? */
7445 log_error_write(srv, __FILE__, __LINE__, "sbs",
7446 - "denying upload as writing to file failed:",
7447 + "denying upload as writing to file failed:",
7448 dst_c->file.name, strerror(errno));
7451 con->http_status = 413; /* Request-Entity too large */
7452 con->keep_alive = 0;
7453 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
7456 close(dst_c->file.fd);
7457 dst_c->file.fd = -1;
7459 @@ -1090,7 +990,7 @@
7462 dst_c->file.length += toRead;
7465 if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) {
7466 /* we read everything, close the chunk */
7467 close(dst_c->file.fd);
7468 @@ -1102,7 +1002,7 @@
7469 b = chunkqueue_get_append_buffer(dst_cq);
7470 buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead);
7474 c->offset += toRead;
7475 dst_cq->bytes_in += toRead;
7477 @@ -1111,7 +1011,7 @@
7478 if (dst_cq->bytes_in == (off_t)con->request.content_length) {
7479 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
7486 @@ -1123,9 +1023,9 @@
7487 handler_t connection_handle_fdevent(void *s, void *context, int revents) {
7488 server *srv = (server *)s;
7489 connection *con = context;
7492 joblist_append(srv, con);
7495 if (revents & FDEVENT_IN) {
7496 con->is_readable = 1;
7498 @@ -1136,19 +1036,19 @@
7499 con->is_writable = 1;
7500 /* we don't need the event twice */
7506 if (revents & ~(FDEVENT_IN | FDEVENT_OUT)) {
7507 /* looks like an error */
7510 /* FIXME: revents = 0x19 still means that we should read from the queue */
7511 if (revents & FDEVENT_HUP) {
7512 if (con->state == CON_STATE_CLOSE) {
7513 con->close_timeout_ts = 0;
7515 /* sigio reports the wrong event here
7517 - * there was no HUP at all
7519 + * there was no HUP at all
7521 #ifdef USE_LINUX_SIGIO
7522 if (srv->ev->in_sigio == 1) {
7523 @@ -1160,32 +1060,39 @@
7525 connection_set_state(srv, con, CON_STATE_ERROR);
7530 } else if (revents & FDEVENT_ERR) {
7531 #ifndef USE_LINUX_SIGIO
7532 log_error_write(srv, __FILE__, __LINE__, "sd",
7533 "connection closed: poll() -> ERR", con->fd);
7536 connection_set_state(srv, con, CON_STATE_ERROR);
7538 log_error_write(srv, __FILE__, __LINE__, "sd",
7539 "connection closed: poll() -> ???", revents);
7545 if (con->state == CON_STATE_READ ||
7546 con->state == CON_STATE_READ_POST) {
7547 connection_handle_read_state(srv, con);
7549 + * if SSL_read() is not readin in the full packet we won't get
7550 + * a fdevent as the low-level has already fetched everything.
7552 + * we have to call the state-engine to read the rest of the packet
7554 + if (con->is_readable) joblist_append(srv, con);
7558 if (con->state == CON_STATE_WRITE &&
7559 !chunkqueue_is_empty(con->write_queue) &&
7563 if (-1 == connection_handle_write(srv, con)) {
7564 connection_set_state(srv, con, CON_STATE_ERROR);
7567 log_error_write(srv, __FILE__, __LINE__, "ds",
7569 "handle write failed.");
7570 @@ -1193,30 +1100,30 @@
7571 con->write_request_ts = srv->cur_ts;
7576 if (con->state == CON_STATE_CLOSE) {
7577 /* flush the read buffers */
7581 if (ioctl(con->fd, FIONREAD, &b)) {
7582 log_error_write(srv, __FILE__, __LINE__, "ss",
7583 "ioctl() failed", strerror(errno));
7589 log_error_write(srv, __FILE__, __LINE__, "sdd",
7590 "CLOSE-read()", con->fd, b);
7594 read(con->fd, buf, sizeof(buf));
7596 /* nothing to read */
7599 con->close_timeout_ts = 0;
7604 return HANDLER_FINISHED;
7607 @@ -1229,63 +1136,68 @@
7610 /* accept it and register the fd */
7613 cnt_len = sizeof(cnt_addr);
7615 if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
7617 + errno = WSAGetLastError();
7619 if ((errno != EAGAIN) &&
7620 + (errno != EWOULDBLOCK) &&
7622 - log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
7623 + log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), srv_socket->fd);
7633 /* ok, we have the connection, register it */
7635 log_error_write(srv, __FILE__, __LINE__, "sd",
7641 con = connections_get_new_connection(srv);
7647 gettimeofday(&(con->start_tv), NULL);
7650 fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
7653 connection_set_state(srv, con, CON_STATE_REQUEST_START);
7656 con->connection_start = srv->cur_ts;
7657 con->dst_addr = cnt_addr;
7658 buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
7659 con->srv_socket = srv_socket;
7662 if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) {
7663 log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
7664 + connection_close(srv, con);
7668 /* connect FD to SSL */
7669 if (srv_socket->is_ssl) {
7670 if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
7671 - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
7672 + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
7673 ERR_error_string(ERR_get_error(), NULL));
7675 + connection_close(srv, con);
7680 SSL_set_accept_state(con->ssl);
7684 if (1 != (SSL_set_fd(con->ssl, cnt))) {
7685 - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
7686 + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
7687 ERR_error_string(ERR_get_error(), NULL));
7688 + connection_close(srv, con);
7692 @@ -1300,10 +1212,10 @@
7694 server_socket *srv_sock = con->srv_socket;
7698 if (srv->srvconf.log_state_handling) {
7699 - log_error_write(srv, __FILE__, __LINE__, "sds",
7701 + log_error_write(srv, __FILE__, __LINE__, "sds",
7704 connection_get_state(con->state));
7706 @@ -1311,91 +1223,91 @@
7708 size_t ostate = con->state;
7712 switch (con->state) {
7713 case CON_STATE_REQUEST_START: /* transient */
7714 if (srv->srvconf.log_state_handling) {
7715 - log_error_write(srv, __FILE__, __LINE__, "sds",
7716 + log_error_write(srv, __FILE__, __LINE__, "sds",
7717 "state for fd", con->fd, connection_get_state(con->state));
7721 con->request_start = srv->cur_ts;
7722 con->read_idle_ts = srv->cur_ts;
7725 con->request_count++;
7726 con->loops_per_request = 0;
7729 connection_set_state(srv, con, CON_STATE_READ);
7733 case CON_STATE_REQUEST_END: /* transient */
7734 if (srv->srvconf.log_state_handling) {
7735 - log_error_write(srv, __FILE__, __LINE__, "sds",
7736 + log_error_write(srv, __FILE__, __LINE__, "sds",
7737 "state for fd", con->fd, connection_get_state(con->state));
7741 if (http_request_parse(srv, con)) {
7742 /* we have to read some data from the POST request */
7745 connection_set_state(srv, con, CON_STATE_READ_POST);
7751 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
7755 case CON_STATE_HANDLE_REQUEST:
7758 * the request is parsed
7761 * decided what to do with the request
7771 if (srv->srvconf.log_state_handling) {
7772 - log_error_write(srv, __FILE__, __LINE__, "sds",
7773 + log_error_write(srv, __FILE__, __LINE__, "sds",
7774 "state for fd", con->fd, connection_get_state(con->state));
7778 switch (r = http_response_prepare(srv, con)) {
7779 case HANDLER_FINISHED:
7780 if (con->http_status == 404 ||
7781 con->http_status == 403) {
7782 /* 404 error-handler */
7784 - if (con->in_error_handler == 0 &&
7786 + if (con->in_error_handler == 0 &&
7787 (!buffer_is_empty(con->conf.error_handler) ||
7788 !buffer_is_empty(con->error_handler))) {
7789 /* call error-handler */
7792 con->error_handler_saved_status = con->http_status;
7793 con->http_status = 0;
7796 if (buffer_is_empty(con->error_handler)) {
7797 buffer_copy_string_buffer(con->request.uri, con->conf.error_handler);
7799 buffer_copy_string_buffer(con->request.uri, con->error_handler);
7801 buffer_reset(con->physical.path);
7804 con->in_error_handler = 1;
7807 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
7812 } else if (con->in_error_handler) {
7813 /* error-handler is a 404 */
7816 /* continue as normal, status is the same */
7817 - log_error_write(srv, __FILE__, __LINE__, "sb",
7818 + log_error_write(srv, __FILE__, __LINE__, "sb",
7819 "Warning: Either the error-handler returned status 404 or the error-handler itself was not found:", con->request.uri);
7820 - log_error_write(srv, __FILE__, __LINE__, "sd",
7821 + log_error_write(srv, __FILE__, __LINE__, "sd",
7822 "returning the original status", con->error_handler_saved_status);
7823 - log_error_write(srv, __FILE__, __LINE__, "s",
7824 + log_error_write(srv, __FILE__, __LINE__, "s",
7825 "If this is a rails app: check your production.log");
7826 con->http_status = con->error_handler_saved_status;
7828 @@ -1403,26 +1315,26 @@
7829 /* error-handler is back and has generated content */
7830 /* if Status: was set, take it otherwise use 200 */
7834 if (con->http_status == 0) con->http_status = 200;
7837 /* we have something to send, go on */
7838 connection_set_state(srv, con, CON_STATE_RESPONSE_START);
7840 case HANDLER_WAIT_FOR_FD:
7844 fdwaitqueue_append(srv, con);
7847 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
7851 case HANDLER_COMEBACK:
7853 case HANDLER_WAIT_FOR_EVENT:
7854 /* come back here */
7855 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
7860 /* something went wrong */
7861 @@ -1432,44 +1344,44 @@
7862 log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r);
7868 case CON_STATE_RESPONSE_START:
7871 * the decision is done
7872 * - create the HTTP-Response-Header
7878 if (srv->srvconf.log_state_handling) {
7879 - log_error_write(srv, __FILE__, __LINE__, "sds",
7880 + log_error_write(srv, __FILE__, __LINE__, "sds",
7881 "state for fd", con->fd, connection_get_state(con->state));
7885 if (-1 == connection_handle_write_prepare(srv, con)) {
7886 connection_set_state(srv, con, CON_STATE_ERROR);
7893 connection_set_state(srv, con, CON_STATE_WRITE);
7895 case CON_STATE_RESPONSE_END: /* transient */
7896 /* log the request */
7899 if (srv->srvconf.log_state_handling) {
7900 - log_error_write(srv, __FILE__, __LINE__, "sds",
7901 + log_error_write(srv, __FILE__, __LINE__, "sds",
7902 "state for fd", con->fd, connection_get_state(con->state));
7906 plugins_call_handle_request_done(srv, con);
7912 if (con->keep_alive) {
7913 connection_set_state(srv, con, CON_STATE_REQUEST_START);
7918 con->request_start = srv->cur_ts;
7919 con->read_idle_ts = srv->cur_ts;
7921 @@ -1482,7 +1394,7 @@
7922 log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
7928 if (srv_sock->is_ssl) {
7929 switch (SSL_shutdown(con->ssl)) {
7930 @@ -1490,44 +1402,44 @@
7934 - /* wait for fd-event
7936 + /* wait for fd-event
7938 * FIXME: wait for fdevent and call SSL_shutdown again
7946 - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
7947 + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
7948 ERR_error_string(ERR_get_error(), NULL));
7952 connection_close(srv, con);
7959 connection_reset(srv, con);
7963 case CON_STATE_CONNECT:
7964 if (srv->srvconf.log_state_handling) {
7965 - log_error_write(srv, __FILE__, __LINE__, "sds",
7966 + log_error_write(srv, __FILE__, __LINE__, "sds",
7967 "state for fd", con->fd, connection_get_state(con->state));
7971 chunkqueue_reset(con->read_queue);
7974 con->request_count = 0;
7978 case CON_STATE_CLOSE:
7979 if (srv->srvconf.log_state_handling) {
7980 - log_error_write(srv, __FILE__, __LINE__, "sds",
7981 + log_error_write(srv, __FILE__, __LINE__, "sds",
7982 "state for fd", con->fd, connection_get_state(con->state));
7986 if (con->keep_alive) {
7987 if (ioctl(con->fd, FIONREAD, &b)) {
7988 log_error_write(srv, __FILE__, __LINE__, "ss",
7989 @@ -1537,43 +1449,43 @@
7991 log_error_write(srv, __FILE__, __LINE__, "sdd",
7992 "CLOSE-read()", con->fd, b);
7996 read(con->fd, buf, sizeof(buf));
7998 /* nothing to read */
8001 con->close_timeout_ts = 0;
8004 con->close_timeout_ts = 0;
8008 if (srv->cur_ts - con->close_timeout_ts > 1) {
8009 connection_close(srv, con);
8012 if (srv->srvconf.log_state_handling) {
8013 - log_error_write(srv, __FILE__, __LINE__, "sd",
8014 + log_error_write(srv, __FILE__, __LINE__, "sd",
8015 "connection closed for fd", con->fd);
8021 case CON_STATE_READ_POST:
8022 case CON_STATE_READ:
8023 if (srv->srvconf.log_state_handling) {
8024 - log_error_write(srv, __FILE__, __LINE__, "sds",
8025 + log_error_write(srv, __FILE__, __LINE__, "sds",
8026 "state for fd", con->fd, connection_get_state(con->state));
8030 connection_handle_read_state(srv, con);
8032 case CON_STATE_WRITE:
8033 if (srv->srvconf.log_state_handling) {
8034 - log_error_write(srv, __FILE__, __LINE__, "sds",
8035 + log_error_write(srv, __FILE__, __LINE__, "sds",
8036 "state for fd", con->fd, connection_get_state(con->state));
8040 /* only try to write if we have something in the queue */
8041 if (!chunkqueue_is_empty(con->write_queue)) {
8043 @@ -1593,10 +1505,10 @@
8044 con->write_request_ts = srv->cur_ts;
8050 case CON_STATE_ERROR: /* transient */
8053 /* even if the connection was drop we still have to write it to the access log */
8054 if (con->http_status) {
8055 plugins_call_handle_request_done(srv, con);
8056 @@ -1612,19 +1524,19 @@
8057 SSL_shutdown(con->ssl);
8060 - log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
8061 - SSL_get_error(con->ssl, ret),
8062 + log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
8063 + SSL_get_error(con->ssl, ret),
8064 ERR_error_string(ERR_get_error(), NULL));
8074 - log_error_write(srv, __FILE__, __LINE__, "sd",
8075 - "emergency exit: direct",
8076 + log_error_write(srv, __FILE__, __LINE__, "sd",
8077 + "emergency exit: direct",
8081 @@ -1639,35 +1551,35 @@
8087 connection_reset(srv, con);
8090 /* close the connection */
8091 if ((con->keep_alive == 1) &&
8092 (0 == shutdown(con->fd, SHUT_WR))) {
8093 con->close_timeout_ts = srv->cur_ts;
8094 connection_set_state(srv, con, CON_STATE_CLOSE);
8097 if (srv->srvconf.log_state_handling) {
8098 - log_error_write(srv, __FILE__, __LINE__, "sd",
8099 + log_error_write(srv, __FILE__, __LINE__, "sd",
8100 "shutdown for fd", con->fd);
8103 connection_close(srv, con);
8107 con->keep_alive = 0;
8115 - log_error_write(srv, __FILE__, __LINE__, "sdd",
8116 + log_error_write(srv, __FILE__, __LINE__, "sdd",
8117 "unknown state:", con->fd, con->state);
8126 } else if (ostate == con->state) {
8127 @@ -1676,12 +1588,12 @@
8130 if (srv->srvconf.log_state_handling) {
8131 - log_error_write(srv, __FILE__, __LINE__, "sds",
8133 + log_error_write(srv, __FILE__, __LINE__, "sds",
8136 connection_get_state(con->state));
8140 switch(con->state) {
8141 case CON_STATE_READ_POST:
8142 case CON_STATE_READ:
8143 @@ -1689,11 +1601,11 @@
8144 fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_IN);
8146 case CON_STATE_WRITE:
8147 - /* request write-fdevent only if we really need it
8148 + /* request write-fdevent only if we really need it
8149 * - if we have data to write
8150 - * - if the socket is not writable yet
8151 + * - if the socket is not writable yet
8153 - if (!chunkqueue_is_empty(con->write_queue) &&
8154 + if (!chunkqueue_is_empty(con->write_queue) &&
8155 (con->is_writable == 0) &&
8156 (con->traffic_limit_reached == 0)) {
8157 fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT);
8158 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/crc32.h lighttpd-1.4.12/src/crc32.h
8159 --- lighttpd-1.4.11/src/crc32.h 2005-09-30 20:18:59.000000000 +0300
8160 +++ lighttpd-1.4.12/src/crc32.h 2006-07-11 21:23:40.000000000 +0300
8164 #include <sys/types.h>
8165 +#include <stdlib.h>
8167 #if defined HAVE_STDINT_H
8170 #include <inttypes.h>
8174 +#define uint32_t unsigned __int32
8177 uint32_t generate_crc32c(char *string, size_t length);
8180 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_array.c lighttpd-1.4.12/src/data_array.c
8181 --- lighttpd-1.4.11/src/data_array.c 2005-08-23 17:36:12.000000000 +0300
8182 +++ lighttpd-1.4.12/src/data_array.c 2006-07-11 21:23:40.000000000 +0300
8185 static void data_array_free(data_unset *d) {
8186 data_array *ds = (data_array *)d;
8189 buffer_free(ds->key);
8190 array_free(ds->value);
8196 static void data_array_reset(data_unset *d) {
8197 data_array *ds = (data_array *)d;
8200 /* reused array elements */
8201 buffer_reset(ds->key);
8202 array_reset(ds->value);
8214 data_array *data_array_init(void) {
8218 ds = calloc(1, sizeof(*ds));
8221 ds->key = buffer_init();
8222 ds->value = array_init();
8225 ds->copy = data_array_copy;
8226 ds->free = data_array_free;
8227 ds->reset = data_array_reset;
8228 ds->insert_dup = data_array_insert_dup;
8229 ds->print = data_array_print;
8230 ds->type = TYPE_ARRAY;
8235 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_config.c lighttpd-1.4.12/src/data_config.c
8236 --- lighttpd-1.4.11/src/data_config.c 2005-08-17 12:53:19.000000000 +0300
8237 +++ lighttpd-1.4.12/src/data_config.c 2006-07-11 21:23:39.000000000 +0300
8240 static void data_config_free(data_unset *d) {
8241 data_config *ds = (data_config *)d;
8244 buffer_free(ds->key);
8245 buffer_free(ds->op);
8246 buffer_free(ds->comp_key);
8249 array_free(ds->value);
8250 array_free(ds->childs);
8253 if (ds->string) buffer_free(ds->string);
8255 if (ds->regex) pcre_free(ds->regex);
8256 if (ds->regex_study) pcre_free(ds->regex_study);
8263 static void data_config_reset(data_unset *d) {
8264 data_config *ds = (data_config *)d;
8267 /* reused array elements */
8268 buffer_reset(ds->key);
8269 buffer_reset(ds->comp_key);
8272 static int data_config_insert_dup(data_unset *dst, data_unset *src) {
8283 array *a = (array *)ds->value;
8288 if (0 == ds->context_ndx) {
8289 fprintf(stderr, "config {\n");
8291 @@ -117,22 +117,22 @@
8293 data_config *data_config_init(void) {
8297 ds = calloc(1, sizeof(*ds));
8300 ds->key = buffer_init();
8301 ds->op = buffer_init();
8302 ds->comp_key = buffer_init();
8303 ds->value = array_init();
8304 ds->childs = array_init();
8305 ds->childs->is_weakref = 1;
8308 ds->copy = data_config_copy;
8309 ds->free = data_config_free;
8310 ds->reset = data_config_reset;
8311 ds->insert_dup = data_config_insert_dup;
8312 ds->print = data_config_print;
8313 ds->type = TYPE_CONFIG;
8318 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_count.c lighttpd-1.4.12/src/data_count.c
8319 --- lighttpd-1.4.11/src/data_count.c 2005-08-23 17:36:12.000000000 +0300
8320 +++ lighttpd-1.4.12/src/data_count.c 2006-07-11 21:23:40.000000000 +0300
8323 static void data_count_free(data_unset *d) {
8324 data_count *ds = (data_count *)d;
8327 buffer_free(ds->key);
8333 static void data_count_reset(data_unset *d) {
8334 data_count *ds = (data_count *)d;
8337 buffer_reset(ds->key);
8343 static int data_count_insert_dup(data_unset *dst, data_unset *src) {
8344 data_count *ds_dst = (data_count *)dst;
8345 data_count *ds_src = (data_count *)src;
8348 ds_dst->count += ds_src->count;
8357 static void data_count_print(const data_unset *d, int depth) {
8358 data_count *ds = (data_count *)d;
8362 fprintf(stderr, "count(%d)", ds->count);
8366 data_count *data_count_init(void) {
8370 ds = calloc(1, sizeof(*ds));
8373 ds->key = buffer_init();
8377 ds->copy = data_count_copy;
8378 ds->free = data_count_free;
8379 ds->reset = data_count_reset;
8380 ds->insert_dup = data_count_insert_dup;
8381 ds->print = data_count_print;
8382 ds->type = TYPE_COUNT;
8387 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_fastcgi.c lighttpd-1.4.12/src/data_fastcgi.c
8388 --- lighttpd-1.4.11/src/data_fastcgi.c 2005-08-23 17:36:12.000000000 +0300
8389 +++ lighttpd-1.4.12/src/data_fastcgi.c 2006-07-11 21:23:40.000000000 +0300
8392 static void data_fastcgi_free(data_unset *d) {
8393 data_fastcgi *ds = (data_fastcgi *)d;
8396 buffer_free(ds->key);
8397 buffer_free(ds->host);
8403 static void data_fastcgi_reset(data_unset *d) {
8404 data_fastcgi *ds = (data_fastcgi *)d;
8407 buffer_reset(ds->key);
8408 buffer_reset(ds->host);
8413 static int data_fastcgi_insert_dup(data_unset *dst, data_unset *src) {
8422 static void data_fastcgi_print(const data_unset *d, int depth) {
8423 data_fastcgi *ds = (data_fastcgi *)d;
8427 fprintf(stderr, "fastcgi(%s)", ds->host->ptr);
8431 data_fastcgi *data_fastcgi_init(void) {
8435 ds = calloc(1, sizeof(*ds));
8438 ds->key = buffer_init();
8439 ds->host = buffer_init();
8441 ds->is_disabled = 0;
8444 ds->copy = data_fastcgi_copy;
8445 ds->free = data_fastcgi_free;
8446 ds->reset = data_fastcgi_reset;
8447 ds->insert_dup = data_fastcgi_insert_dup;
8448 ds->print = data_fastcgi_print;
8449 ds->type = TYPE_FASTCGI;
8454 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_integer.c lighttpd-1.4.12/src/data_integer.c
8455 --- lighttpd-1.4.11/src/data_integer.c 2005-08-23 17:36:12.000000000 +0300
8456 +++ lighttpd-1.4.12/src/data_integer.c 2006-07-11 21:23:39.000000000 +0300
8459 static void data_integer_free(data_unset *d) {
8460 data_integer *ds = (data_integer *)d;
8463 buffer_free(ds->key);
8469 static void data_integer_reset(data_unset *d) {
8470 data_integer *ds = (data_integer *)d;
8473 /* reused integer elements */
8474 buffer_reset(ds->key);
8478 static int data_integer_insert_dup(data_unset *dst, data_unset *src) {
8490 data_integer *data_integer_init(void) {
8494 ds = calloc(1, sizeof(*ds));
8497 ds->key = buffer_init();
8501 ds->copy = data_integer_copy;
8502 ds->free = data_integer_free;
8503 ds->reset = data_integer_reset;
8504 ds->insert_dup = data_integer_insert_dup;
8505 ds->print = data_integer_print;
8506 ds->type = TYPE_INTEGER;
8511 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/data_string.c lighttpd-1.4.12/src/data_string.c
8512 --- lighttpd-1.4.11/src/data_string.c 2005-08-23 17:36:12.000000000 +0300
8513 +++ lighttpd-1.4.12/src/data_string.c 2006-07-11 21:23:40.000000000 +0300
8516 static void data_string_free(data_unset *d) {
8517 data_string *ds = (data_string *)d;
8520 buffer_free(ds->key);
8521 buffer_free(ds->value);
8527 static void data_string_reset(data_unset *d) {
8528 data_string *ds = (data_string *)d;
8531 /* reused array elements */
8532 buffer_reset(ds->key);
8533 buffer_reset(ds->value);
8535 static int data_string_insert_dup(data_unset *dst, data_unset *src) {
8536 data_string *ds_dst = (data_string *)dst;
8537 data_string *ds_src = (data_string *)src;
8540 if (ds_dst->value->used) {
8541 buffer_append_string(ds_dst->value, ", ");
8542 buffer_append_string_buffer(ds_dst->value, ds_src->value);
8544 buffer_copy_string_buffer(ds_dst->value, ds_src->value);
8554 static int data_response_insert_dup(data_unset *dst, data_unset *src) {
8555 data_string *ds_dst = (data_string *)dst;
8556 data_string *ds_src = (data_string *)src;
8559 if (ds_dst->value->used) {
8560 buffer_append_string(ds_dst->value, "\r\n");
8561 buffer_append_string_buffer(ds_dst->value, ds_dst->key);
8564 buffer_copy_string_buffer(ds_dst->value, ds_src->value);
8576 data_string *data_string_init(void) {
8580 ds = calloc(1, sizeof(*ds));
8584 ds->key = buffer_init();
8585 ds->value = buffer_init();
8588 ds->copy = data_string_copy;
8589 ds->free = data_string_free;
8590 ds->reset = data_string_reset;
8591 ds->insert_dup = data_string_insert_dup;
8592 ds->print = data_string_print;
8593 ds->type = TYPE_STRING;
8599 data_string *data_response_init(void) {
8603 ds = data_string_init();
8604 ds->insert_dup = data_response_insert_dup;
8609 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/etag.c lighttpd-1.4.12/src/etag.c
8610 --- lighttpd-1.4.11/src/etag.c 2005-08-11 01:26:40.000000000 +0300
8611 +++ lighttpd-1.4.12/src/etag.c 2006-07-11 21:23:40.000000000 +0300
8613 buffer_append_off_t(etag, st->st_size);
8614 buffer_append_string_len(etag, CONST_STR_LEN("-"));
8615 buffer_append_long(etag, st->st_mtime);
8621 int etag_mutate(buffer *mut, buffer *etag) {
8625 for (h=0, i=0; i < etag->used; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
8629 buffer_copy_string_len(mut, CONST_STR_LEN("\""));
8630 buffer_append_long(mut, h);
8631 buffer_append_string_len(mut, CONST_STR_LEN("\""));
8636 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/etag.h lighttpd-1.4.12/src/etag.h
8637 --- lighttpd-1.4.11/src/etag.h 2005-08-11 01:26:40.000000000 +0300
8638 +++ lighttpd-1.4.12/src/etag.h 2006-07-11 21:23:40.000000000 +0300
8641 #include <sys/types.h>
8642 #include <sys/stat.h>
8643 -#include <unistd.h>
8647 int etag_is_equal(buffer *etag, const char *matches);
8648 int etag_create(buffer *etag, struct stat *st);
8649 int etag_mutate(buffer *mut, buffer *etag);
8654 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fastcgi.h lighttpd-1.4.12/src/fastcgi.h
8655 --- lighttpd-1.4.11/src/fastcgi.h 2005-08-11 01:26:40.000000000 +0300
8656 +++ lighttpd-1.4.12/src/fastcgi.h 2006-07-11 21:23:40.000000000 +0300
8662 * Defines for the FastCGI protocol.
8667 - unsigned char type;
8668 + unsigned char type;
8669 unsigned char reserved[7];
8670 } FCGI_UnknownTypeBody;
8672 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent.c lighttpd-1.4.12/src/fdevent.c
8673 --- lighttpd-1.4.11/src/fdevent.c 2005-11-15 10:51:05.000000000 +0200
8674 +++ lighttpd-1.4.12/src/fdevent.c 2006-07-11 21:23:40.000000000 +0300
8677 #include "settings.h"
8679 -#include <unistd.h>
8684 #include "fdevent.h"
8687 +#include "sys-socket.h"
8689 fdevents *fdevent_init(size_t maxfds, fdevent_handler_t type) {
8693 ev = calloc(1, sizeof(*ev));
8694 ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray));
8695 ev->maxfds = maxfds;
8699 case FDEVENT_HANDLER_POLL:
8700 if (0 != fdevent_poll_init(ev)) {
8701 - fprintf(stderr, "%s.%d: event-handler poll failed\n",
8702 + fprintf(stderr, "%s.%d: event-handler poll failed\n",
8703 __FILE__, __LINE__);
8709 case FDEVENT_HANDLER_SELECT:
8710 if (0 != fdevent_select_init(ev)) {
8711 - fprintf(stderr, "%s.%d: event-handler select failed\n",
8712 + fprintf(stderr, "%s.%d: event-handler select failed\n",
8713 __FILE__, __LINE__);
8717 case FDEVENT_HANDLER_LINUX_RTSIG:
8718 if (0 != fdevent_linux_rtsig_init(ev)) {
8719 - fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n",
8720 + fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n",
8721 __FILE__, __LINE__);
8725 case FDEVENT_HANDLER_LINUX_SYSEPOLL:
8726 if (0 != fdevent_linux_sysepoll_init(ev)) {
8727 - fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
8728 + fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
8729 __FILE__, __LINE__);
8733 case FDEVENT_HANDLER_SOLARIS_DEVPOLL:
8734 if (0 != fdevent_solaris_devpoll_init(ev)) {
8735 - fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
8736 + fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
8737 __FILE__, __LINE__);
8741 case FDEVENT_HANDLER_FREEBSD_KQUEUE:
8742 if (0 != fdevent_freebsd_kqueue_init(ev)) {
8743 - fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n",
8744 + fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n",
8745 __FILE__, __LINE__);
8750 - fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n",
8751 + fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n",
8752 __FILE__, __LINE__);
8756 void fdevent_free(fdevents *ev) {
8761 if (ev->free) ev->free(ev);
8764 for (i = 0; i < ev->maxfds; i++) {
8765 if (ev->fdarray[i]) free(ev->fdarray[i]);
8773 int fdevent_reset(fdevents *ev) {
8774 if (ev->reset) return ev->reset(ev);
8780 fdnode *fdnode_init() {
8784 fdn = calloc(1, sizeof(*fdn));
8787 @@ -106,12 +107,12 @@
8789 int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
8793 fdn = fdnode_init();
8794 fdn->handler = handler;
8799 ev->fdarray[fd] = fdn;
8802 @@ -121,31 +122,31 @@
8805 fdn = ev->fdarray[fd];
8811 ev->fdarray[fd] = NULL;
8817 int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) {
8818 int fde = fde_ndx ? *fde_ndx : -1;
8821 if (ev->event_del) fde = ev->event_del(ev, fde, fd);
8824 if (fde_ndx) *fde_ndx = fde;
8830 int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events) {
8831 int fde = fde_ndx ? *fde_ndx : -1;
8834 if (ev->event_add) fde = ev->event_add(ev, fde, fd, events);
8837 if (fde_ndx) *fde_ndx = fde;
8843 @@ -156,38 +157,43 @@
8845 int fdevent_event_get_revent(fdevents *ev, size_t ndx) {
8846 if (ev->event_get_revent == NULL) SEGFAULT();
8849 return ev->event_get_revent(ev, ndx);
8852 int fdevent_event_get_fd(fdevents *ev, size_t ndx) {
8853 if (ev->event_get_fd == NULL) SEGFAULT();
8856 return ev->event_get_fd(ev, ndx);
8859 fdevent_handler fdevent_get_handler(fdevents *ev, int fd) {
8860 if (ev->fdarray[fd] == NULL) SEGFAULT();
8861 if (ev->fdarray[fd]->fd != fd) SEGFAULT();
8864 return ev->fdarray[fd]->handler;
8867 void * fdevent_get_context(fdevents *ev, int fd) {
8868 if (ev->fdarray[fd] == NULL) SEGFAULT();
8869 if (ev->fdarray[fd]->fd != fd) SEGFAULT();
8872 return ev->fdarray[fd]->ctx;
8875 int fdevent_fcntl_set(fdevents *ev, int fd) {
8880 /* close fd on exec (cgi) */
8881 fcntl(fd, F_SETFD, FD_CLOEXEC);
8883 if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
8886 return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
8887 +#elif defined _WIN32
8888 + return ioctlsocket(fd, FIONBIO, &i);
8894 int fdevent_event_next_fdndx(fdevents *ev, int ndx) {
8895 if (ev->event_next_fdndx) return ev->event_next_fdndx(ev, ndx);
8901 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent.h lighttpd-1.4.12/src/fdevent.h
8902 --- lighttpd-1.4.11/src/fdevent.h 2005-09-27 11:26:33.000000000 +0300
8903 +++ lighttpd-1.4.12/src/fdevent.h 2006-07-11 21:23:39.000000000 +0300
8905 # include <sys/epoll.h>
8908 -/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes
8909 +/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes
8910 * under /usr/include/sys/ */
8911 #if defined HAVE_POLL && (defined(HAVE_SYS_POLL_H) || defined(HAVE_POLL_H))
8917 # include <sys/poll.h>
8919 # if defined HAVE_SIGTIMEDWAIT && defined(__linux__)
8921 # include <signal.h>
8926 +# define HAVE_SELECT
8928 #if defined HAVE_SELECT
8931 # include <winsock2.h>
8935 #define FDEVENT_HUP BV(4)
8936 #define FDEVENT_NVAL BV(5)
8938 -typedef enum { FD_EVENT_TYPE_UNSET = -1,
8939 - FD_EVENT_TYPE_CONNECTION,
8940 - FD_EVENT_TYPE_FCGI_CONNECTION,
8941 - FD_EVENT_TYPE_DIRWATCH,
8942 - FD_EVENT_TYPE_CGI_CONNECTION
8943 +typedef enum { FD_EVENT_TYPE_UNSET = -1,
8944 + FD_EVENT_TYPE_CONNECTION,
8945 + FD_EVENT_TYPE_FCGI_CONNECTION,
8946 + FD_EVENT_TYPE_DIRWATCH,
8947 + FD_EVENT_TYPE_CGI_CONNECTION
8950 -typedef enum { FDEVENT_HANDLER_UNSET,
8951 +typedef enum { FDEVENT_HANDLER_UNSET,
8952 FDEVENT_HANDLER_SELECT,
8953 FDEVENT_HANDLER_POLL,
8954 FDEVENT_HANDLER_LINUX_RTSIG,
8958 * a mapping from fd to connection structure
8963 int fd; /**< the fd */
8964 @@ -98,41 +100,41 @@
8975 * array of unused fd's
8980 typedef struct _fdnode {
8981 fdevent_handler handler;
8986 struct _fdnode *prev, *next;
8998 * fd-event handler for select(), poll() and rt-signals on Linux 2.4
9002 typedef struct fdevents {
9003 fdevent_handler_t type;
9010 #ifdef USE_LINUX_SIGIO
9013 @@ -146,21 +148,21 @@
9016 struct pollfd *pollfds;
9027 fd_set select_write;
9028 fd_set select_error;
9031 fd_set select_set_read;
9032 fd_set select_set_write;
9033 fd_set select_set_error;
9038 #ifdef USE_SOLARIS_DEVPOLL
9039 @@ -177,16 +179,16 @@
9041 int (*reset)(struct fdevents *ev);
9042 void (*free)(struct fdevents *ev);
9045 int (*event_add)(struct fdevents *ev, int fde_ndx, int fd, int events);
9046 int (*event_del)(struct fdevents *ev, int fde_ndx, int fd);
9047 int (*event_get_revent)(struct fdevents *ev, size_t ndx);
9048 int (*event_get_fd)(struct fdevents *ev, size_t ndx);
9051 int (*event_next_fdndx)(struct fdevents *ev, int ndx);
9054 int (*poll)(struct fdevents *ev, int timeout_ms);
9057 int (*fcntl_set)(struct fdevents *ev, int fd);
9060 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c lighttpd-1.4.12/src/fdevent_freebsd_kqueue.c
9061 --- lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c 2005-09-01 10:46:24.000000000 +0300
9062 +++ lighttpd-1.4.12/src/fdevent_freebsd_kqueue.c 2006-07-11 21:23:39.000000000 +0300
9064 #include <sys/types.h>
9066 -#include <unistd.h>
9085 ret = kevent(ev->kq_fd,
9094 if (filter == EVFILT_READ) {
9095 bitset_set_bit(ev->kq_bevents, fd);
9098 } else if (e == EVFILT_WRITE) {
9099 events |= FDEVENT_OUT;
9103 e = ev->kq_results[ndx].flags;
9106 @@ -152,10 +151,10 @@
9107 if (-1 == (ev->kq_fd = kqueue())) {
9108 fprintf(stderr, "%s.%d: kqueue failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
9109 __FILE__, __LINE__, strerror(errno));
9120 if (-1 == (ev->kq_fd = kqueue())) {
9121 fprintf(stderr, "%s.%d: kqueue failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
9122 __FILE__, __LINE__, strerror(errno));
9128 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_linux_rtsig.c lighttpd-1.4.12/src/fdevent_linux_rtsig.c
9129 --- lighttpd-1.4.11/src/fdevent_linux_rtsig.c 2005-11-21 19:56:11.000000000 +0200
9130 +++ lighttpd-1.4.12/src/fdevent_linux_rtsig.c 2006-07-11 21:23:40.000000000 +0300
9132 #include <sys/types.h>
9134 -#include <unistd.h>
9139 #include "fdevent.h"
9140 #include "settings.h"
9142 +#include "sys-process.h"
9144 #ifdef USE_LINUX_SIGIO
9145 static void fdevent_linux_rtsig_free(fdevents *ev) {
9148 static int fdevent_linux_rtsig_event_del(fdevents *ev, int fde_ndx, int fd) {
9149 if (fde_ndx < 0) return -1;
9152 if ((size_t)fde_ndx >= ev->used) {
9153 fprintf(stderr, "%s.%d: del! out of range %d %zu\n", __FILE__, __LINE__, fde_ndx, ev->used);
9158 if (ev->pollfds[fde_ndx].fd == fd) {
9162 ev->pollfds[k].fd = -1;
9164 bitset_clear_bit(ev->sigbset, fd);
9167 if (ev->unused.size == 0) {
9168 ev->unused.size = 16;
9169 ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
9171 ev->unused.size += 16;
9172 ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
9176 ev->unused.ptr[ev->unused.used++] = k;
9178 fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[fde_ndx].fd, fd);
9189 static int fdevent_linux_rtsig_event_compress(fdevents *ev) {
9193 if (ev->used == 0) return 0;
9194 if (ev->unused.used != 0) return 0;
9197 for (j = ev->used - 1; j + 1 > 0; j--) {
9198 if (ev->pollfds[j].fd == -1) ev->used--;
9208 if (fde_ndx != -1) {
9209 if (ev->pollfds[fde_ndx].fd == fd) {
9210 ev->pollfds[fde_ndx].events = events;
9215 fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
9220 if (ev->unused.used > 0) {
9221 int k = ev->unused.ptr[--ev->unused.used];
9224 ev->pollfds[k].fd = fd;
9225 ev->pollfds[k].events = events;
9227 bitset_set_bit(ev->sigbset, fd);
9232 if (ev->size == 0) {
9233 @@ -102,12 +102,12 @@
9235 ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
9239 ev->pollfds[ev->used].fd = fd;
9240 ev->pollfds[ev->used].events = events;
9242 bitset_set_bit(ev->sigbset, fd);
9248 @@ -115,20 +115,20 @@
9249 static int fdevent_linux_rtsig_poll(fdevents *ev, int timeout_ms) {
9255 fdevent_linux_rtsig_event_compress(ev);
9262 ts.tv_sec = timeout_ms / 1000;
9263 ts.tv_nsec = (timeout_ms % 1000) * 1000000;
9264 r = sigtimedwait(&(ev->sigset), &(ev->siginfo), &(ts));
9269 if (errno == EAGAIN) return 0;
9272 } else if (r == SIGIO) {
9273 struct sigaction act;
9276 /* re-enable the signal queue */
9277 act.sa_handler = SIG_DFL;
9278 sigaction(ev->signum, &act, NULL);
9282 r = poll(ev->pollfds, ev->used, timeout_ms);
9284 @@ -162,12 +162,12 @@
9285 if (ev->siginfo.si_band == POLLERR) {
9286 fprintf(stderr, "event: %d %02lx %02x %s\n", ev->siginfo.si_fd, ev->siginfo.si_band, errno, strerror(errno));
9291 fprintf(stderr, "+\n");
9296 return ev->siginfo.si_band & 0x3f;
9298 if (ndx >= ev->used) {
9299 @@ -188,13 +188,13 @@
9301 static int fdevent_linux_rtsig_fcntl_set(fdevents *ev, int fd) {
9302 static pid_t pid = 0;
9305 if (pid == 0) pid = getpid();
9308 if (-1 == fcntl(fd, F_SETSIG, ev->signum)) return -1;
9311 if (-1 == fcntl(fd, F_SETOWN, (int) pid)) return -1;
9314 return fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR);
9317 @@ -205,12 +205,12 @@
9323 i = (ndx < 0) ? 0 : ndx + 1;
9324 for (; i < ev->used; i++) {
9325 if (ev->pollfds[i].revents) break;
9332 @@ -219,34 +219,34 @@
9333 ev->type = FDEVENT_HANDLER_LINUX_RTSIG;
9335 ev->x = fdevent_linux_rtsig_##x;
9346 SET(event_next_fdndx);
9349 SET(event_get_revent);
9352 ev->signum = SIGRTMIN + 1;
9355 sigemptyset(&(ev->sigset));
9356 sigaddset(&(ev->sigset), ev->signum);
9357 sigaddset(&(ev->sigset), SIGIO);
9358 if (-1 == sigprocmask(SIG_BLOCK, &(ev->sigset), NULL)) {
9359 fprintf(stderr, "%s.%d: sigprocmask failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
9360 __FILE__, __LINE__, strerror(errno));
9369 ev->sigbset = bitset_init(ev->maxfds);
9375 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_linux_sysepoll.c lighttpd-1.4.12/src/fdevent_linux_sysepoll.c
9376 --- lighttpd-1.4.11/src/fdevent_linux_sysepoll.c 2005-09-30 20:29:27.000000000 +0300
9377 +++ lighttpd-1.4.12/src/fdevent_linux_sysepoll.c 2006-07-11 21:23:40.000000000 +0300
9379 #include <sys/types.h>
9381 -#include <unistd.h>
9386 #include "settings.h"
9389 +#include "sys-files.h"
9391 #ifdef USE_LINUX_EPOLL
9392 static void fdevent_linux_sysepoll_free(fdevents *ev) {
9393 close(ev->epoll_fd);
9396 static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
9397 struct epoll_event ep;
9400 if (fde_ndx < 0) return -1;
9403 memset(&ep, 0, sizeof(ep));
9410 if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
9411 fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
9426 static int fdevent_linux_sysepoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
9427 struct epoll_event ep;
9431 if (fde_ndx == -1) add = 1;
9434 memset(&ep, 0, sizeof(ep));
9440 if (events & FDEVENT_IN) ep.events |= EPOLLIN;
9441 if (events & FDEVENT_OUT) ep.events |= EPOLLOUT;
9449 ep.events |= EPOLLERR | EPOLLHUP /* | EPOLLET */;
9456 if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
9457 fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
9472 static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
9476 e = ev->epoll_events[ndx].events;
9477 if (e & EPOLLIN) events |= FDEVENT_IN;
9478 if (e & EPOLLOUT) events |= FDEVENT_OUT;
9479 if (e & EPOLLERR) events |= FDEVENT_ERR;
9480 if (e & EPOLLHUP) events |= FDEVENT_HUP;
9481 if (e & EPOLLPRI) events |= FDEVENT_PRI;
9489 fprintf(stderr, "%s.%d: %d, %d\n", __FILE__, __LINE__, ndx, ev->epoll_events[ndx].data.fd);
9493 return ev->epoll_events[ndx].data.fd;
9496 static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
9502 i = (ndx < 0) ? 0 : ndx + 1;
9508 @@ -116,17 +117,17 @@
9509 ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
9511 ev->x = fdevent_linux_sysepoll_##x;
9522 SET(event_next_fdndx);
9524 SET(event_get_revent);
9527 if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) {
9528 fprintf(stderr, "%s.%d: epoll_create failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
9529 __FILE__, __LINE__, strerror(errno));
9532 fprintf(stderr, "%s.%d: linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
9533 __FILE__, __LINE__);
9539 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_poll.c lighttpd-1.4.12/src/fdevent_poll.c
9540 --- lighttpd-1.4.11/src/fdevent_poll.c 2005-11-18 13:59:16.000000000 +0200
9541 +++ lighttpd-1.4.12/src/fdevent_poll.c 2006-07-11 21:23:40.000000000 +0300
9543 #include <sys/types.h>
9545 -#include <unistd.h>
9551 static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
9552 if (fde_ndx < 0) return -1;
9555 if ((size_t)fde_ndx >= ev->used) {
9556 fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, fde_ndx, ev->used);
9561 if (ev->pollfds[fde_ndx].fd == fd) {
9565 ev->pollfds[k].fd = -1;
9566 /* ev->pollfds[k].events = 0; */
9567 /* ev->pollfds[k].revents = 0; */
9570 if (ev->unused.size == 0) {
9571 ev->unused.size = 16;
9572 ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
9574 ev->unused.size += 16;
9575 ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
9579 ev->unused.ptr[ev->unused.used++] = k;
9589 static int fdevent_poll_event_compress(fdevents *ev) {
9593 if (ev->used == 0) return 0;
9594 if (ev->unused.used != 0) return 0;
9597 for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--;
9604 static int fdevent_poll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
9608 if (fde_ndx != -1) {
9609 if (ev->pollfds[fde_ndx].fd == fd) {
9610 ev->pollfds[fde_ndx].events = events;
9615 fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
9620 if (ev->unused.used > 0) {
9621 int k = ev->unused.ptr[--ev->unused.used];
9624 ev->pollfds[k].fd = fd;
9625 ev->pollfds[k].events = events;
9630 if (ev->size == 0) {
9633 ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
9637 ev->pollfds[ev->used].fd = fd;
9638 ev->pollfds[ev->used].events = events;
9644 @@ -109,12 +108,12 @@
9646 if (ndx >= ev->used) {
9647 fprintf(stderr, "%s.%d: dying because: event: %zd >= %zd\n", __FILE__, __LINE__, ndx, ev->used);
9657 if (ev->pollfds[ndx].revents & POLLNVAL) {
9658 /* should never happen */
9661 if (poll_r & POLLHUP) r |= FDEVENT_HUP;
9662 if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
9663 if (poll_r & POLLPRI) r |= FDEVENT_PRI;
9666 return ev->pollfds[ndx].revents;
9669 @@ -141,12 +140,12 @@
9671 static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
9675 i = (ndx < 0) ? 0 : ndx + 1;
9676 for (; i < ev->used; i++) {
9677 if (ev->pollfds[i].revents) break;
9684 @@ -154,17 +153,17 @@
9685 ev->type = FDEVENT_HANDLER_POLL;
9687 ev->x = fdevent_poll_##x;
9698 SET(event_next_fdndx);
9700 SET(event_get_revent);
9706 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_select.c lighttpd-1.4.12/src/fdevent_select.c
9707 --- lighttpd-1.4.11/src/fdevent_select.c 2005-08-31 11:12:46.000000000 +0300
9708 +++ lighttpd-1.4.12/src/fdevent_select.c 2006-07-11 21:23:40.000000000 +0300
9710 -#include <sys/time.h>
9711 #include <sys/types.h>
9713 -#include <unistd.h>
9722 #include "fdevent.h"
9723 #include "settings.h"
9726 +#include "sys-socket.h"
9730 static int fdevent_select_reset(fdevents *ev) {
9734 /* we should be protected by max-fds, but you never know */
9736 assert(fd < FD_SETSIZE);
9739 if (events & FDEVENT_IN) {
9740 FD_SET(fd, &(ev->select_set_read));
9742 FD_SET(fd, &(ev->select_set_write));
9744 FD_SET(fd, &(ev->select_set_error));
9747 if (fd > ev->select_max_fd) ev->select_max_fd = fd;
9753 static int fdevent_select_poll(fdevents *ev, int timeout_ms) {
9757 tv.tv_sec = timeout_ms / 1000;
9758 tv.tv_usec = (timeout_ms % 1000) * 1000;
9761 ev->select_read = ev->select_set_read;
9762 ev->select_write = ev->select_set_write;
9763 ev->select_error = ev->select_set_error;
9766 return select(ev->select_max_fd + 1, &(ev->select_read), &(ev->select_write), &(ev->select_error), &tv);
9769 static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) {
9773 if (FD_ISSET(ndx, &(ev->select_read))) {
9774 revents |= FDEVENT_IN;
9777 if (FD_ISSET(ndx, &(ev->select_error))) {
9778 revents |= FDEVENT_ERR;
9787 static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) {
9791 i = (ndx < 0) ? 0 : ndx + 1;
9794 for (; i < ev->select_max_fd + 1; i++) {
9795 if (FD_ISSET(i, &(ev->select_read))) break;
9796 if (FD_ISSET(i, &(ev->select_write))) break;
9797 if (FD_ISSET(i, &(ev->select_error))) break;
9804 @@ -108,17 +111,17 @@
9805 ev->type = FDEVENT_HANDLER_SELECT;
9807 ev->x = fdevent_select_##x;
9818 SET(event_next_fdndx);
9820 SET(event_get_revent);
9826 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/fdevent_solaris_devpoll.c lighttpd-1.4.12/src/fdevent_solaris_devpoll.c
9827 --- lighttpd-1.4.11/src/fdevent_solaris_devpoll.c 2005-09-01 10:45:26.000000000 +0300
9828 +++ lighttpd-1.4.12/src/fdevent_solaris_devpoll.c 2006-07-11 21:23:40.000000000 +0300
9830 #include <sys/types.h>
9832 -#include <unistd.h>
9838 static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd) {
9842 if (fde_ndx < 0) return -1;
9846 pfd.events = POLLREMOVE;
9850 if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
9851 - fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
9852 - __FILE__, __LINE__,
9853 + fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
9854 + __FILE__, __LINE__,
9855 fd, strerror(errno));
9865 static int fdevent_solaris_devpoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
9870 if (fde_ndx == -1) add = 1;
9874 pfd.events = events;
9878 if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
9879 - fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
9880 - __FILE__, __LINE__,
9881 + fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
9882 + __FILE__, __LINE__,
9883 fd, strerror(errno));
9893 static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
9894 struct dvpoll dopoll;
9898 dopoll.dp_timeout = timeout_ms;
9899 dopoll.dp_nfds = ev->maxfds;
9900 dopoll.dp_fds = ev->devpollfds;
9903 ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
9911 static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) {
9917 i = (last_ndx < 0) ? 0 : last_ndx + 1;
9923 @@ -117,20 +116,20 @@
9924 ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
9926 ev->x = fdevent_solaris_devpoll_##x;
9938 SET(event_next_fdndx);
9940 SET(event_get_revent);
9943 ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds);
9946 if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
9947 fprintf(stderr, "%s.%d: opening /dev/poll failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
9948 __FILE__, __LINE__, strerror(errno));
9951 fprintf(stderr, "%s.%d: solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
9952 __FILE__, __LINE__);
9958 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http-header-glue.c lighttpd-1.4.12/src/http-header-glue.c
9959 --- lighttpd-1.4.11/src/http-header-glue.c 2006-02-08 15:31:36.000000000 +0200
9960 +++ lighttpd-1.4.12/src/http-header-glue.c 2006-07-11 21:23:40.000000000 +0300
9962 # ifdef HAVE_STRUCT_SOCKADDR_STORAGE
9963 static size_t get_sa_len(const struct sockaddr *addr) {
9964 switch (addr->sa_family) {
9969 return (sizeof (struct sockaddr_in));
9975 return (sizeof (struct sockaddr_in6));
9980 return (sizeof (struct sockaddr));
9985 # define SA_LEN(addr) (get_sa_len(addr))
9988 int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
9994 if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
9997 buffer_copy_string_len(ds->key, key, keylen);
9998 buffer_copy_string_len(ds->value, value, vallen);
10001 array_insert_unique(con->response.headers, (data_unset *)ds);
10007 int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
10013 /* if there already is a key by this name overwrite the value */
10014 if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) {
10015 buffer_copy_string(ds->value, value);
10022 return response_header_insert(srv, con, key, keylen, value, vallen);
10025 int http_response_redirect_to_directory(server *srv, connection *con) {
10032 if (con->conf.is_ssl) {
10033 buffer_copy_string(o, "https://");
10035 @@ -123,36 +123,36 @@
10037 sock_addr our_addr;
10038 socklen_t our_addr_len;
10041 our_addr_len = sizeof(our_addr);
10044 if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
10045 con->http_status = 500;
10048 log_error_write(srv, __FILE__, __LINE__, "ss",
10049 "can't get sockname", strerror(errno));
10059 /* Lookup name: secondly try to get hostname for bind address */
10060 switch(our_addr.plain.sa_family) {
10063 - if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6),
10064 - SA_LEN((const struct sockaddr *)&our_addr.ipv6),
10065 + if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6),
10066 + SA_LEN((const struct sockaddr *)&our_addr.ipv6),
10067 hbuf, sizeof(hbuf), NULL, 0, 0)) {
10070 char dst[INET6_ADDRSTRLEN];
10073 log_error_write(srv, __FILE__, __LINE__,
10074 "SSSS", "NOTICE: getnameinfo failed: ",
10075 strerror(errno), ", using ip-address instead");
10077 - buffer_append_string(o,
10078 - inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr,
10080 + buffer_append_string(o,
10081 + inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr,
10082 dst, sizeof(dst)));
10084 buffer_append_string(o, hbuf);
10085 @@ -164,7 +164,7 @@
10086 log_error_write(srv, __FILE__, __LINE__,
10087 "SdSS", "NOTICE: gethostbyaddr failed: ",
10088 h_errno, ", using ip-address instead");
10091 buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr));
10093 buffer_append_string(o, he->h_name);
10094 @@ -173,12 +173,12 @@
10096 log_error_write(srv, __FILE__, __LINE__,
10097 "S", "ERROR: unsupported address-type");
10104 - if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) ||
10106 + if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) ||
10107 (con->conf.is_ssl == 1 && srv->srvconf.port == 443))) {
10108 buffer_append_string(o, ":");
10109 buffer_append_long(o, srv->srvconf.port);
10110 @@ -190,41 +190,41 @@
10111 buffer_append_string(o, "?");
10112 buffer_append_string_buffer(o, con->uri.query);
10116 response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(o));
10119 con->http_status = 301;
10120 con->file_finished = 1;
10129 buffer * strftime_cache_get(server *srv, time_t last_mod) {
10134 for (i = 0; i < FILE_CACHE_MAX; i++) {
10135 /* found cache-entry */
10136 if (srv->mtime_cache[i].mtime == last_mod) return srv->mtime_cache[i].str;
10139 /* found empty slot */
10140 if (srv->mtime_cache[i].mtime == 0) break;
10144 if (i == FILE_CACHE_MAX) {
10149 srv->mtime_cache[i].mtime = last_mod;
10150 buffer_prepare_copy(srv->mtime_cache[i].str, 1024);
10151 tm = gmtime(&(srv->mtime_cache[i].mtime));
10152 - srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
10153 + srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
10154 srv->mtime_cache[i].str->size - 1,
10155 "%a, %d %b %Y %H:%M:%S GMT", tm);
10156 srv->mtime_cache[i].str->used++;
10159 return srv->mtime_cache[i].str;
10162 @@ -239,56 +239,60 @@
10163 * request. That is, if no entity tags match, then the server MUST NOT
10164 * return a 304 (Not Modified) response.
10168 /* last-modified handling */
10169 if (con->request.http_if_none_match) {
10170 if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) {
10171 - if (con->request.http_method == HTTP_METHOD_GET ||
10172 + if (con->request.http_method == HTTP_METHOD_GET ||
10173 con->request.http_method == HTTP_METHOD_HEAD) {
10176 /* check if etag + last-modified */
10177 if (con->request.http_if_modified_since) {
10182 if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
10183 used_len = strlen(con->request.http_if_modified_since);
10185 used_len = semicolon - con->request.http_if_modified_since;
10189 if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
10190 con->http_status = 304;
10191 return HANDLER_FINISHED;
10193 +#ifdef HAVE_STRPTIME
10194 char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
10195 + time_t t_header, t_file;
10198 - /* convert to timestamp */
10199 - if (used_len < sizeof(buf)) {
10200 - time_t t_header, t_file;
10203 - strncpy(buf, con->request.http_if_modified_since, used_len);
10204 - buf[used_len] = '\0';
10206 - strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
10207 - t_header = mktime(&tm);
10209 - strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
10210 - t_file = mktime(&tm);
10212 - if (t_file > t_header) {
10213 - con->http_status = 304;
10214 - return HANDLER_FINISHED;
10217 - log_error_write(srv, __FILE__, __LINE__, "ssdd",
10218 - "DEBUG: Last-Modified check failed as the received timestamp was too long:",
10219 + /* check if we can safely copy the string */
10220 + if (used_len >= sizeof(buf)) {
10221 + log_error_write(srv, __FILE__, __LINE__, "ssdd",
10222 + "DEBUG: Last-Modified check failed as the received timestamp was too long:",
10223 con->request.http_if_modified_since, used_len, sizeof(buf) - 1);
10226 con->http_status = 412;
10227 return HANDLER_FINISHED;
10231 + strncpy(buf, con->request.http_if_modified_since, used_len);
10232 + buf[used_len] = '\0';
10234 + strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
10235 + t_header = mktime(&tm);
10237 + strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
10238 + t_file = mktime(&tm);
10240 + if (t_file > t_header) return HANDLER_GO_ON;
10242 + con->http_status = 304;
10243 + return HANDLER_FINISHED;
10245 + return HANDLER_GO_ON;
10249 con->http_status = 304;
10250 @@ -302,16 +306,41 @@
10251 } else if (con->request.http_if_modified_since) {
10256 if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
10257 used_len = strlen(con->request.http_if_modified_since);
10259 used_len = semicolon - con->request.http_if_modified_since;
10263 if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
10264 con->http_status = 304;
10265 return HANDLER_FINISHED;
10267 +#ifdef HAVE_STRPTIME
10268 + char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
10269 + time_t t_header, t_file;
10272 + /* convert to timestamp */
10273 + if (used_len >= sizeof(buf)) return HANDLER_GO_ON;
10275 + strncpy(buf, con->request.http_if_modified_since, used_len);
10276 + buf[used_len] = '\0';
10278 + strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
10279 + t_header = mktime(&tm);
10281 + strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
10282 + t_file = mktime(&tm);
10284 + if (t_file > t_header) return HANDLER_GO_ON;
10286 + con->http_status = 304;
10287 + return HANDLER_FINISHED;
10289 + return HANDLER_GO_ON;
10294 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_auth.c lighttpd-1.4.12/src/http_auth.c
10295 --- lighttpd-1.4.11/src/http_auth.c 2006-02-01 13:02:52.000000000 +0200
10296 +++ lighttpd-1.4.12/src/http_auth.c 2006-07-11 21:23:40.000000000 +0300
10298 #include <string.h>
10301 -#include <unistd.h>
10304 #include "server.h"
10305 @@ -31,23 +30,14 @@
10306 #include "http_auth_digest.h"
10307 #include "stream.h"
10309 +#include "sys-strings.h"
10312 # include <openssl/md5.h>
10319 -#include <security/pam_appl.h>
10320 -#include <security/pam_misc.h>
10322 -static struct pam_conv conv = {
10328 handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
10330 static const char base64_pad = '=';
10331 @@ -75,25 +65,25 @@
10332 unsigned char *result;
10337 size_t in_len = strlen(in);
10340 buffer_prepare_copy(out, in_len);
10343 result = (unsigned char *)out->ptr;
10347 /* run through the whole string, converting as we go */
10348 for (i = 0; i < in_len; i++) {
10352 if (ch == '\0') break;
10355 if (ch == base64_pad) break;
10358 ch = base64_reverse_table[ch];
10359 if (ch < 0) continue;
10364 result[j] = ch << 2;
10365 @@ -125,168 +115,168 @@
10377 static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *username, buffer *realm, buffer *password) {
10381 if (!username->used|| !realm->used) return -1;
10384 if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
10389 if (buffer_is_empty(p->conf.auth_htdigest_userfile)) return -1;
10392 if (0 != stream_open(&f, p->conf.auth_htdigest_userfile)) {
10393 log_error_write(srv, __FILE__, __LINE__, "sbss", "opening digest-userfile", p->conf.auth_htdigest_userfile, "failed:", strerror(errno));
10403 while (f_line - f.start != f.size) {
10404 char *f_user, *f_pwd, *e, *f_realm;
10405 size_t u_len, pwd_len, r_len;
10415 - * user:realm:md5(user:realm:password)
10417 + * user:realm:md5(user:realm:password)
10421 if (NULL == (f_realm = memchr(f_user, ':', f.size - (f_user - f.start) ))) {
10422 - log_error_write(srv, __FILE__, __LINE__, "sbs",
10423 - "parsed error in", p->conf.auth_htdigest_userfile,
10424 + log_error_write(srv, __FILE__, __LINE__, "sbs",
10425 + "parsed error in", p->conf.auth_htdigest_userfile,
10426 "expected 'username:realm:hashed password'");
10436 if (NULL == (f_pwd = memchr(f_realm + 1, ':', f.size - (f_realm + 1 - f.start)))) {
10437 - log_error_write(srv, __FILE__, __LINE__, "sbs",
10438 - "parsed error in", p->conf.auth_plain_userfile,
10439 + log_error_write(srv, __FILE__, __LINE__, "sbs",
10440 + "parsed error in", p->conf.auth_plain_userfile,
10441 "expected 'username:realm:hashed password'");
10451 /* get pointers to the fields */
10452 - u_len = f_realm - f_user;
10453 + u_len = f_realm - f_user;
10455 r_len = f_pwd - f_realm;
10459 if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) {
10460 pwd_len = e - f_pwd;
10462 pwd_len = f.size - (f_pwd - f.start);
10466 if (username->used - 1 == u_len &&
10467 (realm->used - 1 == r_len) &&
10468 (0 == strncmp(username->ptr, f_user, u_len)) &&
10469 (0 == strncmp(realm->ptr, f_realm, r_len))) {
10473 buffer_copy_string_len(password, f_pwd, pwd_len);
10490 } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD ||
10491 p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
10497 auth_fn = (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) ? p->conf.auth_htpasswd_userfile : p->conf.auth_plain_userfile;
10500 if (buffer_is_empty(auth_fn)) return -1;
10503 if (0 != stream_open(&f, auth_fn)) {
10504 - log_error_write(srv, __FILE__, __LINE__, "sbss",
10505 + log_error_write(srv, __FILE__, __LINE__, "sbss",
10506 "opening plain-userfile", auth_fn, "failed:", strerror(errno));
10516 while (f_line - f.start != f.size) {
10517 char *f_user, *f_pwd, *e;
10518 size_t u_len, pwd_len;
10529 * user:crypted passwd
10533 if (NULL == (f_pwd = memchr(f_user, ':', f.size - (f_user - f.start) ))) {
10534 - log_error_write(srv, __FILE__, __LINE__, "sbs",
10535 - "parsed error in", auth_fn,
10536 + log_error_write(srv, __FILE__, __LINE__, "sbs",
10537 + "parsed error in", auth_fn,
10538 "expected 'username:hashed password'");
10548 /* get pointers to the fields */
10549 - u_len = f_pwd - f_user;
10550 + u_len = f_pwd - f_user;
10554 if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) {
10555 pwd_len = e - f_pwd;
10557 pwd_len = f.size - (f_pwd - f.start);
10561 if (username->used - 1 == u_len &&
10562 (0 == strncmp(username->ptr, f_user, u_len))) {
10566 buffer_copy_string_len(password, f_pwd, pwd_len);
10583 } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
10593 @@ -296,7 +286,7 @@
10595 data_string *require;
10602 @@ -304,12 +294,12 @@
10603 /* search auth-directives for path */
10604 for (i = 0; i < p->conf.auth_require->used; i++) {
10605 if (p->conf.auth_require->data[i]->key->used == 0) continue;
10608 if (0 == strncmp(url, p->conf.auth_require->data[i]->key->ptr, p->conf.auth_require->data[i]->key->used - 1)) {
10614 if (i == p->conf.auth_require->used) {
10617 @@ -317,72 +307,72 @@
10618 req = ((data_array *)(p->conf.auth_require->data[i]))->value;
10620 require = (data_string *)array_get_element(req, "require");
10623 /* if we get here, the user we got a authed user */
10624 if (0 == strcmp(require->value->ptr, "valid-user")) {
10629 /* user=name1|group=name3|host=name4 */
10632 /* seperate the string by | */
10634 log_error_write(srv, __FILE__, __LINE__, "sb", "rules", require->value);
10639 username_len = username ? strlen(username) : 0;
10642 r = rules = require->value->ptr;
10647 const char *k, *v, *e;
10648 int k_len, v_len, r_len;
10651 e = strchr(r, '|');
10657 r_len = strlen(rules) - (r - rules);
10661 /* from r to r + r_len is a rule */
10664 if (0 == strncmp(r, "valid-user", r_len)) {
10665 - log_error_write(srv, __FILE__, __LINE__, "sb",
10666 + log_error_write(srv, __FILE__, __LINE__, "sb",
10667 "parsing the 'require' section in 'auth.require' failed: valid-user cannot be combined with other require rules",
10673 /* search for = in the rules */
10674 if (NULL == (eq = strchr(r, '='))) {
10675 - log_error_write(srv, __FILE__, __LINE__, "sb",
10676 - "parsing the 'require' section in 'auth.require' failed: a = is missing",
10677 + log_error_write(srv, __FILE__, __LINE__, "sb",
10678 + "parsing the 'require' section in 'auth.require' failed: a = is missing",
10684 /* = out of range */
10685 if (eq > r + r_len) {
10686 - log_error_write(srv, __FILE__, __LINE__, "sb",
10687 + log_error_write(srv, __FILE__, __LINE__, "sb",
10688 "parsing the 'require' section in 'auth.require' failed: = out of range",
10696 /* the part before the = is user|group|host */
10702 v_len = r_len - k_len - 1;
10706 if (0 == strncmp(k, "user", k_len)) {
10709 username_len == v_len &&
10710 0 == strncmp(username, v, v_len)) {
10712 @@ -404,19 +394,19 @@
10713 log_error_write(srv, __FILE__, __LINE__, "s", "unknown key");
10723 log_error_write(srv, __FILE__, __LINE__, "s", "nothing matched");
10734 * @param password password-string from the auth-backend
10735 * @param pw password-string from the client
10737 @@ -426,16 +416,16 @@
10740 if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
10745 - * user:realm:md5(user:realm:password)
10747 + * user:realm:md5(user:realm:password)
10757 MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1);
10758 MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
10759 @@ -443,24 +433,24 @@
10760 MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
10761 MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw));
10762 MD5_Final(HA1, &Md5Ctx);
10768 if (0 == strcmp(password->ptr, a1)) {
10771 - } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) {
10773 + } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) {
10777 size_t salt_len = 0;
10783 * user:crypted password
10789 * CRYPT_STD_DES 2-character (Default)
10790 * CRYPT_EXT_DES 9-character
10791 @@ -478,7 +468,7 @@
10793 } else if (password->ptr[0] == '$' && password->ptr[2] == '$') {
10794 char *dollar = NULL;
10797 if (NULL == (dollar = strchr(password->ptr + 3, '$'))) {
10798 fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
10800 @@ -495,7 +485,7 @@
10801 strncpy(salt, password->ptr, salt_len);
10803 salt[salt_len] = '\0';
10806 crypted = crypt(pw, salt);
10808 if (0 == strcmp(password->ptr, crypted)) {
10809 @@ -503,40 +493,13 @@
10811 fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
10815 - } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
10818 + } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
10819 if (0 == strcmp(password->ptr, pw)) {
10822 - } else if (p->conf.auth_backend == AUTH_BACKEND_PAM) {
10824 - pam_handle_t *pamh=NULL;
10827 - retval = pam_start("lighttpd", username->ptr, &conv, &pamh);
10829 - if (retval == PAM_SUCCESS)
10830 - retval = pam_authenticate(pamh, 0); /* is user really user? */
10832 - if (retval == PAM_SUCCESS)
10833 - retval = pam_acct_mgmt(pamh, 0); /* permitted access? */
10835 - /* This is where we have been authorized or not. */
10837 - if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
10839 - log_error_write(srv, __FILE__, __LINE__, "s", "failed to release authenticator");
10842 - if (retval == PAM_SUCCESS) {
10843 - log_error_write(srv, __FILE__, __LINE__, "s", "Authenticated");
10846 - log_error_write(srv, __FILE__, __LINE__, "s", "Not Authenticated");
10849 - } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
10850 + } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
10853 LDAPMessage *lm, *first;
10854 @@ -544,45 +507,45 @@
10856 char *attrs[] = { LDAP_NO_ATTRS, NULL };
10860 /* for now we stay synchronous */
10865 * 1. connect anonymously (done in plugin init)
10866 * 2. get DN for uid = username
10867 * 3. auth against ldap server
10868 * 4. (optional) check a field
10878 * we have to protect us againt username which modifies out filter in
10883 for (i = 0; i < username->used - 1; i++) {
10884 char c = username->ptr[i];
10890 - log_error_write(srv, __FILE__, __LINE__, "sbd",
10892 + log_error_write(srv, __FILE__, __LINE__, "sbd",
10893 "ldap: invalid character (a-zA-Z0-9 allowed) in username:", username, i);
10906 buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
10907 buffer_append_string_buffer(p->ldap_filter, username);
10908 buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post);
10914 if (p->conf.ldap == NULL ||
10915 LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
10916 @@ -590,71 +553,71 @@
10918 if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
10920 - log_error_write(srv, __FILE__, __LINE__, "sssb",
10921 + log_error_write(srv, __FILE__, __LINE__, "sssb",
10922 "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter);
10930 if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) {
10931 log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
10941 if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) {
10942 log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
10958 if (NULL == (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) {
10959 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));
10964 ret = LDAP_VERSION3;
10965 if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
10966 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
10969 ldap_unbind_s(ldap);
10976 if (p->conf.auth_ldap_starttls == 1) {
10977 if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL, NULL))) {
10978 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
10981 ldap_unbind_s(ldap);
10990 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) {
10991 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
10994 ldap_unbind_s(ldap);
11002 ldap_unbind_s(ldap);
11005 /* everything worked, good, access granted */
11011 @@ -664,65 +627,65 @@
11012 int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
11013 buffer *username, *password;
11017 data_string *realm;
11020 realm = (data_string *)array_get_element(req, "realm");
11023 username = buffer_init();
11024 password = buffer_init();
11027 base64_decode(username, realm_str);
11030 /* r2 == user:password */
11031 if (NULL == (pw = strchr(username->ptr, ':'))) {
11032 buffer_free(username);
11035 log_error_write(srv, __FILE__, __LINE__, "sb", ": is missing in", username);
11045 username->used = pw - username->ptr;
11048 /* copy password to r1 */
11049 if (http_auth_get_password(srv, p, username, realm->value, password)) {
11050 buffer_free(username);
11051 buffer_free(password);
11054 log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
11061 /* password doesn't match */
11062 if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw)) {
11063 log_error_write(srv, __FILE__, __LINE__, "sbb", "password doesn't match for", con->uri.path, username);
11066 buffer_free(username);
11067 buffer_free(password);
11074 /* value is our allow-rules */
11075 if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL)) {
11076 buffer_free(username);
11077 buffer_free(password);
11080 log_error_write(srv, __FILE__, __LINE__, "s", "rules didn't match");
11087 /* remember the username */
11088 buffer_copy_string_buffer(p->auth_user, username);
11091 buffer_free(username);
11092 buffer_free(password);
11098 @@ -735,7 +698,7 @@
11099 int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
11107 @@ -745,18 +708,18 @@
11114 const char *m = NULL;
11116 buffer *password, *b, *username_buf, *realm_buf;
11127 /* init pointers */
11129 @@ -771,11 +734,11 @@
11132 { S("response=") },
11140 dkv[0].ptr = &username;
11141 dkv[1].ptr = &realm;
11142 dkv[2].ptr = &nonce;
11143 @@ -786,24 +749,24 @@
11145 dkv[8].ptr = &respons;
11152 for (i = 0; dkv[i].key; i++) {
11153 *(dkv[i].ptr) = NULL;
11159 if (p->conf.auth_backend != AUTH_BACKEND_HTDIGEST &&
11160 p->conf.auth_backend != AUTH_BACKEND_PLAIN) {
11161 - log_error_write(srv, __FILE__, __LINE__, "s",
11162 + log_error_write(srv, __FILE__, __LINE__, "s",
11163 "digest: unsupported backend (only htdigest or plain)");
11170 b = buffer_init_string(realm_str);
11173 /* parse credentials from client */
11174 for (c = b->ptr; *c; c++) {
11175 /* skip whitespaces */
11176 @@ -812,18 +775,18 @@
11178 for (i = 0; dkv[i].key; i++) {
11179 if ((0 == strncmp(c, dkv[i].key, dkv[i].key_len))) {
11180 - if ((c[dkv[i].key_len] == '"') &&
11181 + if ((c[dkv[i].key_len] == '"') &&
11182 (NULL != (e = strchr(c + dkv[i].key_len + 1, '"')))) {
11183 /* value with "..." */
11184 *(dkv[i].ptr) = c + dkv[i].key_len + 1;
11189 } else if (NULL != (e = strchr(c + dkv[i].key_len, ','))) {
11190 /* value without "...", terminated by ',' */
11191 *(dkv[i].ptr) = c + dkv[i].key_len;
11197 /* value without "...", terminated by EOL */
11198 @@ -833,7 +796,7 @@
11204 if (p->conf.auth_debug > 1) {
11205 log_error_write(srv, __FILE__, __LINE__, "ss", "username", username);
11206 log_error_write(srv, __FILE__, __LINE__, "ss", "realm", realm);
11207 @@ -845,22 +808,22 @@
11208 log_error_write(srv, __FILE__, __LINE__, "ss", "nc", nc);
11209 log_error_write(srv, __FILE__, __LINE__, "ss", "response", respons);
11213 /* check if everything is transmitted */
11219 (qop && (!nc || !cnonce)) ||
11221 /* missing field */
11223 - log_error_write(srv, __FILE__, __LINE__, "s",
11225 + log_error_write(srv, __FILE__, __LINE__, "s",
11226 "digest: missing field");
11230 - m = get_http_method_name(con->request.http_method);
11231 + m = get_http_method_name(con->request.http_method);
11233 /* password-string == HA1 */
11234 password = buffer_init();
11235 @@ -873,10 +836,10 @@
11236 buffer_free(realm_buf);
11241 buffer_free(username_buf);
11242 buffer_free(realm_buf);
11245 if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
11246 /* generate password from plain-text */
11248 @@ -890,16 +853,16 @@
11250 /* transform the 32-byte-hex-md5 to a 16-byte-md5 */
11251 for (i = 0; i < HASHLEN; i++) {
11252 - HA1[i] = hex2int(password->ptr[i*2]) << 4;
11253 - HA1[i] |= hex2int(password->ptr[i*2+1]);
11254 + HA1[i] = hex2int(password->ptr[i*2]) << 4;
11255 + HA1[i] |= hex2int(password->ptr[i*2+1]);
11258 /* we already check that above */
11263 buffer_free(password);
11267 strcasecmp(algorithm, "md5-sess") == 0) {
11269 @@ -910,9 +873,9 @@
11270 MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
11271 MD5_Final(HA1, &Md5Ctx);
11278 /* calculate H(A2) */
11280 MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m));
11281 @@ -924,7 +887,7 @@
11283 MD5_Final(HA2, &Md5Ctx);
11284 CvtHex(HA2, HA2Hex);
11287 /* calculate response */
11289 MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN);
11290 @@ -942,39 +905,39 @@
11291 MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN);
11292 MD5_Final(RespHash, &Md5Ctx);
11293 CvtHex(RespHash, a2);
11296 if (0 != strcmp(a2, respons)) {
11297 /* digest not ok */
11300 if (p->conf.auth_debug) {
11301 - log_error_write(srv, __FILE__, __LINE__, "sss",
11302 + log_error_write(srv, __FILE__, __LINE__, "sss",
11303 "digest: digest mismatch", a2, respons);
11306 - log_error_write(srv, __FILE__, __LINE__, "sss",
11308 + log_error_write(srv, __FILE__, __LINE__, "sss",
11309 "digest: auth failed for", username, "wrong password");
11317 /* value is our allow-rules */
11318 if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL)) {
11321 - log_error_write(srv, __FILE__, __LINE__, "s",
11323 + log_error_write(srv, __FILE__, __LINE__, "s",
11324 "digest: rules did match");
11331 /* remember the username */
11332 buffer_copy_string(p->auth_user, username);
11338 if (p->conf.auth_debug) {
11339 - log_error_write(srv, __FILE__, __LINE__, "s",
11340 + log_error_write(srv, __FILE__, __LINE__, "s",
11341 "digest: auth ok");
11344 @@ -985,23 +948,23 @@
11352 /* generate shared-secret */
11354 MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1);
11355 MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
11358 /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
11359 ltostr(hh, srv->cur_ts);
11360 MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
11361 ltostr(hh, rand());
11362 MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
11365 MD5_Final(h, &Md5Ctx);
11373 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_auth.h lighttpd-1.4.12/src/http_auth.h
11374 --- lighttpd-1.4.11/src/http_auth.h 2005-08-14 17:12:31.000000000 +0300
11375 +++ lighttpd-1.4.12/src/http_auth.h 2006-07-11 21:23:40.000000000 +0300
11380 -typedef enum { AUTH_BACKEND_UNSET, AUTH_BACKEND_PLAIN,
11381 - AUTH_BACKEND_LDAP, AUTH_BACKEND_HTPASSWD,
11382 - AUTH_BACKEND_HTDIGEST, AUTH_BACKEND_PAM } auth_backend_t;
11384 + AUTH_BACKEND_UNSET,
11385 + AUTH_BACKEND_PLAIN,
11386 + AUTH_BACKEND_LDAP,
11387 + AUTH_BACKEND_HTPASSWD,
11388 + AUTH_BACKEND_HTDIGEST
11393 array *auth_require;
11396 buffer *auth_plain_groupfile;
11397 buffer *auth_plain_userfile;
11400 buffer *auth_htdigest_userfile;
11401 buffer *auth_htpasswd_userfile;
11404 buffer *auth_backend_conf;
11407 buffer *auth_ldap_hostname;
11408 buffer *auth_ldap_basedn;
11409 buffer *auth_ldap_binddn;
11410 @@ -32,15 +36,15 @@
11411 buffer *auth_ldap_filter;
11412 buffer *auth_ldap_cafile;
11413 unsigned short auth_ldap_starttls;
11416 unsigned short auth_debug;
11420 auth_backend_t auth_backend;
11427 buffer *ldap_filter_pre;
11428 buffer *ldap_filter_post;
11430 @@ -49,15 +53,15 @@
11439 buffer *ldap_filter;
11443 mod_auth_plugin_config **config_storage;
11446 mod_auth_plugin_config conf; /* this is only used as long as no handler_ctx is setup */
11447 } mod_auth_plugin_data;
11449 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_auth_digest.h lighttpd-1.4.12/src/http_auth_digest.h
11450 --- lighttpd-1.4.11/src/http_auth_digest.h 2006-01-05 00:54:01.000000000 +0200
11451 +++ lighttpd-1.4.12/src/http_auth_digest.h 2006-07-11 21:23:40.000000000 +0300
11461 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_chunk.c lighttpd-1.4.12/src/http_chunk.c
11462 --- lighttpd-1.4.11/src/http_chunk.c 2005-08-11 01:26:50.000000000 +0300
11463 +++ lighttpd-1.4.12/src/http_chunk.c 2006-07-11 21:23:40.000000000 +0300
11466 * the HTTP chunk-API
11473 #include <sys/types.h>
11476 #include <stdlib.h>
11478 -#include <unistd.h>
11482 @@ -23,19 +22,19 @@
11483 static int http_chunk_append_len(server *srv, connection *con, size_t len) {
11484 size_t i, olen = len, j;
11488 b = srv->tmp_chunk_len;
11492 buffer_copy_string(b, "0");
11494 for (i = 0; i < 8 && len; i++) {
11499 /* i is the number of hex digits we have */
11500 buffer_prepare_copy(b, i + 1);
11503 for (j = i-1, len = olen; j+1 > 0; j--) {
11504 b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
11506 @@ -43,61 +42,61 @@
11508 b->ptr[b->used++] = '\0';
11512 buffer_append_string(b, "\r\n");
11513 chunkqueue_append_buffer(con->write_queue, b);
11520 int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
11524 if (!con) return -1;
11527 cq = con->write_queue;
11530 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
11531 http_chunk_append_len(srv, con, len);
11535 chunkqueue_append_file(cq, fn, offset, len);
11538 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) {
11539 chunkqueue_append_mem(cq, "\r\n", 2 + 1);
11546 int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
11550 if (!con) return -1;
11553 cq = con->write_queue;
11556 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
11557 http_chunk_append_len(srv, con, mem->used - 1);
11561 chunkqueue_append_buffer(cq, mem);
11564 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) {
11565 chunkqueue_append_mem(cq, "\r\n", 2 + 1);
11572 int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
11576 if (!con) return -1;
11579 cq = con->write_queue;
11583 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
11584 http_chunk_append_len(srv, con, 0);
11585 @@ -107,17 +106,17 @@
11591 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
11592 http_chunk_append_len(srv, con, len - 1);
11596 chunkqueue_append_mem(cq, mem, len);
11599 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
11600 chunkqueue_append_mem(cq, "\r\n", 2 + 1);
11607 @@ -125,9 +124,9 @@
11608 off_t http_chunkqueue_length(server *srv, connection *con) {
11610 log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!");
11617 return chunkqueue_length(con->write_queue);
11619 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_resp.c lighttpd-1.4.12/src/http_resp.c
11620 --- lighttpd-1.4.11/src/http_resp.c 1970-01-01 03:00:00.000000000 +0300
11621 +++ lighttpd-1.4.12/src/http_resp.c 2006-07-11 21:23:40.000000000 +0300
11623 +#include <string.h>
11624 +#include <stdlib.h>
11625 +#include <stdio.h>
11626 +#include <assert.h>
11628 +#include "http_resp.h"
11629 +#include "http_resp_parser.h"
11631 +/* declare prototypes for the parser */
11632 +void *http_resp_parserAlloc(void *(*mallocProc)(size_t));
11633 +void http_resp_parserFree(void *p, void (*freeProc)(void*));
11634 +void http_resp_parserTrace(FILE *TraceFILE, char *zTracePrompt);
11635 +void http_resp_parser(void *, int, buffer *, http_resp_ctx_t *);
11640 + chunk *c; /* current chunk in the chunkqueue */
11641 + size_t offset; /* current offset in current chunk */
11644 + size_t lookup_offset;
11647 + int is_statusline;
11648 +} http_resp_tokenizer_t;
11650 +http_resp *http_response_init(void) {
11651 + http_resp *resp = calloc(1, sizeof(*resp));
11653 + resp->reason = buffer_init();
11654 + resp->headers = array_init();
11659 +void http_response_reset(http_resp *resp) {
11660 + if (!resp) return;
11662 + buffer_reset(resp->reason);
11663 + array_reset(resp->headers);
11667 +void http_response_free(http_resp *resp) {
11668 + if (!resp) return;
11670 + buffer_free(resp->reason);
11671 + array_free(resp->headers);
11676 +static int http_resp_get_next_char(http_resp_tokenizer_t *t, unsigned char *c) {
11677 + if (t->offset == t->c->mem->used - 1) {
11678 + /* end of chunk, open next chunk */
11680 + if (!t->c->next) return -1;
11682 + t->c = t->c->next;
11686 + *c = t->c->mem->ptr[t->offset++];
11688 + t->lookup_offset = t->offset;
11689 + t->lookup_c = t->c;
11692 + fprintf(stderr, "%s.%d: get: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->offset - 1);
11698 +static int http_resp_lookup_next_char(http_resp_tokenizer_t *t, unsigned char *c) {
11699 + if (t->lookup_offset == t->lookup_c->mem->used - 1) {
11700 + /* end of chunk, open next chunk */
11702 + if (!t->lookup_c->next) return -1;
11704 + t->lookup_c = t->lookup_c->next;
11705 + t->lookup_offset = 0;
11708 + *c = t->lookup_c->mem->ptr[t->lookup_offset++];
11710 + fprintf(stderr, "%s.%d: lookup: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->lookup_offset - 1);
11717 +static int http_resp_tokenizer(
11718 + http_resp_tokenizer_t *t,
11725 + /* push the token to the parser */
11727 + while (tid == 0 && 0 == http_resp_get_next_char(t, &c)) {
11741 + if (0 != http_resp_lookup_next_char(t, &c)) return -1;
11746 + t->c = t->lookup_c;
11747 + t->offset = t->lookup_offset;
11749 + t->is_statusline = 0;
11752 + fprintf(stderr, "%s.%d: CR with out LF\r\n", __FILE__, __LINE__);
11759 + t->is_statusline = 0;
11764 + while (c >= 32 && c != 127 && c != 255) {
11765 + if (t->is_statusline) {
11766 + if (c == ':') {t->is_statusline = 0; break; } /* this is not a status line by a real header */
11767 + if (c == 32) break; /* the space is a splitter in the statusline */
11770 + if (c == ':') break; /* the : is the splitter between key and value */
11773 + if (0 != http_resp_lookup_next_char(t, &c)) return -1;
11776 + if (t->c == t->lookup_c &&
11777 + t->offset == t->lookup_offset + 1) {
11779 + fprintf(stderr, "%s.%d: invalid char in string\n", __FILE__, __LINE__);
11785 + /* the lookup points to the first invalid char */
11786 + t->lookup_offset--;
11788 + /* no overlapping string */
11789 + if (t->c == t->lookup_c) {
11790 + buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->lookup_offset - t->offset + 1);
11792 + /* first chunk */
11793 + buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->c->mem->used - t->offset);
11795 + /* chunks in the middle */
11796 + for (t->c = t->c->next; t->c != t->lookup_c; t->c = t->c->next) {
11797 + buffer_append_string_buffer(token, t->c->mem);
11798 + t->offset = t->c->mem->used - 1;
11802 + buffer_append_string_len(token, t->c->mem->ptr, t->lookup_offset);
11805 + t->offset = t->lookup_offset;
11820 +parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *resp) {
11821 + http_resp_tokenizer_t t;
11822 + void *pParser = NULL;
11823 + int token_id = 0;
11824 + buffer *token = NULL;
11825 + http_resp_ctx_t context;
11826 + parse_status_t ret = PARSE_UNSET;
11827 + int last_token_id = 0;
11831 + t.offset = t.c->offset;
11833 + t.is_statusline = 1;
11836 + context.errmsg = buffer_init();
11837 + context.resp = resp;
11839 + pParser = http_resp_parserAlloc( malloc );
11840 + token = buffer_init();
11841 + /* http_resp_parserTrace(stderr, "http-response: "); */
11843 + while((1 == http_resp_tokenizer(&t, &token_id, token)) && context.ok) {
11844 + http_resp_parser(pParser, token_id, token, &context);
11846 + token = buffer_init();
11848 + if (last_token_id == TK_CRLF &&
11849 + token_id == TK_CRLF) break;
11851 + last_token_id = token_id;
11854 + /* oops, the parser failed */
11855 + if (context.ok == 0) {
11856 + ret = PARSE_ERROR;
11858 + fprintf(stderr, "%s.%d: parsing failed at: ...%20s\r\n",
11859 + __FILE__, __LINE__, t.c->mem->ptr + t.offset);
11862 + http_resp_parser(pParser, 0, token, &context);
11863 + http_resp_parserFree(pParser, free );
11865 + if (context.ok == 0) {
11866 + /* we are missing the some tokens */
11868 + if (ret == PARSE_UNSET) ret = PARSE_NEED_MORE;
11872 + for (c = cq->first; c != t.c; c = c->next) {
11873 + c->offset = c->mem->used - 1;
11876 + c->offset = t.offset;
11878 + ret = PARSE_SUCCESS;
11881 + buffer_free(token);
11886 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_resp.h lighttpd-1.4.12/src/http_resp.h
11887 --- lighttpd-1.4.11/src/http_resp.h 1970-01-01 03:00:00.000000000 +0300
11888 +++ lighttpd-1.4.12/src/http_resp.h 2006-07-11 21:23:40.000000000 +0300
11890 +#ifndef _HTTP_RESP_H_
11891 +#define _HTTP_RESP_H_
11893 +#include "array.h"
11894 +#include "chunk.h"
11904 + int protocol; /* http/1.0, http/1.1 */
11905 + int status; /* e.g. 200 */
11906 + buffer *reason; /* e.g. Ok */
11915 +} http_resp_ctx_t;
11917 +http_resp *http_response_init(void);
11918 +void http_response_free(http_resp *resp);
11919 +void http_response_reset(http_resp *resp);
11921 +parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *http_response);
11924 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/http_resp_parser.c lighttpd-1.4.12/src/http_resp_parser.c
11925 --- lighttpd-1.4.11/src/http_resp_parser.c 1970-01-01 03:00:00.000000000 +0300
11926 +++ lighttpd-1.4.12/src/http_resp_parser.c 2006-07-11 21:49:18.000000000 +0300
11928 +/* Driver template for the LEMON parser generator.
11929 +** The author disclaims copyright to this source code.
11931 +/* First off, code is include which follows the "include" declaration
11932 +** in the input file. */
11933 +#include <stdio.h>
11934 +#line 6 "./http_resp_parser.y"
11936 +#include <assert.h>
11937 +#include <string.h>
11938 +#include "http_resp.h"
11939 +#include "keyvalue.h"
11940 +#include "array.h"
11942 +#line 16 "http_resp_parser.c"
11943 +/* Next is all token values, in a form suitable for use by makeheaders.
11944 +** This section will be null unless lemon is run with the -m switch.
11947 +** These constants (all generated automatically by the parser generator)
11948 +** specify the various kinds of tokens (terminals) that the parser
11951 +** Each symbol here is a terminal symbol in the grammar.
11953 +/* Make sure the INTERFACE macro is defined.
11956 +# define INTERFACE 1
11958 +/* The next thing included is series of defines which control
11959 +** various aspects of the generated parser.
11960 +** YYCODETYPE is the data type used for storing terminal
11961 +** and nonterminal numbers. "unsigned char" is
11962 +** used if there are fewer than 250 terminals
11963 +** and nonterminals. "int" is used otherwise.
11964 +** YYNOCODE is a number of type YYCODETYPE which corresponds
11965 +** to no legal terminal or nonterminal number. This
11966 +** number is used to fill in empty slots of the hash
11968 +** YYFALLBACK If defined, this indicates that one or more tokens
11969 +** have fall-back values which should be used if the
11970 +** original value of the token will not parse.
11971 +** YYACTIONTYPE is the data type used for storing terminal
11972 +** and nonterminal numbers. "unsigned char" is
11973 +** used if there are fewer than 250 rules and
11974 +** states combined. "int" is used otherwise.
11975 +** http_resp_parserTOKENTYPE is the data type used for minor tokens given
11976 +** directly to the parser from the tokenizer.
11977 +** YYMINORTYPE is the data type used for all minor tokens.
11978 +** This is typically a union of many types, one of
11979 +** which is http_resp_parserTOKENTYPE. The entry in the union
11980 +** for base tokens is called "yy0".
11981 +** YYSTACKDEPTH is the maximum depth of the parser's stack.
11982 +** http_resp_parserARG_SDECL A static variable declaration for the %extra_argument
11983 +** http_resp_parserARG_PDECL A parameter declaration for the %extra_argument
11984 +** http_resp_parserARG_STORE Code to store %extra_argument into yypParser
11985 +** http_resp_parserARG_FETCH Code to extract %extra_argument from yypParser
11986 +** YYNSTATE the combined number of states.
11987 +** YYNRULE the number of rules in the grammar
11988 +** YYERRORSYMBOL is the code number of the error symbol. If not
11989 +** defined, then do no error processing.
11992 +#define YYCODETYPE unsigned char
11993 +#define YYNOCODE 12
11994 +#define YYACTIONTYPE unsigned char
11995 +#define http_resp_parserTOKENTYPE buffer *
11997 + http_resp_parserTOKENTYPE yy0;
11999 + data_string * yy9;
12004 +#define YYSTACKDEPTH 100
12005 +#define http_resp_parserARG_SDECL http_resp_ctx_t *ctx;
12006 +#define http_resp_parserARG_PDECL ,http_resp_ctx_t *ctx
12007 +#define http_resp_parserARG_FETCH http_resp_ctx_t *ctx = yypParser->ctx
12008 +#define http_resp_parserARG_STORE yypParser->ctx = ctx
12009 +#define YYNSTATE 19
12011 +#define YYERRORSYMBOL 4
12012 +#define YYERRSYMDT yy23
12013 +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
12014 +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
12015 +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
12017 +/* Next are that tables used to determine what action to take based on the
12018 +** current state and lookahead token. These tables are used to implement
12019 +** functions that take a state number and lookahead value and return an
12020 +** action integer.
12022 +** Suppose the action integer is N. Then the action is determined as
12025 +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
12026 +** token onto the stack and goto state N.
12028 +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
12030 +** N == YYNSTATE+YYNRULE A syntax error has occurred.
12032 +** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
12034 +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
12035 +** slots in the yy_action[] table.
12037 +** The action table is constructed as a single large table named yy_action[].
12038 +** Given state S and lookahead X, the action is computed as
12040 +** yy_action[ yy_shift_ofst[S] + X ]
12042 +** If the index value yy_shift_ofst[S]+X is out of range or if the value
12043 +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
12044 +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
12045 +** and that yy_default[S] should be used instead.
12047 +** The formula above is for computing the action when the lookahead is
12048 +** a terminal symbol. If the lookahead is a non-terminal (as occurs after
12049 +** a reduce action) then the yy_reduce_ofst[] array is used in place of
12050 +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
12051 +** YY_SHIFT_USE_DFLT.
12053 +** The following are the tables generated in this section:
12055 +** yy_action[] A single table containing all actions.
12056 +** yy_lookahead[] A table containing the lookahead for each entry in
12057 +** yy_action. Used to detect hash collisions.
12058 +** yy_shift_ofst[] For each state, the offset into yy_action for
12059 +** shifting terminals.
12060 +** yy_reduce_ofst[] For each state, the offset into yy_action for
12061 +** shifting non-terminals after a reduce.
12062 +** yy_default[] Default action for each state.
12064 +static YYACTIONTYPE yy_action[] = {
12065 + /* 0 */ 8, 29, 18, 1, 14, 2, 4, 11, 15, 12,
12066 + /* 10 */ 14, 13, 4, 21, 5, 19, 3, 5, 6, 7,
12067 + /* 20 */ 9, 17, 16, 4, 20, 22, 22, 10,
12069 +static YYCODETYPE yy_lookahead[] = {
12070 + /* 0 */ 5, 6, 2, 8, 9, 1, 2, 1, 2, 8,
12071 + /* 10 */ 9, 1, 2, 2, 3, 0, 9, 3, 2, 1,
12072 + /* 20 */ 7, 2, 2, 2, 0, 2, 11, 10,
12074 +#define YY_SHIFT_USE_DFLT (-1)
12075 +static signed char yy_shift_ofst[] = {
12076 + /* 0 */ 0, 4, 15, -1, 14, 16, 18, -1, 19, 20,
12077 + /* 10 */ 6, 21, 10, 24, -1, -1, -1, 23, 11,
12079 +#define YY_REDUCE_USE_DFLT (-6)
12080 +static signed char yy_reduce_ofst[] = {
12081 + /* 0 */ -5, 7, -6, -6, -6, -6, -6, -6, 13, 17,
12082 + /* 10 */ -6, 1, 7, -6, -6, -6, -6, -6, -6,
12084 +static YYACTIONTYPE yy_default[] = {
12085 + /* 0 */ 28, 28, 28, 25, 28, 28, 28, 27, 28, 28,
12086 + /* 10 */ 28, 28, 28, 28, 26, 24, 23, 28, 28,
12088 +#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
12090 +/* The next table maps tokens into fallback tokens. If a construct
12091 +** like the following:
12093 +** %fallback ID X Y Z.
12095 +** appears in the grammer, then ID becomes a fallback token for X, Y,
12096 +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
12097 +** but it does not parse, the type of the token is changed to ID and
12098 +** the parse is retried before an error is thrown.
12101 +static const YYCODETYPE yyFallback[] = {
12103 +#endif /* YYFALLBACK */
12105 +/* The following structure represents a single element of the
12106 +** parser's stack. Information stored includes:
12108 +** + The state number for the parser at this level of the stack.
12110 +** + The value of the token stored at this level of the stack.
12111 +** (In other words, the "major" token.)
12113 +** + The semantic value stored at this level of the stack. This is
12114 +** the information used by the action routines in the grammar.
12115 +** It is sometimes called the "minor" token.
12117 +struct yyStackEntry {
12118 + int stateno; /* The state-number */
12119 + int major; /* The major token value. This is the code
12120 + ** number for the token at this stack level */
12121 + YYMINORTYPE minor; /* The user-supplied minor token value. This
12122 + ** is the value of the token */
12124 +typedef struct yyStackEntry yyStackEntry;
12126 +/* The state of the parser is completely contained in an instance of
12127 +** the following structure */
12129 + int yyidx; /* Index of top element in stack */
12130 + int yyerrcnt; /* Shifts left before out of the error */
12131 + http_resp_parserARG_SDECL /* A place to hold %extra_argument */
12132 + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
12134 +typedef struct yyParser yyParser;
12137 +#include <stdio.h>
12138 +static FILE *yyTraceFILE = 0;
12139 +static char *yyTracePrompt = 0;
12140 +#endif /* NDEBUG */
12144 +** Turn parser tracing on by giving a stream to which to write the trace
12145 +** and a prompt to preface each trace message. Tracing is turned off
12146 +** by making either argument NULL
12150 +** <li> A FILE* to which trace output should be written.
12151 +** If NULL, then tracing is turned off.
12152 +** <li> A prefix string written at the beginning of every
12153 +** line of trace output. If NULL, then tracing is
12160 +void http_resp_parserTrace(FILE *TraceFILE, char *zTracePrompt){
12161 + yyTraceFILE = TraceFILE;
12162 + yyTracePrompt = zTracePrompt;
12163 + if( yyTraceFILE==0 ) yyTracePrompt = 0;
12164 + else if( yyTracePrompt==0 ) yyTraceFILE = 0;
12166 +#endif /* NDEBUG */
12169 +/* For tracing shifts, the names of all terminals and nonterminals
12170 +** are required. The following table supplies these names */
12171 +static const char *yyTokenName[] = {
12172 + "$", "CRLF", "STRING", "COLON",
12173 + "error", "protocol", "response_hdr", "number",
12174 + "headers", "header", "reason",
12176 +#endif /* NDEBUG */
12179 +/* For tracing reduce actions, the names of all rules are required.
12181 +static const char *yyRuleName[] = {
12182 + /* 0 */ "response_hdr ::= headers CRLF",
12183 + /* 1 */ "response_hdr ::= protocol number reason CRLF headers CRLF",
12184 + /* 2 */ "protocol ::= STRING",
12185 + /* 3 */ "number ::= STRING",
12186 + /* 4 */ "reason ::= STRING",
12187 + /* 5 */ "reason ::= reason STRING",
12188 + /* 6 */ "headers ::= headers header",
12189 + /* 7 */ "headers ::= header",
12190 + /* 8 */ "header ::= STRING COLON STRING CRLF",
12192 +#endif /* NDEBUG */
12195 +** This function returns the symbolic name associated with a token
12198 +const char *http_resp_parserTokenName(int tokenType){
12200 + if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
12201 + return yyTokenName[tokenType];
12203 + return "Unknown";
12211 +** This function allocates a new parser.
12212 +** The only argument is a pointer to a function which works like
12216 +** A pointer to the function used to allocate memory.
12219 +** A pointer to a parser. This pointer is used in subsequent calls
12220 +** to http_resp_parser and http_resp_parserFree.
12222 +void *http_resp_parserAlloc(void *(*mallocProc)(size_t)){
12223 + yyParser *pParser;
12224 + pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
12226 + pParser->yyidx = -1;
12231 +/* The following function deletes the value associated with a
12232 +** symbol. The symbol can be either a terminal or nonterminal.
12233 +** "yymajor" is the symbol code, and "yypminor" is a pointer to
12236 +static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
12237 + switch( yymajor ){
12238 + /* Here is inserted the actions which take place when a
12239 + ** terminal or non-terminal is destroyed. This can happen
12240 + ** when the symbol is popped from the stack during a
12241 + ** reduce or during error processing or when a parser is
12242 + ** being destroyed before it is finished parsing.
12244 + ** Note: during a reduce, the only symbols destroyed are those
12245 + ** which appear on the RHS of the rule, but which are not used
12246 + ** inside the C code.
12251 +#line 23 "./http_resp_parser.y"
12252 +{ buffer_free((yypminor->yy0)); }
12253 +#line 326 "http_resp_parser.c"
12255 + default: break; /* If no destructor action specified: do nothing */
12260 +** Pop the parser's stack once.
12262 +** If there is a destructor routine associated with the token which
12263 +** is popped from the stack, then call it.
12265 +** Return the major token number for the symbol popped.
12267 +static int yy_pop_parser_stack(yyParser *pParser){
12268 + YYCODETYPE yymajor;
12269 + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
12271 + if( pParser->yyidx<0 ) return 0;
12273 + if( yyTraceFILE && pParser->yyidx>=0 ){
12274 + fprintf(yyTraceFILE,"%sPopping %s\n",
12276 + yyTokenName[yytos->major]);
12279 + yymajor = yytos->major;
12280 + yy_destructor( yymajor, &yytos->minor);
12281 + pParser->yyidx--;
12286 +** Deallocate and destroy a parser. Destructors are all called for
12287 +** all stack elements before shutting the parser down.
12291 +** <li> A pointer to the parser. This should be a pointer
12292 +** obtained from http_resp_parserAlloc.
12293 +** <li> A pointer to a function used to reclaim memory obtained
12297 +void http_resp_parserFree(
12298 + void *p, /* The parser to be deleted */
12299 + void (*freeProc)(void*) /* Function used to reclaim memory */
12301 + yyParser *pParser = (yyParser*)p;
12302 + if( pParser==0 ) return;
12303 + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
12304 + (*freeProc)((void*)pParser);
12308 +** Find the appropriate action for a parser given the terminal
12309 +** look-ahead token iLookAhead.
12311 +** If the look-ahead token is YYNOCODE, then check to see if the action is
12312 +** independent of the look-ahead. If it is, return the action, otherwise
12313 +** return YY_NO_ACTION.
12315 +static int yy_find_shift_action(
12316 + yyParser *pParser, /* The parser */
12317 + int iLookAhead /* The look-ahead token */
12320 + int stateno = pParser->yystack[pParser->yyidx].stateno;
12322 + /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */
12323 + i = yy_shift_ofst[stateno];
12324 + if( i==YY_SHIFT_USE_DFLT ){
12325 + return yy_default[stateno];
12327 + if( iLookAhead==YYNOCODE ){
12328 + return YY_NO_ACTION;
12331 + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
12333 + int iFallback; /* Fallback token */
12334 + if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
12335 + && (iFallback = yyFallback[iLookAhead])!=0 ){
12337 + if( yyTraceFILE ){
12338 + fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
12339 + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
12342 + return yy_find_shift_action(pParser, iFallback);
12345 + return yy_default[stateno];
12347 + return yy_action[i];
12352 +** Find the appropriate action for a parser given the non-terminal
12353 +** look-ahead token iLookAhead.
12355 +** If the look-ahead token is YYNOCODE, then check to see if the action is
12356 +** independent of the look-ahead. If it is, return the action, otherwise
12357 +** return YY_NO_ACTION.
12359 +static int yy_find_reduce_action(
12360 + yyParser *pParser, /* The parser */
12361 + int iLookAhead /* The look-ahead token */
12364 + int stateno = pParser->yystack[pParser->yyidx].stateno;
12366 + i = yy_reduce_ofst[stateno];
12367 + if( i==YY_REDUCE_USE_DFLT ){
12368 + return yy_default[stateno];
12370 + if( iLookAhead==YYNOCODE ){
12371 + return YY_NO_ACTION;
12374 + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
12375 + return yy_default[stateno];
12377 + return yy_action[i];
12382 +** Perform a shift action.
12384 +static void yy_shift(
12385 + yyParser *yypParser, /* The parser to be shifted */
12386 + int yyNewState, /* The new state to shift in */
12387 + int yyMajor, /* The major token to shift in */
12388 + YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */
12390 + yyStackEntry *yytos;
12391 + yypParser->yyidx++;
12392 + if( yypParser->yyidx>=YYSTACKDEPTH ){
12393 + http_resp_parserARG_FETCH;
12394 + yypParser->yyidx--;
12396 + if( yyTraceFILE ){
12397 + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
12400 + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
12401 + /* Here code is inserted which will execute if the parser
12402 + ** stack every overflows */
12403 + http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument var */
12406 + yytos = &yypParser->yystack[yypParser->yyidx];
12407 + yytos->stateno = yyNewState;
12408 + yytos->major = yyMajor;
12409 + yytos->minor = *yypMinor;
12411 + if( yyTraceFILE && yypParser->yyidx>0 ){
12413 + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
12414 + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
12415 + for(i=1; i<=yypParser->yyidx; i++)
12416 + fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
12417 + fprintf(yyTraceFILE,"\n");
12422 +/* The following table contains information about every rule that
12423 +** is used during the reduce.
12426 + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
12427 + unsigned char nrhs; /* Number of right-hand side symbols in the rule */
12428 +} yyRuleInfo[] = {
12440 +static void yy_accept(yyParser*); /* Forward Declaration */
12443 +** Perform a reduce action and the shift that must immediately
12444 +** follow the reduce.
12446 +static void yy_reduce(
12447 + yyParser *yypParser, /* The parser */
12448 + int yyruleno /* Number of the rule by which to reduce */
12450 + int yygoto; /* The next state */
12451 + int yyact; /* The next action */
12452 + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
12453 + yyStackEntry *yymsp; /* The top of the parser's stack */
12454 + int yysize; /* Amount to pop the stack */
12455 + http_resp_parserARG_FETCH;
12456 + yymsp = &yypParser->yystack[yypParser->yyidx];
12458 + if( yyTraceFILE && yyruleno>=0
12459 + && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
12460 + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
12461 + yyRuleName[yyruleno]);
12463 +#endif /* NDEBUG */
12465 + switch( yyruleno ){
12466 + /* Beginning here are the reduction cases. A typical example
12469 + ** #line <lineno> <grammarfile>
12470 + ** { ... } // User supplied code
12471 + ** #line <lineno> <thisfile>
12475 +#line 26 "./http_resp_parser.y"
12477 + http_resp *resp = ctx->resp;
12480 + resp->protocol = HTTP_VERSION_UNSET;
12482 + buffer_copy_string(resp->reason, ""); /* no reason */
12483 + array_free(resp->headers);
12484 + resp->headers = yymsp[-1].minor.yy12;
12486 + if (NULL == (ds = (data_string *)array_get_element(yymsp[-1].minor.yy12, "Status"))) {
12487 + resp->status = 0;
12490 + resp->status = strtol(ds->value->ptr, &err, 10);
12492 + if (*err != '\0') {
12493 + buffer_copy_string(ctx->errmsg, "expected a number: ");
12494 + buffer_append_string_buffer(ctx->errmsg, ds->value);
12501 + yymsp[-1].minor.yy12 = NULL;
12503 +#line 576 "http_resp_parser.c"
12504 + yy_destructor(1,&yymsp[0].minor);
12507 +#line 54 "./http_resp_parser.y"
12509 + http_resp *resp = ctx->resp;
12511 + resp->status = yymsp[-4].minor.yy20;
12512 + resp->protocol = yymsp[-5].minor.yy20;
12513 + buffer_copy_string_buffer(resp->reason, yymsp[-3].minor.yy0);
12515 + array_free(resp->headers);
12517 + resp->headers = yymsp[-1].minor.yy12;
12519 + yymsp[-1].minor.yy12 = NULL;
12521 +#line 594 "http_resp_parser.c"
12522 + yy_destructor(1,&yymsp[-2].minor);
12523 + yy_destructor(1,&yymsp[0].minor);
12526 +#line 68 "./http_resp_parser.y"
12528 + if (buffer_is_equal_string(yymsp[0].minor.yy0, CONST_STR_LEN("HTTP/1.0"))) {
12529 + yygotominor.yy20 = HTTP_VERSION_1_0;
12530 + } else if (buffer_is_equal_string(yymsp[0].minor.yy0, CONST_STR_LEN("HTTP/1.1"))) {
12531 + yygotominor.yy20 = HTTP_VERSION_1_1;
12533 + buffer_copy_string(ctx->errmsg, "unknown protocol: ");
12534 + buffer_append_string_buffer(ctx->errmsg, yymsp[0].minor.yy0);
12539 +#line 612 "http_resp_parser.c"
12542 +#line 81 "./http_resp_parser.y"
12545 + yygotominor.yy20 = strtol(yymsp[0].minor.yy0->ptr, &err, 10);
12547 + if (*err != '\0') {
12548 + buffer_copy_string(ctx->errmsg, "expected a number: ");
12549 + buffer_append_string_buffer(ctx->errmsg, yymsp[0].minor.yy0);
12554 +#line 627 "http_resp_parser.c"
12557 +#line 93 "./http_resp_parser.y"
12559 + buffer_copy_string_buffer(yygotominor.yy0, yymsp[0].minor.yy0);
12561 +#line 634 "http_resp_parser.c"
12564 +#line 97 "./http_resp_parser.y"
12566 + yygotominor.yy0 = yymsp[-1].minor.yy0;
12568 + buffer_append_string(yygotominor.yy0, " ");
12569 + buffer_append_string_buffer(yygotominor.yy0, yymsp[0].minor.yy0);
12571 + yymsp[-1].minor.yy0 = NULL;
12573 +#line 646 "http_resp_parser.c"
12576 +#line 106 "./http_resp_parser.y"
12578 + yygotominor.yy12 = yymsp[-1].minor.yy12;
12580 + array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9);
12582 + yymsp[-1].minor.yy12 = NULL;
12584 +#line 657 "http_resp_parser.c"
12587 +#line 114 "./http_resp_parser.y"
12589 + yygotominor.yy12 = array_init();
12591 + array_insert_unique(yygotominor.yy12, (data_unset *)yymsp[0].minor.yy9);
12593 +#line 666 "http_resp_parser.c"
12596 +#line 119 "./http_resp_parser.y"
12598 + yygotominor.yy9 = data_string_init();
12600 + buffer_copy_string_buffer(yygotominor.yy9->key, yymsp[-3].minor.yy0);
12601 + buffer_copy_string_buffer(yygotominor.yy9->value, yymsp[-1].minor.yy0);
12603 +#line 676 "http_resp_parser.c"
12604 + yy_destructor(3,&yymsp[-2].minor);
12605 + yy_destructor(1,&yymsp[0].minor);
12608 + yygoto = yyRuleInfo[yyruleno].lhs;
12609 + yysize = yyRuleInfo[yyruleno].nrhs;
12610 + yypParser->yyidx -= yysize;
12611 + yyact = yy_find_reduce_action(yypParser,yygoto);
12612 + if( yyact < YYNSTATE ){
12613 + yy_shift(yypParser,yyact,yygoto,&yygotominor);
12614 + }else if( yyact == YYNSTATE + YYNRULE + 1 ){
12615 + yy_accept(yypParser);
12620 +** The following code executes when the parse fails
12622 +static void yy_parse_failed(
12623 + yyParser *yypParser /* The parser */
12625 + http_resp_parserARG_FETCH;
12627 + if( yyTraceFILE ){
12628 + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
12631 + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
12632 + /* Here code is inserted which will be executed whenever the
12633 + ** parser fails */
12634 +#line 14 "./http_resp_parser.y"
12638 +#line 711 "http_resp_parser.c"
12639 + http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
12643 +** The following code executes when a syntax error first occurs.
12645 +static void yy_syntax_error(
12646 + yyParser *yypParser, /* The parser */
12647 + int yymajor, /* The major type of the error token */
12648 + YYMINORTYPE yyminor /* The minor type of the error token */
12650 + http_resp_parserARG_FETCH;
12651 +#define TOKEN (yyminor.yy0)
12652 + http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
12656 +** The following is executed when the parser accepts
12658 +static void yy_accept(
12659 + yyParser *yypParser /* The parser */
12661 + http_resp_parserARG_FETCH;
12663 + if( yyTraceFILE ){
12664 + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
12667 + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
12668 + /* Here code is inserted which will be executed whenever the
12669 + ** parser accepts */
12670 + http_resp_parserARG_STORE; /* Suppress warning about unused %extra_argument variable */
12673 +/* The main parser program.
12674 +** The first argument is a pointer to a structure obtained from
12675 +** "http_resp_parserAlloc" which describes the current state of the parser.
12676 +** The second argument is the major token number. The third is
12677 +** the minor token. The fourth optional argument is whatever the
12678 +** user wants (and specified in the grammar) and is available for
12679 +** use by the action routines.
12683 +** <li> A pointer to the parser (an opaque structure.)
12684 +** <li> The major token number.
12685 +** <li> The minor token number.
12686 +** <li> An option argument of a grammar-specified type.
12692 +void http_resp_parser(
12693 + void *yyp, /* The parser */
12694 + int yymajor, /* The major token code number */
12695 + http_resp_parserTOKENTYPE yyminor /* The value for the token */
12696 + http_resp_parserARG_PDECL /* Optional %extra_argument parameter */
12698 + YYMINORTYPE yyminorunion;
12699 + int yyact; /* The parser action. */
12700 + int yyendofinput; /* True if we are at the end of input */
12701 + int yyerrorhit = 0; /* True if yymajor has invoked an error */
12702 + yyParser *yypParser; /* The parser */
12704 + /* (re)initialize the parser, if necessary */
12705 + yypParser = (yyParser*)yyp;
12706 + if( yypParser->yyidx<0 ){
12707 + if( yymajor==0 ) return;
12708 + yypParser->yyidx = 0;
12709 + yypParser->yyerrcnt = -1;
12710 + yypParser->yystack[0].stateno = 0;
12711 + yypParser->yystack[0].major = 0;
12713 + yyminorunion.yy0 = yyminor;
12714 + yyendofinput = (yymajor==0);
12715 + http_resp_parserARG_STORE;
12718 + if( yyTraceFILE ){
12719 + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
12724 + yyact = yy_find_shift_action(yypParser,yymajor);
12725 + if( yyact<YYNSTATE ){
12726 + yy_shift(yypParser,yyact,yymajor,&yyminorunion);
12727 + yypParser->yyerrcnt--;
12728 + if( yyendofinput && yypParser->yyidx>=0 ){
12731 + yymajor = YYNOCODE;
12733 + }else if( yyact < YYNSTATE + YYNRULE ){
12734 + yy_reduce(yypParser,yyact-YYNSTATE);
12735 + }else if( yyact == YY_ERROR_ACTION ){
12738 + if( yyTraceFILE ){
12739 + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
12742 +#ifdef YYERRORSYMBOL
12743 + /* A syntax error has occurred.
12744 + ** The response to an error depends upon whether or not the
12745 + ** grammar defines an error token "ERROR".
12747 + ** This is what we do if the grammar does define ERROR:
12749 + ** * Call the %syntax_error function.
12751 + ** * Begin popping the stack until we enter a state where
12752 + ** it is legal to shift the error symbol, then shift
12753 + ** the error symbol.
12755 + ** * Set the error count to three.
12757 + ** * Begin accepting and shifting new tokens. No new error
12758 + ** processing will occur until three tokens have been
12759 + ** shifted successfully.
12762 + if( yypParser->yyerrcnt<0 ){
12763 + yy_syntax_error(yypParser,yymajor,yyminorunion);
12765 + yymx = yypParser->yystack[yypParser->yyidx].major;
12766 + if( yymx==YYERRORSYMBOL || yyerrorhit ){
12768 + if( yyTraceFILE ){
12769 + fprintf(yyTraceFILE,"%sDiscard input token %s\n",
12770 + yyTracePrompt,yyTokenName[yymajor]);
12773 + yy_destructor(yymajor,&yyminorunion);
12774 + yymajor = YYNOCODE;
12777 + yypParser->yyidx >= 0 &&
12778 + yymx != YYERRORSYMBOL &&
12779 + (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE
12781 + yy_pop_parser_stack(yypParser);
12783 + if( yypParser->yyidx < 0 || yymajor==0 ){
12784 + yy_destructor(yymajor,&yyminorunion);
12785 + yy_parse_failed(yypParser);
12786 + yymajor = YYNOCODE;
12787 + }else if( yymx!=YYERRORSYMBOL ){
12789 + u2.YYERRSYMDT = 0;
12790 + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
12793 + yypParser->yyerrcnt = 3;
12795 +#else /* YYERRORSYMBOL is not defined */
12796 + /* This is what we do if the grammar does not define ERROR:
12798 + ** * Report an error message, and throw away the input token.
12800 + ** * If the input token is $, then fail the parse.
12802 + ** As before, subsequent error messages are suppressed until
12803 + ** three input tokens have been successfully shifted.
12805 + if( yypParser->yyerrcnt<=0 ){
12806 + yy_syntax_error(yypParser,yymajor,yyminorunion);
12808 + yypParser->yyerrcnt = 3;
12809 + yy_destructor(yymajor,&yyminorunion);
12810 + if( yyendofinput ){
12811 + yy_parse_failed(yypParser);
12813 + yymajor = YYNOCODE;
12816 + yy_accept(yypParser);
12817 + yymajor = YYNOCODE;
12819 + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
12822 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/inet_ntop_cache.c lighttpd-1.4.12/src/inet_ntop_cache.c
12823 --- lighttpd-1.4.11/src/inet_ntop_cache.c 2005-08-11 01:26:38.000000000 +0300
12824 +++ lighttpd-1.4.12/src/inet_ntop_cache.c 2006-07-11 21:23:40.000000000 +0300
12826 #include "sys-socket.h"
12828 const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {
12832 for (i = 0; i < INET_NTOP_CACHE_MAX; i++) {
12833 if (srv->inet_ntop_cache[i].ts != 0) {
12834 @@ -20,31 +20,31 @@
12835 srv->inet_ntop_cache[i].addr.ipv4.s_addr == addr->ipv4.sin_addr.s_addr) {
12836 /* IPv4 found in cache */
12845 if (i == INET_NTOP_CACHE_MAX) {
12846 /* not found in cache */
12850 - inet_ntop(addr->plain.sa_family,
12851 - addr->plain.sa_family == AF_INET6 ?
12852 + inet_ntop(addr->plain.sa_family,
12853 + addr->plain.sa_family == AF_INET6 ?
12854 (const void *) &(addr->ipv6.sin6_addr) :
12855 (const void *) &(addr->ipv4.sin_addr),
12856 srv->inet_ntop_cache[i].b2, INET6_ADDRSTRLEN);
12859 srv->inet_ntop_cache[i].ts = srv->cur_ts;
12860 srv->inet_ntop_cache[i].family = addr->plain.sa_family;
12863 if (srv->inet_ntop_cache[i].family == AF_INET) {
12864 srv->inet_ntop_cache[i].addr.ipv4.s_addr = addr->ipv4.sin_addr.s_addr;
12865 } else if (srv->inet_ntop_cache[i].family == AF_INET6) {
12866 memcpy(srv->inet_ntop_cache[i].addr.ipv6.s6_addr, addr->ipv6.sin6_addr.s6_addr, 16);
12871 return srv->inet_ntop_cache[i].b2;
12874 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/joblist.c lighttpd-1.4.12/src/joblist.c
12875 --- lighttpd-1.4.11/src/joblist.c 2005-08-11 01:26:41.000000000 +0300
12876 +++ lighttpd-1.4.12/src/joblist.c 2006-07-11 21:23:39.000000000 +0300
12879 int joblist_append(server *srv, connection *con) {
12880 if (con->in_joblist) return 0;
12883 if (srv->joblist->size == 0) {
12884 srv->joblist->size = 16;
12885 srv->joblist->ptr = malloc(sizeof(*srv->joblist->ptr) * srv->joblist->size);
12886 @@ -15,15 +15,15 @@
12887 srv->joblist->size += 16;
12888 srv->joblist->ptr = realloc(srv->joblist->ptr, sizeof(*srv->joblist->ptr) * srv->joblist->size);
12892 srv->joblist->ptr[srv->joblist->used++] = con;
12898 void joblist_free(server *srv, connections *joblist) {
12902 free(joblist->ptr);
12905 @@ -31,14 +31,14 @@
12906 connection *fdwaitqueue_unshift(server *srv, connections *fdwaitqueue) {
12913 if (fdwaitqueue->used == 0) return NULL;
12916 con = fdwaitqueue->ptr[0];
12919 memmove(fdwaitqueue->ptr, &(fdwaitqueue->ptr[1]), --fdwaitqueue->used * sizeof(*(fdwaitqueue->ptr)));
12926 srv->fdwaitqueue->size += 16;
12927 srv->fdwaitqueue->ptr = realloc(srv->fdwaitqueue->ptr, sizeof(*(srv->fdwaitqueue->ptr)) * srv->fdwaitqueue->size);
12931 srv->fdwaitqueue->ptr[srv->fdwaitqueue->used++] = con;
12937 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/keyvalue.c lighttpd-1.4.12/src/keyvalue.c
12938 --- lighttpd-1.4.11/src/keyvalue.c 2006-03-02 16:08:06.000000000 +0200
12939 +++ lighttpd-1.4.12/src/keyvalue.c 2006-07-11 21:23:40.000000000 +0300
12941 { 504, "Gateway Timeout" },
12942 { 505, "HTTP Version Not Supported" },
12943 { 507, "Insufficient Storage" }, /* WebDAV */
12945 + { 509, "Bandwidth Limit exceeded" },
12950 @@ -102,12 +103,12 @@
12951 { 501, "501.html" },
12952 { 503, "503.html" },
12953 { 505, "505.html" },
12960 -const char *keyvalue_get_value(keyvalue *kv, int k) {
12961 +const char *keyvalue_get_value(keyvalue *kv, int k) {
12963 for (i = 0; kv[i].value; i++) {
12964 if (kv[i].key == k) return kv[i].value;
12965 @@ -115,7 +116,7 @@
12969 -int keyvalue_get_key(keyvalue *kv, const char *s) {
12970 +int keyvalue_get_key(keyvalue *kv, const char *s) {
12972 for (i = 0; kv[i].value; i++) {
12973 if (0 == strcmp(kv[i].value, s)) return kv[i].key;
12974 @@ -125,9 +126,9 @@
12976 keyvalue_buffer *keyvalue_buffer_init(void) {
12977 keyvalue_buffer *kvb;
12980 kvb = calloc(1, sizeof(*kvb));
12986 @@ -135,49 +136,49 @@
12988 if (kvb->size == 0) {
12992 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
12995 for(i = 0; i < kvb->size; i++) {
12996 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
12998 } else if (kvb->used == kvb->size) {
13002 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
13005 for(i = kvb->used; i < kvb->size; i++) {
13006 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
13011 kvb->kv[kvb->used]->key = key;
13012 kvb->kv[kvb->used]->value = strdup(value);
13021 void keyvalue_buffer_free(keyvalue_buffer *kvb) {
13025 for (i = 0; i < kvb->size; i++) {
13026 if (kvb->kv[i]->value) free(kvb->kv[i]->value);
13031 if (kvb->kv) free(kvb->kv);
13038 s_keyvalue_buffer *s_keyvalue_buffer_init(void) {
13039 s_keyvalue_buffer *kvb;
13042 kvb = calloc(1, sizeof(*kvb));
13048 @@ -186,50 +187,50 @@
13049 if (kvb->size == 0) {
13054 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
13057 for(i = 0; i < kvb->size; i++) {
13058 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
13060 } else if (kvb->used == kvb->size) {
13064 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
13067 for(i = kvb->used; i < kvb->size; i++) {
13068 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
13073 kvb->kv[kvb->used]->key = key ? strdup(key) : NULL;
13074 kvb->kv[kvb->used]->value = strdup(value);
13083 void s_keyvalue_buffer_free(s_keyvalue_buffer *kvb) {
13087 for (i = 0; i < kvb->size; i++) {
13088 if (kvb->kv[i]->key) free(kvb->kv[i]->key);
13089 if (kvb->kv[i]->value) free(kvb->kv[i]->value);
13094 if (kvb->kv) free(kvb->kv);
13101 httpauth_keyvalue_buffer *httpauth_keyvalue_buffer_init(void) {
13102 httpauth_keyvalue_buffer *kvb;
13105 kvb = calloc(1, sizeof(*kvb));
13111 @@ -237,42 +238,42 @@
13113 if (kvb->size == 0) {
13117 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
13120 for(i = 0; i < kvb->size; i++) {
13121 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
13123 } else if (kvb->used == kvb->size) {
13127 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
13130 for(i = kvb->used; i < kvb->size; i++) {
13131 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
13136 kvb->kv[kvb->used]->key = strdup(key);
13137 kvb->kv[kvb->used]->realm = strdup(realm);
13138 kvb->kv[kvb->used]->type = type;
13147 void httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer *kvb) {
13151 for (i = 0; i < kvb->size; i++) {
13152 if (kvb->kv[i]->key) free(kvb->kv[i]->key);
13153 if (kvb->kv[i]->realm) free(kvb->kv[i]->realm);
13158 if (kvb->kv) free(kvb->kv);
13164 @@ -306,9 +307,9 @@
13166 pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) {
13167 pcre_keyvalue_buffer *kvb;
13170 kvb = calloc(1, sizeof(*kvb));
13176 @@ -319,46 +320,46 @@
13182 if (!key) return -1;
13185 if (kvb->size == 0) {
13190 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
13193 for(i = 0; i < kvb->size; i++) {
13194 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
13196 } else if (kvb->used == kvb->size) {
13200 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
13203 for(i = kvb->used; i < kvb->size; i++) {
13204 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
13209 kv = kvb->kv[kvb->used];
13210 if (NULL == (kv->key = pcre_compile(key,
13211 0, &errptr, &erroff, NULL))) {
13214 fprintf(stderr, "%s.%d: rexexp compilation error at %s\n", __FILE__, __LINE__, errptr);
13218 - if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
13219 + if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
13225 kv->value = buffer_init_string(value);
13234 @@ -380,9 +381,9 @@
13235 if (kv->value) buffer_free(kv->value);
13240 if (kvb->kv) free(kvb->kv);
13246 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/keyvalue.h lighttpd-1.4.12/src/keyvalue.h
13247 --- lighttpd-1.4.11/src/keyvalue.h 2006-03-02 16:08:06.000000000 +0200
13248 +++ lighttpd-1.4.12/src/keyvalue.h 2006-07-11 21:23:40.000000000 +0300
13254 - HTTP_METHOD_UNSET = -1,
13256 - HTTP_METHOD_POST,
13257 - HTTP_METHOD_HEAD,
13258 - HTTP_METHOD_OPTIONS,
13260 + HTTP_METHOD_UNSET = -1,
13262 + HTTP_METHOD_POST,
13263 + HTTP_METHOD_HEAD,
13264 + HTTP_METHOD_OPTIONS,
13265 HTTP_METHOD_PROPFIND, /* WebDAV */
13266 - HTTP_METHOD_MKCOL,
13268 - HTTP_METHOD_DELETE,
13269 - HTTP_METHOD_COPY,
13270 - HTTP_METHOD_MOVE,
13271 - HTTP_METHOD_PROPPATCH,
13272 + HTTP_METHOD_MKCOL,
13274 + HTTP_METHOD_DELETE,
13275 + HTTP_METHOD_COPY,
13276 + HTTP_METHOD_MOVE,
13277 + HTTP_METHOD_PROPPATCH,
13278 HTTP_METHOD_REPORT, /* DeltaV */
13279 HTTP_METHOD_CHECKOUT,
13280 HTTP_METHOD_CHECKIN,
13281 @@ -39,13 +39,13 @@
13299 pcre_extra *key_extra;
13313 httpauth_type type;
13314 } httpauth_keyvalue;
13315 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/lemon.c lighttpd-1.4.12/src/lemon.c
13316 --- lighttpd-1.4.11/src/lemon.c 2005-09-01 00:21:34.000000000 +0300
13317 +++ lighttpd-1.4.12/src/lemon.c 2006-07-11 21:23:40.000000000 +0300
13318 @@ -579,7 +579,7 @@
13321 /* Find a precedence symbol of every rule in the grammar.
13324 ** Those rules which have a precedence symbol coded in the input
13325 ** grammar using the "[symbol]" construct will already have the
13326 ** rp->precsym field filled. Other rules take as their precedence
13327 @@ -869,7 +869,7 @@
13328 cfp->status = INCOMPLETE;
13335 for(i=0; i<lemp->nstate; i++){
13336 @@ -900,7 +900,7 @@
13340 - /* Add all of the reduce actions
13341 + /* Add all of the reduce actions
13342 ** A reduce action is added for each element of the followset of
13343 ** a configuration which has its dot at the extreme right.
13345 @@ -1017,7 +1017,7 @@
13346 apx->type = RD_RESOLVED;
13351 apx->type==SH_RESOLVED ||
13352 apx->type==RD_RESOLVED ||
13353 apx->type==CONFLICT ||
13354 @@ -1350,7 +1350,7 @@
13355 OptInit(argv,options,stderr);
13357 printf("Lemon version 1.0\n");
13361 if( OptNArgs() < 1 ){
13362 fprintf(stderr,"Exactly one filename argument is required.\n");
13363 @@ -2031,7 +2031,7 @@
13367 - rp = (struct rule *)malloc( sizeof(struct rule) +
13368 + rp = (struct rule *)malloc( sizeof(struct rule) +
13369 sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs );
13371 ErrorMsg(psp->filename,psp->tokenlineno,
13372 @@ -2546,7 +2546,7 @@
13376 -/* Duplicate the input file without comments and without actions
13377 +/* Duplicate the input file without comments and without actions
13380 struct lemon *lemp;
13381 @@ -2822,7 +2822,7 @@
13382 PRIVATE FILE *tplt_open(lemp)
13383 struct lemon *lemp;
13390 @@ -2930,7 +2930,7 @@
13396 ** Generate code which executes when the rule "rp" is reduced. Write
13397 ** the code to "out". Make sure lineno stays up-to-date.
13399 @@ -3384,7 +3384,7 @@
13401 /* Output the yy_shift_ofst[] table */
13402 fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
13403 - fprintf(out, "static %s yy_shift_ofst[] = {\n",
13404 + fprintf(out, "static %s yy_shift_ofst[] = {\n",
13405 minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++;
13407 for(i=j=0; i<n; i++){
13408 @@ -3405,7 +3405,7 @@
13410 /* Output the yy_reduce_ofst[] table */
13411 fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++;
13412 - fprintf(out, "static %s yy_reduce_ofst[] = {\n",
13413 + fprintf(out, "static %s yy_reduce_ofst[] = {\n",
13414 minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++;
13416 for(i=j=0; i<n; i++){
13417 @@ -3480,7 +3480,7 @@
13418 tplt_xfer(lemp->name,in,out,&lineno);
13420 /* Generate code which executes every time a symbol is popped from
13421 - ** the stack while processing errors or while destroying the parser.
13422 + ** the stack while processing errors or while destroying the parser.
13423 ** (In other words, generate the %destructor actions)
13425 if( lemp->tokendest ){
13426 @@ -3522,7 +3522,7 @@
13427 tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno);
13428 tplt_xfer(lemp->name,in,out,&lineno);
13430 - /* Generate the table of rule information
13431 + /* Generate the table of rule information
13433 ** Note: This code depends on the fact that rules are number
13434 ** sequentually beginning with 0.
13435 @@ -3589,7 +3589,7 @@
13436 for(i=1; i<lemp->nterminal; i++){
13437 fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
13444 @@ -3630,7 +3630,7 @@
13450 /* Do not make a default if the number of rules to default
13451 ** is not at least 2 */
13452 if( nbest<2 ) continue;
13453 @@ -3781,7 +3781,7 @@
13457 - x1a->tbl = (x1node*)malloc(
13458 + x1a->tbl = (x1node*)malloc(
13459 (sizeof(x1node) + sizeof(x1node*))*1024 );
13462 @@ -3943,7 +3943,7 @@
13466 - x2a->tbl = (x2node*)malloc(
13467 + x2a->tbl = (x2node*)malloc(
13468 (sizeof(x2node) + sizeof(x2node*))*128 );
13471 @@ -4149,7 +4149,7 @@
13475 - x3a->tbl = (x3node*)malloc(
13476 + x3a->tbl = (x3node*)malloc(
13477 (sizeof(x3node) + sizeof(x3node*))*128 );
13480 @@ -4295,7 +4295,7 @@
13484 - x4a->tbl = (x4node*)malloc(
13485 + x4a->tbl = (x4node*)malloc(
13486 (sizeof(x4node) + sizeof(x4node*))*64 );
13489 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/lempar.c lighttpd-1.4.12/src/lempar.c
13490 --- lighttpd-1.4.11/src/lempar.c 2005-08-11 01:26:40.000000000 +0300
13491 +++ lighttpd-1.4.12/src/lempar.c 2006-07-11 21:23:39.000000000 +0300
13493 /* Next is all token values, in a form suitable for use by makeheaders.
13494 ** This section will be null unless lemon is run with the -m switch.
13498 ** These constants (all generated automatically by the parser generator)
13499 ** specify the various kinds of tokens (terminals) that the parser
13503 ** Each symbol here is a terminal symbol in the grammar.
13506 ** and nonterminals. "int" is used otherwise.
13507 ** YYNOCODE is a number of type YYCODETYPE which corresponds
13508 ** to no legal terminal or nonterminal number. This
13509 -** number is used to fill in empty slots of the hash
13510 +** number is used to fill in empty slots of the hash
13512 ** YYFALLBACK If defined, this indicates that one or more tokens
13513 ** have fall-back values which should be used if the
13515 ** and nonterminal numbers. "unsigned char" is
13516 ** used if there are fewer than 250 rules and
13517 ** states combined. "int" is used otherwise.
13518 -** ParseTOKENTYPE is the data type used for minor tokens given
13519 +** ParseTOKENTYPE is the data type used for minor tokens given
13520 ** directly to the parser from the tokenizer.
13521 ** YYMINORTYPE is the data type used for all minor tokens.
13522 ** This is typically a union of many types, one of
13524 /* Next are that tables used to determine what action to take based on the
13525 ** current state and lookahead token. These tables are used to implement
13526 ** functions that take a state number and lookahead value and return an
13527 -** action integer.
13528 +** action integer.
13530 ** Suppose the action integer is N. Then the action is determined as
13533 ** If the index value yy_shift_ofst[S]+X is out of range or if the value
13534 ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
13535 ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
13536 -** and that yy_default[S] should be used instead.
13537 +** and that yy_default[S] should be used instead.
13539 ** The formula above is for computing the action when the lookahead is
13540 ** a terminal symbol. If the lookahead is a non-terminal (as occurs after
13541 @@ -111,7 +111,7 @@
13543 /* The next table maps tokens into fallback tokens. If a construct
13544 ** like the following:
13547 ** %fallback ID X Y Z.
13549 ** appears in the grammer, then ID becomes a fallback token for X, Y,
13550 @@ -163,10 +163,10 @@
13551 #endif /* NDEBUG */
13556 ** Turn parser tracing on by giving a stream to which to write the trace
13557 ** and a prompt to preface each trace message. Tracing is turned off
13558 -** by making either argument NULL
13559 +** by making either argument NULL
13563 @@ -191,7 +191,7 @@
13565 /* For tracing shifts, the names of all terminals and nonterminals
13566 ** are required. The following table supplies these names */
13567 -static const char *yyTokenName[] = {
13568 +static const char *yyTokenName[] = {
13571 #endif /* NDEBUG */
13572 @@ -220,7 +220,7 @@
13578 ** This function allocates a new parser.
13579 ** The only argument is a pointer to a function which works like
13581 @@ -251,7 +251,7 @@
13582 /* Here is inserted the actions which take place when a
13583 ** terminal or non-terminal is destroyed. This can happen
13584 ** when the symbol is popped from the stack during a
13585 - ** reduce or during error processing or when a parser is
13586 + ** reduce or during error processing or when a parser is
13587 ** being destroyed before it is finished parsing.
13589 ** Note: during a reduce, the only symbols destroyed are those
13590 @@ -289,7 +289,7 @@
13596 ** Deallocate and destroy a parser. Destructors are all called for
13597 ** all stack elements before shutting the parser down.
13599 @@ -325,7 +325,7 @@
13602 int stateno = pParser->yystack[pParser->yyidx].stateno;
13605 /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */
13606 i = yy_shift_ofst[stateno];
13607 if( i==YY_SHIFT_USE_DFLT ){
13608 @@ -369,7 +369,7 @@
13611 int stateno = pParser->yystack[pParser->yyidx].stateno;
13614 i = yy_reduce_ofst[stateno];
13615 if( i==YY_REDUCE_USE_DFLT ){
13616 return yy_default[stateno];
13617 @@ -455,7 +455,7 @@
13619 yymsp = &yypParser->yystack[yypParser->yyidx];
13621 - if( yyTraceFILE && yyruleno>=0
13622 + if( yyTraceFILE && yyruleno>=0
13623 && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
13624 fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
13625 yyRuleName[yyruleno]);
13626 @@ -608,7 +608,7 @@
13627 #ifdef YYERRORSYMBOL
13628 /* A syntax error has occurred.
13629 ** The response to an error depends upon whether or not the
13630 - ** grammar defines an error token "ERROR".
13631 + ** grammar defines an error token "ERROR".
13633 ** This is what we do if the grammar does define ERROR:
13635 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/log.c lighttpd-1.4.12/src/log.c
13636 --- lighttpd-1.4.11/src/log.c 2005-11-07 15:01:35.000000000 +0200
13637 +++ lighttpd-1.4.12/src/log.c 2006-07-11 21:23:40.000000000 +0300
13642 -#include <unistd.h>
13643 #include <string.h>
13644 #include <stdlib.h>
13647 #include "config.h"
13651 +#undef HAVE_SYSLOG_H
13654 #ifdef HAVE_SYSLOG_H
13655 #include <syslog.h>
13661 +#include "sys-files.h"
13663 #ifdef HAVE_VALGRIND_VALGRIND_H
13664 #include <valgrind/valgrind.h>
13666 @@ -31,38 +36,38 @@
13667 # define O_LARGEFILE 0
13672 * open the errorlog
13675 * we have 3 possibilities:
13676 * - stderr (default)
13682 * if the open failed, report to the user and die
13687 int log_error_open(server *srv) {
13689 int close_stderr = 1;
13692 #ifdef HAVE_SYSLOG_H
13693 /* perhaps someone wants to use syslog() */
13694 openlog("lighttpd", LOG_CONS | LOG_PID, LOG_DAEMON);
13696 srv->errorlog_mode = ERRORLOG_STDERR;
13699 if (srv->srvconf.errorlog_use_syslog) {
13700 srv->errorlog_mode = ERRORLOG_SYSLOG;
13701 } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
13702 const char *logfile = srv->srvconf.errorlog_file->ptr;
13705 if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
13706 - log_error_write(srv, __FILE__, __LINE__, "SSSS",
13707 + log_error_write(srv, __FILE__, __LINE__, "SSSS",
13708 "opening errorlog '", logfile,
13709 "' failed: ", strerror(errno));
13715 @@ -71,15 +76,15 @@
13717 srv->errorlog_mode = ERRORLOG_FILE;
13721 log_error_write(srv, __FILE__, __LINE__, "s", "server started");
13724 #ifdef HAVE_VALGRIND_VALGRIND_H
13725 /* don't close stderr for debugging purposes if run in valgrind */
13726 if (RUNNING_ON_VALGRIND) close_stderr = 0;
13728 if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0;
13731 /* move stderr to /dev/null */
13732 if (close_stderr &&
13733 -1 != (fd = open("/dev/null", O_WRONLY))) {
13734 @@ -90,33 +95,33 @@
13740 * open the errorlog
13743 * if the open failed, report to the user and die
13744 * if no filename is given, use syslog instead
13749 int log_error_cycle(server *srv) {
13750 /* only cycle if we are not in syslog-mode */
13753 if (srv->errorlog_mode == ERRORLOG_FILE) {
13754 const char *logfile = srv->srvconf.errorlog_file->ptr;
13755 /* already check of opening time */
13761 if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
13762 /* write to old log */
13763 - log_error_write(srv, __FILE__, __LINE__, "SSSSS",
13764 + log_error_write(srv, __FILE__, __LINE__, "SSSSS",
13765 "cycling errorlog '", logfile,
13766 "' failed: ", strerror(errno),
13767 ", falling back to syslog()");
13770 close(srv->errorlog_fd);
13771 srv->errorlog_fd = -1;
13772 -#ifdef HAVE_SYSLOG_H
13773 +#ifdef HAVE_SYSLOG_H
13774 srv->errorlog_mode = ERRORLOG_SYSLOG;
13777 @@ -125,15 +130,15 @@
13778 srv->errorlog_fd = new_fd;
13783 log_error_write(srv, __FILE__, __LINE__, "s", "logfiles cycled");
13789 int log_error_close(server *srv) {
13790 log_error_write(srv, __FILE__, __LINE__, "s", "server stopped");
13793 switch(srv->errorlog_mode) {
13794 case ERRORLOG_FILE:
13795 close(srv->errorlog_fd);
13796 @@ -146,13 +151,13 @@
13797 case ERRORLOG_STDERR:
13805 int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...) {
13809 switch(srv->errorlog_mode) {
13810 case ERRORLOG_FILE:
13811 case ERRORLOG_STDERR:
13812 @@ -161,7 +166,7 @@
13813 buffer_prepare_copy(srv->ts_debug_str, 255);
13814 strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
13815 srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1;
13818 srv->last_generated_debug_ts = srv->cur_ts;
13821 @@ -173,19 +178,19 @@
13822 BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "(");
13827 buffer_append_string(srv->errorlog_buf, filename);
13828 BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ".");
13829 buffer_append_long(srv->errorlog_buf, line);
13830 BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") ");
13835 for(va_start(ap, fmt); *fmt; fmt++) {
13843 case 's': /* string */
13844 s = va_arg(ap, char *);
13845 @@ -227,7 +232,7 @@
13854 @@ -236,7 +241,7 @@
13860 switch(srv->errorlog_mode) {
13861 case ERRORLOG_FILE:
13862 BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
13863 @@ -246,11 +251,13 @@
13864 BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
13865 write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
13867 +#ifdef HAVE_SYSLOG_H
13868 case ERRORLOG_SYSLOG:
13869 syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
13878 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/log.h lighttpd-1.4.12/src/log.h
13879 --- lighttpd-1.4.11/src/log.h 2005-08-11 01:26:36.000000000 +0300
13880 +++ lighttpd-1.4.12/src/log.h 2006-07-11 21:23:40.000000000 +0300
13882 int log_error_close(server *srv);
13883 int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...);
13884 int log_error_cycle(server *srv);
13888 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/md5.h lighttpd-1.4.12/src/md5.h
13889 --- lighttpd-1.4.11/src/md5.h 2005-11-17 16:20:40.000000000 +0200
13890 +++ lighttpd-1.4.12/src/md5.h 2006-07-11 21:23:40.000000000 +0300
13892 # include <inttypes.h>
13896 +#define UINT4 unsigned __int32
13897 +#define UINT2 unsigned __int16
13898 +#define POINTER unsigned char *
13900 #define UINT4 uint32_t
13901 #define UINT2 uint16_t
13902 #define POINTER unsigned char *
13907 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_access.c lighttpd-1.4.12/src/mod_access.c
13908 --- lighttpd-1.4.11/src/mod_access.c 2006-01-14 19:44:54.000000000 +0200
13909 +++ lighttpd-1.4.12/src/mod_access.c 2006-07-11 21:23:40.000000000 +0300
13910 @@ -8,126 +8,125 @@
13912 #include "plugin.h"
13914 +#include "sys-strings.h"
13917 array *access_deny;
13924 plugin_config **config_storage;
13926 - plugin_config conf;
13928 + plugin_config conf;
13931 INIT_FUNC(mod_access_init) {
13935 p = calloc(1, sizeof(*p));
13941 FREE_FUNC(mod_access_free) {
13942 plugin_data *p = p_d;
13947 if (!p) return HANDLER_GO_ON;
13950 if (p->config_storage) {
13952 for (i = 0; i < srv->config_context->used; i++) {
13953 plugin_config *s = p->config_storage[i];
13956 array_free(s->access_deny);
13961 free(p->config_storage);
13968 return HANDLER_GO_ON;
13971 SETDEFAULTS_FUNC(mod_access_set_defaults) {
13972 plugin_data *p = p_d;
13975 - config_values_t cv[] = {
13977 + config_values_t cv[] = {
13978 { "url.access-deny", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },
13979 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
13983 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
13986 for (i = 0; i < srv->config_context->used; i++) {
13990 s = calloc(1, sizeof(plugin_config));
13991 s->access_deny = array_init();
13994 cv[0].destination = s->access_deny;
13997 p->config_storage[i] = s;
14000 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
14001 return HANDLER_ERROR;
14006 return HANDLER_GO_ON;
14009 -#define PATCH(x) \
14010 - p->conf.x = s->x;
14011 static int mod_access_patch_connection(server *srv, connection *con, plugin_data *p) {
14013 plugin_config *s = p->config_storage[0];
14015 - PATCH(access_deny);
14017 + PATCH_OPTION(access_deny);
14019 /* skip the first, the global context */
14020 for (i = 1; i < srv->config_context->used; i++) {
14021 data_config *dc = (data_config *)srv->config_context->data[i];
14022 s = p->config_storage[i];
14025 /* condition didn't match */
14026 if (!config_check_cond(srv, con, dc)) continue;
14030 for (j = 0; j < dc->value->used; j++) {
14031 data_unset *du = dc->value->data[j];
14034 if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-deny"))) {
14035 - PATCH(access_deny);
14036 + PATCH_OPTION(access_deny);
14046 URIHANDLER_FUNC(mod_access_uri_handler) {
14047 plugin_data *p = p_d;
14052 if (con->uri.path->used == 0) return HANDLER_GO_ON;
14055 mod_access_patch_connection(srv, con, p);
14058 s_len = con->uri.path->used - 1;
14061 for (k = 0; k < p->conf.access_deny->used; k++) {
14062 data_string *ds = (data_string *)p->conf.access_deny->data[k];
14063 int ct_len = ds->value->used - 1;
14066 if (ct_len > s_len) continue;
14069 if (ds->value->used == 0) continue;
14071 /* if we have a case-insensitive FS we have to lower-case the URI here too */
14072 @@ -135,18 +134,18 @@
14073 if (con->conf.force_lowercase_filenames) {
14074 if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
14075 con->http_status = 403;
14078 return HANDLER_FINISHED;
14081 if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
14082 con->http_status = 403;
14085 return HANDLER_FINISHED;
14092 return HANDLER_GO_ON;
14094 @@ -155,13 +154,13 @@
14095 int mod_access_plugin_init(plugin *p) {
14096 p->version = LIGHTTPD_VERSION_ID;
14097 p->name = buffer_init_string("access");
14100 p->init = mod_access_init;
14101 p->set_defaults = mod_access_set_defaults;
14102 p->handle_uri_clean = mod_access_uri_handler;
14103 p->cleanup = mod_access_free;
14111 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_accesslog.c lighttpd-1.4.12/src/mod_accesslog.c
14112 --- lighttpd-1.4.11/src/mod_accesslog.c 2006-01-31 14:01:43.000000000 +0200
14113 +++ lighttpd-1.4.12/src/mod_accesslog.c 2006-07-11 21:23:40.000000000 +0300
14116 #include <stdlib.h>
14117 #include <string.h>
14118 -#include <fcntl.h>
14119 -#include <unistd.h>
14120 +#include <fcntl.h> /* only the defines on windows */
14125 #include "inet_ntop_cache.h"
14127 #include "sys-socket.h"
14128 +#include "sys-files.h"
14130 #ifdef HAVE_SYSLOG_H
14131 # include <syslog.h>
14139 FORMAT_UNSUPPORTED,
14143 FORMAT_BYTES_OUT_NO_HEADER,
14147 FORMAT_REMOTE_ADDR,
14150 @@ -59,20 +59,20 @@
14151 FORMAT_CONNECTION_STATUS,
14156 FORMAT_RESPONSE_HEADER
14165 * "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
14170 -const format_mapping fmap[] =
14172 +const format_mapping fmap[] =
14174 { '%', FORMAT_PERCENT },
14175 { 'h', FORMAT_REMOTE_HOST },
14176 { 'l', FORMAT_REMOTE_IDENT },
14178 { 's', FORMAT_STATUS },
14179 { 'b', FORMAT_BYTES_OUT_NO_HEADER },
14180 { 'i', FORMAT_HEADER },
14183 { 'a', FORMAT_REMOTE_ADDR },
14184 { 'A', FORMAT_LOCAL_ADDR },
14185 { 'B', FORMAT_BYTES_OUT_NO_HEADER },
14186 @@ -103,23 +103,23 @@
14187 { 'X', FORMAT_CONNECTION_STATUS },
14188 { 'I', FORMAT_BYTES_IN },
14189 { 'O', FORMAT_BYTES_OUT },
14192 { 'o', FORMAT_RESPONSE_HEADER },
14195 { '\0', FORMAT_UNSET }
14200 enum { FIELD_UNSET, FIELD_STRING, FIELD_FORMAT } type;
14208 format_field **ptr;
14214 @@ -128,39 +128,39 @@
14215 buffer *access_logfile;
14217 unsigned short use_syslog;
14223 time_t last_generated_accesslog_ts;
14224 time_t *last_generated_accesslog_ts_ptr;
14229 buffer *access_logbuffer;
14230 buffer *ts_accesslog_str;
14233 format_fields *parsed_format;
14240 plugin_config **config_storage;
14241 - plugin_config conf;
14242 + plugin_config conf;
14245 INIT_FUNC(mod_accesslog_init) {
14249 p = calloc(1, sizeof(*p));
14255 int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
14256 size_t i, j, k = 0, start = 0;
14259 for (i = 0; i < format->used - 1; i++) {
14262 switch(format->ptr[i]) {
14265 @@ -173,19 +173,19 @@
14266 fields->size += 16;
14267 fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
14271 fields->ptr[fields->used] = malloc(sizeof(format_fields));
14272 fields->ptr[fields->used]->type = FIELD_STRING;
14273 fields->ptr[fields->used]->string = buffer_init();
14276 buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start);
14285 /* we need a new field */
14288 if (fields->size == 0) {
14291 @@ -194,43 +194,43 @@
14292 fields->size += 16;
14293 fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
14297 /* search for the terminating command */
14298 switch (format->ptr[i+1]) {
14304 for (j = 0; fmap[j].key != '\0'; j++) {
14305 if (fmap[j].key != format->ptr[i+2]) continue;
14311 fields->ptr[fields->used] = malloc(sizeof(format_fields));
14312 fields->ptr[fields->used]->type = FIELD_FORMAT;
14313 fields->ptr[fields->used]->field = fmap[j].type;
14314 fields->ptr[fields->used]->string = NULL;
14324 if (fmap[j].key == '\0') {
14325 log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
14335 /* go forward to } */
14338 for (k = i+2; k < format->used - 1; k++) {
14339 if (format->ptr[k] == '}') break;
14343 if (k == format->used - 1) {
14344 log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
14346 @@ -239,62 +239,62 @@
14347 log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
14352 for (j = 0; fmap[j].key != '\0'; j++) {
14353 if (fmap[j].key != format->ptr[k+1]) continue;
14359 fields->ptr[fields->used] = malloc(sizeof(format_fields));
14360 fields->ptr[fields->used]->type = FIELD_FORMAT;
14361 fields->ptr[fields->used]->field = fmap[j].type;
14362 fields->ptr[fields->used]->string = buffer_init();
14365 buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + i + 2, k - (i + 2));
14375 if (fmap[j].key == '\0') {
14376 log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
14386 for (j = 0; fmap[j].key != '\0'; j++) {
14387 if (fmap[j].key != format->ptr[i+1]) continue;
14393 fields->ptr[fields->used] = malloc(sizeof(format_fields));
14394 fields->ptr[fields->used]->type = FIELD_FORMAT;
14395 fields->ptr[fields->used]->field = fmap[j].type;
14396 fields->ptr[fields->used]->string = NULL;
14406 if (fmap[j].key == '\0') {
14407 log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
14425 /* copy the string */
14426 if (fields->size == 0) {
14427 @@ -305,32 +305,32 @@
14428 fields->size += 16;
14429 fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
14433 fields->ptr[fields->used] = malloc(sizeof(format_fields));
14434 fields->ptr[fields->used]->type = FIELD_STRING;
14435 fields->ptr[fields->used]->string = buffer_init();
14438 buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start);
14448 FREE_FUNC(mod_accesslog_free) {
14449 plugin_data *p = p_d;
14453 if (!p) return HANDLER_GO_ON;
14456 if (p->config_storage) {
14459 for (i = 0; i < srv->config_context->used; i++) {
14460 plugin_config *s = p->config_storage[i];
14465 if (s->access_logbuffer->used) {
14466 if (s->use_syslog) {
14467 # ifdef HAVE_SYSLOG_H
14468 @@ -342,14 +342,14 @@
14469 write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
14474 if (s->log_access_fd != -1) close(s->log_access_fd);
14477 buffer_free(s->ts_accesslog_str);
14478 buffer_free(s->access_logbuffer);
14479 buffer_free(s->format);
14480 buffer_free(s->access_logfile);
14483 if (s->parsed_format) {
14485 for (j = 0; j < s->parsed_format->used; j++) {
14486 @@ -359,36 +359,36 @@
14487 free(s->parsed_format->ptr);
14488 free(s->parsed_format);
14496 free(p->config_storage);
14503 return HANDLER_GO_ON;
14506 SETDEFAULTS_FUNC(log_access_open) {
14507 plugin_data *p = p_d;
14510 - config_values_t cv[] = {
14512 + config_values_t cv[] = {
14513 { "accesslog.filename", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
14514 { "accesslog.use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
14515 { "accesslog.format", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
14516 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
14520 if (!p) return HANDLER_ERROR;
14523 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
14526 for (i = 0; i < srv->config_context->used; i++) {
14530 s = calloc(1, sizeof(plugin_config));
14531 s->access_logfile = buffer_init();
14532 s->format = buffer_init();
14533 @@ -397,44 +397,44 @@
14534 s->log_access_fd = -1;
14535 s->last_generated_accesslog_ts = 0;
14536 s->last_generated_accesslog_ts_ptr = &(s->last_generated_accesslog_ts);
14541 cv[0].destination = s->access_logfile;
14542 cv[1].destination = &(s->use_syslog);
14543 cv[2].destination = s->format;
14546 p->config_storage[i] = s;
14549 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
14550 return HANDLER_ERROR;
14554 if (i == 0 && buffer_is_empty(s->format)) {
14555 /* set a default logfile string */
14558 buffer_copy_string(s->format, "%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"");
14565 if (s->format->used) {
14566 s->parsed_format = calloc(1, sizeof(*(s->parsed_format)));
14569 if (-1 == accesslog_parse_format(srv, s->parsed_format, s->format)) {
14571 - log_error_write(srv, __FILE__, __LINE__, "sb",
14572 + log_error_write(srv, __FILE__, __LINE__, "sb",
14573 "parsing accesslog-definition failed:", s->format);
14575 return HANDLER_ERROR;
14580 for (j = 0; j < s->parsed_format->used; j++) {
14581 switch (s->parsed_format->ptr[j]->type) {
14583 - log_error_write(srv, __FILE__, __LINE__, "ssds",
14584 + log_error_write(srv, __FILE__, __LINE__, "ssds",
14585 "config:", "format", s->parsed_format->ptr[j]->field,
14586 - s->parsed_format->ptr[j]->string ?
14587 + s->parsed_format->ptr[j]->string ?
14588 s->parsed_format->ptr[j]->string->ptr : "" );
14591 @@ -446,52 +446,52 @@
14597 if (s->use_syslog) {
14598 /* ignore the next checks */
14603 if (buffer_is_empty(s->access_logfile)) continue;
14606 if (s->access_logfile->ptr[0] == '|') {
14608 /* create write pipe and spawn process */
14615 if (pipe(to_log_fds)) {
14616 log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
14617 return HANDLER_ERROR;
14622 switch (pid = fork()) {
14628 close(STDIN_FILENO);
14629 dup2(to_log_fds[0], STDIN_FILENO);
14630 close(to_log_fds[0]);
14632 close(to_log_fds[1]);
14635 /* we don't need the client socket */
14636 for (i = 3; i < 256; i++) {
14640 - /* exec the log-process (skip the | )
14643 + /* exec the log-process (skip the | )
14648 execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, NULL);
14650 - log_error_write(srv, __FILE__, __LINE__, "sss",
14651 - "spawning log-process failed: ", strerror(errno),
14652 + log_error_write(srv, __FILE__, __LINE__, "sss",
14653 + "spawning log-process failed: ", strerror(errno),
14654 s->access_logfile->ptr + 1);
14660 @@ -500,27 +500,28 @@
14663 close(to_log_fds[0]);
14666 s->log_access_fd = to_log_fds[1];
14674 - } else if (-1 == (s->log_access_fd =
14675 + } else if (-1 == (s->log_access_fd =
14676 open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
14678 - log_error_write(srv, __FILE__, __LINE__, "ssb",
14679 - "opening access-log failed:",
14681 + log_error_write(srv, __FILE__, __LINE__, "ssb",
14682 + "opening access-log failed:",
14683 strerror(errno), s->access_logfile);
14686 return HANDLER_ERROR;
14689 fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC);
14695 return HANDLER_GO_ON;
14698 @@ -529,7 +530,7 @@
14701 if (!p->config_storage) return HANDLER_GO_ON;
14704 for (i = 0; i < srv->config_context->used; i++) {
14705 plugin_config *s = p->config_storage[i];
14707 @@ -544,90 +545,87 @@
14708 } else if (s->log_access_fd != -1) {
14709 write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
14713 buffer_reset(s->access_logbuffer);
14717 if (s->use_syslog == 0 &&
14718 !buffer_is_empty(s->access_logfile) &&
14719 s->access_logfile->ptr[0] != '|') {
14722 close(s->log_access_fd);
14724 - if (-1 == (s->log_access_fd =
14726 + if (-1 == (s->log_access_fd =
14727 open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
14730 log_error_write(srv, __FILE__, __LINE__, "ss", "cycling access-log failed:", strerror(errno));
14733 return HANDLER_ERROR;
14739 return HANDLER_GO_ON;
14742 -#define PATCH(x) \
14743 - p->conf.x = s->x;
14744 static int mod_accesslog_patch_connection(server *srv, connection *con, plugin_data *p) {
14746 plugin_config *s = p->config_storage[0];
14748 - PATCH(access_logfile);
14750 - PATCH(log_access_fd);
14751 - PATCH(last_generated_accesslog_ts_ptr);
14752 - PATCH(access_logbuffer);
14753 - PATCH(ts_accesslog_str);
14754 - PATCH(parsed_format);
14755 - PATCH(use_syslog);
14758 + PATCH_OPTION(access_logfile);
14759 + PATCH_OPTION(format);
14760 + PATCH_OPTION(log_access_fd);
14761 + PATCH_OPTION(last_generated_accesslog_ts_ptr);
14762 + PATCH_OPTION(access_logbuffer);
14763 + PATCH_OPTION(ts_accesslog_str);
14764 + PATCH_OPTION(parsed_format);
14765 + PATCH_OPTION(use_syslog);
14767 /* skip the first, the global context */
14768 for (i = 1; i < srv->config_context->used; i++) {
14769 data_config *dc = (data_config *)srv->config_context->data[i];
14770 s = p->config_storage[i];
14773 /* condition didn't match */
14774 if (!config_check_cond(srv, con, dc)) continue;
14778 for (j = 0; j < dc->value->used; j++) {
14779 data_unset *du = dc->value->data[j];
14782 if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.filename"))) {
14783 - PATCH(access_logfile);
14784 - PATCH(log_access_fd);
14785 - PATCH(last_generated_accesslog_ts_ptr);
14786 - PATCH(access_logbuffer);
14787 - PATCH(ts_accesslog_str);
14788 + PATCH_OPTION(access_logfile);
14789 + PATCH_OPTION(log_access_fd);
14790 + PATCH_OPTION(last_generated_accesslog_ts_ptr);
14791 + PATCH_OPTION(access_logbuffer);
14792 + PATCH_OPTION(ts_accesslog_str);
14793 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.format"))) {
14795 - PATCH(parsed_format);
14796 + PATCH_OPTION(format);
14797 + PATCH_OPTION(parsed_format);
14798 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.use-syslog"))) {
14799 - PATCH(use_syslog);
14800 + PATCH_OPTION(use_syslog);
14810 REQUESTDONE_FUNC(log_access_write) {
14811 plugin_data *p = p_d;
14820 mod_accesslog_patch_connection(srv, con, p);
14823 b = p->conf.access_logbuffer;
14824 if (b->used == 0) {
14825 buffer_copy_string(b, "");
14829 for (j = 0; j < p->conf.parsed_format->used; j++) {
14830 switch(p->conf.parsed_format->ptr[j]->type) {
14832 @@ -636,14 +634,14 @@
14834 switch(p->conf.parsed_format->ptr[j]->field) {
14835 case FORMAT_TIMESTAMP:
14838 /* cache the generated timestamp */
14839 if (srv->cur_ts != *(p->conf.last_generated_accesslog_ts_ptr)) {
14841 #if defined(HAVE_STRUCT_TM_GMTOFF)
14842 long scd, hrs, min;
14846 buffer_prepare_copy(p->conf.ts_accesslog_str, 255);
14847 #if defined(HAVE_STRUCT_TM_GMTOFF)
14848 # ifdef HAVE_LOCALTIME_R
14849 @@ -653,17 +651,17 @@
14850 strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime_r(&(srv->cur_ts)));
14852 p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
14855 buffer_append_string(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-");
14858 scd = abs(tm.tm_gmtoff);
14860 min = (scd % 3600) / 60;
14864 if (hrs < 10) buffer_append_string(p->conf.ts_accesslog_str, "0");
14865 buffer_append_long(p->conf.ts_accesslog_str, hrs);
14868 if (min < 10) buffer_append_string(p->conf.ts_accesslog_str, "0");
14869 buffer_append_long(p->conf.ts_accesslog_str, min);
14870 BUFFER_APPEND_STRING_CONST(p->conf.ts_accesslog_str, "]");
14871 @@ -676,20 +674,20 @@
14873 p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
14877 *(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts;
14882 buffer_append_string_buffer(b, p->conf.ts_accesslog_str);
14886 case FORMAT_REMOTE_HOST:
14889 /* handle inet_ntop cache */
14892 buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
14896 case FORMAT_REMOTE_IDENT:
14898 @@ -710,10 +708,10 @@
14899 case FORMAT_STATUS:
14900 buffer_append_long(b, con->http_status);
14904 case FORMAT_BYTES_OUT_NO_HEADER:
14905 if (con->bytes_written > 0) {
14906 - buffer_append_off_t(b,
14907 + buffer_append_off_t(b,
14908 con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header);
14910 BUFFER_APPEND_STRING_CONST(b, "-");
14911 @@ -772,7 +770,7 @@
14914 case FORMAT_REQUEST_PROTOCOL:
14915 - buffer_append_string(b,
14916 + buffer_append_string(b,
14917 con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0");
14919 case FORMAT_REQUEST_METHOD:
14920 @@ -801,7 +799,7 @@
14921 { 'D', FORMAT_TIME_USED_MS },
14922 { 'e', FORMAT_ENV },
14929 @@ -809,7 +807,7 @@
14935 BUFFER_APPEND_STRING_CONST(b, "\n");
14937 if (p->conf.use_syslog || /* syslog doesn't cache */
14938 @@ -828,7 +826,7 @@
14944 return HANDLER_GO_ON;
14947 @@ -836,15 +834,15 @@
14948 int mod_accesslog_plugin_init(plugin *p) {
14949 p->version = LIGHTTPD_VERSION_ID;
14950 p->name = buffer_init_string("accesslog");
14953 p->init = mod_accesslog_init;
14954 p->set_defaults= log_access_open;
14955 p->cleanup = mod_accesslog_free;
14958 p->handle_request_done = log_access_write;
14959 p->handle_sighup = log_access_cycle;
14967 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_alias.c lighttpd-1.4.12/src/mod_alias.c
14968 --- lighttpd-1.4.11/src/mod_alias.c 2006-03-01 23:18:51.000000000 +0200
14969 +++ lighttpd-1.4.12/src/mod_alias.c 2006-07-11 21:23:39.000000000 +0300
14971 #include "buffer.h"
14973 #include "plugin.h"
14974 +#include "sys-strings.h"
14976 /* plugin config for all request/connections */
14978 @@ -16,44 +17,44 @@
14984 plugin_config **config_storage;
14986 - plugin_config conf;
14988 + plugin_config conf;
14991 /* init the plugin data */
14992 INIT_FUNC(mod_alias_init) {
14996 p = calloc(1, sizeof(*p));
15006 /* detroy the plugin data */
15007 FREE_FUNC(mod_alias_free) {
15008 plugin_data *p = p_d;
15011 if (!p) return HANDLER_GO_ON;
15014 if (p->config_storage) {
15018 for (i = 0; i < srv->config_context->used; i++) {
15019 plugin_config *s = p->config_storage[i];
15022 array_free(s->alias);
15027 free(p->config_storage);
15034 return HANDLER_GO_ON;
15037 @@ -62,25 +63,25 @@
15038 SETDEFAULTS_FUNC(mod_alias_set_defaults) {
15039 plugin_data *p = p_d;
15042 - config_values_t cv[] = {
15044 + config_values_t cv[] = {
15045 { "alias.url", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
15046 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
15050 if (!p) return HANDLER_ERROR;
15053 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
15056 for (i = 0; i < srv->config_context->used; i++) {
15060 s = calloc(1, sizeof(plugin_config));
15061 - s->alias = array_init();
15062 + s->alias = array_init();
15063 cv[0].destination = s->alias;
15066 p->config_storage[i] = s;
15069 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
15070 return HANDLER_ERROR;
15072 @@ -110,76 +111,73 @@
15078 return HANDLER_GO_ON;
15081 -#define PATCH(x) \
15082 - p->conf.x = s->x;
15083 static int mod_alias_patch_connection(server *srv, connection *con, plugin_data *p) {
15085 plugin_config *s = p->config_storage[0];
15090 + PATCH_OPTION(alias);
15092 /* skip the first, the global context */
15093 for (i = 1; i < srv->config_context->used; i++) {
15094 data_config *dc = (data_config *)srv->config_context->data[i];
15095 s = p->config_storage[i];
15098 /* condition didn't match */
15099 if (!config_check_cond(srv, con, dc)) continue;
15103 for (j = 0; j < dc->value->used; j++) {
15104 data_unset *du = dc->value->data[j];
15107 if (buffer_is_equal_string(du->key, CONST_STR_LEN("alias.url"))) {
15109 + PATCH_OPTION(alias);
15119 PHYSICALPATH_FUNC(mod_alias_physical_handler) {
15120 plugin_data *p = p_d;
15121 int uri_len, basedir_len;
15126 if (con->physical.path->used == 0) return HANDLER_GO_ON;
15129 mod_alias_patch_connection(srv, con, p);
15132 /* not to include the tailing slash */
15133 basedir_len = (con->physical.basedir->used - 1) - 1;
15134 uri_len = con->physical.path->used - 1 - basedir_len;
15135 uri_ptr = con->physical.path->ptr + basedir_len;
15138 for (k = 0; k < p->conf.alias->used; k++) {
15139 data_string *ds = (data_string *)p->conf.alias->data[k];
15140 int alias_len = ds->key->used - 1;
15143 if (alias_len > uri_len) continue;
15144 if (ds->key->used == 0) continue;
15147 if (0 == (con->conf.force_lowercase_filenames ?
15148 strncasecmp(uri_ptr, ds->key->ptr, alias_len) :
15149 strncmp(uri_ptr, ds->key->ptr, alias_len))) {
15153 buffer_copy_string_buffer(con->physical.basedir, ds->value);
15154 buffer_copy_string_buffer(srv->tmp_buf, ds->value);
15155 buffer_append_string(srv->tmp_buf, uri_ptr + alias_len);
15156 buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
15159 return HANDLER_GO_ON;
15165 return HANDLER_GO_ON;
15167 @@ -189,13 +187,13 @@
15168 int mod_alias_plugin_init(plugin *p) {
15169 p->version = LIGHTTPD_VERSION_ID;
15170 p->name = buffer_init_string("alias");
15173 p->init = mod_alias_init;
15174 p->handle_physical= mod_alias_physical_handler;
15175 p->set_defaults = mod_alias_set_defaults;
15176 p->cleanup = mod_alias_free;
15184 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_auth.c lighttpd-1.4.12/src/mod_auth.c
15185 --- lighttpd-1.4.11/src/mod_auth.c 2006-02-15 20:01:31.000000000 +0200
15186 +++ lighttpd-1.4.12/src/mod_auth.c 2006-07-11 21:23:40.000000000 +0300
15187 @@ -5,168 +5,167 @@
15188 #include <string.h>
15191 -#include <unistd.h>
15193 #include "plugin.h"
15194 #include "http_auth.h"
15196 #include "response.h"
15198 +#include "sys-strings.h"
15199 +#include "sys-files.h"
15201 handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
15205 * the basic and digest auth framework
15208 * - config handling
15209 * - protocol handling
15212 - * http_auth_digest.c
15216 + * http_auth_digest.c
15221 INIT_FUNC(mod_auth_init) {
15222 mod_auth_plugin_data *p;
15225 p = calloc(1, sizeof(*p));
15228 p->tmp_buf = buffer_init();
15231 p->auth_user = buffer_init();
15233 p->ldap_filter = buffer_init();
15240 FREE_FUNC(mod_auth_free) {
15241 mod_auth_plugin_data *p = p_d;
15246 if (!p) return HANDLER_GO_ON;
15249 buffer_free(p->tmp_buf);
15250 buffer_free(p->auth_user);
15252 buffer_free(p->ldap_filter);
15256 if (p->config_storage) {
15258 for (i = 0; i < srv->config_context->used; i++) {
15259 mod_auth_plugin_config *s = p->config_storage[i];
15265 array_free(s->auth_require);
15266 buffer_free(s->auth_plain_groupfile);
15267 buffer_free(s->auth_plain_userfile);
15268 buffer_free(s->auth_htdigest_userfile);
15269 buffer_free(s->auth_htpasswd_userfile);
15270 buffer_free(s->auth_backend_conf);
15273 buffer_free(s->auth_ldap_hostname);
15274 buffer_free(s->auth_ldap_basedn);
15275 buffer_free(s->auth_ldap_binddn);
15276 buffer_free(s->auth_ldap_bindpw);
15277 buffer_free(s->auth_ldap_filter);
15278 buffer_free(s->auth_ldap_cafile);
15282 buffer_free(s->ldap_filter_pre);
15283 buffer_free(s->ldap_filter_post);
15286 if (s->ldap) ldap_unbind_s(s->ldap);
15292 free(p->config_storage);
15299 return HANDLER_GO_ON;
15302 -#define PATCH(x) \
15303 - p->conf.x = s->x;
15304 static int mod_auth_patch_connection(server *srv, connection *con, mod_auth_plugin_data *p) {
15306 mod_auth_plugin_config *s = p->config_storage[0];
15308 - PATCH(auth_backend);
15309 - PATCH(auth_plain_groupfile);
15310 - PATCH(auth_plain_userfile);
15311 - PATCH(auth_htdigest_userfile);
15312 - PATCH(auth_htpasswd_userfile);
15313 - PATCH(auth_require);
15314 - PATCH(auth_debug);
15315 - PATCH(auth_ldap_hostname);
15316 - PATCH(auth_ldap_basedn);
15317 - PATCH(auth_ldap_binddn);
15318 - PATCH(auth_ldap_bindpw);
15319 - PATCH(auth_ldap_filter);
15320 - PATCH(auth_ldap_cafile);
15321 - PATCH(auth_ldap_starttls);
15322 + PATCH_OPTION(auth_backend);
15323 + PATCH_OPTION(auth_plain_groupfile);
15324 + PATCH_OPTION(auth_plain_userfile);
15325 + PATCH_OPTION(auth_htdigest_userfile);
15326 + PATCH_OPTION(auth_htpasswd_userfile);
15327 + PATCH_OPTION(auth_require);
15328 + PATCH_OPTION(auth_debug);
15329 + PATCH_OPTION(auth_ldap_hostname);
15330 + PATCH_OPTION(auth_ldap_basedn);
15331 + PATCH_OPTION(auth_ldap_binddn);
15332 + PATCH_OPTION(auth_ldap_bindpw);
15333 + PATCH_OPTION(auth_ldap_filter);
15334 + PATCH_OPTION(auth_ldap_cafile);
15335 + PATCH_OPTION(auth_ldap_starttls);
15338 - PATCH(ldap_filter_pre);
15339 - PATCH(ldap_filter_post);
15340 + PATCH_OPTION(ldap);
15341 + PATCH_OPTION(ldap_filter_pre);
15342 + PATCH_OPTION(ldap_filter_post);
15346 /* skip the first, the global context */
15347 for (i = 1; i < srv->config_context->used; i++) {
15348 data_config *dc = (data_config *)srv->config_context->data[i];
15349 s = p->config_storage[i];
15352 /* condition didn't match */
15353 if (!config_check_cond(srv, con, dc)) continue;
15357 for (j = 0; j < dc->value->used; j++) {
15358 data_unset *du = dc->value->data[j];
15361 if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend"))) {
15362 - PATCH(auth_backend);
15363 + PATCH_OPTION(auth_backend);
15364 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.groupfile"))) {
15365 - PATCH(auth_plain_groupfile);
15366 + PATCH_OPTION(auth_plain_groupfile);
15367 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.userfile"))) {
15368 - PATCH(auth_plain_userfile);
15369 + PATCH_OPTION(auth_plain_userfile);
15370 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htdigest.userfile"))) {
15371 - PATCH(auth_htdigest_userfile);
15372 + PATCH_OPTION(auth_htdigest_userfile);
15373 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htpasswd.userfile"))) {
15374 - PATCH(auth_htpasswd_userfile);
15375 + PATCH_OPTION(auth_htpasswd_userfile);
15376 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.require"))) {
15377 - PATCH(auth_require);
15378 + PATCH_OPTION(auth_require);
15379 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.debug"))) {
15380 - PATCH(auth_debug);
15381 + PATCH_OPTION(auth_debug);
15382 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.hostname"))) {
15383 - PATCH(auth_ldap_hostname);
15384 + PATCH_OPTION(auth_ldap_hostname);
15387 - PATCH(ldap_filter_pre);
15388 - PATCH(ldap_filter_post);
15389 + PATCH_OPTION(ldap);
15390 + PATCH_OPTION(ldap_filter_pre);
15391 + PATCH_OPTION(ldap_filter_post);
15393 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) {
15394 - PATCH(auth_ldap_basedn);
15395 + PATCH_OPTION(auth_ldap_basedn);
15396 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) {
15397 - PATCH(auth_ldap_filter);
15398 + PATCH_OPTION(auth_ldap_filter);
15399 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.ca-file"))) {
15400 - PATCH(auth_ldap_cafile);
15401 + PATCH_OPTION(auth_ldap_cafile);
15402 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) {
15403 - PATCH(auth_ldap_starttls);
15404 + PATCH_OPTION(auth_ldap_starttls);
15414 static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
15416 @@ -175,22 +174,22 @@
15418 mod_auth_plugin_data *p = p_d;
15422 /* select the right config */
15423 mod_auth_patch_connection(srv, con, p);
15426 if (p->conf.auth_require == NULL) return HANDLER_GO_ON;
15436 /* do we have to ask for auth ? */
15440 auth_satisfied = 0;
15443 /* search auth-directives for path */
15444 for (k = 0; k < p->conf.auth_require->used; k++) {
15445 buffer *req = p->conf.auth_require->data[k]->key;
15446 @@ -212,31 +211,31 @@
15452 /* nothing to do for us */
15453 if (auth_required == 0) return HANDLER_GO_ON;
15456 req = ((data_array *)(p->conf.auth_require->data[k]))->value;
15459 /* try to get Authorization-header */
15462 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization"))) {
15463 http_authorization = ds->value->ptr;
15467 if (ds && ds->value && ds->value->used) {
15469 data_string *method;
15472 method = (data_string *)array_get_element(req, "method");
15475 /* parse auth-header */
15476 if (NULL != (auth_realm = strchr(http_authorization, ' '))) {
15477 int auth_type_len = auth_realm - http_authorization;
15480 if ((auth_type_len == 5) &&
15481 (0 == strncmp(http_authorization, "Basic", auth_type_len))) {
15484 if (0 == strcmp(method->value->ptr, "basic")) {
15485 auth_satisfied = http_auth_basic_check(srv, con, p, req, con->uri.path, auth_realm+1);
15487 @@ -245,43 +244,43 @@
15488 if (0 == strcmp(method->value->ptr, "digest")) {
15489 if (-1 == (auth_satisfied = http_auth_digest_check(srv, con, p, req, con->uri.path, auth_realm+1))) {
15490 con->http_status = 400;
15493 /* a field was missing */
15496 return HANDLER_FINISHED;
15500 - log_error_write(srv, __FILE__, __LINE__, "ss",
15501 + log_error_write(srv, __FILE__, __LINE__, "ss",
15502 "unknown authentification type:",
15503 http_authorization);
15509 if (!auth_satisfied) {
15510 data_string *method, *realm;
15511 method = (data_string *)array_get_element(req, "method");
15512 realm = (data_string *)array_get_element(req, "realm");
15515 con->http_status = 401;
15518 if (0 == strcmp(method->value->ptr, "basic")) {
15519 buffer_copy_string(p->tmp_buf, "Basic realm=\"");
15520 buffer_append_string_buffer(p->tmp_buf, realm->value);
15521 buffer_append_string(p->tmp_buf, "\"");
15524 response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf));
15525 } else if (0 == strcmp(method->value->ptr, "digest")) {
15527 http_auth_digest_generate_nonce(srv, p, srv->tmp_buf, hh);
15530 buffer_copy_string(p->tmp_buf, "Digest realm=\"");
15531 buffer_append_string_buffer(p->tmp_buf, realm->value);
15532 buffer_append_string(p->tmp_buf, "\", nonce=\"");
15533 buffer_append_string(p->tmp_buf, hh);
15534 buffer_append_string(p->tmp_buf, "\", qop=\"auth\"");
15537 response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf));
15540 @@ -289,18 +288,18 @@
15541 return HANDLER_FINISHED;
15543 /* the REMOTE_USER header */
15546 buffer_copy_string_buffer(con->authed_user, p->auth_user);
15550 return HANDLER_GO_ON;
15553 SETDEFAULTS_FUNC(mod_auth_set_defaults) {
15554 mod_auth_plugin_data *p = p_d;
15557 - config_values_t cv[] = {
15559 + config_values_t cv[] = {
15560 { "auth.backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
15561 { "auth.backend.plain.groupfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
15562 { "auth.backend.plain.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
15563 @@ -317,7 +316,7 @@
15564 { "auth.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
15565 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
15569 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
15571 for (i = 0; i < srv->config_context->used; i++) {
15572 @@ -325,14 +324,14 @@
15578 s = calloc(1, sizeof(mod_auth_plugin_config));
15579 s->auth_plain_groupfile = buffer_init();
15580 s->auth_plain_userfile = buffer_init();
15581 s->auth_htdigest_userfile = buffer_init();
15582 s->auth_htpasswd_userfile = buffer_init();
15583 s->auth_backend_conf = buffer_init();
15586 s->auth_ldap_hostname = buffer_init();
15587 s->auth_ldap_basedn = buffer_init();
15588 s->auth_ldap_binddn = buffer_init();
15589 @@ -341,15 +340,15 @@
15590 s->auth_ldap_cafile = buffer_init();
15591 s->auth_ldap_starttls = 0;
15595 s->auth_require = array_init();
15599 s->ldap_filter_pre = buffer_init();
15600 s->ldap_filter_post = buffer_init();
15605 cv[0].destination = s->auth_backend_conf;
15606 cv[1].destination = s->auth_plain_groupfile;
15607 cv[2].destination = s->auth_plain_userfile;
15608 @@ -364,14 +363,14 @@
15609 cv[11].destination = s->auth_htdigest_userfile;
15610 cv[12].destination = s->auth_htpasswd_userfile;
15611 cv[13].destination = &(s->auth_debug);
15614 p->config_storage[i] = s;
15615 ca = ((data_config *)srv->config_context->data[i])->value;
15618 if (0 != config_insert_values_global(srv, ca, cv)) {
15619 return HANDLER_ERROR;
15623 if (s->auth_backend_conf->used) {
15624 if (0 == strcmp(s->auth_backend_conf->ptr, "htpasswd")) {
15625 s->auth_backend = AUTH_BACKEND_HTPASSWD;
15626 @@ -383,31 +382,31 @@
15627 s->auth_backend = AUTH_BACKEND_LDAP;
15629 log_error_write(srv, __FILE__, __LINE__, "sb", "auth.backend not supported:", s->auth_backend_conf);
15632 return HANDLER_ERROR;
15636 /* no auth.require for this section */
15637 if (NULL == (da = (data_array *)array_get_element(ca, "auth.require"))) continue;
15640 if (da->type != TYPE_ARRAY) continue;
15643 for (n = 0; n < da->value->used; n++) {
15645 data_array *da_file = (data_array *)da->value->data[n];
15646 const char *method, *realm, *require;
15649 if (da->value->data[n]->type != TYPE_ARRAY) {
15650 - log_error_write(srv, __FILE__, __LINE__, "ss",
15651 - "auth.require should contain an array as in:",
15652 + log_error_write(srv, __FILE__, __LINE__, "ss",
15653 + "auth.require should contain an array as in:",
15654 "auth.require = ( \"...\" => ( ..., ...) )");
15656 return HANDLER_ERROR;
15660 method = realm = require = NULL;
15663 for (m = 0; m < da_file->value->used; m++) {
15664 if (da_file->value->data[m]->type == TYPE_STRING) {
15665 if (0 == strcmp(da_file->value->data[m]->key->ptr, "method")) {
15666 @@ -417,8 +416,8 @@
15667 } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "require")) {
15668 require = ((data_string *)(da_file->value->data[m]))->value->ptr;
15670 - log_error_write(srv, __FILE__, __LINE__, "ssbs",
15671 - "the field is unknown in:",
15672 + log_error_write(srv, __FILE__, __LINE__, "ssbs",
15673 + "the field is unknown in:",
15674 "auth.require = ( \"...\" => ( ..., -> \"",
15675 da_file->value->data[m]->key,
15676 "\" <- => \"...\" ) )");
15677 @@ -426,19 +425,19 @@
15678 return HANDLER_ERROR;
15681 - log_error_write(srv, __FILE__, __LINE__, "ssbs",
15682 - "a string was expected for:",
15683 + log_error_write(srv, __FILE__, __LINE__, "ssbs",
15684 + "a string was expected for:",
15685 "auth.require = ( \"...\" => ( ..., -> \"",
15686 da_file->value->data[m]->key,
15687 "\" <- => \"...\" ) )");
15690 return HANDLER_ERROR;
15695 if (method == NULL) {
15696 - log_error_write(srv, __FILE__, __LINE__, "ss",
15697 - "the require field is missing in:",
15698 + log_error_write(srv, __FILE__, __LINE__, "ss",
15699 + "the require field is missing in:",
15700 "auth.require = ( \"...\" => ( ..., \"method\" => \"...\" ) )");
15701 return HANDLER_ERROR;
15703 @@ -450,60 +449,60 @@
15704 return HANDLER_ERROR;
15709 if (realm == NULL) {
15710 - log_error_write(srv, __FILE__, __LINE__, "ss",
15711 - "the require field is missing in:",
15712 + log_error_write(srv, __FILE__, __LINE__, "ss",
15713 + "the require field is missing in:",
15714 "auth.require = ( \"...\" => ( ..., \"realm\" => \"...\" ) )");
15715 return HANDLER_ERROR;
15719 if (require == NULL) {
15720 - log_error_write(srv, __FILE__, __LINE__, "ss",
15721 - "the require field is missing in:",
15722 + log_error_write(srv, __FILE__, __LINE__, "ss",
15723 + "the require field is missing in:",
15724 "auth.require = ( \"...\" => ( ..., \"require\" => \"...\" ) )");
15725 return HANDLER_ERROR;
15729 if (method && realm && require) {
15734 a = data_array_init();
15735 buffer_copy_string_buffer(a->key, da_file->key);
15738 ds = data_string_init();
15741 buffer_copy_string(ds->key, "method");
15742 buffer_copy_string(ds->value, method);
15745 array_insert_unique(a->value, (data_unset *)ds);
15748 ds = data_string_init();
15751 buffer_copy_string(ds->key, "realm");
15752 buffer_copy_string(ds->value, realm);
15755 array_insert_unique(a->value, (data_unset *)ds);
15758 ds = data_string_init();
15761 buffer_copy_string(ds->key, "require");
15762 buffer_copy_string(ds->value, require);
15765 array_insert_unique(a->value, (data_unset *)ds);
15768 array_insert_unique(s->auth_require, (data_unset *)a);
15773 switch(s->auth_backend) {
15774 case AUTH_BACKEND_PLAIN:
15775 if (s->auth_plain_userfile->used) {
15778 if (-1 == (fd = open(s->auth_plain_userfile->ptr, O_RDONLY))) {
15779 - log_error_write(srv, __FILE__, __LINE__, "sbss",
15780 + log_error_write(srv, __FILE__, __LINE__, "sbss",
15781 "opening auth.backend.plain.userfile:", s->auth_plain_userfile,
15782 "failed:", strerror(errno));
15783 return HANDLER_ERROR;
15784 @@ -516,7 +515,7 @@
15787 if (-1 == (fd = open(s->auth_htpasswd_userfile->ptr, O_RDONLY))) {
15788 - log_error_write(srv, __FILE__, __LINE__, "sbss",
15789 + log_error_write(srv, __FILE__, __LINE__, "sbss",
15790 "opening auth.backend.htpasswd.userfile:", s->auth_htpasswd_userfile,
15791 "failed:", strerror(errno));
15792 return HANDLER_ERROR;
15793 @@ -529,7 +528,7 @@
15796 if (-1 == (fd = open(s->auth_htdigest_userfile->ptr, O_RDONLY))) {
15797 - log_error_write(srv, __FILE__, __LINE__, "sbss",
15798 + log_error_write(srv, __FILE__, __LINE__, "sbss",
15799 "opening auth.backend.htdigest.userfile:", s->auth_htdigest_userfile,
15800 "failed:", strerror(errno));
15801 return HANDLER_ERROR;
15802 @@ -554,75 +553,75 @@
15803 handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
15808 if (s->auth_ldap_basedn->used == 0) {
15809 log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set");
15812 return HANDLER_ERROR;
15817 if (s->auth_ldap_filter->used) {
15824 if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) {
15825 log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'");
15828 return HANDLER_ERROR;
15832 buffer_copy_string_len(s->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr);
15833 buffer_copy_string(s->ldap_filter_post, dollar+1);
15837 if (s->auth_ldap_hostname->used) {
15838 if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) {
15839 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));
15842 return HANDLER_ERROR;
15846 ret = LDAP_VERSION3;
15847 if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
15848 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
15851 return HANDLER_ERROR;
15854 if (s->auth_ldap_starttls) {
15855 - /* if no CA file is given, it is ok, as we will use encryption
15856 + /* if no CA file is given, it is ok, as we will use encryption
15857 * if the server requires a CAfile it will tell us */
15858 if (!buffer_is_empty(s->auth_ldap_cafile)) {
15859 - if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
15860 + if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
15861 s->auth_ldap_cafile->ptr))) {
15862 - log_error_write(srv, __FILE__, __LINE__, "ss",
15863 + log_error_write(srv, __FILE__, __LINE__, "ss",
15864 "Loading CA certificate failed:", ldap_err2string(ret));
15867 return HANDLER_ERROR;
15872 if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL, NULL))) {
15873 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
15876 return HANDLER_ERROR;
15884 if (s->auth_ldap_binddn->used) {
15885 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) {
15886 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
15889 return HANDLER_ERROR;
15892 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) {
15893 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
15896 return HANDLER_ERROR;
15899 @@ -641,8 +640,8 @@
15900 p->set_defaults = mod_auth_set_defaults;
15901 p->handle_uri_clean = mod_auth_uri_handler;
15902 p->cleanup = mod_auth_free;
15910 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cgi.c lighttpd-1.4.12/src/mod_cgi.c
15911 --- lighttpd-1.4.11/src/mod_cgi.c 2006-02-22 15:15:10.000000000 +0200
15912 +++ lighttpd-1.4.12/src/mod_cgi.c 2006-07-11 21:23:39.000000000 +0300
15914 #include <sys/types.h>
15916 -#include <winsock2.h>
15918 -#include <sys/socket.h>
15919 -#include <sys/wait.h>
15920 -#include <sys/mman.h>
15922 -#include <netinet/in.h>
15924 -#include <arpa/inet.h>
15927 -#include <unistd.h>
15929 #include <stdlib.h>
15930 #include <string.h>
15931 -#include <fdevent.h>
15932 #include <signal.h>
15934 #include <assert.h>
15936 #include "connections.h"
15937 #include "joblist.h"
15938 #include "http_chunk.h"
15939 +#include "fdevent.h"
15941 #include "plugin.h"
15943 +#include "sys-files.h"
15944 +#include "sys-mmap.h"
15945 +#include "sys-socket.h"
15946 +#include "sys-strings.h"
15947 +#include "sys-process.h"
15949 #ifdef HAVE_SYS_FILIO_H
15950 # include <sys/filio.h>
15952 @@ -40,11 +34,12 @@
15966 @@ -58,23 +53,23 @@
15969 buffer_pid_t cgi_pid;
15973 buffer *parse_response;
15976 plugin_config **config_storage;
15978 - plugin_config conf;
15980 + plugin_config conf;
15986 int fde_ndx; /* index into the fd-event buffer */
15989 connection *remote_conn; /* dumb pointer */
15990 plugin_data *plugin_data; /* dumb pointer */
15994 buffer *response_header;
15996 @@ -83,17 +78,17 @@
15997 handler_ctx *hctx = calloc(1, sizeof(*hctx));
16002 hctx->response = buffer_init();
16003 hctx->response_header = buffer_init();
16009 static void cgi_handler_ctx_free(handler_ctx *hctx) {
16010 buffer_free(hctx->response);
16011 buffer_free(hctx->response_header);
16017 @@ -101,14 +96,14 @@
16019 INIT_FUNC(mod_cgi_init) {
16023 p = calloc(1, sizeof(*p));
16028 p->tmp_buf = buffer_init();
16029 p->parse_response = buffer_init();
16035 @@ -116,62 +111,62 @@
16036 FREE_FUNC(mod_cgi_free) {
16037 plugin_data *p = p_d;
16038 buffer_pid_t *r = &(p->cgi_pid);
16044 if (p->config_storage) {
16046 for (i = 0; i < srv->config_context->used; i++) {
16047 plugin_config *s = p->config_storage[i];
16050 array_free(s->cgi);
16055 free(p->config_storage);
16060 if (r->ptr) free(r->ptr);
16063 buffer_free(p->tmp_buf);
16064 buffer_free(p->parse_response);
16070 return HANDLER_GO_ON;
16073 SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
16074 plugin_data *p = p_d;
16077 - config_values_t cv[] = {
16079 + config_values_t cv[] = {
16080 { "cgi.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
16081 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET}
16084 if (!p) return HANDLER_ERROR;
16087 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
16090 for (i = 0; i < srv->config_context->used; i++) {
16094 s = calloc(1, sizeof(plugin_config));
16098 s->cgi = array_init();
16101 cv[0].destination = s->cgi;
16104 p->config_storage[i] = s;
16107 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
16108 return HANDLER_ERROR;
16113 return HANDLER_GO_ON;
16116 @@ -180,13 +175,13 @@
16119 buffer_pid_t *r = &(p->cgi_pid);
16124 for (i = 0; i < r->used; i++) {
16125 if (r->ptr[i] > m) m = r->ptr[i];
16129 if (r->size == 0) {
16131 r->ptr = malloc(sizeof(*r->ptr) * r->size);
16132 @@ -194,31 +189,31 @@
16134 r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
16138 r->ptr[r->used++] = pid;
16144 static int cgi_pid_del(server *srv, plugin_data *p, pid_t pid) {
16146 buffer_pid_t *r = &(p->cgi_pid);
16151 for (i = 0; i < r->used; i++) {
16152 if (r->ptr[i] == pid) break;
16156 if (i != r->used) {
16160 if (i != r->used - 1) {
16161 r->ptr[i] = r->ptr[r->used - 1];
16170 @@ -226,32 +221,32 @@
16179 buffer_copy_string_buffer(p->parse_response, in);
16181 - for (s = p->parse_response->ptr;
16182 - NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
16184 + for (s = p->parse_response->ptr;
16185 + NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
16186 s = ns + (eol == EOL_RN ? 2 : 1), line++) {
16187 const char *key, *value;
16197 0 == strncmp(s, "HTTP/1.", 7)) {
16198 /* non-parsed header ... we parse them anyway */
16201 if ((s[7] == '1' ||
16205 /* after the space should be a status code for us */
16208 status = strtol(s+9, NULL, 10);
16211 if (con->http_status >= 100 &&
16212 con->http_status < 1000) {
16213 /* we expected 3 digits and didn't got them */
16214 @@ -260,27 +255,27 @@
16221 if (NULL == (value = strchr(s, ':'))) {
16222 /* we expect: "<key>: <value>\r\n" */
16227 key_len = value - key;
16232 while (*value == ' ' || *value == '\t') value++;
16235 if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
16236 ds = data_response_init();
16238 buffer_copy_string_len(ds->key, key, key_len);
16239 buffer_copy_string(ds->value, value);
16242 array_insert_unique(con->response.headers, (data_unset *)ds);
16247 if (0 == strncasecmp(key, "Date", key_len)) {
16248 @@ -315,13 +310,13 @@
16254 /* CGI/1.1 rev 03 - 7.2.1.2 */
16255 if ((con->parsed_response & HTTP_LOCATION) &&
16256 !(con->parsed_response & HTTP_STATUS)) {
16257 con->http_status = 302;
16264 @@ -329,10 +324,10 @@
16265 static int cgi_demux_response(server *srv, handler_ctx *hctx) {
16266 plugin_data *p = hctx->plugin_data;
16267 connection *con = hctx->remote_conn;
16274 buffer_prepare_copy(hctx->response, 1024);
16275 if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
16276 if (errno == EAGAIN || errno == EINTR) {
16277 @@ -343,125 +338,125 @@
16278 log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
16279 return FDEVENT_HANDLED_ERROR;
16284 /* read finished */
16287 con->file_finished = 1;
16290 /* send final chunk */
16291 http_chunk_append_mem(srv, con, NULL, 0);
16292 joblist_append(srv, con);
16295 return FDEVENT_HANDLED_FINISHED;
16299 hctx->response->ptr[n] = '\0';
16300 hctx->response->used = n+1;
16303 /* split header from body */
16306 if (con->file_started == 0) {
16309 int header_end = 0;
16310 int cp, eol = EOL_UNSET;
16314 buffer_append_string_buffer(hctx->response_header, hctx->response);
16317 /* nph (non-parsed headers) */
16318 if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
16321 /* search for the \r\n\r\n or \n\n in the string */
16322 for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
16323 if (*c == ':') in_header = 1;
16324 else if (*c == '\n') {
16325 if (in_header == 0) {
16326 /* got a response without a response header */
16335 if (eol == EOL_UNSET) eol = EOL_N;
16338 if (*(c+1) == '\n') {
16344 } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
16345 if (in_header == 0) {
16346 /* got a response without a response header */
16355 if (eol == EOL_UNSET) eol = EOL_RN;
16359 - *(c+2) == '\r' &&
16360 + *(c+2) == '\r' &&
16377 /* no header, but a body */
16380 if (con->request.http_version == HTTP_VERSION_1_1) {
16381 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
16385 http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
16386 joblist_append(srv, con);
16388 size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
16389 size_t blen = hctx->response_header->used - hlen - 1;
16392 /* a small hack: terminate after at the second \r */
16393 hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
16394 hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
16397 /* parse the response header */
16398 cgi_response_parse(srv, con, p, hctx->response_header, eol);
16401 /* enable chunked-transfer-encoding */
16402 if (con->request.http_version == HTTP_VERSION_1_1 &&
16403 !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
16404 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
16408 if ((hctx->response->used != hlen) && blen > 0) {
16409 http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
16410 joblist_append(srv, con);
16415 con->file_started = 1;
16418 http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
16419 joblist_append(srv, con);
16425 log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
16430 return FDEVENT_HANDLED_NOT_FINISHED;
16433 @@ -470,45 +465,46 @@
16439 if (NULL == hctx) return HANDLER_GO_ON;
16442 p = hctx->plugin_data;
16443 con = hctx->remote_conn;
16446 if (con->mode != p->id) return HANDLER_GO_ON;
16452 /* the connection to the browser went away, but we still have a connection
16453 - * to the CGI script
16454 + * to the CGI script
16456 * close cgi-connection
16460 if (hctx->fd != -1) {
16461 /* close connection to the cgi-script */
16462 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
16463 fdevent_unregister(srv->ev, hctx->fd);
16466 if (close(hctx->fd)) {
16467 log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
16472 hctx->fde_ndx = -1;
16479 con->plugin_ctx[p->id] = NULL;
16482 /* is this a good idea ? */
16483 cgi_handler_ctx_free(hctx);
16486 /* if waitpid hasn't been called by response.c yet, do it here */
16488 /* check if the CGI-script is already gone */
16490 switch(waitpid(pid, &status, WNOHANG)) {
16492 /* not finished yet */
16493 @@ -519,19 +515,19 @@
16496 if (errno == EINTR) break;
16499 - * errno == ECHILD happens if _subrequest catches the process-status before
16502 + * errno == ECHILD happens if _subrequest catches the process-status before
16503 * we have read the response of the cgi process
16507 * -> WAIT_FOR_EVENT
16509 * -> we get here with waitpid == ECHILD
16513 if (errno == ECHILD) return HANDLER_GO_ON;
16516 log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
16517 return HANDLER_ERROR;
16519 @@ -541,13 +537,13 @@
16520 con->http_status = 500;
16521 con->mode = DIRECT;
16525 if (WIFEXITED(status)) {
16527 log_error_write(srv, __FILE__, __LINE__, "sd", "(debug) cgi exited fine, pid:", pid);
16532 return HANDLER_GO_ON;
16534 log_error_write(srv, __FILE__, __LINE__, "sd", "cgi died, pid:", pid);
16535 @@ -555,20 +551,20 @@
16536 return HANDLER_GO_ON;
16543 kill(pid, SIGTERM);
16546 /* cgi-script is still alive, queue the PID for removal */
16547 cgi_pid_add(srv, p, pid);
16551 return HANDLER_GO_ON;
16554 static handler_t cgi_connection_close_callback(server *srv, connection *con, void *p_d) {
16555 plugin_data *p = p_d;
16558 return cgi_connection_close(srv, con->plugin_ctx[p->id]);
16561 @@ -577,43 +573,43 @@
16562 server *srv = (server *)s;
16563 handler_ctx *hctx = ctx;
16564 connection *con = hctx->remote_conn;
16567 joblist_append(srv, con);
16570 if (hctx->fd == -1) {
16571 log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "invalid cgi-fd");
16574 return HANDLER_ERROR;
16578 if (revents & FDEVENT_IN) {
16579 switch (cgi_demux_response(srv, hctx)) {
16580 case FDEVENT_HANDLED_NOT_FINISHED:
16582 case FDEVENT_HANDLED_FINISHED:
16587 log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "finished");
16589 cgi_connection_close(srv, hctx);
16591 - /* if we get a IN|HUP and have read everything don't exec the close twice */
16593 + /* if we get a IN|HUP and have read everything don't exec the close twice */
16594 return HANDLER_FINISHED;
16595 case FDEVENT_HANDLED_ERROR:
16596 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
16597 con->http_status = 500;
16598 con->mode = DIRECT;
16601 log_error_write(srv, __FILE__, __LINE__, "s", "demuxer failed: ");
16607 if (revents & FDEVENT_OUT) {
16608 /* nothing to do */
16612 /* perhaps this issue is already handled */
16613 if (revents & FDEVENT_HUP) {
16614 /* check if we still have a unfinished header package which is a body in reality */
16615 @@ -623,54 +619,54 @@
16616 http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
16617 joblist_append(srv, con);
16621 if (con->file_finished == 0) {
16622 http_chunk_append_mem(srv, con, NULL, 0);
16623 joblist_append(srv, con);
16627 con->file_finished = 1;
16630 if (chunkqueue_is_empty(con->write_queue)) {
16631 /* there is nothing left to write */
16632 connection_set_state(srv, con, CON_STATE_RESPONSE_END);
16634 /* used the write-handler to finish the request on demand */
16641 log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
16645 /* rtsigs didn't liked the close */
16646 cgi_connection_close(srv, hctx);
16647 } else if (revents & FDEVENT_ERR) {
16648 con->file_finished = 1;
16651 /* kill all connections to the cgi process */
16652 cgi_connection_close(srv, hctx);
16654 log_error_write(srv, __FILE__, __LINE__, "s", "cgi-FDEVENT_ERR");
16657 return HANDLER_ERROR;
16661 return HANDLER_FINISHED;
16665 static int cgi_env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
16669 if (!key || !val) return -1;
16672 dst = malloc(key_len + val_len + 3);
16673 memcpy(dst, key, key_len);
16674 dst[key_len] = '=';
16675 /* add the \0 from the value */
16676 memcpy(dst + key_len + 1, val, val_len + 1);
16679 if (env->size == 0) {
16681 env->ptr = malloc(env->size * sizeof(*env->ptr));
16682 @@ -678,45 +674,45 @@
16684 env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
16688 env->ptr[env->used++] = dst;
16694 static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *cgi_handler) {
16699 char b2[INET6_ADDRSTRLEN + 1];
16704 int from_cgi_fds[2];
16712 if (cgi_handler->used > 1) {
16713 /* stat the exec file */
16714 if (-1 == (stat(cgi_handler->ptr, &st))) {
16715 - log_error_write(srv, __FILE__, __LINE__, "sbss",
16716 + log_error_write(srv, __FILE__, __LINE__, "sbss",
16717 "stat for cgi-handler", cgi_handler,
16718 "failed:", strerror(errno));
16724 if (pipe(to_cgi_fds)) {
16725 log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno));
16730 if (pipe(from_cgi_fds)) {
16731 log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno));
16737 switch (pid = fork()) {
16739 @@ -730,22 +726,22 @@
16742 server_socket *srv_sock = con->srv_socket;
16745 /* move stdout to from_cgi_fd[1] */
16746 close(STDOUT_FILENO);
16747 dup2(from_cgi_fds[1], STDOUT_FILENO);
16748 close(from_cgi_fds[1]);
16750 close(from_cgi_fds[0]);
16753 /* move the stdin to to_cgi_fd[0] */
16754 close(STDIN_FILENO);
16755 dup2(to_cgi_fds[0], STDIN_FILENO);
16756 close(to_cgi_fds[0]);
16758 close(to_cgi_fds[1]);
16763 * this is not nice, but it works
16765 * we feed the stderr of the CGI to our errorlog, if possible
16766 @@ -754,20 +750,20 @@
16767 close(STDERR_FILENO);
16768 dup2(srv->errorlog_fd, STDERR_FILENO);
16772 /* create environment */
16778 cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
16780 if (!buffer_is_empty(con->server_name)) {
16781 cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
16784 - s = inet_ntop(srv_sock->addr.plain.sa_family,
16785 - srv_sock->addr.plain.sa_family == AF_INET6 ?
16786 + s = inet_ntop(srv_sock->addr.plain.sa_family,
16787 + srv_sock->addr.plain.sa_family == AF_INET6 ?
16788 (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
16789 (const void *) &(srv_sock->addr.ipv4.sin_addr),
16791 @@ -779,10 +775,10 @@
16792 cgi_env_add(&env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
16794 s = get_http_version_name(con->request.http_version);
16797 cgi_env_add(&env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
16803 ntohs(srv_sock->addr.plain.sa_family == AF_INET6 ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
16805 @@ -790,10 +786,10 @@
16808 cgi_env_add(&env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
16812 - s = inet_ntop(srv_sock->addr.plain.sa_family,
16813 - srv_sock->addr.plain.sa_family == AF_INET6 ?
16814 + s = inet_ntop(srv_sock->addr.plain.sa_family,
16815 + srv_sock->addr.plain.sa_family == AF_INET6 ?
16816 (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
16817 (const void *) &(srv_sock->addr.ipv4.sin_addr),
16819 @@ -811,15 +807,18 @@
16820 cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200"));
16821 if (!buffer_is_empty(con->uri.query)) {
16822 cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
16824 + /* set a empty QUERY_STRING */
16825 + cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
16827 if (!buffer_is_empty(con->request.orig_uri)) {
16828 cgi_env_add(&env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
16835 - s = inet_ntop(con->dst_addr.plain.sa_family,
16836 - con->dst_addr.plain.sa_family == AF_INET6 ?
16837 + s = inet_ntop(con->dst_addr.plain.sa_family,
16838 + con->dst_addr.plain.sa_family == AF_INET6 ?
16839 (const void *) &(con->dst_addr.ipv6.sin6_addr) :
16840 (const void *) &(con->dst_addr.ipv4.sin_addr),
16842 @@ -828,7 +827,7 @@
16844 cgi_env_add(&env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
16849 ntohs(con->dst_addr.plain.sa_family == AF_INET6 ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
16851 @@ -836,19 +835,19 @@
16854 cgi_env_add(&env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
16857 if (!buffer_is_empty(con->authed_user)) {
16858 cgi_env_add(&env, CONST_STR_LEN("REMOTE_USER"),
16859 CONST_BUF_LEN(con->authed_user));
16863 /* request.content_length < SSIZE_MAX, see request.c */
16864 ltostr(buf, con->request.content_length);
16865 cgi_env_add(&env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
16866 cgi_env_add(&env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
16867 cgi_env_add(&env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
16868 cgi_env_add(&env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
16872 if (NULL != (s = getenv("LD_PRELOAD"))) {
16873 cgi_env_add(&env, CONST_STR_LEN("LD_PRELOAD"), s, strlen(s));
16874 @@ -863,24 +862,24 @@
16875 cgi_env_add(&env, CONST_STR_LEN("SYSTEMROOT"), s, strlen(s));
16880 for (n = 0; n < con->request.headers->used; n++) {
16884 ds = (data_string *)con->request.headers->data[n];
16887 if (ds->value->used && ds->key->used) {
16891 buffer_reset(p->tmp_buf);
16894 if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
16895 buffer_copy_string(p->tmp_buf, "HTTP_");
16896 p->tmp_buf->used--; /* strip \0 after HTTP_ */
16900 buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
16903 for (j = 0; j < ds->key->used - 1; j++) {
16905 if (light_isalpha(ds->key->ptr[j])) {
16906 @@ -893,46 +892,46 @@
16907 p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
16909 p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
16912 cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
16917 for (n = 0; n < con->environment->used; n++) {
16921 ds = (data_string *)con->environment->data[n];
16924 if (ds->value->used && ds->key->used) {
16928 buffer_reset(p->tmp_buf);
16931 buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
16934 for (j = 0; j < ds->key->used - 1; j++) {
16935 - p->tmp_buf->ptr[p->tmp_buf->used++] =
16936 - isalpha((unsigned char)ds->key->ptr[j]) ?
16937 + p->tmp_buf->ptr[p->tmp_buf->used++] =
16938 + isalpha((unsigned char)ds->key->ptr[j]) ?
16939 toupper((unsigned char)ds->key->ptr[j]) : '_';
16941 p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
16944 cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
16949 if (env.size == env.used) {
16951 env.ptr = realloc(env.ptr, env.size * sizeof(*env.ptr));
16955 env.ptr[env.used] = NULL;
16960 args = malloc(sizeof(*args) * argc);
16964 if (cgi_handler->used > 1) {
16965 args[i++] = cgi_handler->ptr;
16967 @@ -942,7 +941,7 @@
16968 /* search for the last / */
16969 if (NULL != (c = strrchr(con->physical.path->ptr, '/'))) {
16973 /* change to the physical directory */
16974 if (-1 == chdir(con->physical.path->ptr)) {
16975 log_error_write(srv, __FILE__, __LINE__, "ssb", "chdir failed:", strerror(errno), con->physical.path);
16976 @@ -954,12 +953,12 @@
16977 for (i = 3; i < 256; i++) {
16978 if (i != srv->errorlog_fd) close(i);
16983 execve(args[0], args, env.ptr);
16986 log_error_write(srv, __FILE__, __LINE__, "sss", "CGI failed:", strerror(errno), args[0]);
16992 @@ -974,11 +973,11 @@
16994 close(from_cgi_fds[1]);
16995 close(to_cgi_fds[0]);
16998 if (con->request.content_length) {
16999 chunkqueue *cq = con->request_content_queue;
17003 assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
17005 /* there is content to send */
17006 @@ -993,16 +992,16 @@
17007 if (-1 == c->file.fd && /* open the file if not already open */
17008 -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
17009 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
17012 close(from_cgi_fds[0]);
17013 close(to_cgi_fds[1]);
17017 c->file.mmap.length = c->file.length;
17020 if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.mmap.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
17021 - log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
17022 + log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
17023 strerror(errno), c->file.name, c->file.fd);
17025 close(from_cgi_fds[0]);
17026 @@ -1012,7 +1011,7 @@
17032 /* chunk_reset() or chunk_free() will cleanup for us */
17035 @@ -1020,7 +1019,7 @@
17038 con->http_status = 507;
17043 con->http_status = 403;
17044 @@ -1033,7 +1032,7 @@
17047 con->http_status = 507;
17052 con->http_status = 403;
17053 @@ -1056,103 +1055,100 @@
17056 close(to_cgi_fds[1]);
17059 /* register PID and wait for them asyncronously */
17061 buffer_reset(con->physical.path);
17064 hctx = cgi_handler_ctx_init();
17067 hctx->remote_conn = con;
17068 hctx->plugin_data = p;
17070 hctx->fd = from_cgi_fds[0];
17071 hctx->fde_ndx = -1;
17074 con->plugin_ctx[p->id] = hctx;
17077 fdevent_register(srv->ev, hctx->fd, cgi_handle_fdevent, hctx);
17078 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
17081 if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
17082 log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
17085 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
17086 fdevent_unregister(srv->ev, hctx->fd);
17089 log_error_write(srv, __FILE__, __LINE__, "sd", "cgi close:", hctx->fd);
17095 cgi_handler_ctx_free(hctx);
17098 con->plugin_ctx[p->id] = NULL;
17116 -#define PATCH(x) \
17117 - p->conf.x = s->x;
17118 static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p) {
17120 plugin_config *s = p->config_storage[0];
17125 + PATCH_OPTION(cgi);
17127 /* skip the first, the global context */
17128 for (i = 1; i < srv->config_context->used; i++) {
17129 data_config *dc = (data_config *)srv->config_context->data[i];
17130 s = p->config_storage[i];
17133 /* condition didn't match */
17134 if (!config_check_cond(srv, con, dc)) continue;
17138 for (j = 0; j < dc->value->used; j++) {
17139 data_unset *du = dc->value->data[j];
17142 if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.assign"))) {
17144 + PATCH_OPTION(cgi);
17154 URIHANDLER_FUNC(cgi_is_handled) {
17156 plugin_data *p = p_d;
17157 buffer *fn = con->physical.path;
17160 if (fn->used == 0) return HANDLER_GO_ON;
17163 mod_cgi_patch_connection(srv, con, p);
17166 s_len = fn->used - 1;
17169 for (k = 0; k < p->conf.cgi->used; k++) {
17170 data_string *ds = (data_string *)p->conf.cgi->data[k];
17171 size_t ct_len = ds->key->used - 1;
17174 if (ds->key->used == 0) continue;
17175 if (s_len < ct_len) continue;
17178 if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) {
17179 if (cgi_create_env(srv, con, p, ds->value)) {
17180 con->http_status = 500;
17183 buffer_reset(con->physical.path);
17184 return HANDLER_FINISHED;
17186 @@ -1160,7 +1156,7 @@
17192 return HANDLER_GO_ON;
17195 @@ -1168,11 +1164,11 @@
17196 plugin_data *p = p_d;
17198 /* the trigger handle only cares about lonely PID which we have to wait for */
17202 for (ndx = 0; ndx < p->cgi_pid.used; ndx++) {
17206 switch(waitpid(p->cgi_pid.ptr[ndx], &status, WNOHANG)) {
17208 /* not finished yet */
17209 @@ -1182,7 +1178,7 @@
17212 log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
17215 return HANDLER_ERROR;
17218 @@ -1193,16 +1189,16 @@
17220 log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?");
17224 cgi_pid_del(srv, p, p->cgi_pid.ptr[ndx]);
17225 - /* del modified the buffer structure
17226 + /* del modified the buffer structure
17227 * and copies the last entry to the current one
17228 * -> recheck the current index
17235 return HANDLER_GO_ON;
17238 @@ -1210,15 +1206,15 @@
17240 plugin_data *p = p_d;
17241 handler_ctx *hctx = con->plugin_ctx[p->id];
17244 if (con->mode != p->id) return HANDLER_GO_ON;
17245 if (NULL == hctx) return HANDLER_GO_ON;
17249 log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid);
17252 if (hctx->pid == 0) return HANDLER_FINISHED;
17255 switch(waitpid(hctx->pid, &status, WNOHANG)) {
17257 /* we only have for events here if we don't have the header yet,
17258 @@ -1228,61 +1224,61 @@
17259 return HANDLER_WAIT_FOR_EVENT;
17261 if (errno == EINTR) return HANDLER_WAIT_FOR_EVENT;
17264 if (errno == ECHILD && con->file_started == 0) {
17266 - * second round but still not response
17267 + * second round but still not response
17269 - return HANDLER_WAIT_FOR_EVENT;
17270 + return HANDLER_WAIT_FOR_EVENT;
17274 log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
17275 con->mode = DIRECT;
17276 con->http_status = 500;
17282 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
17283 fdevent_unregister(srv->ev, hctx->fd);
17286 if (close(hctx->fd)) {
17287 log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
17291 cgi_handler_ctx_free(hctx);
17294 con->plugin_ctx[p->id] = NULL;
17297 return HANDLER_FINISHED;
17299 - /* cgi process exited cleanly
17301 - * check if we already got the response
17302 + /* cgi process exited cleanly
17304 + * check if we already got the response
17308 if (!con->file_started) return HANDLER_WAIT_FOR_EVENT;
17311 if (WIFEXITED(status)) {
17314 log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?");
17317 con->mode = DIRECT;
17318 con->http_status = 500;
17327 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
17328 fdevent_unregister(srv->ev, hctx->fd);
17331 if (close(hctx->fd)) {
17332 log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
17336 cgi_handler_ctx_free(hctx);
17339 con->plugin_ctx[p->id] = NULL;
17340 return HANDLER_FINISHED;
17342 @@ -1306,8 +1302,8 @@
17343 p->init = mod_cgi_init;
17344 p->cleanup = mod_cgi_free;
17345 p->set_defaults = mod_fastcgi_set_defaults;
17353 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cml.c lighttpd-1.4.12/src/mod_cml.c
17354 --- lighttpd-1.4.11/src/mod_cml.c 2006-01-30 13:51:48.000000000 +0200
17355 +++ lighttpd-1.4.12/src/mod_cml.c 2006-07-11 21:23:39.000000000 +0300
17357 #include <stdlib.h>
17358 #include <string.h>
17360 -#include <unistd.h>
17363 #include "buffer.h"
17364 @@ -20,50 +19,50 @@
17365 /* init the plugin data */
17366 INIT_FUNC(mod_cml_init) {
17370 p = calloc(1, sizeof(*p));
17373 p->basedir = buffer_init();
17374 p->baseurl = buffer_init();
17375 p->trigger_handler = buffer_init();
17381 /* detroy the plugin data */
17382 FREE_FUNC(mod_cml_free) {
17383 plugin_data *p = p_d;
17388 if (!p) return HANDLER_GO_ON;
17391 if (p->config_storage) {
17393 for (i = 0; i < srv->config_context->used; i++) {
17394 plugin_config *s = p->config_storage[i];
17397 buffer_free(s->ext);
17400 buffer_free(s->mc_namespace);
17401 buffer_free(s->power_magnet);
17402 array_free(s->mc_hosts);
17405 #if defined(HAVE_MEMCACHE_H)
17406 if (s->mc) mc_free(s->mc);
17412 free(p->config_storage);
17416 buffer_free(p->trigger_handler);
17417 buffer_free(p->basedir);
17418 buffer_free(p->baseurl);
17424 return HANDLER_GO_ON;
17427 @@ -72,22 +71,22 @@
17428 SETDEFAULTS_FUNC(mod_cml_set_defaults) {
17429 plugin_data *p = p_d;
17432 - config_values_t cv[] = {
17434 + config_values_t cv[] = {
17435 { "cml.extension", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
17436 { "cml.memcache-hosts", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
17437 { "cml.memcache-namespace", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
17438 { "cml.power-magnet", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
17439 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
17443 if (!p) return HANDLER_ERROR;
17446 p->config_storage = malloc(srv->config_context->used * sizeof(specific_config *));
17449 for (i = 0; i < srv->config_context->used; i++) {
17453 s = malloc(sizeof(plugin_config));
17454 s->ext = buffer_init();
17455 s->mc_hosts = array_init();
17456 @@ -96,87 +95,84 @@
17457 #if defined(HAVE_MEMCACHE_H)
17462 cv[0].destination = s->ext;
17463 cv[1].destination = s->mc_hosts;
17464 cv[2].destination = s->mc_namespace;
17465 cv[3].destination = s->power_magnet;
17468 p->config_storage[i] = s;
17471 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
17472 return HANDLER_ERROR;
17476 if (s->mc_hosts->used) {
17477 #if defined(HAVE_MEMCACHE_H)
17482 for (k = 0; k < s->mc_hosts->used; k++) {
17483 data_string *ds = (data_string *)s->mc_hosts->data[k];
17486 if (0 != mc_server_add4(s->mc, ds->value->ptr)) {
17487 - log_error_write(srv, __FILE__, __LINE__, "sb",
17488 - "connection to host failed:",
17489 + log_error_write(srv, __FILE__, __LINE__, "sb",
17490 + "connection to host failed:",
17494 return HANDLER_ERROR;
17498 - log_error_write(srv, __FILE__, __LINE__, "s",
17499 + log_error_write(srv, __FILE__, __LINE__, "s",
17500 "memcache support is not compiled in but cml.memcache-hosts is set, aborting");
17501 return HANDLER_ERROR;
17507 return HANDLER_GO_ON;
17510 -#define PATCH(x) \
17511 - p->conf.x = s->x;
17512 static int mod_cml_patch_connection(server *srv, connection *con, plugin_data *p) {
17514 plugin_config *s = p->config_storage[0];
17518 + PATCH_OPTION(ext);
17519 #if defined(HAVE_MEMCACHE_H)
17521 + PATCH_OPTION(mc);
17523 - PATCH(mc_namespace);
17524 - PATCH(power_magnet);
17526 + PATCH_OPTION(mc_namespace);
17527 + PATCH_OPTION(power_magnet);
17529 /* skip the first, the global context */
17530 for (i = 1; i < srv->config_context->used; i++) {
17531 data_config *dc = (data_config *)srv->config_context->data[i];
17532 s = p->config_storage[i];
17535 /* condition didn't match */
17536 if (!config_check_cond(srv, con, dc)) continue;
17540 for (j = 0; j < dc->value->used; j++) {
17541 data_unset *du = dc->value->data[j];
17544 if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.extension"))) {
17546 + PATCH_OPTION(ext);
17547 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-hosts"))) {
17548 #if defined(HAVE_MEMCACHE_H)
17550 + PATCH_OPTION(mc);
17552 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-namespace"))) {
17553 - PATCH(mc_namespace);
17554 + PATCH_OPTION(mc_namespace);
17555 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.power-magnet"))) {
17556 - PATCH(power_magnet);
17557 + PATCH_OPTION(power_magnet);
17567 int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
17569 @@ -187,57 +183,57 @@
17571 buffer_copy_string_buffer(b, con->uri.path);
17572 for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
17576 b->used = c - b->ptr + 2;
17582 buffer_copy_string_buffer(b, con->physical.path);
17583 for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
17587 b->used = c - b->ptr + 2;
17593 /* prepare variables
17595 * - get-param-based
17599 return cache_parse_lua(srv, con, p, cml_file);
17604 URIHANDLER_FUNC(mod_cml_power_magnet) {
17605 plugin_data *p = p_d;
17608 mod_cml_patch_connection(srv, con, p);
17611 buffer_reset(p->basedir);
17612 buffer_reset(p->baseurl);
17613 buffer_reset(p->trigger_handler);
17615 if (buffer_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON;
17621 * cml.power-magnet = server.docroot + "/rewrite.cml"
17623 * is called on EACH request, take the original REQUEST_URI and modifies the
17624 - * request header as neccesary.
17625 + * request header as neccesary.
17628 * if file_exists("/maintainance.html") {
17629 * output_include = ( "/maintainance.html" )
17630 - * return CACHE_HIT
17631 + * return CACHE_HIT
17634 * as we only want to rewrite HTML like requests we should cover it in a conditional
17639 switch(cache_call_lua(srv, con, p, p->conf.power_magnet)) {
17640 @@ -266,20 +262,20 @@
17642 URIHANDLER_FUNC(mod_cml_is_handled) {
17643 plugin_data *p = p_d;
17646 if (buffer_is_empty(con->physical.path)) return HANDLER_ERROR;
17649 mod_cml_patch_connection(srv, con, p);
17652 buffer_reset(p->basedir);
17653 buffer_reset(p->baseurl);
17654 buffer_reset(p->trigger_handler);
17656 if (buffer_is_empty(p->conf.ext)) return HANDLER_GO_ON;
17659 if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, p->conf.ext->used - 1)) {
17660 return HANDLER_GO_ON;
17664 switch(cache_call_lua(srv, con, p, con->physical.path)) {
17666 @@ -311,15 +307,15 @@
17667 int mod_cml_plugin_init(plugin *p) {
17668 p->version = LIGHTTPD_VERSION_ID;
17669 p->name = buffer_init_string("cache");
17672 p->init = mod_cml_init;
17673 p->cleanup = mod_cml_free;
17674 p->set_defaults = mod_cml_set_defaults;
17677 p->handle_subrequest_start = mod_cml_is_handled;
17678 p->handle_physical = mod_cml_power_magnet;
17686 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cml.h lighttpd-1.4.12/src/mod_cml.h
17687 --- lighttpd-1.4.11/src/mod_cml.h 2006-01-30 13:51:35.000000000 +0200
17688 +++ lighttpd-1.4.12/src/mod_cml.h 2006-07-11 21:23:39.000000000 +0300
17689 @@ -16,10 +16,10 @@
17696 buffer *mc_namespace;
17697 -#if defined(HAVE_MEMCACHE_H)
17698 +#if defined(HAVE_MEMCACHE_H)
17699 struct memcache *mc;
17701 buffer *power_magnet;
17702 @@ -27,15 +27,15 @@
17712 buffer *trigger_handler;
17715 plugin_config **config_storage;
17717 - plugin_config conf;
17719 + plugin_config conf;
17722 int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn);
17723 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cml_funcs.c lighttpd-1.4.12/src/mod_cml_funcs.c
17724 --- lighttpd-1.4.11/src/mod_cml_funcs.c 2005-11-17 16:15:08.000000000 +0200
17725 +++ lighttpd-1.4.12/src/mod_cml_funcs.c 2006-07-11 21:23:40.000000000 +0300
17727 #include <stdlib.h>
17728 #include <string.h>
17730 -#include <unistd.h>
17731 -#include <dirent.h>
17735 #include "buffer.h"
17738 #include "plugin.h"
17739 #include "response.h"
17740 +#include "sys-files.h"
17742 #include "mod_cml.h"
17743 #include "mod_cml_funcs.h"
17753 @@ -42,29 +42,29 @@
17756 int n = lua_gettop(L);
17761 b.size = sizeof(hex);
17765 lua_pushstring(L, "md5: expected one argument");
17770 if (!lua_isstring(L, 1)) {
17771 lua_pushstring(L, "md5: argument has to be a string");
17777 MD5_Update(&Md5Ctx, (unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1));
17778 MD5_Final(HA1, &Md5Ctx);
17781 buffer_copy_string_hex(&b, (char *)HA1, 16);
17784 lua_pushstring(L, b.ptr);
17790 @@ -72,37 +72,37 @@
17791 int f_file_mtime(lua_State *L) {
17793 int n = lua_gettop(L);
17797 lua_pushstring(L, "file_mtime: expected one argument");
17802 if (!lua_isstring(L, 1)) {
17803 lua_pushstring(L, "file_mtime: argument has to be a string");
17808 if (-1 == stat(lua_tostring(L, 1), &st)) {
17814 lua_pushnumber(L, st.st_mtime);
17821 int f_dir_files_iter(lua_State *L) {
17826 d = lua_touserdata(L, lua_upvalueindex(1));
17829 if (NULL == (de = readdir(d))) {
17836 lua_pushstring(L, de->d_name);
17837 @@ -113,75 +113,75 @@
17838 int f_dir_files(lua_State *L) {
17840 int n = lua_gettop(L);
17844 lua_pushstring(L, "dir_files: expected one argument");
17849 if (!lua_isstring(L, 1)) {
17850 lua_pushstring(L, "dir_files: argument has to be a string");
17854 - /* check if there is a valid DIR handle on the stack */
17856 + /* check if there is a valid DIR handle on the stack */
17857 if (NULL == (d = opendir(lua_tostring(L, 1)))) {
17863 /* push d into registry */
17864 lua_pushlightuserdata(L, d);
17865 lua_pushcclosure(L, f_dir_files_iter, 1);
17872 int f_file_isreg(lua_State *L) {
17874 int n = lua_gettop(L);
17878 lua_pushstring(L, "file_isreg: expected one argument");
17883 if (!lua_isstring(L, 1)) {
17884 lua_pushstring(L, "file_isreg: argument has to be a string");
17889 if (-1 == stat(lua_tostring(L, 1), &st)) {
17895 lua_pushnumber(L, S_ISREG(st.st_mode));
17901 int f_file_isdir(lua_State *L) {
17903 int n = lua_gettop(L);
17907 lua_pushstring(L, "file_isreg: expected one argument");
17912 if (!lua_isstring(L, 1)) {
17913 lua_pushstring(L, "file_isreg: argument has to be a string");
17918 if (-1 == stat(lua_tostring(L, 1), &st)) {
17924 lua_pushnumber(L, S_ISDIR(st.st_mode));
17930 @@ -192,33 +192,33 @@
17932 int n = lua_gettop(L);
17933 struct memcache *mc;
17936 if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
17937 lua_pushstring(L, "where is my userdata ?");
17942 mc = lua_touserdata(L, lua_upvalueindex(1));
17946 lua_pushstring(L, "expected one argument");
17951 if (!lua_isstring(L, 1)) {
17952 lua_pushstring(L, "argument has to be a string");
17956 - if (NULL == (r = mc_aget(mc,
17958 + if (NULL == (r = mc_aget(mc,
17959 lua_tostring(L, 1), lua_strlen(L, 1)))) {
17962 lua_pushboolean(L, 0);
17970 lua_pushboolean(L, 1);
17973 @@ -226,74 +226,74 @@
17974 int f_memcache_get_string(lua_State *L) {
17976 int n = lua_gettop(L);
17979 struct memcache *mc;
17982 if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
17983 lua_pushstring(L, "where is my userdata ?");
17988 mc = lua_touserdata(L, lua_upvalueindex(1));
17994 lua_pushstring(L, "expected one argument");
17999 if (!lua_isstring(L, 1)) {
18000 lua_pushstring(L, "argument has to be a string");
18004 - if (NULL == (r = mc_aget(mc,
18006 + if (NULL == (r = mc_aget(mc,
18007 lua_tostring(L, 1), lua_strlen(L, 1)))) {
18013 lua_pushstring(L, r);
18022 int f_memcache_get_long(lua_State *L) {
18024 int n = lua_gettop(L);
18027 struct memcache *mc;
18030 if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
18031 lua_pushstring(L, "where is my userdata ?");
18036 mc = lua_touserdata(L, lua_upvalueindex(1));
18042 lua_pushstring(L, "expected one argument");
18047 if (!lua_isstring(L, 1)) {
18048 lua_pushstring(L, "argument has to be a string");
18052 - if (NULL == (r = mc_aget(mc,
18054 + if (NULL == (r = mc_aget(mc,
18055 lua_tostring(L, 1), lua_strlen(L, 1)))) {
18061 lua_pushnumber(L, strtol(r, NULL, 10));
18070 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_cml_lua.c lighttpd-1.4.12/src/mod_cml_lua.c
18071 --- lighttpd-1.4.11/src/mod_cml_lua.c 2006-01-30 13:56:40.000000000 +0200
18072 +++ lighttpd-1.4.12/src/mod_cml_lua.c 2006-07-11 21:23:40.000000000 +0300
18085 #include <lualib.h>
18086 +#include <lauxlib.h>
18090 @@ -39,11 +40,11 @@
18092 static const char * load_file(lua_State *L, void *data, size_t *size) {
18099 if (rm->done) return 0;
18102 *size = rm->st.size;
18104 return rm->st.start;
18105 @@ -51,47 +52,47 @@
18107 static int lua_to_c_get_string(lua_State *L, const char *varname, buffer *b) {
18111 lua_pushstring(L, varname);
18114 curelem = lua_gettop(L);
18115 lua_gettable(L, LUA_GLOBALSINDEX);
18118 /* it should be a table */
18119 if (!lua_isstring(L, curelem)) {
18120 lua_settop(L, curelem - 1);
18127 buffer_copy_string(b, lua_tostring(L, curelem));
18133 assert(curelem - 1 == lua_gettop(L));
18139 static int lua_to_c_is_table(lua_State *L, const char *varname) {
18143 lua_pushstring(L, varname);
18146 curelem = lua_gettop(L);
18147 lua_gettable(L, LUA_GLOBALSINDEX);
18150 /* it should be a table */
18151 if (!lua_istable(L, curelem)) {
18152 lua_settop(L, curelem - 1);
18159 lua_settop(L, curelem - 1);
18162 assert(curelem - 1 == lua_gettop(L));
18169 lua_pushlstring(L, key, key_len);
18170 lua_pushlstring(L, val, val_len);
18171 lua_settable(L, tbl);
18177 @@ -108,21 +109,21 @@
18180 char *key = NULL, *val = NULL;
18186 /* we need the \0 */
18187 for (i = 0; i < qrystr->used; i++) {
18188 switch(qrystr->ptr[i]) {
18191 val = qrystr->ptr + i + 1;
18194 qrystr->ptr[i] = '\0';
18203 case '\0': /* fin symbol */
18204 @@ -131,19 +132,19 @@
18206 /* terminate the value */
18207 qrystr->ptr[i] = '\0';
18209 - c_to_lua_push(L, tbl,
18211 + c_to_lua_push(L, tbl,
18217 key = qrystr->ptr + i + 1;
18228 @@ -151,21 +152,21 @@
18234 if (NULL != (d = array_get_element(con->request.headers, "Cookie"))) {
18235 data_string *ds = (data_string *)d;
18236 size_t key = 0, value = 0;
18237 size_t is_key = 1, is_sid = 0;
18242 if (!DATA_IS_STRING(d)) return -1;
18243 if (ds->value->used == 0) return -1;
18246 if (ds->value->ptr[0] == '\0' ||
18247 ds->value->ptr[0] == '=' ||
18248 ds->value->ptr[0] == ';') return -1;
18251 buffer_reset(p->session_id);
18252 for (i = 0; i < ds->value->used; i++) {
18253 switch(ds->value->ptr[i]) {
18254 @@ -176,16 +177,16 @@
18267 buffer_copy_string_len(p->session_id, ds->value->ptr + value, i - value);
18274 @@ -204,48 +205,43 @@
18284 int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
18289 buffer *b = buffer_init();
18290 int header_tbl = 0;
18294 stream_open(&rm.st, fn);
18297 /* push the lua file to the interpreter and see what happends */
18301 - luaopen_table(L);
18302 - luaopen_string(L);
18306 + L = luaL_newstate();
18307 + luaL_openlibs(L);
18309 /* register functions */
18310 lua_register(L, "md5", f_crypto_md5);
18311 lua_register(L, "file_mtime", f_file_mtime);
18312 lua_register(L, "file_isreg", f_file_isreg);
18313 lua_register(L, "file_isdir", f_file_isreg);
18314 lua_register(L, "dir_files", f_dir_files);
18317 #ifdef HAVE_MEMCACHE_H
18318 lua_pushliteral(L, "memcache_get_long");
18319 lua_pushlightuserdata(L, p->conf.mc);
18320 lua_pushcclosure(L, f_memcache_get_long, 1);
18321 lua_settable(L, LUA_GLOBALSINDEX);
18324 lua_pushliteral(L, "memcache_get_string");
18325 lua_pushlightuserdata(L, p->conf.mc);
18326 lua_pushcclosure(L, f_memcache_get_string, 1);
18327 lua_settable(L, LUA_GLOBALSINDEX);
18330 lua_pushliteral(L, "memcache_exists");
18331 lua_pushlightuserdata(L, p->conf.mc);
18332 lua_pushcclosure(L, f_memcache_exists, 1);
18333 @@ -255,11 +251,11 @@
18334 lua_pushliteral(L, "request");
18336 lua_settable(L, LUA_GLOBALSINDEX);
18339 lua_pushliteral(L, "request");
18340 header_tbl = lua_gettop(L);
18341 lua_gettable(L, LUA_GLOBALSINDEX);
18344 c_to_lua_push(L, header_tbl, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
18345 c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
18346 c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
18347 @@ -267,84 +263,84 @@
18348 if (!buffer_is_empty(con->request.pathinfo)) {
18349 c_to_lua_push(L, header_tbl, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
18353 c_to_lua_push(L, header_tbl, CONST_STR_LEN("CWD"), CONST_BUF_LEN(p->basedir));
18354 c_to_lua_push(L, header_tbl, CONST_STR_LEN("BASEURL"), CONST_BUF_LEN(p->baseurl));
18357 /* register GET parameter */
18358 lua_pushliteral(L, "get");
18360 lua_settable(L, LUA_GLOBALSINDEX);
18363 lua_pushliteral(L, "get");
18364 header_tbl = lua_gettop(L);
18365 lua_gettable(L, LUA_GLOBALSINDEX);
18368 buffer_copy_string_buffer(b, con->uri.query);
18369 cache_export_get_params(L, header_tbl, b);
18372 - /* 2 default constants */
18373 + /* 2 default constants */
18374 lua_pushliteral(L, "CACHE_HIT");
18375 lua_pushboolean(L, 0);
18376 lua_settable(L, LUA_GLOBALSINDEX);
18379 lua_pushliteral(L, "CACHE_MISS");
18380 lua_pushboolean(L, 1);
18381 lua_settable(L, LUA_GLOBALSINDEX);
18384 /* load lua program */
18385 if (lua_load(L, load_file, &rm, fn->ptr) || lua_pcall(L,0,1,0)) {
18386 log_error_write(srv, __FILE__, __LINE__, "s",
18387 lua_tostring(L,-1));
18394 /* get return value */
18395 ret = (int)lua_tonumber(L, -1);
18398 - /* fetch the data from lua */
18400 + /* fetch the data from lua */
18401 lua_to_c_get_string(L, "trigger_handler", p->trigger_handler);
18404 if (0 == lua_to_c_get_string(L, "output_contenttype", b)) {
18405 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(b));
18410 /* up to now it is a cache-hit, check if all files exist */
18417 if (!lua_to_c_is_table(L, "output_include")) {
18418 log_error_write(srv, __FILE__, __LINE__, "s",
18419 "output_include is missing or not a table");
18427 lua_pushstring(L, "output_include");
18430 curelem = lua_gettop(L);
18431 lua_gettable(L, LUA_GLOBALSINDEX);
18433 /* HOW-TO build a etag ?
18434 - * as we don't just have one file we have to take the stat()
18435 + * as we don't just have one file we have to take the stat()
18436 * from all base files, merge them and build the etag from
18440 * The mtime of the content is the mtime of the freshest base file
18446 lua_pushnil(L); /* first key */
18447 while (lua_next(L, curelem) != 0) {
18448 stat_cache_entry *sce = NULL;
18449 /* key' is at index -2 and value' at index -1 */
18452 if (lua_isstring(L, -1)) {
18453 const char *s = lua_tostring(L, -1);
18455 @@ -364,18 +360,18 @@
18456 /* a file is missing, call the handler to generate it */
18457 if (!buffer_is_empty(p->trigger_handler)) {
18458 ret = 1; /* cache-miss */
18461 log_error_write(srv, __FILE__, __LINE__, "s",
18462 "a file is missing, calling handler");
18467 /* handler not set -> 500 */
18471 log_error_write(srv, __FILE__, __LINE__, "s",
18472 "a file missing and no handler set");
18478 @@ -393,12 +389,12 @@
18484 lua_pop(L, 1); /* removes value'; keeps key' for next iteration */
18488 lua_settop(L, curelem - 1);
18493 char timebuf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
18494 @@ -410,9 +406,9 @@
18496 /* no Last-Modified specified */
18497 if ((mtime) && (NULL == ds)) {
18500 strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&mtime));
18503 response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), timebuf, sizeof(timebuf) - 1);
18506 @@ -428,9 +424,9 @@
18512 if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, &tbuf)) {
18513 - /* ok, the client already has our content,
18514 + /* ok, the client already has our content,
18515 * no need to send it again */
18517 chunkqueue_reset(con->write_queue);
18518 @@ -440,24 +436,24 @@
18519 chunkqueue_reset(con->write_queue);
18524 if (ret == 1 && !buffer_is_empty(p->trigger_handler)) {
18526 buffer_copy_string_buffer(con->uri.path, p->baseurl);
18527 buffer_append_string_buffer(con->uri.path, p->trigger_handler);
18530 buffer_copy_string_buffer(con->physical.path, p->basedir);
18531 buffer_append_string_buffer(con->physical.path, p->trigger_handler);
18534 chunkqueue_reset(con->write_queue);
18542 stream_close(&rm.st);
18546 return ret /* cache-error */;
18549 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_compress.c lighttpd-1.4.12/src/mod_compress.c
18550 --- lighttpd-1.4.11/src/mod_compress.c 2005-11-18 13:49:14.000000000 +0200
18551 +++ lighttpd-1.4.12/src/mod_compress.c 2006-07-11 21:23:40.000000000 +0300
18553 #include <sys/stat.h>
18556 -#include <unistd.h>
18558 #include <stdlib.h>
18559 #include <string.h>
18561 #include "buffer.h"
18562 #include "response.h"
18563 #include "stat_cache.h"
18564 +#include "http_chunk.h"
18566 #include "plugin.h"
18571 #include "sys-mmap.h"
18572 +#include "sys-files.h"
18574 /* request: accept-encoding */
18575 #define HTTP_ACCEPT_ENCODING_IDENTITY BV(0)
18576 @@ -55,97 +56,127 @@
18582 plugin_config **config_storage;
18583 - plugin_config conf;
18584 + plugin_config conf;
18587 INIT_FUNC(mod_compress_init) {
18591 p = calloc(1, sizeof(*p));
18594 p->ofn = buffer_init();
18595 p->b = buffer_init();
18601 FREE_FUNC(mod_compress_free) {
18602 plugin_data *p = p_d;
18607 if (!p) return HANDLER_GO_ON;
18610 buffer_free(p->ofn);
18614 if (p->config_storage) {
18616 for (i = 0; i < srv->config_context->used; i++) {
18617 plugin_config *s = p->config_storage[i];
18622 array_free(s->compress);
18623 buffer_free(s->compress_cache_dir);
18628 free(p->config_storage);
18637 return HANDLER_GO_ON;
18640 +void mkdir_recursive(const char *dir) {
18642 + char dir_copy[256];
18643 + char *p = dir_copy;
18645 + if (!dir || !dir[0])
18648 + strncpy(dir_copy, dir, sizeof(dir_copy) / sizeof(dir_copy[0]));
18650 + while ((p = strchr(p + 1, '/')) != NULL) {
18653 + if ((mkdir(dir_copy, 0700) != 0) && (errno != EEXIST))
18659 + mkdir(dir, 0700);
18662 SETDEFAULTS_FUNC(mod_compress_setdefaults) {
18663 plugin_data *p = p_d;
18666 - config_values_t cv[] = {
18668 + config_values_t cv[] = {
18669 { "compress.cache-dir", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
18670 { "compress.filetype", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },
18671 { "compress.max-filesize", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
18672 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
18676 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
18679 for (i = 0; i < srv->config_context->used; i++) {
18683 s = calloc(1, sizeof(plugin_config));
18684 s->compress_cache_dir = buffer_init();
18685 s->compress = array_init();
18686 s->compress_max_filesize = 0;
18689 cv[0].destination = s->compress_cache_dir;
18690 cv[1].destination = s->compress;
18691 cv[2].destination = &(s->compress_max_filesize);
18694 p->config_storage[i] = s;
18697 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
18698 return HANDLER_ERROR;
18702 if (!buffer_is_empty(s->compress_cache_dir)) {
18704 if (0 != stat(s->compress_cache_dir->ptr, &st)) {
18705 - log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir",
18707 + log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, attempting to create",
18708 s->compress_cache_dir, strerror(errno));
18710 - return HANDLER_ERROR;
18711 + mkdir_recursive(s->compress_cache_dir->ptr);
18713 + if (0 != stat(s->compress_cache_dir->ptr, &st)) {
18715 + log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, create failed",
18716 + s->compress_cache_dir, strerror(errno));
18718 + return HANDLER_ERROR;
18725 return HANDLER_GO_ON;
18731 @@ -153,32 +184,32 @@
18744 - if (Z_OK != deflateInit2(&z,
18746 + if (Z_OK != deflateInit2(&z,
18747 Z_DEFAULT_COMPRESSION,
18750 -MAX_WBITS, /* supress zlib-header */
18752 Z_DEFAULT_STRATEGY)) {
18757 z.next_in = (unsigned char *)start;
18758 z.avail_in = st_size;
18764 buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12 + 18);
18767 /* write gzip header */
18770 c = (unsigned char *)p->b->ptr;
18773 @@ -190,24 +221,24 @@
18774 c[7] = (mtime >> 24) & 0xff;
18775 c[8] = 0x00; /* extra flags */
18776 c[9] = 0x03; /* UNIX */
18780 z.next_out = (unsigned char *)p->b->ptr + p->b->used;
18781 z.avail_out = p->b->size - p->b->used - 8;
18785 if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
18792 p->b->used += z.total_out;
18795 crc = generate_crc32c(start, st_size);
18798 c = (unsigned char *)p->b->ptr + p->b->used;
18801 c[0] = (crc >> 0) & 0xff;
18802 c[1] = (crc >> 8) & 0xff;
18803 c[2] = (crc >> 16) & 0xff;
18804 @@ -221,51 +252,51 @@
18805 if (Z_OK != deflateEnd(&z)) {
18813 static int deflate_file_to_buffer_deflate(server *srv, connection *con, plugin_data *p, unsigned char *start, off_t st_size) {
18824 - if (Z_OK != deflateInit2(&z,
18826 + if (Z_OK != deflateInit2(&z,
18827 Z_DEFAULT_COMPRESSION,
18830 -MAX_WBITS, /* supress zlib-header */
18832 Z_DEFAULT_STRATEGY)) {
18838 z.avail_in = st_size;
18842 buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12);
18845 z.next_out = (unsigned char *)p->b->ptr;
18846 z.avail_out = p->b->size;
18850 if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
18857 p->b->used += z.total_out;
18860 if (Z_OK != deflateEnd(&z)) {
18868 @@ -274,48 +305,48 @@
18870 static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_data *p, unsigned char *start, off_t st_size) {
18881 - if (BZ_OK != BZ2_bzCompressInit(&bz,
18883 + if (BZ_OK != BZ2_bzCompressInit(&bz,
18884 9, /* blocksize = 900k */
18886 0)) { /* workFactor: default */
18891 bz.next_in = (char *)start;
18892 bz.avail_in = st_size;
18893 bz.total_in_lo32 = 0;
18894 bz.total_in_hi32 = 0;
18897 buffer_prepare_copy(p->b, (bz.avail_in * 1.1) + 12);
18900 bz.next_out = p->b->ptr;
18901 bz.avail_out = p->b->size;
18902 bz.total_out_lo32 = 0;
18903 bz.total_out_hi32 = 0;
18906 if (BZ_STREAM_END != BZ2_bzCompress(&bz, BZ_FINISH)) {
18907 BZ2_bzCompressEnd(&bz);
18912 /* file is too large for now */
18913 if (bz.total_out_hi32) return -1;
18917 p->b->used = bz.total_out_lo32;
18920 if (BZ_OK != BZ2_bzCompressEnd(&bz)) {
18928 @@ -326,47 +357,50 @@
18930 const char *filename = fn->ptr;
18933 + stat_cache_entry *compressed_sce = NULL;
18935 + if (buffer_is_empty(p->conf.compress_cache_dir)) return -1;
18938 if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1;
18940 - /* don't mmap files > 128Mb
18943 + /* don't mmap files > 128Mb
18945 * we could use a sliding window, but currently there is no need for it
18949 if (sce->st.st_size > 128 * 1024 * 1024) return -1;
18952 buffer_reset(p->ofn);
18953 buffer_copy_string_buffer(p->ofn, p->conf.compress_cache_dir);
18954 - BUFFER_APPEND_SLASH(p->ofn);
18956 + PATHNAME_APPEND_SLASH(p->ofn);
18958 if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) {
18959 size_t offset = p->ofn->used - 1;
18960 char *dir, *nextdir;
18963 buffer_append_string(p->ofn, con->physical.path->ptr + con->physical.doc_root->used - 1);
18966 buffer_copy_string_buffer(p->b, p->ofn);
18970 for (dir = p->b->ptr + offset; NULL != (nextdir = strchr(dir, '/')); dir = nextdir + 1) {
18974 if (-1 == mkdir(p->b->ptr, 0700)) {
18975 if (errno != EEXIST) {
18976 log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cache-directory", p->b, "failed", strerror(errno));
18987 buffer_append_string_buffer(p->ofn, con->uri.path);
18992 case HTTP_ACCEPT_ENCODING_GZIP:
18993 buffer_append_string(p->ofn, "-gzip-");
18994 @@ -381,55 +415,64 @@
18995 log_error_write(srv, __FILE__, __LINE__, "sd", "unknown compression type", type);
19000 buffer_append_string_buffer(p->ofn, sce->etag);
19004 + if (HANDLER_ERROR != stat_cache_get_entry(srv, con, p->ofn, &compressed_sce)) {
19005 + /* file exists */
19007 + http_chunk_append_file(srv, con, p->ofn, 0, compressed_sce->st.st_size);
19008 + con->file_finished = 1;
19013 if (-1 == (ofd = open(p->ofn->ptr, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600))) {
19014 if (errno == EEXIST) {
19015 /* cache-entry exists */
19017 - log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit");
19019 - buffer_copy_string_buffer(con->physical.path, p->ofn);
19025 - log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cachefile", p->ofn, "failed", strerror(errno));
19028 + log_error_write(srv, __FILE__, __LINE__, "sbss",
19029 + "creating cachefile", p->ofn,
19030 + "failed", strerror(errno));
19035 - log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache miss");
19038 if (-1 == (ifd = open(filename, O_RDONLY | O_BINARY))) {
19039 - log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
19041 + log_error_write(srv, __FILE__, __LINE__, "sbss",
19042 + "opening plain-file", fn,
19043 + "failed", strerror(errno));
19054 if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
19055 - log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno));
19057 + log_error_write(srv, __FILE__, __LINE__, "sbss",
19059 + "failed", strerror(errno));
19069 - case HTTP_ACCEPT_ENCODING_GZIP:
19070 + case HTTP_ACCEPT_ENCODING_GZIP:
19071 ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime);
19073 - case HTTP_ACCEPT_ENCODING_DEFLATE:
19074 + case HTTP_ACCEPT_ENCODING_DEFLATE:
19075 ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size);
19079 - case HTTP_ACCEPT_ENCODING_BZIP2:
19080 + case HTTP_ACCEPT_ENCODING_BZIP2:
19081 ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size);
19084 @@ -437,26 +480,27 @@
19090 if (-1 == (r = write(ofd, p->b->ptr, p->b->used))) {
19091 - munmap(start, sce->st.st_size);
19092 + munmap(start, sce->st.st_size);
19099 if ((size_t)r != p->b->used) {
19105 munmap(start, sce->st.st_size);
19110 if (ret != 0) return -1;
19112 - buffer_copy_string_buffer(con->physical.path, p->ofn);
19115 + http_chunk_append_file(srv, con, p->ofn, 0, r);
19116 + con->file_finished = 1;
19121 @@ -465,43 +509,44 @@
19128 if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1;
19131 /* don't mmap files > 128M
19134 * we could use a sliding window, but currently there is no need for it
19138 if (sce->st.st_size > 128 * 1024 * 1024) return -1;
19142 if (-1 == (ifd = open(fn->ptr, O_RDONLY | O_BINARY))) {
19143 log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
19150 - if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
19152 + start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0);
19156 + if (MAP_FAILED == start) {
19157 log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno));
19167 - case HTTP_ACCEPT_ENCODING_GZIP:
19168 + case HTTP_ACCEPT_ENCODING_GZIP:
19169 ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime);
19171 - case HTTP_ACCEPT_ENCODING_DEFLATE:
19172 + case HTTP_ACCEPT_ENCODING_DEFLATE:
19173 ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size);
19177 - case HTTP_ACCEPT_ENCODING_BZIP2:
19178 + case HTTP_ACCEPT_ENCODING_BZIP2:
19179 ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size);
19182 @@ -509,69 +554,64 @@
19188 munmap(start, sce->st.st_size);
19192 if (ret != 0) return -1;
19195 chunkqueue_reset(con->write_queue);
19196 b = chunkqueue_get_append_buffer(con->write_queue);
19197 buffer_copy_memory(b, p->b->ptr, p->b->used + 1);
19200 buffer_reset(con->physical.path);
19203 con->file_finished = 1;
19204 con->file_started = 1;
19211 -#define PATCH(x) \
19212 - p->conf.x = s->x;
19213 static int mod_compress_patch_connection(server *srv, connection *con, plugin_data *p) {
19215 plugin_config *s = p->config_storage[0];
19217 - PATCH(compress_cache_dir);
19219 - PATCH(compress_max_filesize);
19221 + PATCH_OPTION(compress_cache_dir);
19222 + PATCH_OPTION(compress);
19223 + PATCH_OPTION(compress_max_filesize);
19225 /* skip the first, the global context */
19226 for (i = 1; i < srv->config_context->used; i++) {
19227 data_config *dc = (data_config *)srv->config_context->data[i];
19228 s = p->config_storage[i];
19231 /* condition didn't match */
19232 if (!config_check_cond(srv, con, dc)) continue;
19236 for (j = 0; j < dc->value->used; j++) {
19237 data_unset *du = dc->value->data[j];
19240 if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.cache-dir"))) {
19241 - PATCH(compress_cache_dir);
19242 + PATCH_OPTION(compress_cache_dir);
19243 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.filetype"))) {
19245 + PATCH_OPTION(compress);
19246 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.max-filesize"))) {
19247 - PATCH(compress_max_filesize);
19248 + PATCH_OPTION(compress_max_filesize);
19258 PHYSICALPATH_FUNC(mod_compress_physical) {
19259 plugin_data *p = p_d;
19262 stat_cache_entry *sce = NULL;
19265 /* only GET and POST can get compressed */
19266 - if (con->request.http_method != HTTP_METHOD_GET &&
19267 + if (con->request.http_method != HTTP_METHOD_GET &&
19268 con->request.http_method != HTTP_METHOD_POST) {
19269 return HANDLER_GO_ON;
19271 @@ -579,46 +619,49 @@
19272 if (buffer_is_empty(con->physical.path)) {
19273 return HANDLER_GO_ON;
19277 mod_compress_patch_connection(srv, con, p);
19280 max_fsize = p->conf.compress_max_filesize;
19282 stat_cache_get_entry(srv, con, con->physical.path, &sce);
19284 /* don't compress files that are too large as we need to much time to handle them */
19285 if (max_fsize && (sce->st.st_size >> 10) > max_fsize) return HANDLER_GO_ON;
19288 + /* compressing the file might lead to larger files instead */
19289 + if (sce->st.st_size < 128) return HANDLER_GO_ON;
19291 /* check if mimetype is in compress-config */
19292 for (m = 0; m < p->conf.compress->used; m++) {
19293 data_string *compress_ds = (data_string *)p->conf.compress->data[m];
19296 if (!compress_ds) {
19297 log_error_write(srv, __FILE__, __LINE__, "sbb", "evil", con->physical.path, con->uri.path);
19300 return HANDLER_GO_ON;
19304 if (buffer_is_equal(compress_ds->value, sce->content_type)) {
19305 /* mimetype found */
19309 /* the response might change according to Accept-Encoding */
19310 response_header_insert(srv, con, CONST_STR_LEN("Vary"), CONST_STR_LEN("Accept-Encoding"));
19313 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Encoding"))) {
19314 int accept_encoding = 0;
19315 char *value = ds->value->ptr;
19316 int srv_encodings = 0;
19317 int matched_encodings = 0;
19320 /* get client side support encodings */
19321 if (NULL != strstr(value, "gzip")) accept_encoding |= HTTP_ACCEPT_ENCODING_GZIP;
19322 if (NULL != strstr(value, "deflate")) accept_encoding |= HTTP_ACCEPT_ENCODING_DEFLATE;
19323 if (NULL != strstr(value, "compress")) accept_encoding |= HTTP_ACCEPT_ENCODING_COMPRESS;
19324 if (NULL != strstr(value, "bzip2")) accept_encoding |= HTTP_ACCEPT_ENCODING_BZIP2;
19325 if (NULL != strstr(value, "identity")) accept_encoding |= HTTP_ACCEPT_ENCODING_IDENTITY;
19328 /* get server side supported ones */
19330 srv_encodings |= HTTP_ACCEPT_ENCODING_BZIP2;
19331 @@ -627,18 +670,31 @@
19332 srv_encodings |= HTTP_ACCEPT_ENCODING_GZIP;
19333 srv_encodings |= HTTP_ACCEPT_ENCODING_DEFLATE;
19337 /* find matching entries */
19338 matched_encodings = accept_encoding & srv_encodings;
19341 if (matched_encodings) {
19342 const char *dflt_gzip = "gzip";
19343 const char *dflt_deflate = "deflate";
19344 const char *dflt_bzip2 = "bzip2";
19347 const char *compression_name = NULL;
19348 int compression_type = 0;
19352 + mtime = strftime_cache_get(srv, sce->st.st_mtime);
19353 + etag_mutate(con->physical.etag, sce->etag);
19355 + response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
19356 + response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
19358 + /* perhaps we don't even have to compress the file as the browser still has the
19359 + * current version */
19360 + if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) {
19361 + return HANDLER_FINISHED;
19364 /* select best matching encoding */
19365 if (matched_encodings & HTTP_ACCEPT_ENCODING_BZIP2) {
19366 compression_type = HTTP_ACCEPT_ENCODING_BZIP2;
19367 @@ -650,31 +706,21 @@
19368 compression_type = HTTP_ACCEPT_ENCODING_DEFLATE;
19369 compression_name = dflt_deflate;
19373 - if (p->conf.compress_cache_dir->used) {
19374 - if (0 == deflate_file_to_file(srv, con, p,
19375 - con->physical.path, sce, compression_type)) {
19378 - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
19380 - mtime = strftime_cache_get(srv, sce->st.st_mtime);
19381 - response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
19383 - etag_mutate(con->physical.etag, sce->etag);
19384 - response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
19386 - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
19388 - return HANDLER_GO_ON;
19390 - } else if (0 == deflate_file_to_buffer(srv, con, p,
19391 - con->physical.path, sce, compression_type)) {
19393 - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
19394 - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
19397 + /* deflate it to file (cached) or to memory */
19398 + if (0 == deflate_file_to_file(srv, con, p,
19399 + con->physical.path, sce, compression_type) ||
19400 + 0 == deflate_file_to_buffer(srv, con, p,
19401 + con->physical.path, sce, compression_type)) {
19403 + response_header_overwrite(srv, con,
19404 + CONST_STR_LEN("Content-Encoding"),
19405 + compression_name, strlen(compression_name));
19407 + response_header_overwrite(srv, con,
19408 + CONST_STR_LEN("Content-Type"),
19409 + CONST_BUF_LEN(sce->content_type));
19411 return HANDLER_FINISHED;
19414 @@ -682,20 +728,20 @@
19420 return HANDLER_GO_ON;
19423 int mod_compress_plugin_init(plugin *p) {
19424 p->version = LIGHTTPD_VERSION_ID;
19425 p->name = buffer_init_string("compress");
19428 p->init = mod_compress_init;
19429 p->set_defaults = mod_compress_setdefaults;
19430 p->handle_subrequest_start = mod_compress_physical;
19431 p->cleanup = mod_compress_free;
19439 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_dirlisting.c lighttpd-1.4.12/src/mod_dirlisting.c
19440 --- lighttpd-1.4.11/src/mod_dirlisting.c 2006-01-13 00:00:45.000000000 +0200
19441 +++ lighttpd-1.4.12/src/mod_dirlisting.c 2006-07-11 21:23:40.000000000 +0300
19444 #include <stdlib.h>
19445 #include <string.h>
19446 -#include <dirent.h>
19447 #include <assert.h>
19450 -#include <unistd.h>
19455 #include <attr/attributes.h>
19458 +#include "sys-files.h"
19459 +#include "sys-strings.h"
19461 /* plugin config for all request/connections */
19465 unsigned short hide_readme_file;
19466 unsigned short show_header;
19467 unsigned short hide_header_file;
19470 excludes_buffer *excludes;
19472 buffer *external_css;
19473 @@ -63,13 +64,13 @@
19480 buffer *content_charset;
19483 plugin_config **config_storage;
19485 - plugin_config conf;
19487 + plugin_config conf;
19490 excludes_buffer *excludes_buffer_init(void) {
19491 @@ -146,44 +147,44 @@
19492 /* init the plugin data */
19493 INIT_FUNC(mod_dirlisting_init) {
19497 p = calloc(1, sizeof(*p));
19499 p->tmp_buf = buffer_init();
19500 p->content_charset = buffer_init();
19506 /* detroy the plugin data */
19507 FREE_FUNC(mod_dirlisting_free) {
19508 plugin_data *p = p_d;
19513 if (!p) return HANDLER_GO_ON;
19516 if (p->config_storage) {
19518 for (i = 0; i < srv->config_context->used; i++) {
19519 plugin_config *s = p->config_storage[i];
19525 excludes_buffer_free(s->excludes);
19526 buffer_free(s->external_css);
19527 buffer_free(s->encoding);
19532 free(p->config_storage);
19536 buffer_free(p->tmp_buf);
19537 buffer_free(p->content_charset);
19543 return HANDLER_GO_ON;
19546 @@ -215,10 +216,10 @@
19547 if (0 != excludes_buffer_append(s->excludes,
19548 ((data_string *)(da->value->data[j]))->value)) {
19550 - log_error_write(srv, __FILE__, __LINE__, "sb",
19551 + log_error_write(srv, __FILE__, __LINE__, "sb",
19552 "pcre-compile failed for", ((data_string *)(da->value->data[j]))->value);
19554 - log_error_write(srv, __FILE__, __LINE__, "s",
19555 + log_error_write(srv, __FILE__, __LINE__, "s",
19556 "pcre support is missing, please install libpcre and the headers");
19559 @@ -233,8 +234,8 @@
19560 SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
19561 plugin_data *p = p_d;
19564 - config_values_t cv[] = {
19566 + config_values_t cv[] = {
19567 { "dir-listing.exclude", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
19568 { "dir-listing.activate", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
19569 { "dir-listing.hide-dotfiles", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
19570 @@ -245,18 +246,18 @@
19571 { "dir-listing.show-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
19572 { "dir-listing.hide-header-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
19573 { "server.dir-listing", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
19576 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
19580 if (!p) return HANDLER_ERROR;
19583 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
19586 for (i = 0; i < srv->config_context->used; i++) {
19591 s = calloc(1, sizeof(plugin_config));
19592 s->excludes = excludes_buffer_init();
19593 s->dir_listing = 0;
19594 @@ -267,7 +268,7 @@
19595 s->show_header = 0;
19596 s->hide_header_file = 0;
19597 s->encoding = buffer_init();
19600 cv[0].destination = s->excludes;
19601 cv[1].destination = &(s->dir_listing);
19602 cv[2].destination = &(s->hide_dot_files);
19603 @@ -292,60 +293,57 @@
19604 return HANDLER_GO_ON;
19607 -#define PATCH(x) \
19608 - p->conf.x = s->x;
19609 static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_data *p) {
19611 plugin_config *s = p->config_storage[0];
19613 - PATCH(dir_listing);
19614 - PATCH(external_css);
19615 - PATCH(hide_dot_files);
19617 - PATCH(show_readme);
19618 - PATCH(hide_readme_file);
19619 - PATCH(show_header);
19620 - PATCH(hide_header_file);
19623 + PATCH_OPTION(dir_listing);
19624 + PATCH_OPTION(external_css);
19625 + PATCH_OPTION(hide_dot_files);
19626 + PATCH_OPTION(encoding);
19627 + PATCH_OPTION(show_readme);
19628 + PATCH_OPTION(hide_readme_file);
19629 + PATCH_OPTION(show_header);
19630 + PATCH_OPTION(hide_header_file);
19631 + PATCH_OPTION(excludes);
19633 /* skip the first, the global context */
19634 for (i = 1; i < srv->config_context->used; i++) {
19635 data_config *dc = (data_config *)srv->config_context->data[i];
19636 s = p->config_storage[i];
19639 /* condition didn't match */
19640 if (!config_check_cond(srv, con, dc)) continue;
19644 for (j = 0; j < dc->value->used; j++) {
19645 data_unset *du = dc->value->data[j];
19648 if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.activate")) ||
19649 buffer_is_equal_string(du->key, CONST_STR_LEN("server.dir-listing"))) {
19650 - PATCH(dir_listing);
19651 + PATCH_OPTION(dir_listing);
19652 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-dotfiles"))) {
19653 - PATCH(hide_dot_files);
19654 + PATCH_OPTION(hide_dot_files);
19655 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.external-css"))) {
19656 - PATCH(external_css);
19657 + PATCH_OPTION(external_css);
19658 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.encoding"))) {
19660 + PATCH_OPTION(encoding);
19661 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-readme"))) {
19662 - PATCH(show_readme);
19663 + PATCH_OPTION(show_readme);
19664 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-readme-file"))) {
19665 - PATCH(hide_readme_file);
19666 + PATCH_OPTION(hide_readme_file);
19667 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-header"))) {
19668 - PATCH(show_header);
19669 + PATCH_OPTION(show_header);
19670 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-header-file"))) {
19671 - PATCH(hide_header_file);
19672 + PATCH_OPTION(hide_header_file);
19673 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.excludes"))) {
19675 + PATCH_OPTION(excludes);
19687 @@ -432,7 +430,7 @@
19689 static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) {
19693 BUFFER_APPEND_STRING_CONST(out,
19694 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
19695 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n"
19696 @@ -492,11 +490,11 @@
19697 if (p->conf.show_header) {
19699 /* if we have a HEADER file, display it in <pre class="header"></pre> */
19702 buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
19703 - BUFFER_APPEND_SLASH(p->tmp_buf);
19704 + PATHNAME_APPEND_SLASH(p->tmp_buf);
19705 BUFFER_APPEND_STRING_CONST(p->tmp_buf, "HEADER.txt");
19708 if (-1 != stream_open(&s, p->tmp_buf)) {
19709 BUFFER_APPEND_STRING_CONST(out, "<pre class=\"header\">");
19710 buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
19711 @@ -531,21 +529,21 @@
19713 static void http_list_directory_footer(server *srv, connection *con, plugin_data *p, buffer *out) {
19717 BUFFER_APPEND_STRING_CONST(out,
19724 if (p->conf.show_readme) {
19726 /* if we have a README file, display it in <pre class="readme"></pre> */
19729 buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
19730 - BUFFER_APPEND_SLASH(p->tmp_buf);
19731 + PATHNAME_APPEND_SLASH(p->tmp_buf);
19732 BUFFER_APPEND_STRING_CONST(p->tmp_buf, "README.txt");
19735 if (-1 != stream_open(&s, p->tmp_buf)) {
19736 BUFFER_APPEND_STRING_CONST(out, "<pre class=\"readme\">");
19737 buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
19738 @@ -553,7 +551,7 @@
19744 BUFFER_APPEND_STRING_CONST(out,
19745 "<div class=\"foot\">"
19747 @@ -595,7 +593,7 @@
19750 if (dir->used == 0) return -1;
19755 #ifdef HAVE_PATHCONF
19756 @@ -606,19 +604,24 @@
19757 name_max = 256; /* stupid default */
19760 -#elif defined __WIN32
19761 +#elif defined _WIN32
19762 name_max = FILENAME_MAX;
19764 name_max = NAME_MAX;
19768 path = malloc(dir->used + name_max);
19770 strcpy(path, dir->ptr);
19772 + /* append \*.* to the path and keep the \ as part of the pathname */
19773 + strcat(path, "\\*.*");
19776 path_file = path + i;
19778 if (NULL == (dp = opendir(path))) {
19779 - log_error_write(srv, __FILE__, __LINE__, "sbs",
19780 + log_error_write(srv, __FILE__, __LINE__, "sbs",
19781 "opendir failed:", dir, strerror(errno));
19784 @@ -633,7 +636,7 @@
19786 files.size = DIRLIST_BLOB_SIZE;
19790 while ((dent = readdir(dp)) != NULL) {
19791 unsigned short exclude_match = 0;
19793 @@ -686,15 +689,17 @@
19796 i = strlen(dent->d_name);
19799 /* NOTE: the manual says, d_name is never more than NAME_MAX
19800 * so this should actually not be a buffer-overflow-risk
19802 if (i > (size_t)name_max) continue;
19805 memcpy(path_file, dent->d_name, i + 1);
19806 - if (stat(path, &st) != 0)
19807 + if (stat(path, &st) != 0) {
19808 + fprintf(stderr, "%s.%d: %s, %s\r\n", __FILE__, __LINE__, path, strerror(errno));
19813 if (S_ISDIR(st.st_mode))
19814 @@ -740,7 +745,7 @@
19816 strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
19820 BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\"");
19821 buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
19822 BUFFER_APPEND_STRING_CONST(out, "/\">");
19823 @@ -758,7 +763,7 @@
19825 content_type = NULL;
19829 if (con->conf.use_xattr) {
19830 memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
19831 attrlen = sizeof(attrval) - 1;
19832 @@ -768,7 +773,7 @@
19838 if (content_type == NULL) {
19839 content_type = "application/octet-stream";
19840 for (k = 0; k < con->conf.mimetypes->used; k++) {
19841 @@ -788,7 +793,7 @@
19847 #ifdef HAVE_LOCALTIME_R
19848 localtime_r(&(tmp->mtime), &tm);
19849 strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
19850 @@ -837,36 +842,36 @@
19851 URIHANDLER_FUNC(mod_dirlisting_subrequest) {
19852 plugin_data *p = p_d;
19853 stat_cache_entry *sce = NULL;
19859 if (con->physical.path->used == 0) return HANDLER_GO_ON;
19860 if (con->uri.path->used == 0) return HANDLER_GO_ON;
19861 if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
19864 mod_dirlisting_patch_connection(srv, con, p);
19866 if (!p->conf.dir_listing) return HANDLER_GO_ON;
19869 if (con->conf.log_request_handling) {
19870 log_error_write(srv, __FILE__, __LINE__, "s", "-- handling the request as Dir-Listing");
19871 log_error_write(srv, __FILE__, __LINE__, "sb", "URI :", con->uri.path);
19875 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
19876 fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, con->physical.path->ptr);
19881 if (!S_ISDIR(sce->st.st_mode)) return HANDLER_GO_ON;
19884 if (http_list_directory(srv, con, p, con->physical.path)) {
19885 /* dirlisting failed */
19886 con->http_status = 403;
19890 buffer_reset(con->physical.path);
19894 return HANDLER_FINISHED;
19896 @@ -876,13 +881,13 @@
19897 int mod_dirlisting_plugin_init(plugin *p) {
19898 p->version = LIGHTTPD_VERSION_ID;
19899 p->name = buffer_init_string("dirlisting");
19902 p->init = mod_dirlisting_init;
19903 p->handle_subrequest_start = mod_dirlisting_subrequest;
19904 p->set_defaults = mod_dirlisting_set_defaults;
19905 p->cleanup = mod_dirlisting_free;
19913 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_evasive.c lighttpd-1.4.12/src/mod_evasive.c
19914 --- lighttpd-1.4.11/src/mod_evasive.c 2006-01-04 15:24:51.000000000 +0200
19915 +++ lighttpd-1.4.12/src/mod_evasive.c 2006-07-11 21:23:40.000000000 +0300
19916 @@ -31,100 +31,97 @@
19922 plugin_config **config_storage;
19924 - plugin_config conf;
19926 + plugin_config conf;
19929 INIT_FUNC(mod_evasive_init) {
19933 p = calloc(1, sizeof(*p));
19939 FREE_FUNC(mod_evasive_free) {
19940 plugin_data *p = p_d;
19945 if (!p) return HANDLER_GO_ON;
19948 if (p->config_storage) {
19950 for (i = 0; i < srv->config_context->used; i++) {
19951 plugin_config *s = p->config_storage[i];
19956 free(p->config_storage);
19963 return HANDLER_GO_ON;
19966 SETDEFAULTS_FUNC(mod_evasive_set_defaults) {
19967 plugin_data *p = p_d;
19970 - config_values_t cv[] = {
19972 + config_values_t cv[] = {
19973 { "evasive.max-conns-per-ip", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
19974 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
19978 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
19981 for (i = 0; i < srv->config_context->used; i++) {
19985 s = calloc(1, sizeof(plugin_config));
19989 cv[0].destination = &(s->max_conns);
19992 p->config_storage[i] = s;
19995 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
19996 return HANDLER_ERROR;
20001 return HANDLER_GO_ON;
20004 -#define PATCH(x) \
20005 - p->conf.x = s->x;
20006 static int mod_evasive_patch_connection(server *srv, connection *con, plugin_data *p) {
20008 plugin_config *s = p->config_storage[0];
20010 - PATCH(max_conns);
20012 + PATCH_OPTION(max_conns);
20014 /* skip the first, the global context */
20015 for (i = 1; i < srv->config_context->used; i++) {
20016 data_config *dc = (data_config *)srv->config_context->data[i];
20017 s = p->config_storage[i];
20020 /* condition didn't match */
20021 if (!config_check_cond(srv, con, dc)) continue;
20025 for (j = 0; j < dc->value->used; j++) {
20026 data_unset *du = dc->value->data[j];
20029 if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.max-conns-per-ip"))) {
20030 - PATCH(max_conns);
20031 + PATCH_OPTION(max_conns);
20041 URIHANDLER_FUNC(mod_evasive_uri_handler) {
20042 plugin_data *p = p_d;
20043 @@ -132,10 +129,10 @@
20046 if (con->uri.path->used == 0) return HANDLER_GO_ON;
20049 mod_evasive_patch_connection(srv, con, p);
20051 - /* no limit set, nothing to block */
20053 + /* no limit set, nothing to block */
20054 if (p->conf.max_conns == 0) return HANDLER_GO_ON;
20056 for (j = 0; j < srv->conns->used; j++) {
20057 @@ -147,7 +144,7 @@
20058 if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr &&
20059 c->state > CON_STATE_REQUEST_END) {
20063 if (conns_by_ip > p->conf.max_conns) {
20064 log_error_write(srv, __FILE__, __LINE__, "ss",
20065 inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
20066 @@ -158,7 +155,7 @@
20072 return HANDLER_GO_ON;
20075 @@ -166,13 +163,13 @@
20076 int mod_evasive_plugin_init(plugin *p) {
20077 p->version = LIGHTTPD_VERSION_ID;
20078 p->name = buffer_init_string("evasive");
20081 p->init = mod_evasive_init;
20082 p->set_defaults = mod_evasive_set_defaults;
20083 p->handle_uri_clean = mod_evasive_uri_handler;
20084 p->cleanup = mod_evasive_free;
20092 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_evhost.c lighttpd-1.4.12/src/mod_evhost.c
20093 --- lighttpd-1.4.11/src/mod_evhost.c 2005-08-17 10:42:03.000000000 +0300
20094 +++ lighttpd-1.4.12/src/mod_evhost.c 2006-07-11 21:23:39.000000000 +0300
20096 #include "response.h"
20097 #include "stat_cache.h"
20099 +#include "sys-files.h"
20102 /* unparsed pieces */
20103 buffer *path_pieces_raw;
20106 /* pieces for path creation */
20108 buffer **path_pieces;
20109 @@ -21,14 +23,14 @@
20112 plugin_config **config_storage;
20113 - plugin_config conf;
20114 + plugin_config conf;
20117 INIT_FUNC(mod_evhost_init) {
20121 p = calloc(1, sizeof(*p));
20124 p->tmp_buf = buffer_init();
20127 @@ -36,34 +38,34 @@
20129 FREE_FUNC(mod_evhost_free) {
20130 plugin_data *p = p_d;
20135 if (!p) return HANDLER_GO_ON;
20138 if (p->config_storage) {
20140 for (i = 0; i < srv->config_context->used; i++) {
20141 plugin_config *s = p->config_storage[i];
20146 if(s->path_pieces) {
20148 for (j = 0; j < s->len; j++) {
20149 buffer_free(s->path_pieces[j]);
20153 free(s->path_pieces);
20157 buffer_free(s->path_pieces_raw);
20162 free(p->config_storage);
20166 buffer_free(p->tmp_buf);
20169 @@ -73,30 +75,30 @@
20171 static void mod_evhost_parse_pattern(plugin_config *s) {
20172 char *ptr = s->path_pieces_raw->ptr,*pos;
20175 s->path_pieces = NULL;
20178 for(pos=ptr;*ptr;ptr++) {
20180 s->path_pieces = realloc(s->path_pieces,(s->len+2) * sizeof(*s->path_pieces));
20181 s->path_pieces[s->len] = buffer_init();
20182 s->path_pieces[s->len+1] = buffer_init();
20185 buffer_copy_string_len(s->path_pieces[s->len],pos,ptr-pos);
20189 buffer_copy_string_len(s->path_pieces[s->len+1],ptr++,2);
20198 s->path_pieces = realloc(s->path_pieces,(s->len+1) * sizeof(*s->path_pieces));
20199 s->path_pieces[s->len] = buffer_init();
20202 buffer_append_memory(s->path_pieces[s->len],pos,ptr-pos);
20208 @@ -104,9 +106,9 @@
20209 SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
20210 plugin_data *p = p_d;
20218 * # define a pattern for the host url finding
20220 @@ -117,39 +119,39 @@
20221 * # %4 => subdomain 2 name
20223 * evhost.path-pattern = "/home/ckruse/dev/www/%3/htdocs/"
20228 - config_values_t cv[] = {
20230 + config_values_t cv[] = {
20231 { "evhost.path-pattern", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
20232 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
20236 if (!p) return HANDLER_ERROR;
20239 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
20242 for (i = 0; i < srv->config_context->used; i++) {
20246 s = calloc(1, sizeof(plugin_config));
20247 s->path_pieces_raw = buffer_init();
20248 s->path_pieces = NULL;
20252 cv[0].destination = s->path_pieces_raw;
20255 p->config_storage[i] = s;
20258 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
20259 return HANDLER_ERROR;
20263 if (s->path_pieces_raw->used != 0) {
20264 mod_evhost_parse_pattern(s);
20269 return HANDLER_GO_ON;
20272 @@ -158,7 +160,7 @@
20273 * - %0 - full hostname (authority w/o port)
20275 * - %2 - domain.tld
20280 static int mod_evhost_parse_host(connection *con,array *host) {
20281 @@ -168,7 +170,7 @@
20287 /* first, find the domain + tld */
20288 for(;ptr > con->uri.authority->ptr;ptr--) {
20290 @@ -179,18 +181,18 @@
20296 ds = data_string_init();
20297 buffer_copy_string(ds->key,"%0");
20300 /* if we stopped at a dot, skip the dot */
20301 if (*ptr == '.') ptr++;
20302 buffer_copy_string_len(ds->value, ptr, colon-ptr);
20305 array_insert_unique(host,(data_unset *)ds);
20308 /* if the : is not the start of the authority, go on parsing the hostname */
20311 if (colon != con->uri.authority->ptr) {
20312 for(ptr = colon - 1, i = 1; ptr > con->uri.authority->ptr; ptr--) {
20314 @@ -200,59 +202,55 @@
20315 buffer_copy_string(ds->key,"%");
20316 buffer_append_long(ds->key, i++);
20317 buffer_copy_string_len(ds->value,ptr+1,colon-ptr-1);
20320 array_insert_unique(host,(data_unset *)ds);
20327 /* if the . is not the first charactor of the hostname */
20328 if (colon != ptr) {
20329 ds = data_string_init();
20330 buffer_copy_string(ds->key,"%");
20331 buffer_append_long(ds->key, i++);
20332 buffer_copy_string_len(ds->value,ptr,colon-ptr);
20335 array_insert_unique(host,(data_unset *)ds);
20343 -#define PATCH(x) \
20344 - p->conf.x = s->x;
20345 static int mod_evhost_patch_connection(server *srv, connection *con, plugin_data *p) {
20347 plugin_config *s = p->config_storage[0];
20349 - PATCH(path_pieces);
20353 + PATCH_OPTION(path_pieces);
20354 + PATCH_OPTION(len);
20356 /* skip the first, the global context */
20357 for (i = 1; i < srv->config_context->used; i++) {
20358 data_config *dc = (data_config *)srv->config_context->data[i];
20359 s = p->config_storage[i];
20362 /* condition didn't match */
20363 if (!config_check_cond(srv, con, dc)) continue;
20367 for (j = 0; j < dc->value->used; j++) {
20368 data_unset *du = dc->value->data[j];
20371 if (buffer_is_equal_string(du->key, CONST_STR_LEN("evhost.path-pattern"))) {
20372 - PATCH(path_pieces);
20374 + PATCH_OPTION(path_pieces);
20375 + PATCH_OPTION(len);
20386 static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d) {
20387 plugin_data *p = p_d;
20388 @@ -261,29 +259,29 @@
20389 register char *ptr;
20391 stat_cache_entry *sce = NULL;
20394 /* not authority set */
20395 if (con->uri.authority->used == 0) return HANDLER_GO_ON;
20398 mod_evhost_patch_connection(srv, con, p);
20401 /* missing even default(global) conf */
20402 if (0 == p->conf.len) {
20403 return HANDLER_GO_ON;
20406 parsed_host = array_init();
20409 mod_evhost_parse_host(con, parsed_host);
20412 /* build document-root */
20413 buffer_reset(p->tmp_buf);
20416 for (i = 0; i < p->conf.len; i++) {
20417 ptr = p->conf.path_pieces[i]->ptr;
20422 if (*(ptr+1) == '%') {
20424 BUFFER_APPEND_STRING_CONST(p->tmp_buf,"%");
20425 @@ -298,11 +296,11 @@
20426 buffer_append_string_buffer(p->tmp_buf,p->conf.path_pieces[i]);
20430 - BUFFER_APPEND_SLASH(p->tmp_buf);
20433 + PATHNAME_APPEND_SLASH(p->tmp_buf);
20435 array_free(parsed_host);
20438 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
20439 log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
20441 @@ -310,11 +308,11 @@
20442 log_error_write(srv, __FILE__, __LINE__, "sb", "not a directory:", p->tmp_buf);
20448 buffer_copy_string_buffer(con->physical.doc_root, p->tmp_buf);
20452 return HANDLER_GO_ON;
20455 @@ -325,9 +323,9 @@
20456 p->set_defaults = mod_evhost_set_defaults;
20457 p->handle_docroot = mod_evhost_uri_handler;
20458 p->cleanup = mod_evhost_free;
20467 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_expire.c lighttpd-1.4.12/src/mod_expire.c
20468 --- lighttpd-1.4.11/src/mod_expire.c 2005-11-03 09:52:13.000000000 +0200
20469 +++ lighttpd-1.4.12/src/mod_expire.c 2006-07-11 21:23:40.000000000 +0300
20471 #include "stat_cache.h"
20474 - * this is a expire module for a lighttpd
20476 + * this is a expire module for a lighttpd
20478 * set 'Expires:' HTTP Headers on demand
20481 @@ -27,51 +27,51 @@
20487 buffer *expire_tstmp;
20490 plugin_config **config_storage;
20492 - plugin_config conf;
20494 + plugin_config conf;
20497 /* init the plugin data */
20498 INIT_FUNC(mod_expire_init) {
20502 p = calloc(1, sizeof(*p));
20505 p->expire_tstmp = buffer_init();
20508 buffer_prepare_copy(p->expire_tstmp, 255);
20514 /* detroy the plugin data */
20515 FREE_FUNC(mod_expire_free) {
20516 plugin_data *p = p_d;
20521 if (!p) return HANDLER_GO_ON;
20524 buffer_free(p->expire_tstmp);
20527 if (p->config_storage) {
20529 for (i = 0; i < srv->config_context->used; i++) {
20530 plugin_config *s = p->config_storage[i];
20533 array_free(s->expire_url);
20538 free(p->config_storage);
20545 return HANDLER_GO_ON;
20548 @@ -79,25 +79,25 @@
20561 * '(access|modification) [plus] {<num> <type>}*'
20564 * e.g. 'access 1 years'
20568 if (expire->used == 0) {
20569 - log_error_write(srv, __FILE__, __LINE__, "s",
20570 + log_error_write(srv, __FILE__, __LINE__, "s",
20579 if (0 == strncmp(ts, "access ", 7)) {
20582 @@ -110,39 +110,39 @@
20583 "invalid <base>:", ts);
20588 if (0 == strncmp(ts, "plus ", 5)) {
20589 /* skip the optional plus */
20594 /* the rest is just <number> (years|months|days|hours|minutes|seconds) */
20600 if (NULL == (space = strchr(ts, ' '))) {
20601 - log_error_write(srv, __FILE__, __LINE__, "ss",
20602 + log_error_write(srv, __FILE__, __LINE__, "ss",
20603 "missing space after <num>:", ts);
20608 num = strtol(ts, &err, 10);
20610 - log_error_write(srv, __FILE__, __LINE__, "ss",
20611 + log_error_write(srv, __FILE__, __LINE__, "ss",
20612 "missing <type> after <num>:", ts);
20620 if (NULL != (space = strchr(ts, ' '))) {
20630 0 == strncmp(ts, "years", slen)) {
20631 num *= 60 * 60 * 24 * 30 * 12;
20632 } else if (slen == 6 &&
20633 @@ -161,13 +161,13 @@
20634 0 == strncmp(ts, "seconds", slen)) {
20637 - log_error_write(srv, __FILE__, __LINE__, "ss",
20638 + log_error_write(srv, __FILE__, __LINE__, "ss",
20639 "unknown type:", ts);
20649 if (0 == strcmp(ts, "years")) {
20650 @@ -183,19 +183,19 @@
20651 } else if (0 == strcmp(ts, "seconds")) {
20654 - log_error_write(srv, __FILE__, __LINE__, "ss",
20655 + log_error_write(srv, __FILE__, __LINE__, "ss",
20656 "unknown type:", ts);
20669 if (offset != NULL) *offset = retts;
20675 @@ -205,102 +205,99 @@
20676 SETDEFAULTS_FUNC(mod_expire_set_defaults) {
20677 plugin_data *p = p_d;
20680 - config_values_t cv[] = {
20682 + config_values_t cv[] = {
20683 { "expire.url", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
20684 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
20688 if (!p) return HANDLER_ERROR;
20691 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
20694 for (i = 0; i < srv->config_context->used; i++) {
20698 s = calloc(1, sizeof(plugin_config));
20699 s->expire_url = array_init();
20702 cv[0].destination = s->expire_url;
20705 p->config_storage[i] = s;
20708 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
20709 return HANDLER_ERROR;
20713 for (k = 0; k < s->expire_url->used; k++) {
20714 data_string *ds = (data_string *)s->expire_url->data[k];
20718 if (-1 == mod_expire_get_offset(srv, p, ds->value, NULL)) {
20719 - log_error_write(srv, __FILE__, __LINE__, "sb",
20720 + log_error_write(srv, __FILE__, __LINE__, "sb",
20721 "parsing expire.url failed:", ds->value);
20722 return HANDLER_ERROR;
20730 return HANDLER_GO_ON;
20733 -#define PATCH(x) \
20734 - p->conf.x = s->x;
20735 static int mod_expire_patch_connection(server *srv, connection *con, plugin_data *p) {
20737 plugin_config *s = p->config_storage[0];
20739 - PATCH(expire_url);
20742 + PATCH_OPTION(expire_url);
20744 /* skip the first, the global context */
20745 for (i = 1; i < srv->config_context->used; i++) {
20746 data_config *dc = (data_config *)srv->config_context->data[i];
20747 s = p->config_storage[i];
20750 /* condition didn't match */
20751 if (!config_check_cond(srv, con, dc)) continue;
20755 for (j = 0; j < dc->value->used; j++) {
20756 data_unset *du = dc->value->data[j];
20759 if (buffer_is_equal_string(du->key, CONST_STR_LEN("expire.url"))) {
20760 - PATCH(expire_url);
20761 + PATCH_OPTION(expire_url);
20771 URIHANDLER_FUNC(mod_expire_path_handler) {
20772 plugin_data *p = p_d;
20777 if (con->uri.path->used == 0) return HANDLER_GO_ON;
20780 mod_expire_patch_connection(srv, con, p);
20783 s_len = con->uri.path->used - 1;
20786 for (k = 0; k < p->conf.expire_url->used; k++) {
20787 data_string *ds = (data_string *)p->conf.expire_url->data[k];
20788 int ct_len = ds->key->used - 1;
20791 if (ct_len > s_len) continue;
20792 if (ds->key->used == 0) continue;
20795 if (0 == strncmp(con->uri.path->ptr, ds->key->ptr, ct_len)) {
20799 stat_cache_entry *sce = NULL;
20802 stat_cache_get_entry(srv, con, con->physical.path, &sce);
20805 switch(mod_expire_get_offset(srv, p, ds->value, &ts)) {
20808 @@ -308,38 +305,38 @@
20814 t = (ts + sce->st.st_mtime);
20817 /* -1 is handled at parse-time */
20822 - if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1,
20825 + if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1,
20826 "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(t))))) {
20827 /* could not set expire header, out of mem */
20830 return HANDLER_GO_ON;
20836 p->expire_tstmp->used = len + 1;
20841 response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_BUF_LEN(p->expire_tstmp));
20845 buffer_copy_string(p->expire_tstmp, "max-age=");
20846 buffer_append_long(p->expire_tstmp, ts);
20849 response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp));
20852 return HANDLER_GO_ON;
20858 return HANDLER_GO_ON;
20860 @@ -349,13 +346,13 @@
20861 int mod_expire_plugin_init(plugin *p) {
20862 p->version = LIGHTTPD_VERSION_ID;
20863 p->name = buffer_init_string("expire");
20866 p->init = mod_expire_init;
20867 p->handle_subrequest_start = mod_expire_path_handler;
20868 p->set_defaults = mod_expire_set_defaults;
20869 p->cleanup = mod_expire_free;
20877 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_fastcgi.c lighttpd-1.4.12/src/mod_fastcgi.c
20878 --- lighttpd-1.4.11/src/mod_fastcgi.c 2006-03-09 13:18:39.000000000 +0200
20879 +++ lighttpd-1.4.12/src/mod_fastcgi.c 2006-07-11 21:23:40.000000000 +0300
20881 #include <sys/types.h>
20882 -#include <unistd.h>
20885 #include <string.h>
20887 #include "inet_ntop_cache.h"
20888 #include "stat_cache.h"
20890 -#include <fastcgi.h>
20891 +#include "fastcgi.h"
20894 #ifdef HAVE_SYS_FILIO_H
20898 #include "sys-socket.h"
20899 +#include "sys-files.h"
20900 +#include "sys-strings.h"
20901 +#include "sys-process.h"
20903 +#include "http_resp.h"
20905 #ifndef UNIX_PATH_MAX
20906 # define UNIX_PATH_MAX 108
20907 @@ -45,14 +48,13 @@
20908 #include <sys/wait.h>
20918 * - add timeout for a connect to a non-fastcgi process
20919 * (use state_timestamp + state)
20924 typedef struct fcgi_proc {
20926 unsigned port; /* config.port + pno */
20928 buffer *connection_name; /* either tcp:<host>:<port> or unix:<socket> for debuggin purposes */
20931 pid_t pid; /* PID of the spawned process (0 if not spawned locally) */
20934 @@ -70,20 +72,20 @@
20935 time_t last_used; /* see idle_timeout */
20936 size_t requests; /* see max_requests */
20937 struct fcgi_proc *prev, *next; /* see first */
20940 time_t disabled_until; /* this proc is disabled until, use something else until than */
20947 PROC_STATE_UNSET, /* init-phase */
20948 PROC_STATE_RUNNING, /* alive */
20949 - PROC_STATE_OVERLOADED, /* listen-queue is full,
20950 + PROC_STATE_OVERLOADED, /* listen-queue is full,
20951 don't send something to this proc for the next 2 seconds */
20952 PROC_STATE_DIED_WAIT_FOR_PID, /* */
20953 PROC_STATE_DIED, /* marked as dead, should be restarted */
20954 PROC_STATE_KILLED /* was killed as we don't have the load anymore */
20960 @@ -94,20 +96,20 @@
20961 * sorted by lowest load
20963 * whenever a job is done move it up in the list
20964 - * until it is sorted, move it down as soon as the
20965 + * until it is sorted, move it down as soon as the
20968 - fcgi_proc *first;
20969 - fcgi_proc *unused_procs;
20970 + fcgi_proc *first;
20971 + fcgi_proc *unused_procs;
20975 * spawn at least min_procs, at max_procs.
20977 - * as soon as the load of the first entry
20978 + * as soon as the load of the first entry
20979 * is max_load_per_proc we spawn a new one
20980 - * and add it to the first entry and give it
20981 + * and add it to the first entry and give it
20987 unsigned short min_procs;
20988 @@ -119,44 +121,44 @@
20991 * kick the process from the list if it was not
20992 - * used for idle_timeout until min_procs is
20993 + * used for idle_timeout until min_procs is
20994 * reached. this helps to get the processlist
20995 * small again we had a small peak load.
21000 unsigned short idle_timeout;
21004 * time after a disabled remote connection is tried to be re-enabled
21012 unsigned short disable_time;
21015 * same fastcgi processes get a little bit larger
21016 - * than wanted. max_requests_per_proc kills a
21017 + * than wanted. max_requests_per_proc kills a
21018 * process after a number of handled requests.
21021 size_t max_requests_per_proc;
21032 - * if host is one of the local IP adresses the
21033 + * if host is one of the local IP adresses the
21034 * whole connection is local
21036 * if tcp/ip should be used host AND port have
21037 - * to be specified
21041 + * to be specified
21045 unsigned short port;
21048 @@ -169,7 +171,7 @@
21050 buffer *unixsocket;
21052 - /* if socket is local we can start the fastcgi
21053 + /* if socket is local we can start the fastcgi
21056 * bin-path is the path to the binary
21057 @@ -177,19 +179,19 @@
21058 * check min_procs and max_procs for the number
21059 * of process to start-up
21061 - buffer *bin_path;
21063 - /* bin-path is set bin-environment is taken to
21064 + buffer *bin_path;
21066 + /* bin-path is set bin-environment is taken to
21067 * create the environement before starting the
21075 array *bin_env_copy;
21079 - * docroot-translation between URL->phys and the
21080 + * docroot-translation between URL->phys and the
21084 @@ -208,7 +210,7 @@
21085 unsigned short mode;
21088 - * check_local tell you if the phys file is stat()ed
21089 + * check_local tell you if the phys file is stat()ed
21090 * or not. FastCGI doesn't care if the service is
21091 * remote. If the web-server side doesn't contain
21092 * the fastcgi-files we should not stat() for them
21093 @@ -218,11 +220,11 @@
21096 * append PATH_INFO to SCRIPT_FILENAME
21099 * php needs this if cgi.fix_pathinfo is provied
21105 unsigned short break_scriptfilename_for_php;
21108 @@ -231,12 +233,12 @@
21111 unsigned short allow_xsendfile;
21114 ssize_t load; /* replace by host->load */
21116 size_t max_id; /* corresponds most of the time to
21120 only if a process is killed max_id waits for the process itself
21121 to die and decrements its afterwards */
21123 @@ -245,17 +247,17 @@
21126 * one extension can have multiple hosts assigned
21127 - * one host can spawn additional processes on the same
21128 + * one host can spawn additional processes on the same
21129 * socket (if we control it)
21131 * ext -> host -> procs
21134 - * if the fastcgi process is remote that whole goes down
21135 + * if the fastcgi process is remote that whole goes down
21138 * ext -> host -> procs
21142 * in case of PHP and FCGI_CHILDREN we have again a procs
21143 * but we don't control it directly.
21144 @@ -268,7 +270,7 @@
21147 fcgi_extension_host **hosts;
21153 @@ -282,10 +284,10 @@
21160 array *ext_mapping;
21166 @@ -297,7 +299,7 @@
21175 @@ -306,44 +308,44 @@
21178 buffer_uint fcgi_request_id;
21185 - buffer *parse_response;
21192 plugin_config **config_storage;
21195 plugin_config conf; /* this is only used as long as no handler_ctx is setup */
21198 /* connection specific data */
21203 - FCGI_STATE_CONNECT_DELAYED,
21204 - FCGI_STATE_PREPARE_WRITE,
21205 - FCGI_STATE_WRITE,
21208 + FCGI_STATE_CONNECT_DELAYED,
21209 + FCGI_STATE_PREPARE_WRITE,
21210 + FCGI_STATE_WRITE,
21212 } fcgi_connection_state_t;
21216 fcgi_extension_host *host;
21217 fcgi_extension *ext;
21220 fcgi_connection_state_t state;
21221 time_t state_timestamp;
21224 int reconnects; /* number of reconnect attempts */
21226 - chunkqueue *rb; /* read queue */
21228 + chunkqueue *rb; /* the raw fcgi read-queue */
21229 + chunkqueue *http_rb; /* the decoded read-queue for http-parsing */
21230 chunkqueue *wb; /* write queue */
21232 - buffer *response_header;
21236 int fd; /* fd to the fastcgi process */
21237 int fde_ndx; /* index into the fd-event buffer */
21238 @@ -352,9 +354,9 @@
21241 int send_content_body;
21244 plugin_config conf;
21247 connection *remote_conn; /* dumb pointer */
21248 plugin_data *plugin_data; /* dumb pointer */
21250 @@ -380,7 +382,7 @@
21254 -/* dummies of the statistic framework functions
21255 +/* dummies of the statistic framework functions
21256 * they will be moved to a statistics.c later */
21257 int status_counter_inc(server *srv, const char *s, size_t len) {
21258 data_integer *di = status_counter_get_counter(srv, s, len);
21259 @@ -429,7 +431,7 @@
21260 CLEAN(".connected");
21267 fastcgi_status_copy_procname(b, host, NULL); \
21268 @@ -438,33 +440,32 @@
21278 static handler_ctx * handler_ctx_init() {
21279 handler_ctx * hctx;
21282 hctx = calloc(1, sizeof(*hctx));
21286 hctx->fde_ndx = -1;
21288 - hctx->response_header = buffer_init();
21291 hctx->request_id = 0;
21292 hctx->state = FCGI_STATE_INIT;
21299 hctx->reconnects = 0;
21300 hctx->send_content_body = 1;
21302 hctx->rb = chunkqueue_init();
21303 + hctx->http_rb = chunkqueue_init();
21304 hctx->wb = chunkqueue_init();
21310 @@ -473,10 +474,9 @@
21311 hctx->host->load--;
21315 - buffer_free(hctx->response_header);
21317 chunkqueue_free(hctx->rb);
21318 + chunkqueue_free(hctx->http_rb);
21319 chunkqueue_free(hctx->wb);
21322 @@ -488,21 +488,21 @@
21323 f = calloc(1, sizeof(*f));
21324 f->unixsocket = buffer_init();
21325 f->connection_name = buffer_init();
21335 void fastcgi_process_free(fcgi_proc *f) {
21339 fastcgi_process_free(f->next);
21342 buffer_free(f->unixsocket);
21343 buffer_free(f->connection_name);
21349 @@ -519,13 +519,13 @@
21350 f->bin_env = array_init();
21351 f->bin_env_copy = array_init();
21352 f->strip_request_uri = buffer_init();
21358 void fastcgi_host_free(fcgi_extension_host *h) {
21362 buffer_free(h->id);
21363 buffer_free(h->host);
21364 buffer_free(h->unixsocket);
21365 @@ -534,49 +534,49 @@
21366 buffer_free(h->strip_request_uri);
21367 array_free(h->bin_env);
21368 array_free(h->bin_env_copy);
21371 fastcgi_process_free(h->first);
21372 fastcgi_process_free(h->unused_procs);
21380 fcgi_exts *fastcgi_extensions_init() {
21383 f = calloc(1, sizeof(*f));
21389 void fastcgi_extensions_free(fcgi_exts *f) {
21396 for (i = 0; i < f->used; i++) {
21397 fcgi_extension *fe;
21404 for (j = 0; j < fe->used; j++) {
21405 fcgi_extension_host *h;
21411 fastcgi_host_free(h);
21415 buffer_free(fe->key);
21429 @@ -625,24 +625,25 @@
21433 - fe->hosts[fe->used++] = fh;
21434 + fe->hosts[fe->used++] = fh;
21441 INIT_FUNC(mod_fastcgi_init) {
21445 p = calloc(1, sizeof(*p));
21448 p->fcgi_env = buffer_init();
21451 p->path = buffer_init();
21452 - p->parse_response = buffer_init();
21454 + p->resp = http_response_init();
21456 p->statuskey = buffer_init();
21462 @@ -650,81 +651,82 @@
21463 FREE_FUNC(mod_fastcgi_free) {
21464 plugin_data *p = p_d;
21465 buffer_uint *r = &(p->fcgi_request_id);
21470 if (r->ptr) free(r->ptr);
21473 buffer_free(p->fcgi_env);
21474 buffer_free(p->path);
21475 - buffer_free(p->parse_response);
21476 buffer_free(p->statuskey);
21479 + http_response_free(p->resp);
21481 if (p->config_storage) {
21483 for (i = 0; i < srv->config_context->used; i++) {
21484 plugin_config *s = p->config_storage[i];
21493 for (j = 0; j < exts->used; j++) {
21494 fcgi_extension *ex;
21497 ex = exts->exts[j];
21500 for (n = 0; n < ex->used; n++) {
21502 fcgi_extension_host *host;
21505 host = ex->hosts[n];
21508 for (proc = host->first; proc; proc = proc->next) {
21509 if (proc->pid != 0) kill(proc->pid, SIGTERM);
21511 - if (proc->is_local &&
21513 + if (proc->is_local &&
21514 !buffer_is_empty(proc->unixsocket)) {
21515 unlink(proc->unixsocket->ptr);
21520 for (proc = host->unused_procs; proc; proc = proc->next) {
21521 if (proc->pid != 0) kill(proc->pid, SIGTERM);
21523 - if (proc->is_local &&
21525 + if (proc->is_local &&
21526 !buffer_is_empty(proc->unixsocket)) {
21527 unlink(proc->unixsocket->ptr);
21534 fastcgi_extensions_free(s->exts);
21535 array_free(s->ext_mapping);
21540 free(p->config_storage);
21547 return HANDLER_GO_ON;
21550 static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
21554 if (!key || !val) return -1;
21557 dst = malloc(key_len + val_len + 3);
21558 memcpy(dst, key, key_len);
21559 dst[key_len] = '=';
21560 /* add the \0 from the value */
21561 memcpy(dst + key_len + 1, val, val_len + 1);
21564 if (env->size == 0) {
21566 env->ptr = malloc(env->size * sizeof(*env->ptr));
21567 @@ -732,9 +734,9 @@
21569 env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
21573 env->ptr[env->used++] = dst;
21579 @@ -753,15 +755,15 @@
21580 if (env->size == 0) {
21582 env->ptr = malloc(env->size * sizeof(*env->ptr));
21583 - } else if (env->size == env->used) {
21584 + } else if (env->size == env->used) {
21586 env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
21592 env->ptr[env->used++] = start;
21595 start = b->ptr + i + 1;
21598 @@ -794,7 +796,7 @@
21602 -static int fcgi_spawn_connection(server *srv,
21603 +static int fcgi_spawn_connection(server *srv,
21605 fcgi_extension_host *host,
21607 @@ -806,31 +808,27 @@
21609 struct sockaddr_in fcgi_addr_in;
21610 struct sockaddr *fcgi_addr;
21621 if (p->conf.debug) {
21622 log_error_write(srv, __FILE__, __LINE__, "sdb",
21623 "new proc, socket:", proc->port, proc->unixsocket);
21627 if (!buffer_is_empty(proc->unixsocket)) {
21628 memset(&fcgi_addr, 0, sizeof(fcgi_addr));
21631 #ifdef HAVE_SYS_UN_H
21632 fcgi_addr_un.sun_family = AF_UNIX;
21633 strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
21637 servlen = SUN_LEN(&fcgi_addr_un);
21639 - /* stevens says: */
21640 - servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
21643 socket_type = AF_UNIX;
21644 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
21646 @@ -844,108 +842,108 @@
21649 fcgi_addr_in.sin_family = AF_INET;
21652 if (buffer_is_empty(host->host)) {
21653 fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
21655 struct hostent *he;
21658 /* set a usefull default */
21659 fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
21664 if (NULL == (he = gethostbyname(host->host->ptr))) {
21665 - log_error_write(srv, __FILE__, __LINE__,
21666 - "sdb", "gethostbyname failed: ",
21667 + log_error_write(srv, __FILE__, __LINE__,
21668 + "sdb", "gethostbyname failed: ",
21669 h_errno, host->host);
21674 if (he->h_addrtype != AF_INET) {
21675 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
21680 if (he->h_length != sizeof(struct in_addr)) {
21681 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
21686 memcpy(&(fcgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
21690 fcgi_addr_in.sin_port = htons(proc->port);
21691 servlen = sizeof(fcgi_addr_in);
21694 socket_type = AF_INET;
21695 fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
21698 buffer_copy_string(proc->connection_name, "tcp:");
21699 buffer_append_string_buffer(proc->connection_name, host->host);
21700 buffer_append_string(proc->connection_name, ":");
21701 buffer_append_long(proc->connection_name, proc->port);
21705 if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
21706 - log_error_write(srv, __FILE__, __LINE__, "ss",
21707 + log_error_write(srv, __FILE__, __LINE__, "ss",
21708 "failed:", strerror(errno));
21713 if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
21714 /* server is not up, spawn in */
21718 - if (errno != ENOENT &&
21720 + if (errno != ENOENT &&
21721 !buffer_is_empty(proc->unixsocket)) {
21722 unlink(proc->unixsocket->ptr);
21729 /* reopen socket */
21730 if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
21731 - log_error_write(srv, __FILE__, __LINE__, "ss",
21732 + log_error_write(srv, __FILE__, __LINE__, "ss",
21733 "socket failed:", strerror(errno));
21739 if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
21740 - log_error_write(srv, __FILE__, __LINE__, "ss",
21741 + log_error_write(srv, __FILE__, __LINE__, "ss",
21742 "socketsockopt failed:", strerror(errno));
21747 /* create socket */
21748 if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
21749 - log_error_write(srv, __FILE__, __LINE__, "sbs",
21750 - "bind failed for:",
21751 + log_error_write(srv, __FILE__, __LINE__, "sbs",
21752 + "bind failed for:",
21753 proc->connection_name,
21759 if (-1 == listen(fcgi_fd, 1024)) {
21760 - log_error_write(srv, __FILE__, __LINE__, "ss",
21761 + log_error_write(srv, __FILE__, __LINE__, "ss",
21762 "listen failed:", strerror(errno));
21769 switch ((child = fork())) {
21777 /* create environment */
21786 @@ -955,18 +953,18 @@
21787 dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
21792 /* we don't need the client socket */
21793 for (i = 3; i < 256; i++) {
21798 /* build clean environment */
21799 if (host->bin_env_copy->used) {
21800 for (i = 0; i < host->bin_env_copy->used; i++) {
21801 data_string *ds = (data_string *)host->bin_env_copy->data[i];
21805 if (NULL != (ge = getenv(ds->value->ptr))) {
21806 env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge));
21808 @@ -974,39 +972,39 @@
21810 for (i = 0; environ[i]; i++) {
21814 if (NULL != (eq = strchr(environ[i], '='))) {
21815 env_add(&env, environ[i], eq - environ[i], eq+1, strlen(eq+1));
21821 /* create environment */
21822 for (i = 0; i < host->bin_env->used; i++) {
21823 data_string *ds = (data_string *)host->bin_env->data[i];
21826 env_add(&env, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
21830 for (i = 0; i < env.used; i++) {
21831 /* search for PHP_FCGI_CHILDREN */
21832 if (0 == strncmp(env.ptr[i], "PHP_FCGI_CHILDREN=", sizeof("PHP_FCGI_CHILDREN=") - 1)) break;
21836 /* not found, add a default */
21837 if (i == env.used) {
21838 env_add(&env, CONST_STR_LEN("PHP_FCGI_CHILDREN"), CONST_STR_LEN("1"));
21842 env.ptr[env.used] = NULL;
21844 parse_binpath(&arg, host->bin_path);
21847 /* chdir into the base of the bin-path,
21848 * search for the last / */
21849 if (NULL != (c = strrchr(arg.ptr[0], '/'))) {
21853 /* change to the physical directory */
21854 if (-1 == chdir(arg.ptr[0])) {
21856 @@ -1018,12 +1016,12 @@
21859 execve(arg.ptr[0], arg.ptr, env.ptr);
21861 - log_error_write(srv, __FILE__, __LINE__, "sbs",
21863 + log_error_write(srv, __FILE__, __LINE__, "sbs",
21864 "execve failed for:", host->bin_path, strerror(errno));
21873 @@ -1031,17 +1029,17 @@
21880 select(0, NULL, NULL, NULL, &tv);
21883 switch (waitpid(child, &status, WNOHANG)) {
21885 /* child still running after timeout, good */
21888 /* no PID found ? should never happen */
21889 - log_error_write(srv, __FILE__, __LINE__, "ss",
21890 + log_error_write(srv, __FILE__, __LINE__, "ss",
21891 "pid not found:", strerror(errno));
21894 @@ -1049,10 +1047,10 @@
21895 "the fastcgi-backend", host->bin_path, "failed to start:");
21896 /* the child should not terminate at all */
21897 if (WIFEXITED(status)) {
21898 - log_error_write(srv, __FILE__, __LINE__, "sdb",
21899 - "child exited with status",
21900 + log_error_write(srv, __FILE__, __LINE__, "sdb",
21901 + "child exited with status",
21902 WEXITSTATUS(status), host->bin_path);
21903 - log_error_write(srv, __FILE__, __LINE__, "s",
21904 + log_error_write(srv, __FILE__, __LINE__, "s",
21905 "if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.\n"
21906 "You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' "
21907 "in the output, NOT (cgi) NOR (cli)\n"
21908 @@ -1060,8 +1058,8 @@
21909 log_error_write(srv, __FILE__, __LINE__, "s",
21910 "If this is PHP on Gentoo add fastcgi to the USE flags");
21911 } else if (WIFSIGNALED(status)) {
21912 - log_error_write(srv, __FILE__, __LINE__, "sd",
21913 - "terminated by signal:",
21914 + log_error_write(srv, __FILE__, __LINE__, "sd",
21915 + "terminated by signal:",
21918 if (WTERMSIG(status) == 11) {
21919 @@ -1071,8 +1069,8 @@
21920 "If this is PHP try to remove the byte-code caches for now and try again.");
21923 - log_error_write(srv, __FILE__, __LINE__, "sd",
21924 - "child died somehow:",
21925 + log_error_write(srv, __FILE__, __LINE__, "sd",
21926 + "child died somehow:",
21930 @@ -1082,26 +1080,26 @@
21932 proc->last_used = srv->cur_ts;
21933 proc->is_local = 1;
21940 proc->is_local = 0;
21944 if (p->conf.debug) {
21945 log_error_write(srv, __FILE__, __LINE__, "sb",
21946 "(debug) socket is already used, won't spawn:",
21947 proc->connection_name);
21952 proc->state = PROC_STATE_RUNNING;
21953 host->active_procs++;
21962 @@ -1111,93 +1109,93 @@
21965 buffer *fcgi_mode = buffer_init();
21967 - config_values_t cv[] = {
21969 + config_values_t cv[] = {
21970 { "fastcgi.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
21971 { "fastcgi.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
21972 { "fastcgi.map-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
21973 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
21977 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
21980 for (i = 0; i < srv->config_context->used; i++) {
21985 s = malloc(sizeof(plugin_config));
21986 s->exts = fastcgi_extensions_init();
21988 s->ext_mapping = array_init();
21991 cv[0].destination = s->exts;
21992 cv[1].destination = &(s->debug);
21993 cv[2].destination = s->ext_mapping;
21996 p->config_storage[i] = s;
21997 ca = ((data_config *)srv->config_context->data[i])->value;
22000 if (0 != config_insert_values_global(srv, ca, cv)) {
22001 return HANDLER_ERROR;
22011 if (NULL != (du = array_get_element(ca, "fastcgi.server"))) {
22013 data_array *da = (data_array *)du;
22016 if (du->type != TYPE_ARRAY) {
22017 - log_error_write(srv, __FILE__, __LINE__, "sss",
22018 + log_error_write(srv, __FILE__, __LINE__, "sss",
22019 "unexpected type for key: ", "fastcgi.server", "array of strings");
22022 return HANDLER_ERROR;
22027 - * fastcgi.server = ( "<ext>" => ( ... ),
22031 + * fastcgi.server = ( "<ext>" => ( ... ),
22032 * "<ext>" => ( ... ) )
22036 for (j = 0; j < da->value->used; j++) {
22038 data_array *da_ext = (data_array *)da->value->data[j];
22041 if (da->value->data[j]->type != TYPE_ARRAY) {
22042 - log_error_write(srv, __FILE__, __LINE__, "sssbs",
22043 - "unexpected type for key: ", "fastcgi.server",
22044 + log_error_write(srv, __FILE__, __LINE__, "sssbs",
22045 + "unexpected type for key: ", "fastcgi.server",
22046 "[", da->value->data[j]->key, "](string)");
22049 return HANDLER_ERROR;
22053 - * da_ext->key == name of the extension
22056 + * da_ext->key == name of the extension
22060 - * fastcgi.server = ( "<ext>" =>
22061 - * ( "<host>" => ( ... ),
22064 + * fastcgi.server = ( "<ext>" =>
22065 + * ( "<host>" => ( ... ),
22066 * "<host>" => ( ... )
22073 for (n = 0; n < da_ext->value->used; n++) {
22074 data_array *da_host = (data_array *)da_ext->value->data[n];
22077 fcgi_extension_host *host;
22079 - config_values_t fcv[] = {
22081 + config_values_t fcv[] = {
22082 { "host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
22083 { "docroot", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
22084 { "mode", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
22085 { "socket", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
22086 { "bin-path", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
22089 { "check-local", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
22090 { "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
22091 { "min-procs-not-working", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 this is broken for now */
22092 @@ -1205,28 +1203,28 @@
22093 { "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
22094 { "idle-timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
22095 { "disable-time", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
22098 { "bin-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
22099 { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
22102 { "broken-scriptfilename", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 14 */
22103 { "allow-x-send-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 15 */
22104 { "strip-request-uri", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 16 */
22107 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
22111 if (da_host->type != TYPE_ARRAY) {
22112 - log_error_write(srv, __FILE__, __LINE__, "ssSBS",
22113 - "unexpected type for key:",
22114 - "fastcgi.server",
22115 + log_error_write(srv, __FILE__, __LINE__, "ssSBS",
22116 + "unexpected type for key:",
22117 + "fastcgi.server",
22118 "[", da_host->key, "](string)");
22121 return HANDLER_ERROR;
22125 host = fastcgi_host_init();
22128 buffer_copy_string_buffer(host->id, da_host->key);
22130 host->check_local = 1;
22131 @@ -1238,13 +1236,13 @@
22132 host->disable_time = 60;
22133 host->break_scriptfilename_for_php = 0;
22134 host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */
22137 fcv[0].destination = host->host;
22138 fcv[1].destination = host->docroot;
22139 fcv[2].destination = fcgi_mode;
22140 fcv[3].destination = host->unixsocket;
22141 fcv[4].destination = host->bin_path;
22144 fcv[5].destination = &(host->check_local);
22145 fcv[6].destination = &(host->port);
22146 fcv[7].destination = &(host->min_procs);
22147 @@ -1252,35 +1250,35 @@
22148 fcv[9].destination = &(host->max_load_per_proc);
22149 fcv[10].destination = &(host->idle_timeout);
22150 fcv[11].destination = &(host->disable_time);
22153 fcv[12].destination = host->bin_env;
22154 fcv[13].destination = host->bin_env_copy;
22155 fcv[14].destination = &(host->break_scriptfilename_for_php);
22156 fcv[15].destination = &(host->allow_xsendfile);
22157 fcv[16].destination = host->strip_request_uri;
22160 if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
22161 return HANDLER_ERROR;
22164 - if ((!buffer_is_empty(host->host) || host->port) &&
22166 + if ((!buffer_is_empty(host->host) || host->port) &&
22167 !buffer_is_empty(host->unixsocket)) {
22168 - log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
22169 + log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
22170 "either host/port or socket have to be set in:",
22173 da_ext->key, " => (",
22174 da_host->key, " ( ...");
22176 return HANDLER_ERROR;
22180 if (!buffer_is_empty(host->unixsocket)) {
22181 /* unix domain socket */
22184 if (host->unixsocket->used > UNIX_PATH_MAX - 2) {
22185 - log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
22186 + log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
22187 "unixsocket is too long in:",
22190 da_ext->key, " => (",
22191 da_host->key, " ( ...");
22193 @@ -1288,37 +1286,37 @@
22198 - if (buffer_is_empty(host->host) &&
22200 + if (buffer_is_empty(host->host) &&
22201 buffer_is_empty(host->bin_path)) {
22202 - log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
22203 + log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
22204 "host or binpath have to be set in:",
22207 da_ext->key, " => (",
22208 da_host->key, " ( ...");
22211 return HANDLER_ERROR;
22212 } else if (host->port == 0) {
22213 - log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
22214 + log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
22215 "port has to be set in:",
22218 da_ext->key, " => (",
22219 da_host->key, " ( ...");
22221 return HANDLER_ERROR;
22225 - if (!buffer_is_empty(host->bin_path)) {
22227 + if (!buffer_is_empty(host->bin_path)) {
22228 /* a local socket + self spawning */
22231 /* HACK: just to make sure the adaptive spawing is disabled */
22232 host->min_procs = host->max_procs;
22235 if (host->min_procs > host->max_procs) host->max_procs = host->min_procs;
22236 if (host->max_load_per_proc < 1) host->max_load_per_proc = 0;
22240 log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
22241 "--- fastcgi spawning local",
22242 @@ -1328,7 +1326,7 @@
22243 "\n\tmin-procs:", host->min_procs,
22244 "\n\tmax-procs:", host->max_procs);
22248 for (pno = 0; pno < host->min_procs; pno++) {
22251 @@ -1343,7 +1341,7 @@
22252 buffer_append_string(proc->unixsocket, "-");
22253 buffer_append_long(proc->unixsocket, pno);
22258 log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
22259 "--- fastcgi spawning",
22260 @@ -1351,7 +1349,7 @@
22261 "\n\tsocket", host->unixsocket,
22262 "\n\tcurrent:", pno, "/", host->min_procs);
22266 if (fcgi_spawn_connection(srv, p, host, proc)) {
22267 log_error_write(srv, __FILE__, __LINE__, "s",
22268 "[ERROR]: spawning fcgi failed.");
22269 @@ -1359,35 +1357,35 @@
22272 fastcgi_status_init(srv, p->statuskey, host, proc);
22275 proc->next = host->first;
22276 if (host->first) host->first->prev = proc;
22279 host->first = proc;
22285 proc = fastcgi_process_init();
22286 proc->id = host->num_procs++;
22288 host->active_procs++;
22289 proc->state = PROC_STATE_RUNNING;
22292 if (buffer_is_empty(host->unixsocket)) {
22293 proc->port = host->port;
22295 buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
22299 fastcgi_status_init(srv, p->statuskey, host, proc);
22301 host->first = proc;
22304 host->min_procs = 1;
22305 host->max_procs = 1;
22309 if (!buffer_is_empty(fcgi_mode)) {
22310 if (strcmp(fcgi_mode->ptr, "responder") == 0) {
22311 host->mode = FCGI_RESPONDER;
22312 @@ -1411,16 +1409,16 @@
22318 buffer_free(fcgi_mode);
22321 return HANDLER_GO_ON;
22324 static int fcgi_set_state(server *srv, handler_ctx *hctx, fcgi_connection_state_t state) {
22325 hctx->state = state;
22326 hctx->state_timestamp = srv->cur_ts;
22332 @@ -1429,13 +1427,13 @@
22335 buffer_uint *r = &(p->fcgi_request_id);
22340 for (i = 0; i < r->used; i++) {
22341 if (r->ptr[i] > m) m = r->ptr[i];
22345 if (r->size == 0) {
22347 r->ptr = malloc(sizeof(*r->ptr) * r->size);
22348 @@ -1443,54 +1441,54 @@
22350 r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
22354 r->ptr[r->used++] = ++m;
22360 static int fcgi_requestid_del(server *srv, plugin_data *p, size_t request_id) {
22362 buffer_uint *r = &(p->fcgi_request_id);
22367 for (i = 0; i < r->used; i++) {
22368 if (r->ptr[i] == request_id) break;
22372 if (i != r->used) {
22376 if (i != r->used - 1) {
22377 r->ptr[i] = r->ptr[r->used - 1];
22385 void fcgi_connection_close(server *srv, handler_ctx *hctx) {
22390 if (NULL == hctx) return;
22393 p = hctx->plugin_data;
22394 con = hctx->remote_conn;
22397 if (con->mode != p->id) {
22403 if (hctx->fd != -1) {
22404 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
22405 fdevent_unregister(srv->ev, hctx->fd);
22411 if (hctx->request_id != 0) {
22412 fcgi_requestid_del(srv, p, hctx->request_id);
22414 @@ -1499,7 +1497,7 @@
22415 if (hctx->got_proc) {
22416 /* after the connect the process gets a load */
22417 hctx->proc->load--;
22420 status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests"));
22422 fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
22423 @@ -1509,39 +1507,39 @@
22425 if (p->conf.debug) {
22426 log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
22427 - "released proc:",
22428 - "pid:", hctx->proc->pid,
22429 - "socket:", hctx->proc->connection_name,
22430 + "released proc:",
22431 + "pid:", hctx->proc->pid,
22432 + "socket:", hctx->proc->connection_name,
22433 "load:", hctx->proc->load);
22440 handler_ctx_free(hctx);
22441 - con->plugin_ctx[p->id] = NULL;
22442 + con->plugin_ctx[p->id] = NULL;
22445 static int fcgi_reconnect(server *srv, handler_ctx *hctx) {
22446 plugin_data *p = hctx->plugin_data;
22457 * connect was ok, connection was accepted
22458 * but the php accept loop checks after the accept if it should die or not.
22460 - * if yes we can only detect it at a write()
22463 + * if yes we can only detect it at a write()
22465 * next step is resetting this attemp and setup a connection again
22468 * if we have more then 5 reconnects for the same request, die
22475 * we have a connection but the child died by some other reason
22480 if (hctx->fd != -1) {
22481 @@ -1551,59 +1549,59 @@
22487 fcgi_requestid_del(srv, p, hctx->request_id);
22490 fcgi_set_state(srv, hctx, FCGI_STATE_INIT);
22493 hctx->request_id = 0;
22494 hctx->reconnects++;
22497 if (p->conf.debug > 2) {
22499 log_error_write(srv, __FILE__, __LINE__, "sdb",
22500 - "release proc for reconnect:",
22501 + "release proc for reconnect:",
22502 hctx->proc->pid, hctx->proc->connection_name);
22504 log_error_write(srv, __FILE__, __LINE__, "sb",
22505 - "release proc for reconnect:",
22506 + "release proc for reconnect:",
22507 hctx->host->unixsocket);
22511 - if (hctx->proc && hctx->got_proc) {
22512 + if (hctx->proc && hctx->got_proc) {
22513 hctx->proc->load--;
22516 /* perhaps another host gives us more luck */
22517 hctx->host->load--;
22525 static handler_t fcgi_connection_reset(server *srv, connection *con, void *p_d) {
22526 plugin_data *p = p_d;
22529 fcgi_connection_close(srv, con->plugin_ctx[p->id]);
22532 return HANDLER_GO_ON;
22536 static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) {
22540 if (!key || !val) return -1;
22543 len = key_len + val_len;
22546 len += key_len > 127 ? 4 : 1;
22547 len += val_len > 127 ? 4 : 1;
22550 buffer_prepare_append(env, len);
22553 if (key_len > 127) {
22554 env->ptr[env->used++] = ((key_len >> 24) & 0xff) | 0x80;
22555 env->ptr[env->used++] = (key_len >> 16) & 0xff;
22556 @@ -1612,7 +1610,7 @@
22558 env->ptr[env->used++] = (key_len >> 0) & 0xff;
22562 if (val_len > 127) {
22563 env->ptr[env->used++] = ((val_len >> 24) & 0xff) | 0x80;
22564 env->ptr[env->used++] = (val_len >> 16) & 0xff;
22565 @@ -1621,12 +1619,12 @@
22567 env->ptr[env->used++] = (val_len >> 0) & 0xff;
22571 memcpy(env->ptr + env->used, key, key_len);
22572 env->used += key_len;
22573 memcpy(env->ptr + env->used, val, val_len);
22574 env->used += val_len;
22580 @@ -1639,11 +1637,11 @@
22581 header->contentLengthB1 = (contentLength >> 8) & 0xff;
22582 header->paddingLength = paddingLength;
22583 header->reserved = 0;
22594 @@ -1665,26 +1663,23 @@
22595 struct sockaddr_un fcgi_addr_un;
22600 fcgi_extension_host *host = hctx->host;
22601 fcgi_proc *proc = hctx->proc;
22602 int fcgi_fd = hctx->fd;
22605 memset(&fcgi_addr, 0, sizeof(fcgi_addr));
22608 if (!buffer_is_empty(proc->unixsocket)) {
22609 #ifdef HAVE_SYS_UN_H
22610 /* use the unix domain socket */
22611 fcgi_addr_un.sun_family = AF_UNIX;
22612 strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
22615 servlen = SUN_LEN(&fcgi_addr_un);
22617 - /* stevens says: */
22618 - servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
22621 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
22624 if (buffer_is_empty(proc->connection_name)) {
22625 /* on remote spawing we have to set the connection-name now */
22626 buffer_copy_string(proc->connection_name, "unix:");
22627 @@ -1695,16 +1690,18 @@
22630 fcgi_addr_in.sin_family = AF_INET;
22632 if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
22633 - log_error_write(srv, __FILE__, __LINE__, "sbs",
22634 - "converting IP-adress failed for", host->host,
22635 + log_error_write(srv, __FILE__, __LINE__, "sbs",
22636 + "converting IP-adress failed for", host->host,
22637 "\nBe sure to specify an IP address here");
22643 fcgi_addr_in.sin_port = htons(proc->port);
22644 servlen = sizeof(fcgi_addr_in);
22647 fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
22649 if (buffer_is_empty(proc->connection_name)) {
22650 @@ -1715,20 +1712,20 @@
22651 buffer_append_long(proc->connection_name, proc->port);
22656 if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
22657 - if (errno == EINPROGRESS ||
22658 + if (errno == EINPROGRESS ||
22659 errno == EALREADY ||
22661 if (hctx->conf.debug > 2) {
22662 - log_error_write(srv, __FILE__, __LINE__, "sb",
22663 + log_error_write(srv, __FILE__, __LINE__, "sb",
22664 "connect delayed, will continue later:", proc->connection_name);
22668 return CONNECTION_DELAYED;
22669 } else if (errno == EAGAIN) {
22670 if (hctx->conf.debug) {
22671 - log_error_write(srv, __FILE__, __LINE__, "sbsd",
22672 + log_error_write(srv, __FILE__, __LINE__, "sbsd",
22673 "This means that the you have more incoming requests than your fastcgi-backend can handle in parallel. "
22674 "Perhaps it helps to spawn more fastcgi backend or php-children, if not decrease server.max-connections."
22675 "The load for this fastcgi backend", proc->connection_name, "is", proc->load);
22676 @@ -1736,8 +1733,8 @@
22678 return CONNECTION_OVERLOADED;
22680 - log_error_write(srv, __FILE__, __LINE__, "sssb",
22681 - "connect failed:",
22682 + log_error_write(srv, __FILE__, __LINE__, "sssb",
22683 + "connect failed:",
22684 strerror(errno), "on",
22685 proc->connection_name);
22687 @@ -1747,7 +1744,7 @@
22689 hctx->reconnects = 0;
22690 if (hctx->conf.debug > 1) {
22691 - log_error_write(srv, __FILE__, __LINE__, "sd",
22692 + log_error_write(srv, __FILE__, __LINE__, "sd",
22693 "connect succeeded: ", fcgi_fd);
22696 @@ -1756,21 +1753,21 @@
22698 static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
22702 for (i = 0; i < con->request.headers->used; i++) {
22706 ds = (data_string *)con->request.headers->data[i];
22709 if (ds->value->used && ds->key->used) {
22711 buffer_reset(srv->tmp_buf);
22714 if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
22715 BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_");
22716 srv->tmp_buf->used--;
22720 buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
22721 for (j = 0; j < ds->key->used - 1; j++) {
22723 @@ -1784,20 +1781,20 @@
22724 srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
22726 srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
22729 fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
22734 for (i = 0; i < con->environment->used; i++) {
22738 ds = (data_string *)con->environment->data[i];
22741 if (ds->value->used && ds->key->used) {
22743 buffer_reset(srv->tmp_buf);
22746 buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
22747 for (j = 0; j < ds->key->used - 1; j++) {
22749 @@ -1811,11 +1808,11 @@
22750 srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
22752 srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
22755 fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
22763 @@ -1824,24 +1821,24 @@
22764 FCGI_BeginRequestRecord beginRecord;
22765 FCGI_Header header;
22772 char b2[INET6_ADDRSTRLEN + 1];
22776 plugin_data *p = hctx->plugin_data;
22777 fcgi_extension_host *host= hctx->host;
22779 connection *con = hctx->remote_conn;
22780 server_socket *srv_sock = con->srv_socket;
22783 sock_addr our_addr;
22784 socklen_t our_addr_len;
22787 /* send FCGI_BEGIN_REQUEST */
22790 fcgi_header(&(beginRecord.header), FCGI_BEGIN_REQUEST, request_id, sizeof(beginRecord.body), 0);
22791 beginRecord.body.roleB0 = host->mode;
22792 beginRecord.body.roleB1 = 0;
22793 @@ -1849,21 +1846,21 @@
22794 memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved));
22796 b = chunkqueue_get_append_buffer(hctx->wb);
22799 buffer_copy_memory(b, (const char *)&beginRecord, sizeof(beginRecord));
22802 /* send FCGI_PARAMS */
22803 buffer_prepare_copy(p->fcgi_env, 1024);
22806 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
22809 if (con->server_name->used) {
22810 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
22813 - s = inet_ntop(srv_sock->addr.plain.sa_family,
22814 - srv_sock->addr.plain.sa_family == AF_INET6 ?
22815 + s = inet_ntop(srv_sock->addr.plain.sa_family,
22816 + srv_sock->addr.plain.sa_family == AF_INET6 ?
22817 (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
22818 (const void *) &(srv_sock->addr.ipv4.sin_addr),
22820 @@ -1872,50 +1869,50 @@
22822 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
22826 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
22832 ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
22834 ntohs(srv_sock->addr.ipv4.sin_port)
22839 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
22842 /* get the server-side of the connection to the client */
22843 our_addr_len = sizeof(our_addr);
22846 if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
22847 s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
22849 s = inet_ntop_cache_get_ip(srv, &(our_addr));
22851 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
22857 ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
22859 ntohs(con->dst_addr.ipv4.sin_port)
22864 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
22867 s = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
22868 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
22871 if (!buffer_is_empty(con->authed_user)) {
22872 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"),
22873 CONST_BUF_LEN(con->authed_user));
22877 if (con->request.content_length > 0 && host->mode != FCGI_AUTHORIZER) {
22878 /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
22881 /* request.content_length < SSIZE_MAX, see request.c */
22882 ltostr(buf, con->request.content_length);
22883 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
22884 @@ -1930,12 +1927,12 @@
22887 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
22890 if (!buffer_is_empty(con->request.pathinfo)) {
22891 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
22894 /* PATH_TRANSLATED is only defined if PATH_INFO is set */
22897 if (!buffer_is_empty(host->docroot)) {
22898 buffer_copy_string_buffer(p->path, host->docroot);
22900 @@ -1957,27 +1954,27 @@
22903 if (!buffer_is_empty(host->docroot)) {
22905 - * rewrite SCRIPT_FILENAME
22908 + * rewrite SCRIPT_FILENAME
22913 buffer_copy_string_buffer(p->path, host->docroot);
22914 buffer_append_string_buffer(p->path, con->uri.path);
22917 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
22918 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot));
22920 buffer_copy_string_buffer(p->path, con->physical.path);
22922 - /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself
22925 + /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself
22927 * see src/sapi/cgi_main.c, init_request_info()
22929 if (host->break_scriptfilename_for_php) {
22930 buffer_append_string_buffer(p->path, con->request.pathinfo);
22934 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
22935 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
22937 @@ -1987,7 +1984,7 @@
22941 - * stripping /app1 or /app1/ should lead to
22942 + * stripping /app1 or /app1/ should lead to
22946 @@ -2001,7 +1998,7 @@
22947 0 == strncmp(con->request.orig_uri->ptr, host->strip_request_uri->ptr, host->strip_request_uri->used - 1)) {
22948 /* the left is the same */
22950 - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"),
22951 + fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"),
22952 con->request.orig_uri->ptr + (host->strip_request_uri->used - 2),
22953 con->request.orig_uri->used - (host->strip_request_uri->used - 2));
22955 @@ -2018,26 +2015,26 @@
22957 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
22961 s = get_http_method_name(con->request.http_method);
22962 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
22963 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */
22964 s = get_http_version_name(con->request.http_version);
22965 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
22969 if (srv_sock->is_ssl) {
22970 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
22977 fcgi_env_add_request_headers(srv, con, p);
22980 fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0);
22981 buffer_append_memory(b, (const char *)&header, sizeof(header));
22982 buffer_append_memory(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
22985 fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
22986 buffer_append_memory(b, (const char *)&header, sizeof(header));
22988 @@ -2057,7 +2054,7 @@
22990 /* we announce toWrite octects
22991 * now take all the request_content chunk that we need to fill this request
22995 b = chunkqueue_get_append_buffer(hctx->wb);
22996 fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
22997 @@ -2080,16 +2077,16 @@
22998 if (weHave > weWant - written) weHave = weWant - written;
23000 if (p->conf.debug > 10) {
23001 - fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n",
23002 - __FILE__, __LINE__,
23005 - req_c->file.length,
23006 + fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n",
23007 + __FILE__, __LINE__,
23010 + req_c->file.length,
23011 req_c->file.name->ptr);
23014 assert(weHave != 0);
23017 chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
23019 req_c->offset += weHave;
23020 @@ -2104,7 +2101,7 @@
23021 * - we reference the tempfile from the request-content-queue several times
23022 * if the req_c is larger than FCGI_MAX_LENGTH
23023 * - we can't simply cleanup the request-content-queue as soon as possible
23024 - * as it would remove the tempfiles
23025 + * as it would remove the tempfiles
23026 * - the idea is to 'steal' the tempfiles and attach the is_temp flag to the last
23027 * referencing chunk of the fastcgi-write-queue
23029 @@ -2141,7 +2138,7 @@
23030 req_c->offset += weHave;
23031 req_cq->bytes_out += weHave;
23035 hctx->wb->bytes_in += weHave;
23037 if (req_c->offset == req_c->mem->used - 1) {
23038 @@ -2155,12 +2152,12 @@
23044 b->used++; /* add virtual \0 */
23050 b = chunkqueue_get_append_buffer(hctx->wb);
23051 /* terminate STDIN */
23052 fcgi_header(&(header), FCGI_STDIN, request_id, 0, 0);
23053 @@ -2175,118 +2172,19 @@
23054 if ((i+1) % 16 == 0) {
23056 for (j = i-15; j <= i; j++) {
23057 - fprintf(stderr, "%c",
23058 + fprintf(stderr, "%c",
23059 isprint((unsigned char)hctx->write_buffer->ptr[j]) ? hctx->write_buffer->ptr[j] : '.');
23061 fprintf(stderr, "\n");
23069 -static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
23072 - handler_ctx *hctx = con->plugin_ctx[p->id];
23073 - fcgi_extension_host *host= hctx->host;
23077 - buffer_copy_string_buffer(p->parse_response, in);
23079 - /* search for \n */
23080 - for (s = p->parse_response->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) {
23081 - char *key, *value;
23085 - /* a good day. Someone has read the specs and is sending a \r\n to us */
23087 - if (ns > p->parse_response->ptr &&
23088 - *(ns-1) == '\r') {
23095 - if (NULL == (value = strchr(s, ':'))) {
23096 - /* we expect: "<key>: <value>\n" */
23100 - key_len = value - key;
23104 - while (*value == ' ' || *value == '\t') value++;
23106 - if (host->mode != FCGI_AUTHORIZER ||
23107 - !(con->http_status == 0 ||
23108 - con->http_status == 200)) {
23109 - /* authorizers shouldn't affect the response headers sent back to the client */
23111 - /* don't forward Status: */
23112 - if (0 != strncasecmp(key, "Status", key_len)) {
23113 - if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
23114 - ds = data_response_init();
23116 - buffer_copy_string_len(ds->key, key, key_len);
23117 - buffer_copy_string(ds->value, value);
23119 - array_insert_unique(con->response.headers, (data_unset *)ds);
23123 - switch(key_len) {
23125 - if (0 == strncasecmp(key, "Date", key_len)) {
23126 - con->parsed_response |= HTTP_DATE;
23130 - if (0 == strncasecmp(key, "Status", key_len)) {
23131 - con->http_status = strtol(value, NULL, 10);
23132 - con->parsed_response |= HTTP_STATUS;
23136 - if (0 == strncasecmp(key, "Location", key_len)) {
23137 - con->parsed_response |= HTTP_LOCATION;
23141 - if (0 == strncasecmp(key, "Connection", key_len)) {
23142 - con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
23143 - con->parsed_response |= HTTP_CONNECTION;
23147 - if (0 == strncasecmp(key, "Content-Length", key_len)) {
23148 - con->response.content_length = strtol(value, NULL, 10);
23149 - con->parsed_response |= HTTP_CONTENT_LENGTH;
23151 - if (con->response.content_length < 0) con->response.content_length = 0;
23159 - /* CGI/1.1 rev 03 - 7.2.1.2 */
23160 - if ((con->parsed_response & HTTP_LOCATION) &&
23161 - !(con->parsed_response & HTTP_STATUS)) {
23162 - con->http_status = 302;
23174 @@ -2327,9 +2225,9 @@
23178 - /* we have at least a header, now check how much me have to fetch */
23179 + /* we have at least a header, now check how much me have to fetch */
23180 header = (FCGI_Header *)(packet->b->ptr);
23183 packet->len = (header->contentLengthB0 | (header->contentLengthB1 << 8)) + header->paddingLength;
23184 packet->request_id = (header->requestIdB0 | (header->requestIdB1 << 8));
23185 packet->type = header->type;
23186 @@ -2348,7 +2246,7 @@
23187 size_t weHave = c->mem->used - c->offset - offset - 1;
23189 if (weHave > weWant) weHave = weWant;
23192 buffer_append_string_len(packet->b, c->mem->ptr + c->offset + offset, weHave);
23194 /* we only skipped the first 8 bytes as they are the fcgi header */
23195 @@ -2380,65 +2278,37 @@
23198 chunkqueue_remove_finished_chunks(hctx->rb);
23204 static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
23210 plugin_data *p = hctx->plugin_data;
23211 connection *con = hctx->remote_conn;
23212 - int fcgi_fd = hctx->fd;
23213 fcgi_extension_host *host= hctx->host;
23214 fcgi_proc *proc = hctx->proc;
23217 - * check how much we have to read
23219 - if (ioctl(hctx->fd, FIONREAD, &toread)) {
23220 - log_error_write(srv, __FILE__, __LINE__, "sd",
23221 - "unexpected end-of-file (perhaps the fastcgi process died):",
23226 - /* init read-buffer */
23228 - if (toread > 0) {
23231 - b = chunkqueue_get_append_buffer(hctx->rb);
23232 - buffer_prepare_copy(b, toread + 1);
23234 - /* append to read-buffer */
23235 - if (-1 == (r = read(hctx->fd, b->ptr, toread))) {
23236 - log_error_write(srv, __FILE__, __LINE__, "sds",
23237 - "unexpected end-of-file (perhaps the fastcgi process died):",
23238 - fcgi_fd, strerror(errno));
23242 - /* this should be catched by the b > 0 above */
23245 - b->used = r + 1; /* one extra for the fake \0 */
23246 - b->ptr[b->used - 1] = '\0';
23248 - log_error_write(srv, __FILE__, __LINE__, "ssdsb",
23249 + switch(srv->network_backend_read(srv, con, hctx->fd, hctx->rb)) {
23250 + case NETWORK_STATUS_WAIT_FOR_EVENT:
23251 + /* we are only triggered when there is a event */
23252 + log_error_write(srv, __FILE__, __LINE__, "ssdsb",
23253 "unexpected end-of-file (perhaps the fastcgi process died):",
23255 "socket:", proc->connection_name);
23258 + case NETWORK_STATUS_SUCCESS:
23261 + log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi-read failed");
23266 * parse the fastcgi packets and forward the content to the write-queue
23271 fastcgi_response_packet packet;
23273 @@ -2454,92 +2324,135 @@
23275 /* is the header already finished */
23276 if (0 == con->file_started) {
23281 - /* search for header terminator
23283 - * if we start with \r\n check if last packet terminated with \r\n
23284 - * if we start with \n check if last packet terminated with \n
23285 - * search for \r\n\r\n
23286 - * search for \n\n
23289 - if (hctx->response_header->used == 0) {
23290 - buffer_copy_string_buffer(hctx->response_header, packet.b);
23292 - buffer_append_string_buffer(hctx->response_header, packet.b);
23295 - if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\r\n\r\n")))) {
23296 - blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4;
23297 - hctx->response_header->used = (c - hctx->response_header->ptr) + 3;
23298 - c += 4; /* point the the start of the response */
23299 - } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) {
23300 - blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2;
23301 - hctx->response_header->used = c - hctx->response_header->ptr + 2;
23302 - c += 2; /* point the the start of the response */
23304 - /* no luck, no header found */
23305 + int have_content_length = 0;
23306 + int need_more = 0;
23309 + /* append the current packet to the chunk queue */
23310 + chunkqueue_append_buffer(hctx->http_rb, packet.b);
23311 + http_response_reset(p->resp);
23313 + switch(http_response_parse_cq(hctx->http_rb, p->resp)) {
23314 + case PARSE_ERROR:
23315 + /* parsing the response header failed */
23317 + con->http_status = 502; /* Bad Gateway */
23320 + case PARSE_NEED_MORE:
23322 + break; /* leave the loop */
23323 + case PARSE_SUCCESS:
23326 + /* should not happen */
23330 - /* parse the response header */
23331 - fcgi_response_parse(srv, con, p, hctx->response_header);
23332 + if (need_more) break;
23334 - con->file_started = 1;
23335 + chunkqueue_remove_finished_chunks(hctx->http_rb);
23337 - if (host->mode == FCGI_AUTHORIZER &&
23338 - (con->http_status == 0 ||
23339 - con->http_status == 200)) {
23340 - /* a authorizer with approved the static request, ignore the content here */
23341 - hctx->send_content_body = 0;
23344 - if (host->allow_xsendfile &&
23345 - NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-LIGHTTPD-send-file"))) {
23346 - stat_cache_entry *sce;
23348 - if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) {
23351 - http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
23352 - hctx->send_content_body = 0; /* ignore the content */
23353 - joblist_append(srv, con);
23354 + con->http_status = p->resp->status;
23356 + /* handle the header fields */
23357 + if (host->mode == FCGI_AUTHORIZER) {
23358 + /* auth mode is a bit different */
23360 + if (con->http_status == 0 ||
23361 + con->http_status == 200) {
23362 + /* a authorizer with approved the static request, ignore the content here */
23363 + hctx->send_content_body = 0;
23367 + /* copy the http-headers */
23368 + for (i = 0; i < p->resp->headers->used; i++) {
23369 + const char *ign[] = { "Status", NULL };
23373 + data_string *header = (data_string *)p->resp->headers->data[i];
23375 + /* ignore all headers in AUTHORIZER mode */
23376 + if (host->mode == FCGI_AUTHORIZER) continue;
23378 + /* some headers are ignored by default */
23379 + for (j = 0; ign[j]; j++) {
23380 + if (0 == strcasecmp(ign[j], header->key->ptr)) break;
23382 + if (ign[j]) continue;
23384 + if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
23385 + /* CGI/1.1 rev 03 - 7.2.1.2 */
23386 + con->http_status = 302;
23387 + } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
23388 + have_content_length = 1;
23389 + } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Sendfile")) ||
23390 + 0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-LIGHTTPD-send-file"))) {
23392 + stat_cache_entry *sce;
23394 - if (hctx->send_content_body && blen > 1) {
23395 - /* enable chunked-transfer-encoding */
23396 + if (host->allow_xsendfile &&
23397 + HANDLER_ERROR != stat_cache_get_entry(srv, con, header->value, &sce)) {
23398 + http_chunk_append_file(srv, con, header->value, 0, sce->st.st_size);
23399 + hctx->send_content_body = 0; /* ignore the content */
23401 + joblist_append(srv, con);
23404 + continue; /* ignore header */
23407 + if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
23408 + ds = data_response_init();
23410 + buffer_copy_string_buffer(ds->key, header->key);
23411 + buffer_copy_string_buffer(ds->value, header->value);
23413 + array_insert_unique(con->response.headers, (data_unset *)ds);
23416 + /* header is complete ... go on with the body */
23418 + con->file_started = 1;
23420 + if (hctx->send_content_body) {
23421 + chunk *c = hctx->http_rb->first;
23423 + /* if we don't have a content-length enable chunked encoding
23426 + * TODO: move this to a later stage in the filter-queue
23428 if (con->request.http_version == HTTP_VERSION_1_1 &&
23429 - !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
23430 + !have_content_length) {
23431 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
23434 - http_chunk_append_mem(srv, con, c, blen);
23435 + /* copy the rest of the data */
23436 + for (c = hctx->http_rb->first; c; c = c->next) {
23437 + if (c->mem->used > 1) {
23438 + http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
23439 + c->offset = c->mem->used - 1;
23442 + chunkqueue_remove_finished_chunks(hctx->http_rb);
23443 joblist_append(srv, con);
23445 } else if (hctx->send_content_body && packet.b->used > 1) {
23446 - if (con->request.http_version == HTTP_VERSION_1_1 &&
23447 - !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
23448 - /* enable chunked-transfer-encoding */
23449 - con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
23452 http_chunk_append_mem(srv, con, packet.b->ptr, packet.b->used);
23453 joblist_append(srv, con);
23457 - log_error_write(srv, __FILE__, __LINE__, "sb",
23458 + log_error_write(srv, __FILE__, __LINE__, "sb",
23459 "FastCGI-stderr:", packet.b);
23463 case FCGI_END_REQUEST:
23464 con->file_finished = 1;
23467 if (host->mode != FCGI_AUTHORIZER ||
23468 !(con->http_status == 0 ||
23469 con->http_status == 200)) {
23470 @@ -2547,39 +2460,39 @@
23471 http_chunk_append_mem(srv, con, NULL, 0);
23472 joblist_append(srv, con);
23479 - log_error_write(srv, __FILE__, __LINE__, "sd",
23480 + log_error_write(srv, __FILE__, __LINE__, "sd",
23481 "FastCGI: header.type not handled: ", packet.type);
23484 buffer_free(packet.b);
23491 static int fcgi_restart_dead_procs(server *srv, plugin_data *p, fcgi_extension_host *host) {
23495 for (proc = host->first; proc; proc = proc->next) {
23498 if (p->conf.debug > 2) {
23499 - log_error_write(srv, __FILE__, __LINE__, "sbdddd",
23501 + log_error_write(srv, __FILE__, __LINE__, "sbdddd",
23503 proc->connection_name,
23513 * if the remote side is overloaded, we check back after <n> seconds
23517 switch (proc->state) {
23518 case PROC_STATE_KILLED:
23519 @@ -2592,13 +2505,13 @@
23521 case PROC_STATE_OVERLOADED:
23522 if (srv->cur_ts <= proc->disabled_until) break;
23525 proc->state = PROC_STATE_RUNNING;
23526 host->active_procs++;
23528 - log_error_write(srv, __FILE__, __LINE__, "sbdb",
23529 - "fcgi-server re-enabled:",
23530 - host->host, host->port,
23532 + log_error_write(srv, __FILE__, __LINE__, "sbdb",
23533 + "fcgi-server re-enabled:",
23534 + host->host, host->port,
23537 case PROC_STATE_DIED_WAIT_FOR_PID:
23538 @@ -2606,7 +2519,7 @@
23539 if (!proc->is_local) break;
23541 /* the child should not terminate at all */
23544 switch(waitpid(proc->pid, &status, WNOHANG)) {
23546 /* child is still alive */
23547 @@ -2616,45 +2529,45 @@
23549 if (WIFEXITED(status)) {
23551 - log_error_write(srv, __FILE__, __LINE__, "sdsd",
23552 + log_error_write(srv, __FILE__, __LINE__, "sdsd",
23553 "child exited, pid:", proc->pid,
23554 "status:", WEXITSTATUS(status));
23556 } else if (WIFSIGNALED(status)) {
23557 - log_error_write(srv, __FILE__, __LINE__, "sd",
23558 - "child signaled:",
23559 + log_error_write(srv, __FILE__, __LINE__, "sd",
23560 + "child signaled:",
23563 - log_error_write(srv, __FILE__, __LINE__, "sd",
23564 - "child died somehow:",
23565 + log_error_write(srv, __FILE__, __LINE__, "sd",
23566 + "child died somehow:",
23571 proc->state = PROC_STATE_DIED;
23576 /* fall through if we have a dead proc now */
23577 if (proc->state != PROC_STATE_DIED) break;
23579 case PROC_STATE_DIED:
23580 - /* local proc get restarted by us,
23581 + /* local proc get restarted by us,
23582 * remote ones hopefully by the admin */
23585 if (proc->is_local) {
23586 /* we still have connections bound to this proc,
23587 * let them terminate first */
23588 if (proc->load != 0) break;
23591 /* restart the child */
23594 if (p->conf.debug) {
23595 log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
23596 "--- fastcgi spawning",
23597 "\n\tsocket", proc->connection_name,
23598 "\n\tcurrent:", 1, "/", host->min_procs);
23602 if (fcgi_spawn_connection(srv, p, host, proc)) {
23603 log_error_write(srv, __FILE__, __LINE__, "s",
23604 "ERROR: spawning fcgi failed.");
23605 @@ -2662,18 +2575,18 @@
23608 if (srv->cur_ts <= proc->disabled_until) break;
23611 proc->state = PROC_STATE_RUNNING;
23612 host->active_procs++;
23614 - log_error_write(srv, __FILE__, __LINE__, "sb",
23615 - "fcgi-server re-enabled:",
23617 + log_error_write(srv, __FILE__, __LINE__, "sb",
23618 + "fcgi-server re-enabled:",
23619 proc->connection_name);
23629 @@ -2682,19 +2595,19 @@
23630 fcgi_extension_host *host= hctx->host;
23631 connection *con = hctx->remote_conn;
23637 - /* sanity check */
23638 + /* sanity check */
23640 ((!host->host->used || !host->port) && !host->unixsocket->used)) {
23641 - log_error_write(srv, __FILE__, __LINE__, "sxddd",
23642 + log_error_write(srv, __FILE__, __LINE__, "sxddd",
23643 "write-req: error",
23647 host->unixsocket->used);
23650 hctx->proc->disabled_until = srv->cur_ts + 10;
23651 hctx->proc->state = PROC_STATE_DIED;
23653 @@ -2705,12 +2618,12 @@
23654 if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
23656 socklen_t socket_error_len = sizeof(socket_error);
23659 /* try to finish the connect() */
23660 if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
23661 - log_error_write(srv, __FILE__, __LINE__, "ss",
23662 + log_error_write(srv, __FILE__, __LINE__, "ss",
23663 "getsockopt failed:", strerror(errno));
23666 hctx->proc->disabled_until = srv->cur_ts + 10;
23667 hctx->proc->state = PROC_STATE_DIED;
23669 @@ -2719,12 +2632,12 @@
23670 if (socket_error != 0) {
23671 if (!hctx->proc->is_local || p->conf.debug) {
23672 /* local procs get restarted */
23675 log_error_write(srv, __FILE__, __LINE__, "sssb",
23676 - "establishing connection failed:", strerror(socket_error),
23677 + "establishing connection failed:", strerror(socket_error),
23678 "socket:", hctx->proc->connection_name);
23682 hctx->proc->disabled_until = srv->cur_ts + 5;
23684 if (hctx->proc->is_local) {
23685 @@ -2732,17 +2645,17 @@
23687 hctx->proc->state = PROC_STATE_DIED;
23691 hctx->proc->state = PROC_STATE_DIED;
23694 fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
23695 buffer_append_string(p->statuskey, ".died");
23697 status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
23700 return HANDLER_ERROR;
23702 - /* go on with preparing the request */
23703 + /* go on with preparing the request */
23704 hctx->state = FCGI_STATE_PREPARE_WRITE;
23707 @@ -2755,14 +2668,14 @@
23708 /* do we have a running process for this host (max-procs) ? */
23711 - for (proc = hctx->host->first;
23712 - proc && proc->state != PROC_STATE_RUNNING;
23713 + for (proc = hctx->host->first;
23714 + proc && proc->state != PROC_STATE_RUNNING;
23715 proc = proc->next);
23718 /* all childs are dead */
23719 if (proc == NULL) {
23720 hctx->fde_ndx = -1;
23723 return HANDLER_ERROR;
23726 @@ -2775,50 +2688,50 @@
23729 ret = host->unixsocket->used ? AF_UNIX : AF_INET;
23732 if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
23733 if (errno == EMFILE ||
23735 - log_error_write(srv, __FILE__, __LINE__, "sd",
23736 + log_error_write(srv, __FILE__, __LINE__, "sd",
23737 "wait for fd at connection:", con->fd);
23740 return HANDLER_WAIT_FOR_FD;
23743 - log_error_write(srv, __FILE__, __LINE__, "ssdd",
23745 + log_error_write(srv, __FILE__, __LINE__, "ssdd",
23746 "socket failed:", strerror(errno), srv->cur_fds, srv->max_fds);
23747 return HANDLER_ERROR;
23749 hctx->fde_ndx = -1;
23755 fdevent_register(srv->ev, hctx->fd, fcgi_handle_fdevent, hctx);
23758 if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
23759 - log_error_write(srv, __FILE__, __LINE__, "ss",
23760 + log_error_write(srv, __FILE__, __LINE__, "ss",
23761 "fcntl failed:", strerror(errno));
23764 return HANDLER_ERROR;
23768 if (hctx->proc->is_local) {
23769 hctx->pid = hctx->proc->pid;
23773 switch (fcgi_establish_connection(srv, hctx)) {
23774 case CONNECTION_DELAYED:
23775 /* connection is in progress, wait for an event and call getsockopt() below */
23778 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
23781 fcgi_set_state(srv, hctx, FCGI_STATE_CONNECT_DELAYED);
23782 return HANDLER_WAIT_FOR_EVENT;
23783 case CONNECTION_OVERLOADED:
23784 /* cool down the backend, it is overloaded
23787 - log_error_write(srv, __FILE__, __LINE__, "ssdsd",
23788 + log_error_write(srv, __FILE__, __LINE__, "ssdsd",
23789 "backend is overloaded, we disable it for a 2 seconds and send the request to another backend instead:",
23790 "reconnects:", hctx->reconnects,
23791 "load:", host->load);
23792 @@ -2831,7 +2744,7 @@
23793 buffer_append_string(p->statuskey, ".overloaded");
23795 status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
23798 return HANDLER_ERROR;
23799 case CONNECTION_DEAD:
23800 /* we got a hard error from the backend like
23801 @@ -2840,19 +2753,19 @@
23803 * for check if the host is back in 5 seconds
23807 hctx->proc->disabled_until = srv->cur_ts + 5;
23808 if (hctx->proc->is_local) {
23809 hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID;
23811 hctx->proc->state = PROC_STATE_DIED;
23814 - log_error_write(srv, __FILE__, __LINE__, "ssdsd",
23816 + log_error_write(srv, __FILE__, __LINE__, "ssdsd",
23817 "backend died, we disable it for a 5 seconds and send the request to another backend instead:",
23818 "reconnects:", hctx->reconnects,
23819 "load:", host->load);
23822 fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
23823 buffer_append_string(p->statuskey, ".died");
23825 @@ -2863,19 +2776,19 @@
23826 /* everything is ok, go on */
23828 fcgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
23832 case CONNECTION_UNSET:
23837 case FCGI_STATE_PREPARE_WRITE:
23838 /* ok, we have the connection */
23841 hctx->proc->load++;
23842 hctx->proc->last_used = srv->cur_ts;
23843 hctx->got_proc = 1;
23846 status_counter_inc(srv, CONST_STR_LEN("fastcgi.requests"));
23847 status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests"));
23849 @@ -2898,9 +2811,9 @@
23851 if (p->conf.debug) {
23852 log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
23854 - "pid:", hctx->proc->pid,
23855 - "socket:", hctx->proc->connection_name,
23857 + "pid:", hctx->proc->pid,
23858 + "socket:", hctx->proc->connection_name,
23859 "load:", hctx->proc->load);
23862 @@ -2908,62 +2821,63 @@
23863 if (hctx->request_id == 0) {
23864 hctx->request_id = fcgi_requestid_new(srv, p);
23866 - log_error_write(srv, __FILE__, __LINE__, "sd",
23867 + log_error_write(srv, __FILE__, __LINE__, "sd",
23868 "fcgi-request is already in use:", hctx->request_id);
23873 fcgi_create_env(srv, hctx, hctx->request_id);
23876 fcgi_set_state(srv, hctx, FCGI_STATE_WRITE);
23880 case FCGI_STATE_WRITE:
23881 - ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
23882 + ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
23884 chunkqueue_remove_finished_chunks(hctx->wb);
23890 - /* the connection got dropped after accept()
23892 - * this is most of the time a PHP which dies
23893 + /* the connection got dropped after accept()
23895 + * this is most of the time a PHP which dies
23896 * after PHP_FCGI_MAX_REQUESTS
23901 if (hctx->wb->bytes_out == 0 &&
23902 hctx->reconnects < 5) {
23903 - usleep(10000); /* take away the load of the webserver
23904 - * to let the php a chance to restart
23906 + usleep(10000); /* take away the load of the webserver
23907 + * to let the php a chance to restart
23911 fcgi_reconnect(srv, hctx);
23914 return HANDLER_WAIT_FOR_FD;
23918 /* not reconnected ... why
23921 * far@#lighttpd report this for FreeBSD
23926 - log_error_write(srv, __FILE__, __LINE__, "ssdsd",
23928 + log_error_write(srv, __FILE__, __LINE__, "ssosd",
23929 "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
23930 "write-offset:", hctx->wb->bytes_out,
23931 "reconnect attempts:", hctx->reconnects);
23934 return HANDLER_ERROR;
23937 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
23940 return HANDLER_WAIT_FOR_EVENT;
23942 - log_error_write(srv, __FILE__, __LINE__, "ssd",
23943 + log_error_write(srv, __FILE__, __LINE__, "ssd",
23944 "write failed:", strerror(errno), errno);
23947 return HANDLER_ERROR;
23950 @@ -2975,7 +2889,7 @@
23951 fcgi_set_state(srv, hctx, FCGI_STATE_READ);
23953 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
23956 return HANDLER_WAIT_FOR_EVENT;
23959 @@ -2987,7 +2901,7 @@
23960 log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
23961 return HANDLER_ERROR;
23965 return HANDLER_WAIT_FOR_EVENT;
23968 @@ -2996,18 +2910,18 @@
23970 SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) {
23971 plugin_data *p = p_d;
23974 handler_ctx *hctx = con->plugin_ctx[p->id];
23976 fcgi_extension_host *host;
23979 if (NULL == hctx) return HANDLER_GO_ON;
23983 if (con->mode != p->id) return HANDLER_GO_ON;
23985 /* we don't have a host yet, choose one
23986 - * -> this happens in the first round
23987 + * -> this happens in the first round
23988 * and when the host died and we have to select a new one */
23989 if (hctx->host == NULL) {
23991 @@ -3016,23 +2930,23 @@
23992 /* get best server */
23993 for (k = 0, ndx = -1; k < hctx->ext->used; k++) {
23994 host = hctx->ext->hosts[k];
23997 /* we should have at least one proc that can do something */
23998 if (host->active_procs == 0) continue;
24000 if (used == -1 || host->load < used) {
24009 /* found a server */
24011 /* all hosts are down */
24013 fcgi_connection_close(srv, hctx);
24016 con->http_status = 500;
24017 con->mode = DIRECT;
24019 @@ -3040,16 +2954,16 @@
24022 host = hctx->ext->hosts[ndx];
24025 - * if check-local is disabled, use the uri.path handler
24029 + * if check-local is disabled, use the uri.path handler
24034 /* init handler-context */
24037 - /* we put a connection on this host, move the other new connections to other hosts
24038 + /* we put a connection on this host, move the other new connections to other hosts
24040 * as soon as hctx->host is unassigned, decrease the load again */
24041 hctx->host->load++;
24042 @@ -3063,7 +2977,7 @@
24043 case HANDLER_ERROR:
24048 if (hctx->state == FCGI_STATE_INIT ||
24049 hctx->state == FCGI_STATE_CONNECT_DELAYED) {
24050 if (proc) host->active_procs--;
24051 @@ -3078,7 +2992,7 @@
24052 return HANDLER_WAIT_FOR_FD;
24054 fcgi_connection_close(srv, hctx);
24057 buffer_reset(con->physical.path);
24058 con->mode = DIRECT;
24059 con->http_status = 500;
24060 @@ -3088,12 +3002,12 @@
24063 fcgi_connection_close(srv, hctx);
24066 buffer_reset(con->physical.path);
24067 con->mode = DIRECT;
24068 con->http_status = 503;
24069 joblist_append(srv, con); /* really ? */
24072 return HANDLER_FINISHED;
24074 case HANDLER_WAIT_FOR_EVENT:
24075 @@ -3115,7 +3029,7 @@
24076 handler_ctx *hctx = ctx;
24077 connection *con = hctx->remote_conn;
24078 plugin_data *p = hctx->plugin_data;
24081 fcgi_proc *proc = hctx->proc;
24082 fcgi_extension_host *host= hctx->host;
24084 @@ -3125,8 +3039,8 @@
24089 - if (host->mode == FCGI_AUTHORIZER &&
24091 + if (host->mode == FCGI_AUTHORIZER &&
24092 (con->http_status == 200 ||
24093 con->http_status == 0)) {
24095 @@ -3136,26 +3050,26 @@
24098 buffer_copy_string_buffer(con->physical.doc_root, host->docroot);
24101 buffer_copy_string_buffer(con->physical.path, host->docroot);
24102 buffer_append_string_buffer(con->physical.path, con->uri.path);
24103 fcgi_connection_close(srv, hctx);
24106 con->mode = DIRECT;
24107 con->file_started = 1; /* fcgi_extension won't touch the request afterwards */
24110 fcgi_connection_close(srv, hctx);
24114 joblist_append(srv, con);
24115 return HANDLER_FINISHED;
24117 if (proc->pid && proc->state != PROC_STATE_DIED) {
24121 /* only fetch the zombie if it is not already done */
24124 switch(waitpid(proc->pid, &status, WNOHANG)) {
24126 /* child is still alive */
24127 @@ -3165,60 +3079,61 @@
24129 /* the child should not terminate at all */
24130 if (WIFEXITED(status)) {
24131 - log_error_write(srv, __FILE__, __LINE__, "sdsd",
24132 + log_error_write(srv, __FILE__, __LINE__, "sdsd",
24133 "child exited, pid:", proc->pid,
24134 "status:", WEXITSTATUS(status));
24135 } else if (WIFSIGNALED(status)) {
24136 - log_error_write(srv, __FILE__, __LINE__, "sd",
24137 - "child signaled:",
24138 + log_error_write(srv, __FILE__, __LINE__, "sd",
24139 + "child signaled:",
24142 - log_error_write(srv, __FILE__, __LINE__, "sd",
24143 - "child died somehow:",
24144 + log_error_write(srv, __FILE__, __LINE__, "sd",
24145 + "child died somehow:",
24150 if (p->conf.debug) {
24151 log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
24152 "--- fastcgi spawning",
24153 "\n\tsocket", proc->connection_name,
24154 "\n\tcurrent:", 1, "/", host->min_procs);
24158 if (fcgi_spawn_connection(srv, p, host, proc)) {
24159 /* respawning failed, retry later */
24160 proc->state = PROC_STATE_DIED;
24162 - log_error_write(srv, __FILE__, __LINE__, "s",
24163 + log_error_write(srv, __FILE__, __LINE__, "s",
24164 "respawning failed, will retry later");
24173 if (con->file_started == 0) {
24174 /* nothing has been send out yet, try to use another child */
24177 if (hctx->wb->bytes_out == 0 &&
24178 hctx->reconnects < 5) {
24179 fcgi_reconnect(srv, hctx);
24181 - log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
24183 + log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
24184 "response not received, request not sent",
24185 - "on socket:", proc->connection_name,
24186 + "on socket:", proc->connection_name,
24187 "for", con->uri.path, ", reconnecting");
24190 return HANDLER_WAIT_FOR_FD;
24193 - log_error_write(srv, __FILE__, __LINE__, "sosbsbs",
24195 + log_error_write(srv, __FILE__, __LINE__, "sosbsbs",
24196 "response not received, request sent:", hctx->wb->bytes_out,
24197 - "on socket:", proc->connection_name,
24198 + "on socket:", proc->connection_name,
24199 "for", con->uri.path, ", closing connection");
24202 fcgi_connection_close(srv, hctx);
24205 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
24206 buffer_reset(con->physical.path);
24207 con->http_status = 500;
24208 @@ -3226,76 +3141,76 @@
24210 /* response might have been already started, kill the connection */
24211 fcgi_connection_close(srv, hctx);
24213 - log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
24215 + log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
24216 "response already sent out, but backend returned error",
24217 - "on socket:", proc->connection_name,
24218 + "on socket:", proc->connection_name,
24219 "for", con->uri.path, ", terminating connection");
24222 connection_set_state(srv, con, CON_STATE_ERROR);
24230 joblist_append(srv, con);
24231 return HANDLER_FINISHED;
24236 if (revents & FDEVENT_OUT) {
24237 if (hctx->state == FCGI_STATE_CONNECT_DELAYED ||
24238 hctx->state == FCGI_STATE_WRITE) {
24239 /* we are allowed to send something out
24242 * 1. in a unfinished connect() call
24243 * 2. in a unfinished write() call (long POST request)
24245 return mod_fastcgi_handle_subrequest(srv, con, p);
24247 - log_error_write(srv, __FILE__, __LINE__, "sd",
24248 - "got a FDEVENT_OUT and didn't know why:",
24249 + log_error_write(srv, __FILE__, __LINE__, "sd",
24250 + "got a FDEVENT_OUT and didn't know why:",
24256 /* perhaps this issue is already handled */
24257 if (revents & FDEVENT_HUP) {
24258 if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
24259 /* getoptsock will catch this one (right ?)
24261 - * if we are in connect we might get a EINPROGRESS
24262 - * in the first call and a FDEVENT_HUP in the
24264 + * if we are in connect we might get a EINPROGRESS
24265 + * in the first call and a FDEVENT_HUP in the
24269 * FIXME: as it is a bit ugly.
24273 return mod_fastcgi_handle_subrequest(srv, con, p);
24274 } else if (hctx->state == FCGI_STATE_READ &&
24275 hctx->proc->port == 0) {
24279 * ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket
24280 * even if the FCGI_FIN packet is not received yet
24283 - log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
24284 - "error: unexpected close of fastcgi connection for",
24285 + log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
24286 + "error: unexpected close of fastcgi connection for",
24288 - "(no fastcgi process on host:",
24289 + "(no fastcgi process on host:",
24298 connection_set_state(srv, con, CON_STATE_ERROR);
24299 fcgi_connection_close(srv, hctx);
24300 joblist_append(srv, con);
24302 } else if (revents & FDEVENT_ERR) {
24303 - log_error_write(srv, __FILE__, __LINE__, "s",
24304 + log_error_write(srv, __FILE__, __LINE__, "s",
24305 "fcgi: got a FDEVENT_ERR. Don't know why.");
24306 /* kill all connections to the fastcgi process */
24308 @@ -3304,45 +3219,42 @@
24309 fcgi_connection_close(srv, hctx);
24310 joblist_append(srv, con);
24314 return HANDLER_FINISHED;
24316 -#define PATCH(x) \
24317 - p->conf.x = s->x;
24319 static int fcgi_patch_connection(server *srv, connection *con, plugin_data *p) {
24321 plugin_config *s = p->config_storage[0];
24325 - PATCH(ext_mapping);
24328 + PATCH_OPTION(exts);
24329 + PATCH_OPTION(debug);
24330 + PATCH_OPTION(ext_mapping);
24332 /* skip the first, the global context */
24333 for (i = 1; i < srv->config_context->used; i++) {
24334 data_config *dc = (data_config *)srv->config_context->data[i];
24335 s = p->config_storage[i];
24338 /* condition didn't match */
24339 if (!config_check_cond(srv, con, dc)) continue;
24343 for (j = 0; j < dc->value->used; j++) {
24344 data_unset *du = dc->value->data[j];
24347 if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.server"))) {
24349 + PATCH_OPTION(exts);
24350 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.debug"))) {
24352 + PATCH_OPTION(debug);
24353 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.map-extensions"))) {
24354 - PATCH(ext_mapping);
24355 + PATCH_OPTION(ext_mapping);
24366 static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
24367 plugin_data *p = p_d;
24368 @@ -3351,16 +3263,16 @@
24370 fcgi_extension *extension = NULL;
24371 fcgi_extension_host *host = NULL;
24374 /* Possibly, we processed already this request */
24375 if (con->file_started == 1) return HANDLER_GO_ON;
24377 fn = uri_path_handler ? con->uri.path : con->physical.path;
24379 if (buffer_is_empty(fn)) return HANDLER_GO_ON;
24382 s_len = fn->used - 1;
24385 fcgi_patch_connection(srv, con, p);
24387 /* fastcgi.map-extensions maps extensions to existing fastcgi.server entries
24388 @@ -3368,24 +3280,24 @@
24389 * fastcgi.map-extensions = ( ".php3" => ".php" )
24391 * fastcgi.server = ( ".php" => ... )
24396 /* check if extension-mapping matches */
24397 for (k = 0; k < p->conf.ext_mapping->used; k++) {
24398 data_string *ds = (data_string *)p->conf.ext_mapping->data[k];
24399 size_t ct_len; /* length of the config entry */
24402 if (ds->key->used == 0) continue;
24405 ct_len = ds->key->used - 1;
24408 if (s_len < ct_len) continue;
24411 /* found a mapping */
24412 if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) {
24413 /* check if we know the extension */
24416 /* we can reuse k here */
24417 for (k = 0; k < p->conf.exts->used; k++) {
24418 extension = p->conf.exts->exts[k];
24419 @@ -3407,15 +3319,15 @@
24420 /* check if extension matches */
24421 for (k = 0; k < p->conf.exts->used; k++) {
24422 size_t ct_len; /* length of the config entry */
24425 extension = p->conf.exts->exts[k];
24428 if (extension->key->used == 0) continue;
24431 ct_len = extension->key->used - 1;
24434 if (s_len < ct_len) continue;
24437 /* check extension in the form "/fcgi_pattern" */
24438 if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
24440 @@ -3441,10 +3353,10 @@
24444 - /* we found one host that is alive */
24445 + /* we found one host that is alive */
24451 /* sorry, we don't have a server alive for this ext */
24452 buffer_reset(con->physical.path);
24453 @@ -3459,72 +3371,72 @@
24454 "on", extension->key,
24459 return HANDLER_FINISHED;
24462 /* a note about no handler is not sent yey */
24463 extension->note_is_sent = 0;
24466 - * if check-local is disabled, use the uri.path handler
24469 + * if check-local is disabled, use the uri.path handler
24474 /* init handler-context */
24475 if (uri_path_handler) {
24476 if (host->check_local == 0) {
24481 hctx = handler_ctx_init();
24484 hctx->remote_conn = con;
24485 hctx->plugin_data = p;
24487 hctx->ext = extension;
24491 hctx->conf.exts = p->conf.exts;
24492 hctx->conf.debug = p->conf.debug;
24495 con->plugin_ctx[p->id] = hctx;
24501 if (con->conf.log_request_handling) {
24502 - log_error_write(srv, __FILE__, __LINE__, "s",
24503 + log_error_write(srv, __FILE__, __LINE__, "s",
24504 "handling it in mod_fastcgi");
24507 - /* the prefix is the SCRIPT_NAME,
24509 + /* the prefix is the SCRIPT_NAME,
24510 * everthing from start to the next slash
24511 * this is important for check-local = "disable"
24514 * if prefix = /admin.fcgi
24517 * /admin.fcgi/foo/bar
24520 * SCRIPT_NAME = /admin.fcgi
24521 * PATH_INFO = /foo/bar
24524 * if prefix = /fcgi-bin/
24527 * /fcgi-bin/foo/bar
24530 * SCRIPT_NAME = /fcgi-bin/foo
24537 /* the rewrite is only done for /prefix/? matches */
24538 if (extension->key->ptr[0] == '/' &&
24539 con->uri.path->used > extension->key->used &&
24540 NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
24541 - /* rewrite uri.path and pathinfo */
24543 + /* rewrite uri.path and pathinfo */
24545 buffer_copy_string(con->request.pathinfo, pathinfo);
24548 con->uri.path->used -= con->request.pathinfo->used - 1;
24549 con->uri.path->ptr[con->uri.path->used - 1] = '\0';
24551 @@ -3532,19 +3444,19 @@
24554 hctx = handler_ctx_init();
24557 hctx->remote_conn = con;
24558 hctx->plugin_data = p;
24560 hctx->ext = extension;
24563 hctx->conf.exts = p->conf.exts;
24564 hctx->conf.debug = p->conf.debug;
24567 con->plugin_ctx[p->id] = hctx;
24573 if (con->conf.log_request_handling) {
24574 log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi");
24576 @@ -3566,19 +3478,19 @@
24577 JOBLIST_FUNC(mod_fastcgi_handle_joblist) {
24578 plugin_data *p = p_d;
24579 handler_ctx *hctx = con->plugin_ctx[p->id];
24582 if (hctx == NULL) return HANDLER_GO_ON;
24584 if (hctx->fd != -1) {
24585 switch (hctx->state) {
24586 case FCGI_STATE_READ:
24587 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
24591 case FCGI_STATE_CONNECT_DELAYED:
24592 case FCGI_STATE_WRITE:
24593 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
24597 case FCGI_STATE_INIT:
24599 @@ -3595,7 +3507,7 @@
24601 static handler_t fcgi_connection_close_callback(server *srv, connection *con, void *p_d) {
24602 plugin_data *p = p_d;
24605 fcgi_connection_close(srv, con->plugin_ctx[p->id]);
24607 return HANDLER_GO_ON;
24608 @@ -3604,16 +3516,39 @@
24609 TRIGGER_FUNC(mod_fastcgi_handle_trigger) {
24610 plugin_data *p = p_d;
24616 /* perhaps we should kill a connect attempt after 10-15 seconds
24619 * currently we wait for the TCP timeout which is on Linux 180 seconds
24626 + for (i = 0; i < srv->conns->used; i++) {
24627 + connection *con = srv->conns->ptr[i];
24628 + handler_ctx *hctx = con->plugin_ctx[p->id];
24630 + /* if a connection is ours and is in handle-req for more than max-request-time
24631 + * kill the connection */
24633 + if (con->mode != p->id) continue;
24634 + if (con->state != CON_STATE_HANDLE_REQUEST) continue;
24635 + if (srv->cur_ts < con->request_start + 60) continue;
24637 + /* the request is waiting for a FCGI_STDOUT since 60 seconds */
24639 + /* kill the connection */
24641 + log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi backend didn't responded after 60 seconds");
24643 + fcgi_connection_close(srv, hctx);
24645 + con->mode = DIRECT;
24646 + con->http_status = 500;
24648 + joblist_append(srv, con);
24651 /* check all childs if they are still up */
24653 for (i = 0; i < srv->config_context->used; i++) {
24654 @@ -3628,45 +3563,45 @@
24655 fcgi_extension *ex;
24657 ex = exts->exts[j];
24660 for (n = 0; n < ex->used; n++) {
24664 unsigned long sum_load = 0;
24665 fcgi_extension_host *host;
24668 host = ex->hosts[n];
24671 fcgi_restart_dead_procs(srv, p, host);
24674 for (proc = host->first; proc; proc = proc->next) {
24675 sum_load += proc->load;
24679 if (host->num_procs &&
24680 host->num_procs < host->max_procs &&
24681 (sum_load / host->num_procs) > host->max_load_per_proc) {
24682 /* overload, spawn new child */
24683 if (p->conf.debug) {
24684 - log_error_write(srv, __FILE__, __LINE__, "s",
24685 + log_error_write(srv, __FILE__, __LINE__, "s",
24686 "overload detected, spawning a new child");
24690 for (proc = host->unused_procs; proc && proc->pid != 0; proc = proc->next);
24694 if (proc == host->unused_procs) host->unused_procs = proc->next;
24697 if (proc->next) proc->next->prev = NULL;
24702 proc = fastcgi_process_init();
24703 proc->id = host->max_id++;
24710 if (buffer_is_empty(host->unixsocket)) {
24711 proc->port = host->port + proc->id;
24713 @@ -3674,13 +3609,13 @@
24714 buffer_append_string(proc->unixsocket, "-");
24715 buffer_append_long(proc->unixsocket, proc->id);
24719 if (fcgi_spawn_connection(srv, p, host, proc)) {
24720 log_error_write(srv, __FILE__, __LINE__, "s",
24721 "ERROR: spawning fcgi failed.");
24722 return HANDLER_ERROR;
24727 proc->next = host->first;
24729 @@ -3688,56 +3623,56 @@
24731 host->first = proc;
24735 for (proc = host->first; proc; proc = proc->next) {
24736 if (proc->load != 0) break;
24737 if (host->num_procs <= host->min_procs) break;
24738 if (proc->pid == 0) continue;
24741 if (srv->cur_ts - proc->last_used > host->idle_timeout) {
24742 /* a proc is idling for a long time now,
24746 if (p->conf.debug) {
24747 - log_error_write(srv, __FILE__, __LINE__, "ssbsd",
24748 - "idle-timeout reached, terminating child:",
24749 - "socket:", proc->connection_name,
24750 + log_error_write(srv, __FILE__, __LINE__, "ssbsd",
24751 + "idle-timeout reached, terminating child:",
24752 + "socket:", proc->connection_name,
24759 if (proc->next) proc->next->prev = proc->prev;
24760 if (proc->prev) proc->prev->next = proc->next;
24763 if (proc->prev == NULL) host->first = proc->next;
24767 proc->next = host->unused_procs;
24770 if (host->unused_procs) host->unused_procs->prev = proc;
24771 host->unused_procs = proc;
24774 kill(proc->pid, SIGTERM);
24777 proc->state = PROC_STATE_KILLED;
24779 - log_error_write(srv, __FILE__, __LINE__, "ssbsd",
24781 - "socket:", proc->connection_name,
24783 + log_error_write(srv, __FILE__, __LINE__, "ssbsd",
24785 + "socket:", proc->connection_name,
24792 /* proc is now in unused, let the next second handle the next process */
24799 for (proc = host->unused_procs; proc; proc = proc->next) {
24803 if (proc->pid == 0) continue;
24806 switch (waitpid(proc->pid, &status, WNOHANG)) {
24808 /* child still running after timeout, good */
24809 @@ -3745,10 +3680,10 @@
24811 if (errno != EINTR) {
24812 /* no PID found ? should never happen */
24813 - log_error_write(srv, __FILE__, __LINE__, "sddss",
24814 + log_error_write(srv, __FILE__, __LINE__, "sddss",
24815 "pid ", proc->pid, proc->state,
24816 "not found:", strerror(errno));
24820 if (errno == ECHILD) {
24821 /* someone else has cleaned up for us */
24822 @@ -3762,25 +3697,26 @@
24823 /* the child should not terminate at all */
24824 if (WIFEXITED(status)) {
24825 if (proc->state != PROC_STATE_KILLED) {
24826 - log_error_write(srv, __FILE__, __LINE__, "sdb",
24828 + log_error_write(srv, __FILE__, __LINE__, "sdb",
24830 WEXITSTATUS(status), proc->connection_name);
24832 } else if (WIFSIGNALED(status)) {
24833 if (WTERMSIG(status) != SIGTERM) {
24834 - log_error_write(srv, __FILE__, __LINE__, "sd",
24835 - "child signaled:",
24836 + log_error_write(srv, __FILE__, __LINE__, "sd",
24837 + "child signaled:",
24841 - log_error_write(srv, __FILE__, __LINE__, "sd",
24842 - "child died somehow:",
24843 + log_error_write(srv, __FILE__, __LINE__, "sd",
24844 + "child died somehow:",
24848 proc->state = PROC_STATE_UNSET;
24855 @@ -3804,8 +3740,8 @@
24856 p->handle_subrequest = mod_fastcgi_handle_subrequest;
24857 p->handle_joblist = mod_fastcgi_handle_joblist;
24858 p->handle_trigger = mod_fastcgi_handle_trigger;
24866 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_flv_streaming.c lighttpd-1.4.12/src/mod_flv_streaming.c
24867 --- lighttpd-1.4.11/src/mod_flv_streaming.c 2006-03-07 14:06:26.000000000 +0200
24868 +++ lighttpd-1.4.12/src/mod_flv_streaming.c 2006-07-11 21:23:40.000000000 +0300
24869 @@ -23,35 +23,35 @@
24879 plugin_config **config_storage;
24881 - plugin_config conf;
24883 + plugin_config conf;
24886 /* init the plugin data */
24887 INIT_FUNC(mod_flv_streaming_init) {
24891 p = calloc(1, sizeof(*p));
24894 p->query_str = buffer_init();
24895 p->get_params = array_init();
24901 /* detroy the plugin data */
24902 FREE_FUNC(mod_flv_streaming_free) {
24903 plugin_data *p = p_d;
24908 if (!p) return HANDLER_GO_ON;
24911 if (p->config_storage) {
24914 @@ -59,19 +59,19 @@
24915 plugin_config *s = p->config_storage[i];
24920 array_free(s->extensions);
24925 free(p->config_storage);
24929 buffer_free(p->query_str);
24930 array_free(p->get_params);
24936 return HANDLER_GO_ON;
24939 @@ -80,83 +80,80 @@
24940 SETDEFAULTS_FUNC(mod_flv_streaming_set_defaults) {
24941 plugin_data *p = p_d;
24944 - config_values_t cv[] = {
24946 + config_values_t cv[] = {
24947 { "flv-streaming.extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
24948 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
24952 if (!p) return HANDLER_ERROR;
24955 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
24958 for (i = 0; i < srv->config_context->used; i++) {
24962 s = calloc(1, sizeof(plugin_config));
24963 s->extensions = array_init();
24966 cv[0].destination = s->extensions;
24969 p->config_storage[i] = s;
24972 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
24973 return HANDLER_ERROR;
24978 return HANDLER_GO_ON;
24981 -#define PATCH(x) \
24982 - p->conf.x = s->x;
24983 static int mod_flv_streaming_patch_connection(server *srv, connection *con, plugin_data *p) {
24985 plugin_config *s = p->config_storage[0];
24987 - PATCH(extensions);
24990 + PATCH_OPTION(extensions);
24992 /* skip the first, the global context */
24993 for (i = 1; i < srv->config_context->used; i++) {
24994 data_config *dc = (data_config *)srv->config_context->data[i];
24995 s = p->config_storage[i];
24998 /* condition didn't match */
24999 if (!config_check_cond(srv, con, dc)) continue;
25003 for (j = 0; j < dc->value->used; j++) {
25004 data_unset *du = dc->value->data[j];
25007 if (buffer_is_equal_string(du->key, CONST_STR_LEN("flv-streaming.extensions"))) {
25008 - PATCH(extensions);
25009 + PATCH_OPTION(extensions);
25019 -static int split_get_params(server *srv, connection *con, array *get_params, buffer *qrystr) {
25020 +static int split_get_params(array *get_params, buffer *qrystr) {
25023 char *key = NULL, *val = NULL;
25029 /* we need the \0 */
25030 for (i = 0; i < qrystr->used; i++) {
25031 switch(qrystr->ptr[i]) {
25034 val = qrystr->ptr + i + 1;
25037 qrystr->ptr[i] = '\0';
25046 case '\0': /* fin symbol */
25047 @@ -167,7 +164,7 @@
25048 /* terminate the value */
25049 qrystr->ptr[i] = '\0';
25051 - if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
25052 + if (NULL == (ds = (data_string *)array_get_unused_element(get_params, TYPE_STRING))) {
25053 ds = data_string_init();
25055 buffer_copy_string_len(ds->key, key, strlen(key));
25056 @@ -175,14 +172,14 @@
25058 array_insert_unique(get_params, (data_unset *)ds);
25062 key = qrystr->ptr + i + 1;
25073 @@ -190,34 +187,34 @@
25074 plugin_data *p = p_d;
25081 if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
25084 mod_flv_streaming_patch_connection(srv, con, p);
25086 s_len = con->physical.path->used - 1;
25089 for (k = 0; k < p->conf.extensions->used; k++) {
25090 data_string *ds = (data_string *)p->conf.extensions->data[k];
25091 int ct_len = ds->value->used - 1;
25094 if (ct_len > s_len) continue;
25095 if (ds->value->used == 0) continue;
25098 if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
25099 data_string *get_param;
25100 stat_cache_entry *sce = NULL;
25104 - /* if there is a start=[0-9]+ in the header use it as start,
25105 + /* if there is a start=[0-9]+ in the header use it as start,
25106 * otherwise send the full file */
25108 array_reset(p->get_params);
25109 buffer_copy_string_buffer(p->query_str, con->uri.query);
25110 - split_get_params(srv, con, p->get_params, p->query_str);
25111 + split_get_params(p->get_params, p->query_str);
25113 if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {
25114 return HANDLER_GO_ON;
25115 @@ -256,7 +253,7 @@
25116 return HANDLER_FINISHED;
25122 return HANDLER_GO_ON;
25124 @@ -266,13 +263,13 @@
25125 int mod_flv_streaming_plugin_init(plugin *p) {
25126 p->version = LIGHTTPD_VERSION_ID;
25127 p->name = buffer_init_string("flv_streaming");
25130 p->init = mod_flv_streaming_init;
25131 p->handle_physical = mod_flv_streaming_path_handler;
25132 p->set_defaults = mod_flv_streaming_set_defaults;
25133 p->cleanup = mod_flv_streaming_free;
25141 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_indexfile.c lighttpd-1.4.12/src/mod_indexfile.c
25142 --- lighttpd-1.4.11/src/mod_indexfile.c 2005-09-30 01:08:53.000000000 +0300
25143 +++ lighttpd-1.4.12/src/mod_indexfile.c 2006-07-11 21:23:40.000000000 +0300
25144 @@ -20,51 +20,51 @@
25153 plugin_config **config_storage;
25155 - plugin_config conf;
25157 + plugin_config conf;
25160 /* init the plugin data */
25161 INIT_FUNC(mod_indexfile_init) {
25165 p = calloc(1, sizeof(*p));
25168 p->tmp_buf = buffer_init();
25174 /* detroy the plugin data */
25175 FREE_FUNC(mod_indexfile_free) {
25176 plugin_data *p = p_d;
25181 if (!p) return HANDLER_GO_ON;
25184 if (p->config_storage) {
25186 for (i = 0; i < srv->config_context->used; i++) {
25187 plugin_config *s = p->config_storage[i];
25192 array_free(s->indexfiles);
25197 free(p->config_storage);
25201 buffer_free(p->tmp_buf);
25207 return HANDLER_GO_ON;
25210 @@ -73,131 +73,128 @@
25211 SETDEFAULTS_FUNC(mod_indexfile_set_defaults) {
25212 plugin_data *p = p_d;
25215 - config_values_t cv[] = {
25217 + config_values_t cv[] = {
25218 { "index-file.names", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
25219 { "server.indexfiles", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
25220 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
25224 if (!p) return HANDLER_ERROR;
25227 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
25230 for (i = 0; i < srv->config_context->used; i++) {
25234 s = calloc(1, sizeof(plugin_config));
25235 s->indexfiles = array_init();
25238 cv[0].destination = s->indexfiles;
25239 cv[1].destination = s->indexfiles; /* old name for [0] */
25242 p->config_storage[i] = s;
25245 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
25246 return HANDLER_ERROR;
25251 return HANDLER_GO_ON;
25254 -#define PATCH(x) \
25255 - p->conf.x = s->x;
25256 static int mod_indexfile_patch_connection(server *srv, connection *con, plugin_data *p) {
25258 plugin_config *s = p->config_storage[0];
25260 - PATCH(indexfiles);
25263 + PATCH_OPTION(indexfiles);
25265 /* skip the first, the global context */
25266 for (i = 1; i < srv->config_context->used; i++) {
25267 data_config *dc = (data_config *)srv->config_context->data[i];
25268 s = p->config_storage[i];
25271 /* condition didn't match */
25272 if (!config_check_cond(srv, con, dc)) continue;
25276 for (j = 0; j < dc->value->used; j++) {
25277 data_unset *du = dc->value->data[j];
25280 if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.indexfiles"))) {
25281 - PATCH(indexfiles);
25282 + PATCH_OPTION(indexfiles);
25283 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("index-file.names"))) {
25284 - PATCH(indexfiles);
25285 + PATCH_OPTION(indexfiles);
25295 URIHANDLER_FUNC(mod_indexfile_subrequest) {
25296 plugin_data *p = p_d;
25298 stat_cache_entry *sce = NULL;
25301 if (con->uri.path->used == 0) return HANDLER_GO_ON;
25302 if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
25305 mod_indexfile_patch_connection(srv, con, p);
25308 if (con->conf.log_request_handling) {
25309 log_error_write(srv, __FILE__, __LINE__, "s", "-- handling the request as Indexfile");
25310 log_error_write(srv, __FILE__, __LINE__, "sb", "URI :", con->uri.path);
25315 for (k = 0; k < p->conf.indexfiles->used; k++) {
25316 data_string *ds = (data_string *)p->conf.indexfiles->data[k];
25319 if (ds->value && ds->value->ptr[0] == '/') {
25320 - /* if the index-file starts with a prefix as use this file as
25321 + /* if the index-file starts with a prefix as use this file as
25322 * index-generator */
25323 buffer_copy_string_buffer(p->tmp_buf, con->physical.doc_root);
25325 buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
25327 buffer_append_string_buffer(p->tmp_buf, ds->value);
25330 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
25331 if (errno == EACCES) {
25332 con->http_status = 403;
25333 buffer_reset(con->physical.path);
25336 return HANDLER_FINISHED;
25340 if (errno != ENOENT &&
25341 errno != ENOTDIR) {
25342 /* we have no idea what happend. let's tell the user so. */
25345 con->http_status = 500;
25348 log_error_write(srv, __FILE__, __LINE__, "ssbsb",
25349 "file not found ... or so: ", strerror(errno),
25351 "->", con->physical.path);
25354 buffer_reset(con->physical.path);
25357 return HANDLER_FINISHED;
25363 /* rewrite uri.path to the real path (/ -> /index.php) */
25364 buffer_append_string_buffer(con->uri.path, ds->value);
25365 buffer_copy_string_buffer(con->physical.path, p->tmp_buf);
25368 /* fce is already set up a few lines above */
25371 return HANDLER_GO_ON;
25376 return HANDLER_GO_ON;
25378 @@ -207,13 +204,13 @@
25379 int mod_indexfile_plugin_init(plugin *p) {
25380 p->version = LIGHTTPD_VERSION_ID;
25381 p->name = buffer_init_string("indexfile");
25384 p->init = mod_indexfile_init;
25385 p->handle_subrequest_start = mod_indexfile_subrequest;
25386 p->set_defaults = mod_indexfile_set_defaults;
25387 p->cleanup = mod_indexfile_free;
25395 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_mysql_vhost.c lighttpd-1.4.12/src/mod_mysql_vhost.c
25396 --- lighttpd-1.4.11/src/mod_mysql_vhost.c 2006-01-14 20:35:10.000000000 +0200
25397 +++ lighttpd-1.4.12/src/mod_mysql_vhost.c 2006-07-11 21:23:40.000000000 +0300
25399 -#include <unistd.h>
25403 -#include <strings.h>
25404 +#include <string.h>
25406 #ifdef HAVE_CONFIG_H
25407 #include "config.h"
25410 +#ifdef HAVE_MYSQL_H
25411 +# ifdef HAVE_LIBMYSQL
25412 +# define HAVE_MYSQL
25419 @@ -16,61 +21,40 @@
25422 #include "stat_cache.h"
25423 -#ifdef DEBUG_MOD_MYSQL_VHOST
25426 +#include "sys-files.h"
25429 - * Plugin for lighttpd to use MySQL
25430 - * for domain to directory lookups,
25431 - * i.e virtual hosts (vhosts).
25433 - * Optionally sets fcgi_offset and fcgi_arg
25434 - * in preparation for fcgi.c to handle
25435 - * per-user fcgi chroot jails.
25437 - * /ada@riksnet.se 2004-12-06
25439 +#include "mod_sql_vhost_core.h"
25443 +#define CORE_PLUGIN "mod_sql_vhost_core"
25453 - buffer *hostname;
25454 - unsigned short port;
25458 buffer *mysql_post;
25460 + mod_sql_vhost_core_plugin_config *core;
25463 /* global plugin data */
25471 plugin_config **config_storage;
25473 - plugin_config conf;
25475 + plugin_config conf;
25478 -/* per connection plugin data */
25480 - buffer *server_name;
25481 - buffer *document_root;
25482 - buffer *fcgi_arg;
25483 - unsigned fcgi_offset;
25484 -} plugin_connection_data;
25485 +SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost);
25487 /* init the plugin data */
25488 INIT_FUNC(mod_mysql_vhost_init) {
25492 p = calloc(1, sizeof(*p));
25494 p->tmp_buf = buffer_init();
25495 @@ -83,144 +67,77 @@
25496 plugin_data *p = p_d;
25501 - log_error_write(srv, __FILE__, __LINE__, "ss",
25502 - "mod_mysql_vhost_cleanup", p ? "yes" : "NO");
25505 if (!p) return HANDLER_GO_ON;
25508 if (p->config_storage) {
25510 for (i = 0; i < srv->config_context->used; i++) {
25511 plugin_config *s = p->config_storage[i];
25516 mysql_close(s->mysql);
25518 - buffer_free(s->mydb);
25519 - buffer_free(s->myuser);
25520 - buffer_free(s->mypass);
25521 - buffer_free(s->mysock);
25523 buffer_free(s->mysql_pre);
25524 buffer_free(s->mysql_post);
25529 free(p->config_storage);
25531 buffer_free(p->tmp_buf);
25535 - return HANDLER_GO_ON;
25538 -/* handle the plugin per connection data */
25539 -static void* mod_mysql_vhost_connection_data(server *srv, connection *con, void *p_d)
25541 - plugin_data *p = p_d;
25542 - plugin_connection_data *c = con->plugin_ctx[p->id];
25547 - log_error_write(srv, __FILE__, __LINE__, "ss",
25548 - "mod_mysql_connection_data", c ? "old" : "NEW");
25552 - c = calloc(1, sizeof(*c));
25554 - c->server_name = buffer_init();
25555 - c->document_root = buffer_init();
25556 - c->fcgi_arg = buffer_init();
25557 - c->fcgi_offset = 0;
25559 - return con->plugin_ctx[p->id] = c;
25562 -/* destroy the plugin per connection data */
25563 -CONNECTION_FUNC(mod_mysql_vhost_handle_connection_close) {
25564 - plugin_data *p = p_d;
25565 - plugin_connection_data *c = con->plugin_ctx[p->id];
25570 - log_error_write(srv, __FILE__, __LINE__, "ss",
25571 - "mod_mysql_vhost_handle_connection_close", c ? "yes" : "NO");
25574 - if (!c) return HANDLER_GO_ON;
25576 - buffer_free(c->server_name);
25577 - buffer_free(c->document_root);
25578 - buffer_free(c->fcgi_arg);
25579 - c->fcgi_offset = 0;
25584 - con->plugin_ctx[p->id] = NULL;
25585 return HANDLER_GO_ON;
25588 /* set configuration values */
25589 SERVER_FUNC(mod_mysql_vhost_set_defaults) {
25590 plugin_data *p = p_d;
25591 + mod_sql_vhost_core_plugin_data *core_config;
25596 - config_values_t cv[] = {
25597 - { "mysql-vhost.db", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },
25598 - { "mysql-vhost.user", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },
25599 - { "mysql-vhost.pass", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },
25600 - { "mysql-vhost.sock", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },
25601 - { "mysql-vhost.sql", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },
25602 - { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER },
25603 - { "mysql-vhost.port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER },
25604 - { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
25607 + /* our very own plugin storage, one entry for each conditional
25609 + * srv->config_context->used is the number of conditionals
25611 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
25614 + /* get the config of the core-plugin */
25615 + core_config = plugin_get_config(srv, CORE_PLUGIN);
25618 + /* walk through all conditionals and check for assignments */
25619 for (i = 0; i < srv->config_context->used; i++) {
25626 + /* get the config from the core plugin for this conditional-context */
25627 s = calloc(1, sizeof(plugin_config));
25628 - s->mydb = buffer_init();
25629 - s->myuser = buffer_init();
25630 - s->mypass = buffer_init();
25631 - s->mysock = buffer_init();
25632 - s->hostname = buffer_init();
25633 - s->port = 0; /* default port for mysql */
25634 - sel = buffer_init();
25637 + s->core = core_config->config_storage[i];
25641 s->mysql_pre = buffer_init();
25642 s->mysql_post = buffer_init();
25644 - cv[0].destination = s->mydb;
25645 - cv[1].destination = s->myuser;
25646 - cv[2].destination = s->mypass;
25647 - cv[3].destination = s->mysock;
25648 - cv[4].destination = sel;
25649 - cv[5].destination = s->hostname;
25650 - cv[6].destination = &(s->port);
25653 p->config_storage[i] = s;
25655 - if (config_insert_values_global(srv,
25656 - ((data_config *)srv->config_context->data[i])->value,
25657 - cv)) return HANDLER_ERROR;
25659 - s->mysql_pre = buffer_init();
25660 - s->mysql_post = buffer_init();
25663 + /* check if we are the plugin for this backend */
25664 + if (!buffer_is_equal_string(s->core->backend, CONST_STR_LEN("mysql"))) continue;
25666 + /* attach us to the core-plugin */
25667 + s->core->backend_data = p;
25668 + s->core->get_vhost = mod_mysql_vhost_get_vhost;
25670 + sel = buffer_init();
25671 + buffer_copy_string_buffer(sel, s->core->select_vhost);
25673 if (sel->used && (qmark = index(sel->ptr, '?'))) {
25675 buffer_copy_string(s->mysql_pre, sel->ptr);
25676 @@ -228,35 +145,35 @@
25678 buffer_copy_string_buffer(s->mysql_pre, sel);
25689 * - password, default: empty
25690 * - socket, default: mysql default
25691 * - hostname, if set overrides socket
25692 * - port, default: 3306
25696 /* all have to be set */
25697 - if (!(buffer_is_empty(s->myuser) ||
25698 - buffer_is_empty(s->mydb))) {
25699 + if (!(buffer_is_empty(s->core->user) ||
25700 + buffer_is_empty(s->core->db))) {
25705 if (NULL == (s->mysql = mysql_init(NULL))) {
25706 log_error_write(srv, __FILE__, __LINE__, "s", "mysql_init() failed, exiting...");
25709 return HANDLER_ERROR;
25711 -#define FOO(x) (s->x->used ? s->x->ptr : NULL)
25713 - if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(myuser), FOO(mypass),
25714 - FOO(mydb), s->port, FOO(mysock), 0)) {
25715 +#define FOO(x) (s->core->x->used ? s->core->x->ptr : NULL)
25717 + if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(user), FOO(pass),
25718 + FOO(db), s->core->port, FOO(sock), 0)) {
25719 log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(s->mysql));
25722 return HANDLER_ERROR;
25725 @@ -265,61 +182,47 @@
25726 /* otherwise we cannot be sure that mysql is fd i-1 */
25727 if (-1 == (fd = open("/dev/null", 0))) {
25729 - fcntl(fd-1, F_SETFD, FD_CLOEXEC);
25730 + fcntl(fd-1, F_SETFD, FD_CLOEXEC);
25739 return HANDLER_GO_ON;
25742 -#define PATCH(x) \
25743 - p->conf.x = s->x;
25744 static int mod_mysql_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
25747 plugin_config *s = p->config_storage[0];
25749 - PATCH(mysql_pre);
25750 - PATCH(mysql_post);
25756 + PATCH_OPTION(mysql_pre);
25757 + PATCH_OPTION(mysql_post);
25758 + PATCH_OPTION(mysql);
25760 /* skip the first, the global context */
25761 for (i = 1; i < srv->config_context->used; i++) {
25762 data_config *dc = (data_config *)srv->config_context->data[i];
25763 s = p->config_storage[i];
25766 /* condition didn't match */
25767 if (!config_check_cond(srv, con, dc)) continue;
25769 - /* merge config */
25770 - for (j = 0; j < dc->value->used; j++) {
25771 - data_unset *du = dc->value->data[j];
25773 - if (buffer_is_equal_string(du->key, CONST_STR_LEN("mysql-vhost.sql"))) {
25774 - PATCH(mysql_pre);
25775 - PATCH(mysql_post);
25782 + PATCH_OPTION(mysql);
25783 + PATCH_OPTION(mysql_pre);
25784 + PATCH_OPTION(mysql_post);
25794 -/* handle document root request */
25795 -CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
25797 + * get the vhost info from the database
25799 +SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost) {
25800 plugin_data *p = p_d;
25801 - plugin_connection_data *c;
25802 - stat_cache_entry *sce;
25806 @@ -332,13 +235,6 @@
25808 if (!p->conf.mysql) return HANDLER_GO_ON;
25810 - /* sets up connection data if not done yet */
25811 - c = mod_mysql_vhost_connection_data(srv, con, p_d);
25813 - /* check if cached this connection */
25814 - if (c->server_name->used && /* con->uri.authority->used && */
25815 - buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON;
25817 /* build and run SQL query */
25818 buffer_copy_string_buffer(p->tmp_buf, p->conf.mysql_pre);
25819 if (p->conf.mysql_post->used) {
25820 @@ -347,77 +243,43 @@
25822 if (mysql_query(p->conf.mysql, p->tmp_buf->ptr)) {
25823 log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(p->conf.mysql));
25826 + mysql_free_result(result);
25827 + return HANDLER_GO_ON;
25829 result = mysql_store_result(p->conf.mysql);
25830 cols = mysql_num_fields(result);
25831 row = mysql_fetch_row(result);
25833 if (!row || cols < 1) {
25834 /* no such virtual host */
25835 mysql_free_result(result);
25836 return HANDLER_GO_ON;
25839 - /* sanity check that really is a directory */
25840 - buffer_copy_string(p->tmp_buf, row[0]);
25841 - BUFFER_APPEND_SLASH(p->tmp_buf);
25843 - if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
25844 - log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
25847 - if (!S_ISDIR(sce->st.st_mode)) {
25848 - log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->tmp_buf);
25851 + buffer_copy_string(docroot, row[0]);
25853 - /* cache the data */
25854 - buffer_copy_string_buffer(c->server_name, con->uri.authority);
25855 - buffer_copy_string_buffer(c->document_root, p->tmp_buf);
25857 - /* fcgi_offset and fcgi_arg are optional */
25858 - if (cols > 1 && row[1]) {
25859 - c->fcgi_offset = atoi(row[1]);
25861 - if (cols > 2 && row[2]) {
25862 - buffer_copy_string(c->fcgi_arg, row[2]);
25864 - c->fcgi_arg->used = 0;
25867 - c->fcgi_offset = c->fcgi_arg->used = 0;
25869 mysql_free_result(result);
25871 - /* fix virtual server and docroot */
25872 -GO_ON: buffer_copy_string_buffer(con->server_name, c->server_name);
25873 - buffer_copy_string_buffer(con->physical.doc_root, c->document_root);
25876 - log_error_write(srv, __FILE__, __LINE__, "sbbdb",
25877 - result ? "NOT CACHED" : "cached",
25878 - con->server_name, con->physical.doc_root,
25879 - c->fcgi_offset, c->fcgi_arg);
25881 - return HANDLER_GO_ON;
25883 -ERR500: if (result) mysql_free_result(result);
25884 - con->http_status = 500; /* Internal Error */
25885 - return HANDLER_FINISHED;
25886 + return HANDLER_GO_ON;
25889 /* this function is called at dlopen() time and inits the callbacks */
25890 int mod_mysql_vhost_plugin_init(plugin *p) {
25893 p->version = LIGHTTPD_VERSION_ID;
25894 p->name = buffer_init_string("mysql_vhost");
25896 p->init = mod_mysql_vhost_init;
25897 p->cleanup = mod_mysql_vhost_cleanup;
25898 - p->handle_request_done = mod_mysql_vhost_handle_connection_close;
25900 p->set_defaults = mod_mysql_vhost_set_defaults;
25901 - p->handle_docroot = mod_mysql_vhost_handle_docroot;
25903 + ds = data_string_init();
25904 + buffer_copy_string(ds->value, CORE_PLUGIN);
25905 + array_insert_unique(p->required_plugins, (data_unset *)ds);
25910 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_proxy.c lighttpd-1.4.12/src/mod_proxy.c
25911 --- lighttpd-1.4.11/src/mod_proxy.c 2006-01-31 13:01:22.000000000 +0200
25912 +++ lighttpd-1.4.12/src/mod_proxy.c 2006-07-11 21:23:40.000000000 +0300
25914 #include <sys/types.h>
25916 -#include <unistd.h>
25919 #include <string.h>
25922 #include "inet_ntop_cache.h"
25924 +#include "network.h"
25926 +#include "http_resp.h"
25933 #include "sys-socket.h"
25934 +#include "sys-files.h"
25935 +#include "sys-strings.h"
25937 #define data_proxy data_fastcgi
25938 #define data_proxy_init data_fastcgi_init
25939 @@ -38,16 +42,16 @@
25940 #define PROXY_RETRY_TIMEOUT 60
25944 - * the proxy module is based on the fastcgi module
25947 + * the proxy module is based on the fastcgi module
25949 * 28.06.2004 Jan Kneschke The first release
25950 * 01.07.2004 Evgeny Rodichev Several bugfixes and cleanups
25951 * - co-ordinate up- and downstream flows correctly (proxy_demux_response
25952 * and proxy_handle_fdevent)
25953 * - correctly transfer upstream http_response_status;
25954 * - some unused structures removed.
25957 * TODO: - delay upstream read if write_queue is too large
25958 * (to prevent memory eating, like in apache). Shoud be
25960 @@ -66,26 +70,31 @@
25963 proxy_balance_t balance;
25965 + array *last_used_backends; /* "extension" : last_used_backend */
25972 buffer *parse_response;
25973 buffer *balance_buf;
25976 + array *ignore_headers;
25978 plugin_config **config_storage;
25981 plugin_config conf;
25985 - PROXY_STATE_INIT,
25986 - PROXY_STATE_CONNECT,
25987 - PROXY_STATE_PREPARE_WRITE,
25988 - PROXY_STATE_WRITE,
25989 - PROXY_STATE_READ,
25990 - PROXY_STATE_ERROR
25992 + PROXY_STATE_INIT,
25993 + PROXY_STATE_CONNECT,
25994 + PROXY_STATE_PREPARE_WRITE,
25995 + PROXY_STATE_WRITE,
25996 + PROXY_STATE_RESPONSE_HEADER,
25997 + PROXY_STATE_RESPONSE_CONTENT,
25998 + PROXY_STATE_ERROR
25999 } proxy_connection_state_t;
26001 enum { PROXY_STDOUT, PROXY_END_REQUEST };
26002 @@ -93,19 +102,20 @@
26004 proxy_connection_state_t state;
26005 time_t state_timestamp;
26012 buffer *response_header;
26018 int fd; /* fd to the proxy process */
26019 int fde_ndx; /* index into the fd-event buffer */
26021 size_t path_info_offset; /* start of path_info in uri.path */
26024 connection *remote_conn; /* dump pointer */
26025 plugin_data *plugin_data; /* dump pointer */
26027 @@ -116,21 +126,22 @@
26029 static handler_ctx * handler_ctx_init() {
26030 handler_ctx * hctx;
26034 hctx = calloc(1, sizeof(*hctx));
26037 hctx->state = PROXY_STATE_INIT;
26041 hctx->response = buffer_init();
26042 hctx->response_header = buffer_init();
26044 hctx->wb = chunkqueue_init();
26045 + hctx->rb = chunkqueue_init();
26048 hctx->fde_ndx = -1;
26054 @@ -138,47 +149,70 @@
26055 buffer_free(hctx->response);
26056 buffer_free(hctx->response_header);
26057 chunkqueue_free(hctx->wb);
26059 + chunkqueue_free(hctx->rb);
26064 INIT_FUNC(mod_proxy_init) {
26069 + char *hop2hop_headers[] = {
26076 p = calloc(1, sizeof(*p));
26079 p->parse_response = buffer_init();
26080 p->balance_buf = buffer_init();
26082 + p->ignore_headers = array_init();
26084 + for (i = 0; hop2hop_headers[i]; i++) {
26087 + if (NULL == (ds = (data_string *)array_get_unused_element(p->ignore_headers, TYPE_STRING))) {
26088 + ds = data_string_init();
26091 + buffer_copy_string(ds->value, hop2hop_headers[i]);
26092 + array_insert_unique(p->ignore_headers, (data_unset *)ds);
26099 FREE_FUNC(mod_proxy_free) {
26100 plugin_data *p = p_d;
26105 buffer_free(p->parse_response);
26106 buffer_free(p->balance_buf);
26109 if (p->config_storage) {
26111 for (i = 0; i < srv->config_context->used; i++) {
26112 plugin_config *s = p->config_storage[i];
26117 array_free(s->extensions);
26119 + array_free(s->last_used_backends);
26124 free(p->config_storage);
26128 + free(p->ignore_headers);
26133 return HANDLER_GO_ON;
26136 @@ -186,37 +220,38 @@
26137 plugin_data *p = p_d;
26141 - config_values_t cv[] = {
26143 + config_values_t cv[] = {
26144 { "proxy.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
26145 { "proxy.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
26146 { "proxy.balance", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
26147 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
26151 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
26154 for (i = 0; i < srv->config_context->used; i++) {
26159 s = malloc(sizeof(plugin_config));
26160 - s->extensions = array_init();
26161 + s->extensions = array_init();
26162 + s->last_used_backends = array_init();
26166 cv[0].destination = s->extensions;
26167 cv[1].destination = &(s->debug);
26168 cv[2].destination = p->balance_buf;
26170 buffer_reset(p->balance_buf);
26173 p->config_storage[i] = s;
26174 ca = ((data_config *)srv->config_context->data[i])->value;
26177 if (0 != config_insert_values_global(srv, ca, cv)) {
26178 return HANDLER_ERROR;
26182 if (buffer_is_empty(p->balance_buf)) {
26183 s->balance = PROXY_BALANCE_FAIR;
26184 } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("fair"))) {
26185 @@ -226,7 +261,7 @@
26186 } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("hash"))) {
26187 s->balance = PROXY_BALANCE_HASH;
26189 - log_error_write(srv, __FILE__, __LINE__, "sb",
26190 + log_error_write(srv, __FILE__, __LINE__, "sb",
26191 "proxy.balance has to be one of: fair, round-robin, hash, but not:", p->balance_buf);
26192 return HANDLER_ERROR;
26194 @@ -234,91 +269,91 @@
26195 if (NULL != (du = array_get_element(ca, "proxy.server"))) {
26197 data_array *da = (data_array *)du;
26200 if (du->type != TYPE_ARRAY) {
26201 - log_error_write(srv, __FILE__, __LINE__, "sss",
26202 + log_error_write(srv, __FILE__, __LINE__, "sss",
26203 "unexpected type for key: ", "proxy.server", "array of strings");
26206 return HANDLER_ERROR;
26212 * proxy.server = ( "<ext>" => ...,
26217 for (j = 0; j < da->value->used; j++) {
26218 data_array *da_ext = (data_array *)da->value->data[j];
26222 if (da_ext->type != TYPE_ARRAY) {
26223 - log_error_write(srv, __FILE__, __LINE__, "sssbs",
26224 - "unexpected type for key: ", "proxy.server",
26225 + log_error_write(srv, __FILE__, __LINE__, "sssbs",
26226 + "unexpected type for key: ", "proxy.server",
26227 "[", da->value->data[j]->key, "](string)");
26230 return HANDLER_ERROR;
26234 - * proxy.server = ( "<ext>" =>
26235 - * ( "<host>" => ( ... ),
26238 + * proxy.server = ( "<ext>" =>
26239 + * ( "<host>" => ( ... ),
26240 * "<host>" => ( ... )
26247 for (n = 0; n < da_ext->value->used; n++) {
26248 data_array *da_host = (data_array *)da_ext->value->data[n];
26254 - config_values_t pcv[] = {
26256 + config_values_t pcv[] = {
26257 { "host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
26258 { "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
26259 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
26263 if (da_host->type != TYPE_ARRAY) {
26264 - log_error_write(srv, __FILE__, __LINE__, "ssSBS",
26265 - "unexpected type for key:",
26267 + log_error_write(srv, __FILE__, __LINE__, "ssSBS",
26268 + "unexpected type for key:",
26270 "[", da_ext->value->data[n]->key, "](string)");
26273 return HANDLER_ERROR;
26277 df = data_proxy_init();
26283 buffer_copy_string_buffer(df->key, da_host->key);
26286 pcv[0].destination = df->host;
26287 pcv[1].destination = &(df->port);
26290 if (0 != config_insert_values_internal(srv, da_host->value, pcv)) {
26291 return HANDLER_ERROR;
26295 if (buffer_is_empty(df->host)) {
26296 - log_error_write(srv, __FILE__, __LINE__, "sbbbs",
26297 - "missing key (string):",
26298 + log_error_write(srv, __FILE__, __LINE__, "sbbbs",
26299 + "missing key (string):",
26306 return HANDLER_ERROR;
26310 /* if extension already exists, take it */
26313 if (NULL == (dfa = (data_array *)array_get_element(s->extensions, da_ext->key->ptr))) {
26314 dfa = data_array_init();
26317 buffer_copy_string_buffer(dfa->key, da_ext->key);
26320 array_insert_unique(dfa->value, (data_unset *)df);
26321 array_insert_unique(s->extensions, (data_unset *)dfa);
26323 @@ -328,19 +363,19 @@
26329 return HANDLER_GO_ON;
26332 void proxy_connection_close(server *srv, handler_ctx *hctx) {
26337 if (NULL == hctx) return;
26340 p = hctx->plugin_data;
26341 con = hctx->remote_conn;
26344 if (hctx->fd != -1) {
26345 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
26346 fdevent_unregister(srv->ev, hctx->fd);
26347 @@ -348,47 +383,56 @@
26353 handler_ctx_free(hctx);
26354 - con->plugin_ctx[p->id] = NULL;
26355 + con->plugin_ctx[p->id] = NULL;
26358 static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
26359 struct sockaddr *proxy_addr;
26360 struct sockaddr_in proxy_addr_in;
26364 plugin_data *p = hctx->plugin_data;
26365 data_proxy *host= hctx->host;
26366 int proxy_fd = hctx->fd;
26369 memset(&proxy_addr, 0, sizeof(proxy_addr));
26372 proxy_addr_in.sin_family = AF_INET;
26373 proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr);
26374 proxy_addr_in.sin_port = htons(host->port);
26375 servlen = sizeof(proxy_addr_in);
26378 proxy_addr = (struct sockaddr *) &proxy_addr_in;
26381 if (-1 == connect(proxy_fd, proxy_addr, servlen)) {
26382 - if (errno == EINPROGRESS || errno == EALREADY) {
26384 + errno = WSAGetLastError();
26388 + case WSAEWOULDBLOCK:
26390 + case EINPROGRESS:
26392 if (p->conf.debug) {
26393 - log_error_write(srv, __FILE__, __LINE__, "sd",
26394 + log_error_write(srv, __FILE__, __LINE__, "sd",
26395 "connect delayed:", proxy_fd);
26402 - log_error_write(srv, __FILE__, __LINE__, "sdsd",
26405 + log_error_write(srv, __FILE__, __LINE__, "sdsd",
26406 "connect failed:", proxy_fd, strerror(errno), errno);
26412 + fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, proxy_fd);
26413 if (p->conf.debug) {
26414 - log_error_write(srv, __FILE__, __LINE__, "sd",
26415 + log_error_write(srv, __FILE__, __LINE__, "sd",
26416 "connect succeeded: ", proxy_fd);
26419 @@ -422,25 +466,26 @@
26421 static int proxy_create_env(server *srv, handler_ctx *hctx) {
26425 connection *con = hctx->remote_conn;
26426 + plugin_data *p = hctx->plugin_data;
26432 b = chunkqueue_get_append_buffer(hctx->wb);
26436 buffer_copy_string(b, get_http_method_name(con->request.http_method));
26437 BUFFER_APPEND_STRING_CONST(b, " ");
26440 buffer_append_string_buffer(b, con->request.uri);
26441 BUFFER_APPEND_STRING_CONST(b, " HTTP/1.0\r\n");
26443 proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
26444 - /* http_host is NOT is just a pointer to a buffer
26445 + /* http_host is NOT is just a pointer to a buffer
26446 * which is NULL if it is not set */
26447 - if (con->request.http_host &&
26448 + if (con->request.http_host &&
26449 !buffer_is_empty(con->request.http_host)) {
26450 proxy_set_header(con, "X-Host", con->request.http_host->ptr);
26452 @@ -449,24 +494,26 @@
26453 /* request header */
26454 for (i = 0; i < con->request.headers->used; i++) {
26458 ds = (data_string *)con->request.headers->data[i];
26461 if (ds->value->used && ds->key->used) {
26462 - if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
26465 + /* don't copy hop-to-hop headers */
26466 + if (array_get_element(p->ignore_headers, ds->key->ptr)) continue;
26468 buffer_append_string_buffer(b, ds->key);
26469 BUFFER_APPEND_STRING_CONST(b, ": ");
26470 buffer_append_string_buffer(b, ds->value);
26471 BUFFER_APPEND_STRING_CONST(b, "\r\n");
26476 BUFFER_APPEND_STRING_CONST(b, "\r\n");
26479 hctx->wb->bytes_in += b->used - 1;
26483 if (con->request.content_length) {
26484 chunkqueue *req_cq = con->request_content_queue;
26486 @@ -479,7 +526,7 @@
26488 /* we announce toWrite octects
26489 * now take all the request_content chunk that we need to fill this request
26493 switch (req_c->type) {
26495 @@ -507,223 +554,125 @@
26497 req_c->offset += weHave;
26498 req_cq->bytes_out += weHave;
26501 hctx->wb->bytes_in += weHave;
26518 static int proxy_set_state(server *srv, handler_ctx *hctx, proxy_connection_state_t state) {
26519 hctx->state = state;
26520 hctx->state_timestamp = srv->cur_ts;
26527 -static int proxy_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
26529 - int http_response_status = -1;
26532 +static void chunkqueue_print(chunkqueue *cq) {
26535 - /* \r\n -> \0\0 */
26537 - buffer_copy_string_buffer(p->parse_response, in);
26539 - for (s = p->parse_response->ptr; NULL != (ns = strstr(s, "\r\n")); s = ns + 2) {
26540 - char *key, *value;
26548 - if (-1 == http_response_status) {
26549 - /* The first line of a Response message is the Status-Line */
26551 - for (key=s; *key && *key != ' '; key++);
26554 - http_response_status = (int) strtol(key, NULL, 10);
26555 - if (http_response_status <= 0) http_response_status = 502;
26557 - http_response_status = 502;
26560 - con->http_status = http_response_status;
26561 - con->parsed_response |= HTTP_STATUS;
26565 - if (NULL == (value = strchr(s, ':'))) {
26566 - /* now we expect: "<key>: <value>\n" */
26572 - key_len = value - key;
26576 - while (*value == ' ' || *value == '\t') value++;
26580 - switch(key_len) {
26582 - if (0 == strncasecmp(key, "Date", key_len)) {
26583 - con->parsed_response |= HTTP_DATE;
26587 - if (0 == strncasecmp(key, "Location", key_len)) {
26588 - con->parsed_response |= HTTP_LOCATION;
26592 - if (0 == strncasecmp(key, "Connection", key_len)) {
26597 - if (0 == strncasecmp(key, "Content-Length", key_len)) {
26598 - con->response.content_length = strtol(value, NULL, 10);
26599 - con->parsed_response |= HTTP_CONTENT_LENGTH;
26606 - if (copy_header) {
26607 - if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
26608 - ds = data_response_init();
26610 - buffer_copy_string_len(ds->key, key, key_len);
26611 - buffer_copy_string(ds->value, value);
26613 - array_insert_unique(con->response.headers, (data_unset *)ds);
26618 + for (c = cq->first; c; c = c->next) {
26619 + fprintf(stderr, "%s", c->mem->ptr + c->offset);
26621 + fprintf(stderr, "\r\n");
26625 static int proxy_demux_response(server *srv, handler_ctx *hctx) {
26630 plugin_data *p = hctx->plugin_data;
26631 connection *con = hctx->remote_conn;
26632 int proxy_fd = hctx->fd;
26634 - /* check how much we have to read */
26635 - if (ioctl(hctx->fd, FIONREAD, &b)) {
26636 - log_error_write(srv, __FILE__, __LINE__, "sd",
26637 - "ioctl failed: ",
26642 + chunkqueue *next_queue = NULL;
26645 - if (p->conf.debug) {
26646 - log_error_write(srv, __FILE__, __LINE__, "sd",
26647 - "proxy - have to read:", b);
26651 - if (hctx->response->used == 0) {
26652 - /* avoid too small buffer */
26653 - buffer_prepare_append(hctx->response, b + 1);
26654 - hctx->response->used = 1;
26656 - buffer_prepare_append(hctx->response, hctx->response->used + b);
26659 - if (-1 == (r = read(hctx->fd, hctx->response->ptr + hctx->response->used - 1, b))) {
26660 - log_error_write(srv, __FILE__, __LINE__, "sds",
26661 - "unexpected end-of-file (perhaps the proxy process died):",
26662 - proxy_fd, strerror(errno));
26666 - /* this should be catched by the b > 0 above */
26669 - hctx->response->used += r;
26670 - hctx->response->ptr[hctx->response->used - 1] = '\0';
26673 - log_error_write(srv, __FILE__, __LINE__, "sdsbs",
26674 - "demux: Response buffer len", hctx->response->used, ":", hctx->response, ":");
26677 - if (0 == con->got_response) {
26678 - con->got_response = 1;
26679 - buffer_prepare_copy(hctx->response_header, 128);
26682 - if (0 == con->file_started) {
26685 - /* search for the \r\n\r\n in the string */
26686 - if (NULL != (c = buffer_search_string_len(hctx->response, "\r\n\r\n", 4))) {
26687 - size_t hlen = c - hctx->response->ptr + 4;
26688 - size_t blen = hctx->response->used - hlen - 1;
26691 - buffer_append_string_len(hctx->response_header, hctx->response->ptr, c - hctx->response->ptr + 4);
26693 - log_error_write(srv, __FILE__, __LINE__, "sb", "Header:", hctx->response_header);
26695 - /* parse the response header */
26696 - proxy_response_parse(srv, con, p, hctx->response_header);
26698 - /* enable chunked-transfer-encoding */
26699 - if (con->request.http_version == HTTP_VERSION_1_1 &&
26700 - !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
26701 - con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
26704 - con->file_started = 1;
26706 - http_chunk_append_mem(srv, con, c + 4, blen + 1);
26707 - joblist_append(srv, con);
26709 - hctx->response->used = 0;
26712 - http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
26713 - joblist_append(srv, con);
26714 - hctx->response->used = 0;
26718 - /* reading from upstream done */
26719 + switch(srv->network_backend_read(srv, con, proxy_fd, hctx->rb)) {
26720 + case NETWORK_STATUS_SUCCESS:
26721 + /* we got content */
26723 + case NETWORK_STATUS_CONNECTION_CLOSE:
26724 + /* we are done, get out of here */
26725 con->file_finished = 1;
26728 + /* close the chunk-queue with a empty chunk */
26729 http_chunk_append_mem(srv, con, NULL, 0);
26730 joblist_append(srv, con);
26740 + /* looks like we got some content
26742 + * split off the header from the incoming stream
26745 + if (hctx->state == PROXY_STATE_RESPONSE_HEADER) {
26746 + http_resp *resp = http_response_init();
26748 + /* the response header is not fully received yet,
26750 + * extract the http-response header from the rb-cq
26752 + fprintf(stderr, "%s.%d: network-read\r\n", __FILE__, __LINE__);
26753 + chunkqueue_print(hctx->rb);
26755 + switch (http_response_parse_cq(hctx->rb, resp)) {
26756 + case PARSE_ERROR:
26757 + /* parsing failed */
26759 + con->http_status = 502; /* Bad Gateway */
26761 + case PARSE_NEED_MORE:
26763 + case PARSE_SUCCESS:
26764 + con->http_status = resp->status;
26766 + fprintf(stderr, "%s.%d: parsing done\r\n", __FILE__, __LINE__);
26767 + chunkqueue_print(hctx->rb);
26769 + con->file_started = 1;
26771 + hctx->state = PROXY_STATE_RESPONSE_CONTENT;
26776 + /* FIXME: pass the response-header to the other plugins to
26777 + * setup the filter-queue
26779 + * - use next-queue instead of con->write_queue
26782 + next_queue = con->write_queue;
26784 + assert(hctx->state == PROXY_STATE_RESPONSE_CONTENT);
26786 + /* FIXME: if we have a content-length or chunked-encoding
26789 + * for now we wait for EOF on the socket */
26791 + /* copy the content to the next cq */
26792 + for (c = hctx->rb->first; c; c = c->next) {
26793 + http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
26795 + c->offset = c->mem->used - 1;
26800 + chunkqueue_remove_finished_chunks(hctx->rb);
26806 @@ -731,12 +680,12 @@
26807 data_proxy *host= hctx->host;
26808 plugin_data *p = hctx->plugin_data;
26809 connection *con = hctx->remote_conn;
26817 (!host->host->used || !host->port)) return -1;
26820 switch(hctx->state) {
26821 case PROXY_STATE_INIT:
26822 if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
26823 @@ -744,19 +693,19 @@
26824 return HANDLER_ERROR;
26826 hctx->fde_ndx = -1;
26832 fdevent_register(srv->ev, hctx->fd, proxy_handle_fdevent, hctx);
26835 if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
26836 log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
26839 return HANDLER_ERROR;
26846 case PROXY_STATE_CONNECT:
26847 /* try to finish the connect() */
26848 if (hctx->state == PROXY_STATE_INIT) {
26849 @@ -764,16 +713,16 @@
26850 switch (proxy_establish_connection(srv, hctx)) {
26852 proxy_set_state(srv, hctx, PROXY_STATE_CONNECT);
26855 /* connection is in progress, wait for an event and call getsockopt() below */
26858 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
26861 return HANDLER_WAIT_FOR_EVENT;
26863 /* if ECONNREFUSED choose another connection -> FIXME */
26864 hctx->fde_ndx = -1;
26867 return HANDLER_ERROR;
26869 /* everything is ok, go on */
26870 @@ -782,152 +731,152 @@
26873 socklen_t socket_error_len = sizeof(socket_error);
26875 - /* we don't need it anymore */
26877 + /* we don't need it anymore */
26878 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
26880 /* try to finish the connect() */
26881 if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
26882 - log_error_write(srv, __FILE__, __LINE__, "ss",
26883 + log_error_write(srv, __FILE__, __LINE__, "ss",
26884 "getsockopt failed:", strerror(errno));
26887 return HANDLER_ERROR;
26889 if (socket_error != 0) {
26890 log_error_write(srv, __FILE__, __LINE__, "ss",
26891 - "establishing connection failed:", strerror(socket_error),
26892 + "establishing connection failed:", strerror(socket_error),
26893 "port:", hctx->host->port);
26896 return HANDLER_ERROR;
26898 if (p->conf.debug) {
26899 - log_error_write(srv, __FILE__, __LINE__, "s", "proxy - connect - delayed success");
26900 + log_error_write(srv, __FILE__, __LINE__, "s", "proxy - connect - delayed success");
26902 + fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, hctx->fd);
26906 proxy_set_state(srv, hctx, PROXY_STATE_PREPARE_WRITE);
26908 case PROXY_STATE_PREPARE_WRITE:
26909 proxy_create_env(srv, hctx);
26912 proxy_set_state(srv, hctx, PROXY_STATE_WRITE);
26916 case PROXY_STATE_WRITE:;
26917 - ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
26918 + ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
26920 chunkqueue_remove_finished_chunks(hctx->wb);
26923 - if (errno != EAGAIN &&
26924 - errno != EINTR) {
26925 - log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno);
26927 - return HANDLER_ERROR;
26929 - fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
26931 + case NETWORK_STATUS_FATAL_ERROR:
26932 + log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno);
26934 - return HANDLER_WAIT_FOR_EVENT;
26936 + return HANDLER_ERROR;
26937 + case NETWORK_STATUS_WAIT_FOR_EVENT:
26939 + fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
26941 + return HANDLER_WAIT_FOR_EVENT;
26944 if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
26945 - proxy_set_state(srv, hctx, PROXY_STATE_READ);
26946 + proxy_set_state(srv, hctx, PROXY_STATE_RESPONSE_HEADER);
26948 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
26949 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
26951 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
26954 return HANDLER_WAIT_FOR_EVENT;
26958 return HANDLER_WAIT_FOR_EVENT;
26959 - case PROXY_STATE_READ:
26960 + case PROXY_STATE_RESPONSE_HEADER:
26961 /* waiting for a response */
26963 return HANDLER_WAIT_FOR_EVENT;
26965 log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
26966 return HANDLER_ERROR;
26970 return HANDLER_GO_ON;
26973 -#define PATCH(x) \
26974 - p->conf.x = s->x;
26975 static int mod_proxy_patch_connection(server *srv, connection *con, plugin_data *p) {
26977 plugin_config *s = p->config_storage[0];
26979 - PATCH(extensions);
26984 + PATCH_OPTION(extensions);
26985 + PATCH_OPTION(debug);
26986 + PATCH_OPTION(balance);
26987 + PATCH_OPTION(last_used_backends);
26989 /* skip the first, the global context */
26990 for (i = 1; i < srv->config_context->used; i++) {
26991 data_config *dc = (data_config *)srv->config_context->data[i];
26992 s = p->config_storage[i];
26995 /* condition didn't match */
26996 if (!config_check_cond(srv, con, dc)) continue;
27000 for (j = 0; j < dc->value->used; j++) {
27001 data_unset *du = dc->value->data[j];
27004 if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.server"))) {
27005 - PATCH(extensions);
27006 + PATCH_OPTION(extensions);
27007 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.debug"))) {
27009 + PATCH_OPTION(debug);
27010 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balance"))) {
27012 + PATCH_OPTION(balance);
27013 + PATCH_OPTION(last_used_backends);
27023 SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
27024 plugin_data *p = p_d;
27027 handler_ctx *hctx = con->plugin_ctx[p->id];
27031 if (NULL == hctx) return HANDLER_GO_ON;
27033 mod_proxy_patch_connection(srv, con, p);
27040 if (con->mode != p->id) return HANDLER_GO_ON;
27043 /* ok, create the request */
27044 switch(proxy_write_request(srv, hctx)) {
27045 case HANDLER_ERROR:
27046 - log_error_write(srv, __FILE__, __LINE__, "sbdd", "proxy-server disabled:",
27047 + log_error_write(srv, __FILE__, __LINE__, "sbdd", "proxy-server disabled:",
27053 /* disable this server */
27054 host->is_disabled = 1;
27055 host->disable_ts = srv->cur_ts;
27058 proxy_connection_close(srv, hctx);
27060 - /* reset the enviroment and restart the sub-request */
27062 + /* reset the enviroment and restart the sub-request */
27063 buffer_reset(con->physical.path);
27064 con->mode = DIRECT;
27066 joblist_append(srv, con);
27068 - /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
27069 - * and hope that the childs will be restarted
27071 + /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
27072 + * and hope that the childs will be restarted
27076 return HANDLER_WAIT_FOR_FD;
27077 @@ -938,7 +887,7 @@
27083 if (con->file_started == 1) {
27084 return HANDLER_FINISHED;
27086 @@ -951,13 +900,14 @@
27087 handler_ctx *hctx = ctx;
27088 connection *con = hctx->remote_conn;
27089 plugin_data *p = hctx->plugin_data;
27094 if ((revents & FDEVENT_IN) &&
27095 - hctx->state == PROXY_STATE_READ) {
27096 + (hctx->state == PROXY_STATE_RESPONSE_HEADER ||
27097 + hctx->state == PROXY_STATE_RESPONSE_CONTENT)) {
27099 if (p->conf.debug) {
27100 - log_error_write(srv, __FILE__, __LINE__, "sd",
27101 + log_error_write(srv, __FILE__, __LINE__, "sd",
27102 "proxy: fdevent-in", hctx->state);
27105 @@ -966,10 +916,10 @@
27108 hctx->host->usage--;
27112 proxy_connection_close(srv, hctx);
27115 joblist_append(srv, con);
27116 return HANDLER_FINISHED;
27118 @@ -982,53 +932,53 @@
27119 /* response might have been already started, kill the connection */
27120 connection_set_state(srv, con, CON_STATE_ERROR);
27124 joblist_append(srv, con);
27125 return HANDLER_FINISHED;
27130 if (revents & FDEVENT_OUT) {
27131 if (p->conf.debug) {
27132 - log_error_write(srv, __FILE__, __LINE__, "sd",
27133 + log_error_write(srv, __FILE__, __LINE__, "sd",
27134 "proxy: fdevent-out", hctx->state);
27137 if (hctx->state == PROXY_STATE_CONNECT ||
27138 hctx->state == PROXY_STATE_WRITE) {
27139 /* we are allowed to send something out
27142 * 1. in a unfinished connect() call
27143 * 2. in a unfinished write() call (long POST request)
27145 return mod_proxy_handle_subrequest(srv, con, p);
27147 - log_error_write(srv, __FILE__, __LINE__, "sd",
27148 + log_error_write(srv, __FILE__, __LINE__, "sd",
27149 "proxy: out", hctx->state);
27154 /* perhaps this issue is already handled */
27155 if (revents & FDEVENT_HUP) {
27156 if (p->conf.debug) {
27157 - log_error_write(srv, __FILE__, __LINE__, "sd",
27158 + log_error_write(srv, __FILE__, __LINE__, "sd",
27159 "proxy: fdevent-hup", hctx->state);
27163 if (hctx->state == PROXY_STATE_CONNECT) {
27164 /* connect() -> EINPROGRESS -> HUP */
27168 - * what is proxy is doing if it can't reach the next hop ?
27170 + * what is proxy is doing if it can't reach the next hop ?
27175 proxy_connection_close(srv, hctx);
27176 joblist_append(srv, con);
27179 con->http_status = 503;
27180 con->mode = DIRECT;
27183 return HANDLER_FINISHED;
27186 @@ -1038,13 +988,13 @@
27187 joblist_append(srv, con);
27188 } else if (revents & FDEVENT_ERR) {
27189 /* kill all connections to the proxy process */
27192 log_error_write(srv, __FILE__, __LINE__, "sd", "proxy-FDEVENT_ERR, but no HUP", revents);
27194 joblist_append(srv, con);
27195 proxy_connection_close(srv, hctx);
27199 return HANDLER_FINISHED;
27202 @@ -1058,44 +1008,49 @@
27204 data_array *extension = NULL;
27205 size_t path_info_offset;
27207 + data_integer *last_used_backend;
27208 + data_proxy *host = NULL;
27209 + handler_ctx *hctx = NULL;
27211 + array *backends = NULL;
27213 /* Possibly, we processed already this request */
27214 if (con->file_started == 1) return HANDLER_GO_ON;
27217 mod_proxy_patch_connection(srv, con, p);
27220 fn = con->uri.path;
27222 if (fn->used == 0) {
27223 return HANDLER_ERROR;
27227 s_len = fn->used - 1;
27232 path_info_offset = 0;
27234 - if (p->conf.debug) {
27235 + if (p->conf.debug) {
27236 log_error_write(srv, __FILE__, __LINE__, "s", "proxy - start");
27239 /* check if extension matches */
27240 for (k = 0; k < p->conf.extensions->used; k++) {
27244 extension = (data_array *)p->conf.extensions->data[k];
27247 if (extension->key->used == 0) continue;
27250 ct_len = extension->key->used - 1;
27253 if (s_len < ct_len) continue;
27256 /* check extension in the form "/proxy_pattern" */
27257 if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
27258 if (s_len > ct_len + 1) {
27262 if (0 != (pi_offset = strchr(fn->ptr + ct_len + 1, '/'))) {
27263 path_info_offset = pi_offset - fn->ptr;
27265 @@ -1106,12 +1061,14 @@
27271 if (k == p->conf.extensions->used) {
27272 return HANDLER_GO_ON;
27275 - if (p->conf.debug) {
27276 + backends = extension->value;
27278 + if (p->conf.debug) {
27279 log_error_write(srv, __FILE__, __LINE__, "s", "proxy - ext found");
27282 @@ -1120,34 +1077,34 @@
27283 /* hash balancing */
27285 if (p->conf.debug) {
27286 - log_error_write(srv, __FILE__, __LINE__, "sd",
27287 - "proxy - used hash balancing, hosts:", extension->value->used);
27288 + log_error_write(srv, __FILE__, __LINE__, "sd",
27289 + "proxy - used hash balancing, hosts:", backends->used);
27292 - for (k = 0, ndx = -1, last_max = ULONG_MAX; k < extension->value->used; k++) {
27293 - data_proxy *host = (data_proxy *)extension->value->data[k];
27294 + for (k = 0, ndx = -1, last_max = ULONG_MAX; k < backends->used; k++) {
27295 unsigned long cur_max;
27297 - if (host->is_disabled) continue;
27299 + data_proxy *cur = (data_proxy *)backends->data[k];
27301 + if (cur->is_disabled) continue;
27303 cur_max = generate_crc32c(CONST_BUF_LEN(con->uri.path)) +
27304 - generate_crc32c(CONST_BUF_LEN(host->host)) + /* we can cache this */
27305 + generate_crc32c(CONST_BUF_LEN(cur->host)) + /* we can cache this */
27306 generate_crc32c(CONST_BUF_LEN(con->uri.authority));
27309 if (p->conf.debug) {
27310 - log_error_write(srv, __FILE__, __LINE__, "sbbbd",
27311 + log_error_write(srv, __FILE__, __LINE__, "sbbbd",
27312 "proxy - election:",
27316 con->uri.authority,
27320 - if ((last_max == ULONG_MAX) || /* first round */
27321 - (cur_max > last_max)) {
27322 + if (host == NULL || (cur_max > last_max)) {
27323 last_max = cur_max;
27330 @@ -1155,19 +1112,20 @@
27331 case PROXY_BALANCE_FAIR:
27332 /* fair balancing */
27333 if (p->conf.debug) {
27334 - log_error_write(srv, __FILE__, __LINE__, "s",
27335 + log_error_write(srv, __FILE__, __LINE__, "s",
27336 "proxy - used fair balancing");
27339 - for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
27340 - data_proxy *host = (data_proxy *)extension->value->data[k];
27342 - if (host->is_disabled) continue;
27344 - if (host->usage < max_usage) {
27345 - max_usage = host->usage;
27348 + /* try to find the host with the lowest load */
27349 + for (k = 0, max_usage = 0; k < backends->used; k++) {
27350 + data_proxy *cur = (data_proxy *)backends->data[k];
27352 + if (cur->is_disabled) continue;
27354 + if (NULL == host || cur->usage < max_usage) {
27355 + max_usage = cur->usage;
27361 @@ -1175,89 +1133,100 @@
27362 case PROXY_BALANCE_RR:
27364 if (p->conf.debug) {
27365 - log_error_write(srv, __FILE__, __LINE__, "s",
27366 + log_error_write(srv, __FILE__, __LINE__, "s",
27367 "proxy - used round-robin balancing");
27370 /* just to be sure */
27371 - assert(extension->value->used < INT_MAX);
27373 - for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
27374 - data_proxy *host = (data_proxy *)extension->value->data[k];
27376 - if (host->is_disabled) continue;
27378 - /* first usable ndx */
27379 - if (max_usage == INT_MAX) {
27382 + assert(backends->used < INT_MAX);
27384 - /* get next ndx */
27385 - if ((int)k > host->last_used_ndx) {
27387 - host->last_used_ndx = k;
27388 + /* send each request to another host:
27392 + * if we have three hosts it is
27394 + * 1 .. 2 .. 3 .. 1 .. 2 .. 3
27400 + /* walk through the list */
27401 + last_used_backend = (data_integer *)array_get_element(p->conf.last_used_backends, extension->key->ptr);
27403 + if (NULL == last_used_backend) {
27404 + last_used_backend = data_integer_init();
27406 + buffer_copy_string_buffer(last_used_backend->key, extension->key);
27407 + last_used_backend->value = 0;
27409 + array_insert_unique(p->conf.last_used_backends, (data_unset *)last_used_backend);
27412 + /* scan all but the last host to see if they are up
27413 + * take the first running host */
27414 + for (k = last_used_backend->value + 1; (int)(k % backends->used) != last_used_backend->value; k++) {
27415 + data_proxy *cur = (data_proxy *)backends->data[k % backends->used];
27417 + if (cur->is_disabled) continue;
27421 + last_used_backend->value = k;
27426 - /* didn't found a higher id, wrap to the start */
27427 - if (ndx != -1 && max_usage != INT_MAX) {
27430 + if (NULL == host) {
27431 + /* we found nothing better, fallback to the last used backend
27432 + * and check if it is still up */
27433 + host = (data_proxy *)backends->data[last_used_backend->value];
27435 + if (host->is_disabled) host = NULL;
27443 - /* found a server */
27445 - data_proxy *host = (data_proxy *)extension->value->data[ndx];
27448 - * if check-local is disabled, use the uri.path handler
27452 - /* init handler-context */
27453 - handler_ctx *hctx;
27454 - hctx = handler_ctx_init();
27456 - hctx->path_info_offset = path_info_offset;
27457 - hctx->remote_conn = con;
27458 - hctx->plugin_data = p;
27459 - hctx->host = host;
27461 - con->plugin_ctx[p->id] = hctx;
27465 - con->mode = p->id;
27467 - if (p->conf.debug) {
27468 - log_error_write(srv, __FILE__, __LINE__, "sbd",
27469 - "proxy - found a host",
27470 - host->host, host->port);
27473 - return HANDLER_GO_ON;
27475 - /* no handler found */
27476 + /* we havn't found a host */
27477 + if (NULL == host) {
27478 con->http_status = 500;
27480 - log_error_write(srv, __FILE__, __LINE__, "sb",
27481 - "no proxy-handler found for:",
27483 + log_error_write(srv, __FILE__, __LINE__, "sb",
27484 + "no proxy-handler found for:",
27488 return HANDLER_FINISHED;
27491 + /* init handler-context */
27492 + hctx = handler_ctx_init();
27494 + hctx->path_info_offset = path_info_offset;
27495 + hctx->remote_conn = con;
27496 + hctx->plugin_data = p;
27497 + hctx->host = host;
27499 + con->plugin_ctx[p->id] = hctx;
27503 + /* we handle this request */
27504 + con->mode = p->id;
27506 + if (p->conf.debug) {
27507 + log_error_write(srv, __FILE__, __LINE__, "sbd",
27508 + "proxy - found a host",
27509 + host->host, host->port);
27512 return HANDLER_GO_ON;
27515 static handler_t mod_proxy_connection_close_callback(server *srv, connection *con, void *p_d) {
27516 plugin_data *p = p_d;
27519 proxy_connection_close(srv, con->plugin_ctx[p->id]);
27521 return HANDLER_GO_ON;
27522 @@ -1276,11 +1245,11 @@
27524 for (i = 0; i < srv->config_context->used; i++) {
27525 plugin_config *s = p->config_storage[i];
27527 - if (!s) continue;
27529 + if (!s) continue;
27531 /* get the extensions for all configs */
27534 for (k = 0; k < s->extensions->used; k++) {
27535 data_array *extension = (data_array *)s->extensions->data[k];
27537 @@ -1290,8 +1259,8 @@
27539 if (!host->is_disabled ||
27540 srv->cur_ts - host->disable_ts < 5) continue;
27542 - log_error_write(srv, __FILE__, __LINE__, "sbd",
27544 + log_error_write(srv, __FILE__, __LINE__, "sbd",
27545 "proxy - re-enabled:",
27546 host->host, host->port);
27548 @@ -1317,8 +1286,8 @@
27549 p->handle_uri_clean = mod_proxy_check_extension;
27550 p->handle_subrequest = mod_proxy_handle_subrequest;
27551 p->handle_trigger = mod_proxy_trigger;
27559 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_redirect.c lighttpd-1.4.12/src/mod_redirect.c
27560 --- lighttpd-1.4.11/src/mod_redirect.c 2006-02-08 15:38:06.000000000 +0200
27561 +++ lighttpd-1.4.12/src/mod_redirect.c 2006-07-11 21:23:40.000000000 +0300
27562 @@ -22,35 +22,35 @@
27568 plugin_config **config_storage;
27570 - plugin_config conf;
27572 + plugin_config conf;
27575 INIT_FUNC(mod_redirect_init) {
27579 p = calloc(1, sizeof(*p));
27582 p->match_buf = buffer_init();
27583 p->location = buffer_init();
27589 FREE_FUNC(mod_redirect_free) {
27590 plugin_data *p = p_d;
27593 if (!p) return HANDLER_GO_ON;
27595 if (p->config_storage) {
27597 for (i = 0; i < srv->config_context->used; i++) {
27598 plugin_config *s = p->config_storage[i];
27601 pcre_keyvalue_buffer_free(s->redirect);
27606 free(p->config_storage);
27609 buffer_free(p->match_buf);
27610 buffer_free(p->location);
27616 return HANDLER_GO_ON;
27619 @@ -69,195 +69,137 @@
27620 plugin_data *p = p_d;
27624 - config_values_t cv[] = {
27626 + config_values_t cv[] = {
27627 { "url.redirect", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
27628 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
27632 if (!p) return HANDLER_ERROR;
27636 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
27639 for (i = 0; i < srv->config_context->used; i++) {
27643 data_array *da = (data_array *)du;
27646 s = calloc(1, sizeof(plugin_config));
27647 s->redirect = pcre_keyvalue_buffer_init();
27650 cv[0].destination = s->redirect;
27653 p->config_storage[i] = s;
27654 ca = ((data_config *)srv->config_context->data[i])->value;
27657 if (0 != config_insert_values_global(srv, ca, cv)) {
27658 return HANDLER_ERROR;
27662 if (NULL == (du = array_get_element(ca, "url.redirect"))) {
27663 /* no url.redirect defined */
27668 if (du->type != TYPE_ARRAY) {
27669 - log_error_write(srv, __FILE__, __LINE__, "sss",
27670 + log_error_write(srv, __FILE__, __LINE__, "sss",
27671 "unexpected type for key: ", "url.redirect", "array of strings");
27674 return HANDLER_ERROR;
27678 da = (data_array *)du;
27681 for (j = 0; j < da->value->used; j++) {
27682 if (da->value->data[j]->type != TYPE_STRING) {
27683 - log_error_write(srv, __FILE__, __LINE__, "sssbs",
27684 - "unexpected type for key: ",
27686 + log_error_write(srv, __FILE__, __LINE__, "sssbs",
27687 + "unexpected type for key: ",
27689 "[", da->value->data[j]->key, "](string)");
27692 return HANDLER_ERROR;
27695 - if (0 != pcre_keyvalue_buffer_append(s->redirect,
27697 + if (0 != pcre_keyvalue_buffer_append(s->redirect,
27698 ((data_string *)(da->value->data[j]))->key->ptr,
27699 ((data_string *)(da->value->data[j]))->value->ptr)) {
27701 - log_error_write(srv, __FILE__, __LINE__, "sb",
27703 + log_error_write(srv, __FILE__, __LINE__, "sb",
27704 "pcre-compile failed for", da->value->data[j]->key);
27710 return HANDLER_GO_ON;
27713 static int mod_redirect_patch_connection(server *srv, connection *con, plugin_data *p) {
27715 plugin_config *s = p->config_storage[0];
27718 p->conf.redirect = s->redirect;
27721 /* skip the first, the global context */
27722 for (i = 1; i < srv->config_context->used; i++) {
27723 data_config *dc = (data_config *)srv->config_context->data[i];
27724 s = p->config_storage[i];
27727 /* condition didn't match */
27728 if (!config_check_cond(srv, con, dc)) continue;
27732 for (j = 0; j < dc->value->used; j++) {
27733 data_unset *du = dc->value->data[j];
27736 if (0 == strcmp(du->key->ptr, "url.redirect")) {
27737 p->conf.redirect = s->redirect;
27738 p->conf.context = dc;
27747 static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_data) {
27749 plugin_data *p = p_data;
27758 * e.g. redirect /base/ to /index.php?section=base
27764 mod_redirect_patch_connection(srv, con, p);
27767 buffer_copy_string_buffer(p->match_buf, con->request.uri);
27769 - for (i = 0; i < p->conf.redirect->used; i++) {
27771 - pcre_extra *extra;
27772 - const char *pattern;
27773 - size_t pattern_len;
27775 - pcre_keyvalue *kv = p->conf.redirect->kv[i];
27780 - extra = kv->key_extra;
27781 - pattern = kv->value->ptr;
27782 - pattern_len = kv->value->used - 1;
27784 - if ((n = pcre_exec(match, extra, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
27785 - if (n != PCRE_ERROR_NOMATCH) {
27786 - log_error_write(srv, __FILE__, __LINE__, "sd",
27787 - "execution error while matching: ", n);
27788 - return HANDLER_ERROR;
27791 - const char **list;
27792 - size_t start, end;
27796 - pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list);
27798 - /* search for $[0-9] */
27800 - buffer_reset(p->location);
27802 - start = 0; end = pattern_len;
27803 - for (k = 0; k < pattern_len; k++) {
27804 - if ((pattern[k] == '$' || pattern[k] == '%') &&
27805 - isdigit((unsigned char)pattern[k + 1])) {
27808 - size_t num = pattern[k + 1] - '0';
27812 - buffer_append_string_len(p->location, pattern + start, end - start);
27814 - if (pattern[k] == '$') {
27815 - /* n is always > 0 */
27816 - if (num < (size_t)n) {
27817 - buffer_append_string(p->location, list[num]);
27820 - config_append_cond_match_buffer(con, p->conf.context, p->location, num);
27828 - buffer_append_string_len(p->location, pattern + start, pattern_len - start);
27832 - response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
27834 - con->http_status = 301;
27835 - con->file_finished = 1;
27837 - return HANDLER_FINISHED;
27839 + i = config_exec_pcre_keyvalue_buffer(con, p->conf.redirect, p->conf.context, p->match_buf, p->location);
27842 + response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
27844 + con->http_status = 301;
27845 + con->file_finished = 1;
27847 + return HANDLER_FINISHED;
27849 + else if (i != PCRE_ERROR_NOMATCH) {
27850 + log_error_write(srv, __FILE__, __LINE__, "s",
27851 + "execution error while matching", i);
27863 return HANDLER_GO_ON;
27866 @@ -265,13 +207,13 @@
27867 int mod_redirect_plugin_init(plugin *p) {
27868 p->version = LIGHTTPD_VERSION_ID;
27869 p->name = buffer_init_string("redirect");
27872 p->init = mod_redirect_init;
27873 p->handle_uri_clean = mod_redirect_uri_handler;
27874 p->set_defaults = mod_redirect_set_defaults;
27875 p->cleanup = mod_redirect_free;
27883 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_rewrite.c lighttpd-1.4.12/src/mod_rewrite.c
27884 --- lighttpd-1.4.11/src/mod_rewrite.c 2005-09-29 20:59:10.000000000 +0300
27885 +++ lighttpd-1.4.12/src/mod_rewrite.c 2006-07-11 21:23:39.000000000 +0300
27890 -#ifdef HAVE_PCRE_H
27900 - rewrite_rule **ptr;
27904 -} rewrite_rule_buffer;
27907 - rewrite_rule_buffer *rewrite;
27908 + pcre_keyvalue_buffer *rewrite;
27910 data_config *context; /* to which apply me */
27913 @@ -42,20 +26,20 @@
27919 plugin_config **config_storage;
27921 - plugin_config conf;
27923 + plugin_config conf;
27926 static handler_ctx * handler_ctx_init() {
27927 handler_ctx * hctx;
27930 hctx = calloc(1, sizeof(*hctx));
27933 hctx->state = REWRITE_STATE_UNSET;
27940 @@ -63,207 +47,136 @@
27944 -rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
27945 - rewrite_rule_buffer *kvb;
27947 - kvb = calloc(1, sizeof(*kvb));
27952 -int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
27953 -#ifdef HAVE_PCRE_H
27955 - const char *errptr;
27958 - if (!key) return -1;
27960 - if (kvb->size == 0) {
27964 - kvb->ptr = malloc(kvb->size * sizeof(*kvb->ptr));
27966 - for(i = 0; i < kvb->size; i++) {
27967 - kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
27969 - } else if (kvb->used == kvb->size) {
27972 - kvb->ptr = realloc(kvb->ptr, kvb->size * sizeof(*kvb->ptr));
27974 - for(i = kvb->used; i < kvb->size; i++) {
27975 - kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
27979 - if (NULL == (kvb->ptr[kvb->used]->key = pcre_compile(key->ptr,
27980 - 0, &errptr, &erroff, NULL))) {
27985 - kvb->ptr[kvb->used]->value = buffer_init();
27986 - buffer_copy_string_buffer(kvb->ptr[kvb->used]->value, value);
27987 - kvb->ptr[kvb->used]->once = once;
28002 -void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
28003 -#ifdef HAVE_PCRE_H
28006 - for (i = 0; i < kvb->size; i++) {
28007 - if (kvb->ptr[i]->key) pcre_free(kvb->ptr[i]->key);
28008 - if (kvb->ptr[i]->value) buffer_free(kvb->ptr[i]->value);
28009 - free(kvb->ptr[i]);
28012 - if (kvb->ptr) free(kvb->ptr);
28019 INIT_FUNC(mod_rewrite_init) {
28023 p = calloc(1, sizeof(*p));
28026 p->match_buf = buffer_init();
28032 FREE_FUNC(mod_rewrite_free) {
28033 plugin_data *p = p_d;
28038 if (!p) return HANDLER_GO_ON;
28041 buffer_free(p->match_buf);
28042 if (p->config_storage) {
28044 for (i = 0; i < srv->config_context->used; i++) {
28045 plugin_config *s = p->config_storage[i];
28046 - rewrite_rule_buffer_free(s->rewrite);
28048 + pcre_keyvalue_buffer_free(s->rewrite);
28049 + buffer_free(s->once);
28053 free(p->config_storage);
28060 return HANDLER_GO_ON;
28063 static int parse_config_entry(server *srv, plugin_config *s, array *ca, const char *option, int once) {
28067 if (NULL != (du = array_get_element(ca, option))) {
28068 data_array *da = (data_array *)du;
28072 if (du->type != TYPE_ARRAY) {
28073 - log_error_write(srv, __FILE__, __LINE__, "sss",
28074 + log_error_write(srv, __FILE__, __LINE__, "sss",
28075 "unexpected type for key: ", option, "array of strings");
28078 return HANDLER_ERROR;
28082 da = (data_array *)du;
28085 for (j = 0; j < da->value->used; j++) {
28086 if (da->value->data[j]->type != TYPE_STRING) {
28087 - log_error_write(srv, __FILE__, __LINE__, "sssbs",
28088 - "unexpected type for key: ",
28090 + log_error_write(srv, __FILE__, __LINE__, "sssbs",
28091 + "unexpected type for key: ",
28093 "[", da->value->data[j]->key, "](string)");
28096 return HANDLER_ERROR;
28099 - if (0 != rewrite_rule_buffer_append(s->rewrite,
28100 - ((data_string *)(da->value->data[j]))->key,
28101 - ((data_string *)(da->value->data[j]))->value,
28104 + if (0 != pcre_keyvalue_buffer_append(s->rewrite,
28105 + ((data_string *)(da->value->data[j]))->key->ptr,
28106 + ((data_string *)(da->value->data[j]))->value->ptr)) {
28108 - log_error_write(srv, __FILE__, __LINE__, "sb",
28109 + log_error_write(srv, __FILE__, __LINE__, "sb",
28110 "pcre-compile failed for", da->value->data[j]->key);
28112 - log_error_write(srv, __FILE__, __LINE__, "s",
28113 + log_error_write(srv, __FILE__, __LINE__, "s",
28114 "pcre support is missing, please install libpcre and the headers");
28119 + buffer_append_string_len(s->once, CONST_STR_LEN("1"));
28121 + buffer_append_string_len(s->once, CONST_STR_LEN("0"));
28130 SETDEFAULTS_FUNC(mod_rewrite_set_defaults) {
28131 plugin_data *p = p_d;
28134 - config_values_t cv[] = {
28136 + config_values_t cv[] = {
28137 { "url.rewrite-repeat", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
28138 { "url.rewrite-once", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
28140 - /* old names, still supported
28143 + /* old names, still supported
28145 * url.rewrite remapped to url.rewrite-once
28146 * url.rewrite-final is url.rewrite-once
28150 { "url.rewrite", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
28151 { "url.rewrite-final", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
28152 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
28156 if (!p) return HANDLER_ERROR;
28160 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
28163 for (i = 0; i < srv->config_context->used; i++) {
28168 s = calloc(1, sizeof(plugin_config));
28169 - s->rewrite = rewrite_rule_buffer_init();
28171 - cv[0].destination = s->rewrite;
28172 - cv[1].destination = s->rewrite;
28173 - cv[2].destination = s->rewrite;
28175 + s->rewrite = pcre_keyvalue_buffer_init();
28176 + s->once = buffer_init();
28178 p->config_storage[i] = s;
28179 ca = ((data_config *)srv->config_context->data[i])->value;
28182 if (0 != config_insert_values_global(srv, ca, cv)) {
28183 return HANDLER_ERROR;
28187 parse_config_entry(srv, s, ca, "url.rewrite-once", 1);
28188 parse_config_entry(srv, s, ca, "url.rewrite-final", 1);
28189 parse_config_entry(srv, s, ca, "url.rewrite", 1);
28190 parse_config_entry(srv, s, ca, "url.rewrite-repeat", 0);
28194 return HANDLER_GO_ON;
28197 @@ -271,157 +184,107 @@
28199 plugin_config *s = p->config_storage[0];
28200 p->conf.rewrite = s->rewrite;
28202 + p->conf.once = s->once;
28204 /* skip the first, the global context */
28205 for (i = 1; i < srv->config_context->used; i++) {
28206 data_config *dc = (data_config *)srv->config_context->data[i];
28207 s = p->config_storage[i];
28210 if (COMP_HTTP_URL == dc->comp) continue;
28213 /* condition didn't match */
28214 if (!config_check_cond(srv, con, dc)) continue;
28218 for (j = 0; j < dc->value->used; j++) {
28219 data_unset *du = dc->value->data[j];
28222 if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite"))) {
28223 p->conf.rewrite = s->rewrite;
28224 + p->conf.once = s->once;
28225 p->conf.context = dc;
28226 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-once"))) {
28227 p->conf.rewrite = s->rewrite;
28228 + p->conf.once = s->once;
28229 p->conf.context = dc;
28230 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-repeat"))) {
28231 p->conf.rewrite = s->rewrite;
28232 + p->conf.once = s->once;
28233 p->conf.context = dc;
28234 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-final"))) {
28235 p->conf.rewrite = s->rewrite;
28236 + p->conf.once = s->once;
28237 p->conf.context = dc;
28246 URIHANDLER_FUNC(mod_rewrite_con_reset) {
28247 plugin_data *p = p_d;
28253 if (con->plugin_ctx[p->id]) {
28254 handler_ctx_free(con->plugin_ctx[p->id]);
28255 con->plugin_ctx[p->id] = NULL;
28259 return HANDLER_GO_ON;
28262 URIHANDLER_FUNC(mod_rewrite_uri_handler) {
28264 plugin_data *p = p_d;
28274 * e.g. rewrite /base/ to /index.php?section=base
28280 if (con->plugin_ctx[p->id]) {
28281 hctx = con->plugin_ctx[p->id];
28284 if (hctx->loops++ > 100) {
28285 - log_error_write(srv, __FILE__, __LINE__, "s",
28286 + log_error_write(srv, __FILE__, __LINE__, "s",
28287 "ENDLESS LOOP IN rewrite-rule DETECTED ... aborting request, perhaps you want to use url.rewrite-once instead of url.rewrite-repeat");
28290 return HANDLER_ERROR;
28294 if (hctx->state == REWRITE_STATE_FINISHED) return HANDLER_GO_ON;
28298 mod_rewrite_patch_connection(srv, con, p);
28300 if (!p->conf.rewrite) return HANDLER_GO_ON;
28303 buffer_copy_string_buffer(p->match_buf, con->request.uri);
28305 - for (i = 0; i < p->conf.rewrite->used; i++) {
28307 - const char *pattern;
28308 - size_t pattern_len;
28310 - rewrite_rule *rule = p->conf.rewrite->ptr[i];
28314 - match = rule->key;
28315 - pattern = rule->value->ptr;
28316 - pattern_len = rule->value->used - 1;
28318 - if ((n = pcre_exec(match, NULL, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
28319 - if (n != PCRE_ERROR_NOMATCH) {
28320 - log_error_write(srv, __FILE__, __LINE__, "sd",
28321 - "execution error while matching: ", n);
28322 - return HANDLER_ERROR;
28325 - const char **list;
28326 - size_t start, end;
28330 - pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list);
28332 - /* search for $[0-9] */
28334 - buffer_reset(con->request.uri);
28336 - start = 0; end = pattern_len;
28337 - for (k = 0; k < pattern_len; k++) {
28338 - if ((pattern[k] == '$' || pattern[k] == '%') &&
28339 - isdigit((unsigned char)pattern[k + 1])) {
28342 - size_t num = pattern[k + 1] - '0';
28346 - buffer_append_string_len(con->request.uri, pattern + start, end - start);
28348 - if (pattern[k] == '$') {
28349 - /* n is always > 0 */
28350 - if (num < (size_t)n) {
28351 - buffer_append_string(con->request.uri, list[num]);
28354 - config_append_cond_match_buffer(con, p->conf.context, con->request.uri, num);
28362 - buffer_append_string_len(con->request.uri, pattern + start, pattern_len - start);
28366 - hctx = handler_ctx_init();
28368 - con->plugin_ctx[p->id] = hctx;
28370 - if (rule->once) hctx->state = REWRITE_STATE_FINISHED;
28372 - return HANDLER_COMEBACK;
28374 + i = config_exec_pcre_keyvalue_buffer(con, p->conf.rewrite, p->conf.context, p->match_buf, con->request.uri);
28377 + hctx = handler_ctx_init();
28379 + con->plugin_ctx[p->id] = hctx;
28381 + if (p->conf.once->ptr[i] == '1')
28382 + hctx->state = REWRITE_STATE_FINISHED;
28384 + return HANDLER_COMEBACK;
28386 + else if (i != PCRE_ERROR_NOMATCH) {
28387 + log_error_write(srv, __FILE__, __LINE__, "s",
28388 + "execution error while matching", i);
28396 @@ -434,17 +297,17 @@
28397 int mod_rewrite_plugin_init(plugin *p) {
28398 p->version = LIGHTTPD_VERSION_ID;
28399 p->name = buffer_init_string("rewrite");
28402 p->init = mod_rewrite_init;
28403 /* it has to stay _raw as we are matching on uri + querystring
28407 p->handle_uri_raw = mod_rewrite_uri_handler;
28408 p->set_defaults = mod_rewrite_set_defaults;
28409 p->cleanup = mod_rewrite_free;
28410 p->connection_reset = mod_rewrite_con_reset;
28418 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_rrdtool.c lighttpd-1.4.12/src/mod_rrdtool.c
28419 --- lighttpd-1.4.11/src/mod_rrdtool.c 2005-08-22 01:52:24.000000000 +0300
28420 +++ lighttpd-1.4.12/src/mod_rrdtool.c 2006-07-11 21:23:40.000000000 +0300
28422 #include <stdlib.h>
28424 #include <string.h>
28425 -#include <unistd.h>
28429 @@ -20,10 +19,14 @@
28430 /* no need for waitpid if we don't have fork */
28431 #include <sys/wait.h>
28434 +#include "sys-files.h"
28435 +#include "sys-process.h"
28438 buffer *path_rrdtool_bin;
28442 double requests, *requests_ptr;
28443 double bytes_written, *bytes_written_ptr;
28444 double bytes_read, *bytes_read_ptr;
28445 @@ -31,84 +34,84 @@
28455 int read_fd, write_fd;
28459 int rrdtool_running;
28462 plugin_config **config_storage;
28463 plugin_config conf;
28466 INIT_FUNC(mod_rrd_init) {
28470 p = calloc(1, sizeof(*p));
28473 p->resp = buffer_init();
28474 p->cmd = buffer_init();
28480 FREE_FUNC(mod_rrd_free) {
28481 plugin_data *p = p_d;
28485 if (!p) return HANDLER_GO_ON;
28488 if (p->config_storage) {
28489 for (i = 0; i < srv->config_context->used; i++) {
28490 plugin_config *s = p->config_storage[i];
28493 buffer_free(s->path_rrdtool_bin);
28494 buffer_free(s->path_rrd);
28500 buffer_free(p->cmd);
28501 buffer_free(p->resp);
28504 free(p->config_storage);
28507 if (p->rrdtool_pid) {
28510 close(p->write_fd);
28513 /* collect status */
28514 waitpid(p->rrdtool_pid, &status, 0);
28522 return HANDLER_GO_ON;
28525 int mod_rrd_create_pipe(server *srv, plugin_data *p) {
28529 int to_rrdtool_fds[2];
28530 int from_rrdtool_fds[2];
28533 if (pipe(to_rrdtool_fds)) {
28534 - log_error_write(srv, __FILE__, __LINE__, "ss",
28535 + log_error_write(srv, __FILE__, __LINE__, "ss",
28536 "pipe failed: ", strerror(errno));
28541 if (pipe(from_rrdtool_fds)) {
28542 - log_error_write(srv, __FILE__, __LINE__, "ss",
28543 + log_error_write(srv, __FILE__, __LINE__, "ss",
28544 "pipe failed: ", strerror(errno));
28550 switch (pid = fork()) {
28552 @@ -117,33 +120,33 @@
28558 /* move stdout to from_rrdtool_fd[1] */
28559 close(STDOUT_FILENO);
28560 dup2(from_rrdtool_fds[1], STDOUT_FILENO);
28561 close(from_rrdtool_fds[1]);
28563 close(from_rrdtool_fds[0]);
28566 /* move the stdin to to_rrdtool_fd[0] */
28567 close(STDIN_FILENO);
28568 dup2(to_rrdtool_fds[0], STDIN_FILENO);
28569 close(to_rrdtool_fds[0]);
28571 close(to_rrdtool_fds[1]);
28574 close(STDERR_FILENO);
28577 if (srv->errorlog_mode == ERRORLOG_FILE) {
28578 dup2(srv->errorlog_fd, STDERR_FILENO);
28579 close(srv->errorlog_fd);
28585 args = malloc(sizeof(*args) * argc);
28589 args[i++] = p->conf.path_rrdtool_bin->ptr;
28592 @@ -152,12 +155,12 @@
28593 for (i = 3; i < 256; i++) {
28599 execv(args[0], args);
28602 log_error_write(srv, __FILE__, __LINE__, "sss", "spawing rrdtool failed: ", strerror(errno), args[0]);
28608 @@ -168,19 +171,19 @@
28614 close(from_rrdtool_fds[1]);
28615 close(to_rrdtool_fds[0]);
28618 /* register PID and wait for them asyncronously */
28619 p->write_fd = to_rrdtool_fds[1];
28620 p->read_fd = from_rrdtool_fds[0];
28621 p->rrdtool_pid = pid;
28632 @@ -189,19 +192,19 @@
28634 static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s) {
28638 /* check if DB already exists */
28639 if (0 == stat(s->path_rrd->ptr, &st)) {
28640 /* check if it is plain file */
28641 if (!S_ISREG(st.st_mode)) {
28642 - log_error_write(srv, __FILE__, __LINE__, "sb",
28643 + log_error_write(srv, __FILE__, __LINE__, "sb",
28644 "not a regular file:", s->path_rrd);
28645 return HANDLER_ERROR;
28649 /* create a new one */
28652 BUFFER_COPY_STRING_CONST(p->cmd, "create ");
28653 buffer_append_string_buffer(p->cmd, s->path_rrd);
28654 buffer_append_string(p->cmd, " --step 60 ");
28655 @@ -220,158 +223,155 @@
28656 buffer_append_string(p->cmd, "RRA:MIN:0.5:6:700 ");
28657 buffer_append_string(p->cmd, "RRA:MIN:0.5:24:775 ");
28658 buffer_append_string(p->cmd, "RRA:MIN:0.5:288:797\n");
28661 if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
28662 - log_error_write(srv, __FILE__, __LINE__, "ss",
28663 + log_error_write(srv, __FILE__, __LINE__, "ss",
28664 "rrdtool-write: failed", strerror(errno));
28667 return HANDLER_ERROR;
28671 buffer_prepare_copy(p->resp, 4096);
28672 if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) {
28673 - log_error_write(srv, __FILE__, __LINE__, "ss",
28674 + log_error_write(srv, __FILE__, __LINE__, "ss",
28675 "rrdtool-read: failed", strerror(errno));
28678 return HANDLER_ERROR;
28685 if (p->resp->ptr[0] != 'O' ||
28686 p->resp->ptr[1] != 'K') {
28687 - log_error_write(srv, __FILE__, __LINE__, "sbb",
28688 + log_error_write(srv, __FILE__, __LINE__, "sbb",
28689 "rrdtool-response:", p->cmd, p->resp);
28692 return HANDLER_ERROR;
28697 return HANDLER_GO_ON;
28700 -#define PATCH(x) \
28701 - p->conf.x = s->x;
28702 static int mod_rrd_patch_connection(server *srv, connection *con, plugin_data *p) {
28704 plugin_config *s = p->config_storage[0];
28706 - PATCH(path_rrdtool_bin);
28710 + PATCH_OPTION(path_rrdtool_bin);
28711 + PATCH_OPTION(path_rrd);
28713 p->conf.bytes_written_ptr = &(s->bytes_written);
28714 p->conf.bytes_read_ptr = &(s->bytes_read);
28715 p->conf.requests_ptr = &(s->requests);
28718 /* skip the first, the global context */
28719 for (i = 1; i < srv->config_context->used; i++) {
28720 data_config *dc = (data_config *)srv->config_context->data[i];
28721 s = p->config_storage[i];
28724 /* condition didn't match */
28725 if (!config_check_cond(srv, con, dc)) continue;
28729 for (j = 0; j < dc->value->used; j++) {
28730 data_unset *du = dc->value->data[j];
28733 if (buffer_is_equal_string(du->key, CONST_STR_LEN("rrdtool.db-name"))) {
28735 + PATCH_OPTION(path_rrd);
28736 /* get pointers to double values */
28739 p->conf.bytes_written_ptr = &(s->bytes_written);
28740 p->conf.bytes_read_ptr = &(s->bytes_read);
28741 p->conf.requests_ptr = &(s->requests);
28751 SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
28752 plugin_data *p = p_d;
28755 - config_values_t cv[] = {
28757 + config_values_t cv[] = {
28758 { "rrdtool.binary", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },
28759 { "rrdtool.db-name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
28760 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
28764 if (!p) return HANDLER_ERROR;
28767 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
28770 for (i = 0; i < srv->config_context->used; i++) {
28774 s = calloc(1, sizeof(plugin_config));
28775 s->path_rrdtool_bin = buffer_init();
28776 s->path_rrd = buffer_init();
28778 s->bytes_written = 0;
28782 cv[0].destination = s->path_rrdtool_bin;
28783 cv[1].destination = s->path_rrd;
28786 p->config_storage[i] = s;
28789 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
28790 return HANDLER_ERROR;
28794 if (i > 0 && !buffer_is_empty(s->path_rrdtool_bin)) {
28795 /* path_rrdtool_bin is a global option */
28797 - log_error_write(srv, __FILE__, __LINE__, "s",
28799 + log_error_write(srv, __FILE__, __LINE__, "s",
28800 "rrdtool.binary can only be set as a global option.");
28803 return HANDLER_ERROR;
28810 p->conf.path_rrdtool_bin = p->config_storage[0]->path_rrdtool_bin;
28811 p->rrdtool_running = 0;
28814 /* check for dir */
28817 if (buffer_is_empty(p->conf.path_rrdtool_bin)) {
28818 - log_error_write(srv, __FILE__, __LINE__, "s",
28819 + log_error_write(srv, __FILE__, __LINE__, "s",
28820 "rrdtool.binary has to be set");
28821 return HANDLER_ERROR;
28825 /* open the pipe to rrdtool */
28826 if (mod_rrd_create_pipe(srv, p)) {
28827 return HANDLER_ERROR;
28831 p->rrdtool_running = 1;
28834 return HANDLER_GO_ON;
28837 TRIGGER_FUNC(mod_rrd_trigger) {
28838 plugin_data *p = p_d;
28842 if (!p->rrdtool_running) return HANDLER_GO_ON;
28843 if ((srv->cur_ts % 60) != 0) return HANDLER_GO_ON;
28846 for (i = 0; i < srv->config_context->used; i++) {
28847 plugin_config *s = p->config_storage[i];
28851 if (buffer_is_empty(s->path_rrd)) continue;
28854 /* write the data down every minute */
28857 if (HANDLER_GO_ON != mod_rrdtool_create_rrd(srv, p, s)) return HANDLER_ERROR;
28860 BUFFER_COPY_STRING_CONST(p->cmd, "update ");
28861 buffer_append_string_buffer(p->cmd, s->path_rrd);
28862 BUFFER_APPEND_STRING_CONST(p->cmd, " N:");
28863 @@ -381,69 +381,69 @@
28864 BUFFER_APPEND_STRING_CONST(p->cmd, ":");
28865 buffer_append_long(p->cmd, s->requests);
28866 BUFFER_APPEND_STRING_CONST(p->cmd, "\n");
28869 if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
28870 p->rrdtool_running = 0;
28872 - log_error_write(srv, __FILE__, __LINE__, "ss",
28874 + log_error_write(srv, __FILE__, __LINE__, "ss",
28875 "rrdtool-write: failed", strerror(errno));
28878 return HANDLER_ERROR;
28882 buffer_prepare_copy(p->resp, 4096);
28883 if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) {
28884 p->rrdtool_running = 0;
28886 - log_error_write(srv, __FILE__, __LINE__, "ss",
28888 + log_error_write(srv, __FILE__, __LINE__, "ss",
28889 "rrdtool-read: failed", strerror(errno));
28892 return HANDLER_ERROR;
28899 if (p->resp->ptr[0] != 'O' ||
28900 p->resp->ptr[1] != 'K') {
28901 p->rrdtool_running = 0;
28903 - log_error_write(srv, __FILE__, __LINE__, "sbb",
28905 + log_error_write(srv, __FILE__, __LINE__, "sbb",
28906 "rrdtool-response:", p->cmd, p->resp);
28909 return HANDLER_ERROR;
28912 s->bytes_written = 0;
28917 return HANDLER_GO_ON;
28920 REQUESTDONE_FUNC(mod_rrd_account) {
28921 plugin_data *p = p_d;
28924 mod_rrd_patch_connection(srv, con, p);
28927 *(p->conf.requests_ptr) += 1;
28928 *(p->conf.bytes_written_ptr) += con->bytes_written;
28929 *(p->conf.bytes_read_ptr) += con->bytes_read;
28932 return HANDLER_GO_ON;
28935 int mod_rrdtool_plugin_init(plugin *p) {
28936 p->version = LIGHTTPD_VERSION_ID;
28937 p->name = buffer_init_string("rrd");
28940 p->init = mod_rrd_init;
28941 p->cleanup = mod_rrd_free;
28942 p->set_defaults= mod_rrd_set_defaults;
28945 p->handle_trigger = mod_rrd_trigger;
28946 p->handle_request_done = mod_rrd_account;
28954 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_scgi.c lighttpd-1.4.12/src/mod_scgi.c
28955 --- lighttpd-1.4.11/src/mod_scgi.c 2006-03-04 17:15:26.000000000 +0200
28956 +++ lighttpd-1.4.12/src/mod_scgi.c 2006-07-11 21:23:40.000000000 +0300
28958 #include <sys/types.h>
28959 -#include <unistd.h>
28962 #include <string.h>
28966 #include "sys-socket.h"
28968 +#include "sys-files.h"
28969 +#include "sys-strings.h"
28970 +#include "sys-process.h"
28972 #ifndef UNIX_PATH_MAX
28973 # define UNIX_PATH_MAX 108
28974 @@ -46,30 +47,29 @@
28975 enum {EOL_UNSET, EOL_N, EOL_RN};
28983 * - add timeout for a connect to a non-scgi process
28984 * (use state_timestamp + state)
28989 typedef struct scgi_proc {
28990 size_t id; /* id will be between 1 and max_procs */
28991 buffer *socket; /* config.socket + "-" + id */
28992 unsigned port; /* config.port + pno */
28994 - pid_t pid; /* PID of the spawned process (0 if not spawned locally) */
28996 + pid_t pid; /* PID of the spawned process (0 if not spawned locally) */
28998 size_t load; /* number of requests waiting on this process */
29000 time_t last_used; /* see idle_timeout */
29001 size_t requests; /* see max_requests */
29002 struct scgi_proc *prev, *next; /* see first */
29005 time_t disable_ts; /* replace by host->something */
29010 enum { PROC_STATE_UNSET, /* init-phase */
29012 PROC_STATE_KILLED, /* was killed as we don't have the load anymore */
29013 PROC_STATE_DIED, /* marked as dead, should be restarted */
29014 PROC_STATE_DISABLED /* proc disabled as it resulted in an error */
29020 @@ -86,20 +86,20 @@
29021 * sorted by lowest load
29023 * whenever a job is done move it up in the list
29024 - * until it is sorted, move it down as soon as the
29025 + * until it is sorted, move it down as soon as the
29028 - scgi_proc *first;
29029 - scgi_proc *unused_procs;
29030 + scgi_proc *first;
29031 + scgi_proc *unused_procs;
29035 * spawn at least min_procs, at max_procs.
29037 - * as soon as the load of the first entry
29038 + * as soon as the load of the first entry
29039 * is max_load_per_proc we spawn a new one
29040 - * and add it to the first entry and give it
29041 + * and add it to the first entry and give it
29047 unsigned short min_procs;
29048 @@ -111,44 +111,44 @@
29051 * kick the process from the list if it was not
29052 - * used for idle_timeout until min_procs is
29053 + * used for idle_timeout until min_procs is
29054 * reached. this helps to get the processlist
29055 * small again we had a small peak load.
29060 unsigned short idle_timeout;
29064 * time after a disabled remote connection is tried to be re-enabled
29072 unsigned short disable_time;
29075 * same scgi processes get a little bit larger
29076 - * than wanted. max_requests_per_proc kills a
29077 + * than wanted. max_requests_per_proc kills a
29078 * process after a number of handled requests.
29081 size_t max_requests_per_proc;
29092 - * if host is one of the local IP adresses the
29093 + * if host is one of the local IP adresses the
29094 * whole connection is local
29096 * if tcp/ip should be used host AND port have
29097 - * to be specified
29101 + * to be specified
29105 unsigned short port;
29108 @@ -161,7 +161,7 @@
29110 buffer *unixsocket;
29112 - /* if socket is local we can start the scgi
29113 + /* if socket is local we can start the scgi
29116 * bin-path is the path to the binary
29117 @@ -169,19 +169,19 @@
29118 * check min_procs and max_procs for the number
29119 * of process to start-up
29121 - buffer *bin_path;
29123 - /* bin-path is set bin-environment is taken to
29124 + buffer *bin_path;
29126 + /* bin-path is set bin-environment is taken to
29127 * create the environement before starting the
29135 array *bin_env_copy;
29139 - * docroot-translation between URL->phys and the
29140 + * docroot-translation between URL->phys and the
29144 @@ -192,7 +192,7 @@
29148 - * check_local tell you if the phys file is stat()ed
29149 + * check_local tell you if the phys file is stat()ed
29150 * or not. FastCGI doesn't care if the service is
29151 * remote. If the web-server side doesn't contain
29152 * the scgi-files we should not stat() for them
29153 @@ -202,33 +202,33 @@
29156 * append PATH_INFO to SCRIPT_FILENAME
29159 * php needs this if cgi.fix_pathinfo is provied
29165 ssize_t load; /* replace by host->load */
29167 size_t max_id; /* corresponds most of the time to
29171 only if a process is killed max_id waits for the process itself
29172 to die and decrements its afterwards */
29173 } scgi_extension_host;
29176 * one extension can have multiple hosts assigned
29177 - * one host can spawn additional processes on the same
29178 + * one host can spawn additional processes on the same
29179 * socket (if we control it)
29181 * ext -> host -> procs
29184 - * if the scgi process is remote that whole goes down
29185 + * if the scgi process is remote that whole goes down
29188 * ext -> host -> procs
29192 * in case of PHP and FCGI_CHILDREN we have again a procs
29193 * but we don't control it directly.
29194 @@ -239,7 +239,7 @@
29195 buffer *key; /* like .php */
29197 scgi_extension_host **hosts;
29203 @@ -253,14 +253,14 @@
29221 @@ -268,52 +268,51 @@
29222 /* generic plugin data, shared between all connections */
29231 buffer *parse_response;
29234 plugin_config **config_storage;
29237 plugin_config conf; /* this is only used as long as no handler_ctx is setup */
29240 /* connection specific data */
29241 -typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE,
29242 - FCGI_STATE_WRITE, FCGI_STATE_READ
29243 +typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE,
29244 + FCGI_STATE_WRITE, FCGI_STATE_READ
29245 } scgi_connection_state_t;
29248 - buffer *response;
29249 + buffer *response;
29250 size_t response_len;
29252 int response_padding;
29256 scgi_extension_host *host;
29259 scgi_connection_state_t state;
29260 time_t state_timestamp;
29263 int reconnects; /* number of reconnect attempts */
29270 buffer *response_header;
29273 int delayed; /* flag to mark that the connect() is delayed */
29277 int fd; /* fd to the scgi process */
29278 int fde_ndx; /* index into the fd-event buffer */
29284 plugin_config conf;
29287 connection *remote_conn; /* dumb pointer */
29288 plugin_data *plugin_data; /* dumb pointer */
29290 @@ -328,28 +327,28 @@
29292 static handler_ctx * handler_ctx_init() {
29293 handler_ctx * hctx;
29296 hctx = calloc(1, sizeof(*hctx));
29300 hctx->fde_ndx = -1;
29303 hctx->response = buffer_init();
29304 hctx->response_header = buffer_init();
29307 hctx->request_id = 0;
29308 hctx->state = FCGI_STATE_INIT;
29312 hctx->response_len = 0;
29313 hctx->response_type = 0;
29314 hctx->response_padding = 0;
29318 hctx->reconnects = 0;
29320 hctx->wb = chunkqueue_init();
29326 @@ -358,12 +357,12 @@
29327 buffer_free(hctx->response_header);
29329 chunkqueue_free(hctx->wb);
29333 if (hctx->rb->ptr) free(hctx->rb->ptr);
29341 @@ -372,20 +371,20 @@
29343 f = calloc(1, sizeof(*f));
29344 f->socket = buffer_init();
29354 void scgi_process_free(scgi_proc *f) {
29358 scgi_process_free(f->next);
29361 buffer_free(f->socket);
29367 @@ -400,62 +399,62 @@
29368 f->bin_path = buffer_init();
29369 f->bin_env = array_init();
29370 f->bin_env_copy = array_init();
29376 void scgi_host_free(scgi_extension_host *h) {
29380 buffer_free(h->host);
29381 buffer_free(h->unixsocket);
29382 buffer_free(h->docroot);
29383 buffer_free(h->bin_path);
29384 array_free(h->bin_env);
29385 array_free(h->bin_env_copy);
29388 scgi_process_free(h->first);
29389 scgi_process_free(h->unused_procs);
29397 scgi_exts *scgi_extensions_init() {
29400 f = calloc(1, sizeof(*f));
29406 void scgi_extensions_free(scgi_exts *f) {
29413 for (i = 0; i < f->used; i++) {
29414 scgi_extension *fe;
29421 for (j = 0; j < fe->used; j++) {
29422 scgi_extension_host *h;
29432 buffer_free(fe->key);
29446 @@ -504,99 +503,103 @@
29450 - fe->hosts[fe->used++] = fh;
29451 + fe->hosts[fe->used++] = fh;
29458 INIT_FUNC(mod_scgi_init) {
29462 p = calloc(1, sizeof(*p));
29465 p->scgi_env = buffer_init();
29468 p->path = buffer_init();
29469 p->parse_response = buffer_init();
29476 FREE_FUNC(mod_scgi_free) {
29477 plugin_data *p = p_d;
29482 buffer_free(p->scgi_env);
29483 buffer_free(p->path);
29484 buffer_free(p->parse_response);
29487 if (p->config_storage) {
29489 for (i = 0; i < srv->config_context->used; i++) {
29490 plugin_config *s = p->config_storage[i];
29499 for (j = 0; j < exts->used; j++) {
29500 scgi_extension *ex;
29503 ex = exts->exts[j];
29506 for (n = 0; n < ex->used; n++) {
29508 scgi_extension_host *host;
29511 host = ex->hosts[n];
29514 for (proc = host->first; proc; proc = proc->next) {
29516 if (proc->pid != 0) kill(proc->pid, SIGTERM);
29518 - if (proc->is_local &&
29521 + if (proc->is_local &&
29522 !buffer_is_empty(proc->socket)) {
29523 unlink(proc->socket->ptr);
29528 for (proc = host->unused_procs; proc; proc = proc->next) {
29530 if (proc->pid != 0) kill(proc->pid, SIGTERM);
29532 - if (proc->is_local &&
29535 + if (proc->is_local &&
29536 !buffer_is_empty(proc->socket)) {
29537 unlink(proc->socket->ptr);
29544 scgi_extensions_free(s->exts);
29549 free(p->config_storage);
29556 return HANDLER_GO_ON;
29559 static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
29563 if (!key || !val) return -1;
29566 dst = malloc(key_len + val_len + 3);
29567 memcpy(dst, key, key_len);
29568 dst[key_len] = '=';
29569 /* add the \0 from the value */
29570 memcpy(dst + key_len + 1, val, val_len + 1);
29573 if (env->size == 0) {
29575 env->ptr = malloc(env->size * sizeof(*env->ptr));
29576 @@ -604,13 +607,13 @@
29578 env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
29582 env->ptr[env->used++] = dst;
29588 -static int scgi_spawn_connection(server *srv,
29589 +static int scgi_spawn_connection(server *srv,
29591 scgi_extension_host *host,
29593 @@ -622,31 +625,27 @@
29595 struct sockaddr_in scgi_addr_in;
29596 struct sockaddr *scgi_addr;
29607 if (p->conf.debug) {
29608 log_error_write(srv, __FILE__, __LINE__, "sdb",
29609 "new proc, socket:", proc->port, proc->socket);
29613 if (!buffer_is_empty(proc->socket)) {
29614 memset(&scgi_addr, 0, sizeof(scgi_addr));
29617 #ifdef HAVE_SYS_UN_H
29618 scgi_addr_un.sun_family = AF_UNIX;
29619 strcpy(scgi_addr_un.sun_path, proc->socket->ptr);
29623 servlen = SUN_LEN(&scgi_addr_un);
29625 - /* stevens says: */
29626 - servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
29629 socket_type = AF_UNIX;
29630 scgi_addr = (struct sockaddr *) &scgi_addr_un;
29632 @@ -656,115 +655,115 @@
29635 scgi_addr_in.sin_family = AF_INET;
29638 if (buffer_is_empty(host->host)) {
29639 scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
29641 struct hostent *he;
29644 /* set a usefull default */
29645 scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
29650 if (NULL == (he = gethostbyname(host->host->ptr))) {
29651 - log_error_write(srv, __FILE__, __LINE__,
29652 - "sdb", "gethostbyname failed: ",
29653 + log_error_write(srv, __FILE__, __LINE__,
29654 + "sdb", "gethostbyname failed: ",
29655 h_errno, host->host);
29660 if (he->h_addrtype != AF_INET) {
29661 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
29666 if (he->h_length != sizeof(struct in_addr)) {
29667 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
29672 memcpy(&(scgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
29676 scgi_addr_in.sin_port = htons(proc->port);
29677 servlen = sizeof(scgi_addr_in);
29680 socket_type = AF_INET;
29681 scgi_addr = (struct sockaddr *) &scgi_addr_in;
29685 if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
29686 - log_error_write(srv, __FILE__, __LINE__, "ss",
29687 + log_error_write(srv, __FILE__, __LINE__, "ss",
29688 "failed:", strerror(errno));
29693 if (-1 == connect(scgi_fd, scgi_addr, servlen)) {
29694 /* server is not up, spawn in */
29699 if (!buffer_is_empty(proc->socket)) {
29700 unlink(proc->socket->ptr);
29707 /* reopen socket */
29708 if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
29709 - log_error_write(srv, __FILE__, __LINE__, "ss",
29710 + log_error_write(srv, __FILE__, __LINE__, "ss",
29711 "socket failed:", strerror(errno));
29717 if (setsockopt(scgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
29718 - log_error_write(srv, __FILE__, __LINE__, "ss",
29719 + log_error_write(srv, __FILE__, __LINE__, "ss",
29720 "socketsockopt failed:", strerror(errno));
29725 /* create socket */
29726 if (-1 == bind(scgi_fd, scgi_addr, servlen)) {
29727 - log_error_write(srv, __FILE__, __LINE__, "sbds",
29728 - "bind failed for:",
29731 + log_error_write(srv, __FILE__, __LINE__, "sbds",
29732 + "bind failed for:",
29740 if (-1 == listen(scgi_fd, 1024)) {
29741 - log_error_write(srv, __FILE__, __LINE__, "ss",
29742 + log_error_write(srv, __FILE__, __LINE__, "ss",
29743 "listen failed:", strerror(errno));
29750 switch ((child = fork())) {
29760 /* create environment */
29766 /* we don't need the client socket */
29767 for (fd = 3; fd < 256; fd++) {
29768 if (fd != 2 && fd != scgi_fd) close(fd);
29772 /* build clean environment */
29773 if (host->bin_env_copy->used) {
29774 for (i = 0; i < host->bin_env_copy->used; i++) {
29775 data_string *ds = (data_string *)host->bin_env_copy->data[i];
29779 if (NULL != (ge = getenv(ds->value->ptr))) {
29780 env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge));
29782 @@ -772,44 +771,44 @@
29784 for (i = 0; environ[i]; i++) {
29788 if (NULL != (eq = strchr(environ[i], '='))) {
29789 env_add(&env, environ[i], eq - environ[i], eq+1, strlen(eq+1));
29795 /* create environment */
29796 for (i = 0; i < host->bin_env->used; i++) {
29797 data_string *ds = (data_string *)host->bin_env->data[i];
29800 env_add(&env, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
29804 for (i = 0; i < env.used; i++) {
29805 /* search for PHP_FCGI_CHILDREN */
29806 if (0 == strncmp(env.ptr[i], "PHP_FCGI_CHILDREN=", sizeof("PHP_FCGI_CHILDREN=") - 1)) break;
29810 /* not found, add a default */
29811 if (i == env.used) {
29812 env_add(&env, CONST_STR_LEN("PHP_FCGI_CHILDREN"), CONST_STR_LEN("1"));
29816 env.ptr[env.used] = NULL;
29820 buffer_copy_string(b, "exec ");
29821 buffer_append_string_buffer(b, host->bin_path);
29825 execle("/bin/sh", "sh", "-c", b->ptr, NULL, env.ptr);
29827 - log_error_write(srv, __FILE__, __LINE__, "sbs",
29829 + log_error_write(srv, __FILE__, __LINE__, "sbs",
29830 "execl failed for:", host->bin_path, strerror(errno));
29839 @@ -817,32 +816,32 @@
29846 select(0, NULL, NULL, NULL, &tv);
29849 switch (waitpid(child, &status, WNOHANG)) {
29851 /* child still running after timeout, good */
29854 /* no PID found ? should never happen */
29855 - log_error_write(srv, __FILE__, __LINE__, "ss",
29856 + log_error_write(srv, __FILE__, __LINE__, "ss",
29857 "pid not found:", strerror(errno));
29860 /* the child should not terminate at all */
29861 if (WIFEXITED(status)) {
29862 - log_error_write(srv, __FILE__, __LINE__, "sd",
29863 - "child exited (is this a SCGI binary ?):",
29864 + log_error_write(srv, __FILE__, __LINE__, "sd",
29865 + "child exited (is this a SCGI binary ?):",
29866 WEXITSTATUS(status));
29867 } else if (WIFSIGNALED(status)) {
29868 - log_error_write(srv, __FILE__, __LINE__, "sd",
29869 - "child signaled:",
29870 + log_error_write(srv, __FILE__, __LINE__, "sd",
29871 + "child signaled:",
29874 - log_error_write(srv, __FILE__, __LINE__, "sd",
29875 - "child died somehow:",
29876 + log_error_write(srv, __FILE__, __LINE__, "sd",
29877 + "child died somehow:",
29881 @@ -852,26 +851,26 @@
29883 proc->last_used = srv->cur_ts;
29884 proc->is_local = 1;
29891 proc->is_local = 0;
29895 if (p->conf.debug) {
29896 log_error_write(srv, __FILE__, __LINE__, "sb",
29897 "(debug) socket is already used, won't spawn:",
29903 proc->state = PROC_STATE_RUNNING;
29904 host->active_procs++;
29913 @@ -880,89 +879,89 @@
29914 plugin_data *p = p_d;
29918 - config_values_t cv[] = {
29920 + config_values_t cv[] = {
29921 { "scgi.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
29922 { "scgi.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
29923 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
29927 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
29930 for (i = 0; i < srv->config_context->used; i++) {
29935 s = malloc(sizeof(plugin_config));
29936 s->exts = scgi_extensions_init();
29940 cv[0].destination = s->exts;
29941 cv[1].destination = &(s->debug);
29944 p->config_storage[i] = s;
29945 ca = ((data_config *)srv->config_context->data[i])->value;
29948 if (0 != config_insert_values_global(srv, ca, cv)) {
29949 return HANDLER_ERROR;
29959 if (NULL != (du = array_get_element(ca, "scgi.server"))) {
29961 data_array *da = (data_array *)du;
29964 if (du->type != TYPE_ARRAY) {
29965 - log_error_write(srv, __FILE__, __LINE__, "sss",
29966 + log_error_write(srv, __FILE__, __LINE__, "sss",
29967 "unexpected type for key: ", "scgi.server", "array of strings");
29970 return HANDLER_ERROR;
29975 - * scgi.server = ( "<ext>" => ( ... ),
29979 + * scgi.server = ( "<ext>" => ( ... ),
29980 * "<ext>" => ( ... ) )
29984 for (j = 0; j < da->value->used; j++) {
29986 data_array *da_ext = (data_array *)da->value->data[j];
29989 if (da->value->data[j]->type != TYPE_ARRAY) {
29990 - log_error_write(srv, __FILE__, __LINE__, "sssbs",
29991 - "unexpected type for key: ", "scgi.server",
29992 + log_error_write(srv, __FILE__, __LINE__, "sssbs",
29993 + "unexpected type for key: ", "scgi.server",
29994 "[", da->value->data[j]->key, "](string)");
29997 return HANDLER_ERROR;
30001 - * da_ext->key == name of the extension
30004 + * da_ext->key == name of the extension
30008 - * scgi.server = ( "<ext>" =>
30009 - * ( "<host>" => ( ... ),
30012 + * scgi.server = ( "<ext>" =>
30013 + * ( "<host>" => ( ... ),
30014 * "<host>" => ( ... )
30021 for (n = 0; n < da_ext->value->used; n++) {
30022 data_array *da_host = (data_array *)da_ext->value->data[n];
30025 scgi_extension_host *df;
30027 - config_values_t fcv[] = {
30029 + config_values_t fcv[] = {
30030 { "host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
30031 { "docroot", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
30032 { "socket", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
30033 { "bin-path", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
30036 { "check-local", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
30037 { "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
30038 { "min-procs-not-working", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 this is broken for now */
30039 @@ -970,37 +969,37 @@
30040 { "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
30041 { "idle-timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
30042 { "disable-time", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
30045 { "bin-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
30046 { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
30051 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
30055 if (da_host->type != TYPE_ARRAY) {
30056 - log_error_write(srv, __FILE__, __LINE__, "ssSBS",
30057 - "unexpected type for key:",
30059 + log_error_write(srv, __FILE__, __LINE__, "ssSBS",
30060 + "unexpected type for key:",
30062 "[", da_host->key, "](string)");
30065 return HANDLER_ERROR;
30069 df = scgi_host_init();
30072 df->check_local = 1;
30075 df->max_load_per_proc = 1;
30076 df->idle_timeout = 60;
30077 df->disable_time = 60;
30080 fcv[0].destination = df->host;
30081 fcv[1].destination = df->docroot;
30082 fcv[2].destination = df->unixsocket;
30083 fcv[3].destination = df->bin_path;
30086 fcv[4].destination = &(df->check_local);
30087 fcv[5].destination = &(df->port);
30088 fcv[6].destination = &(df->min_procs);
30089 @@ -1008,47 +1007,47 @@
30090 fcv[8].destination = &(df->max_load_per_proc);
30091 fcv[9].destination = &(df->idle_timeout);
30092 fcv[10].destination = &(df->disable_time);
30095 fcv[11].destination = df->bin_env;
30096 fcv[12].destination = df->bin_env_copy;
30101 if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
30102 return HANDLER_ERROR;
30105 - if ((!buffer_is_empty(df->host) || df->port) &&
30107 + if ((!buffer_is_empty(df->host) || df->port) &&
30108 !buffer_is_empty(df->unixsocket)) {
30109 - log_error_write(srv, __FILE__, __LINE__, "s",
30110 + log_error_write(srv, __FILE__, __LINE__, "s",
30111 "either host+port or socket");
30114 return HANDLER_ERROR;
30118 if (!buffer_is_empty(df->unixsocket)) {
30119 /* unix domain socket */
30122 if (df->unixsocket->used > UNIX_PATH_MAX - 2) {
30123 - log_error_write(srv, __FILE__, __LINE__, "s",
30124 + log_error_write(srv, __FILE__, __LINE__, "s",
30125 "path of the unixdomain socket is too large");
30126 return HANDLER_ERROR;
30131 - if (buffer_is_empty(df->host) &&
30133 + if (buffer_is_empty(df->host) &&
30134 buffer_is_empty(df->bin_path)) {
30135 - log_error_write(srv, __FILE__, __LINE__, "sbbbs",
30136 - "missing key (string):",
30137 + log_error_write(srv, __FILE__, __LINE__, "sbbbs",
30138 + "missing key (string):",
30145 return HANDLER_ERROR;
30146 } else if (df->port == 0) {
30147 - log_error_write(srv, __FILE__, __LINE__, "sbbbs",
30148 - "missing key (short):",
30149 + log_error_write(srv, __FILE__, __LINE__, "sbbbs",
30150 + "missing key (short):",
30154 @@ -1056,14 +1055,14 @@
30155 return HANDLER_ERROR;
30159 - if (!buffer_is_empty(df->bin_path)) {
30161 + if (!buffer_is_empty(df->bin_path)) {
30162 /* a local socket + self spawning */
30166 if (df->min_procs > df->max_procs) df->max_procs = df->min_procs;
30167 if (df->max_load_per_proc < 1) df->max_load_per_proc = 0;
30171 log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
30172 "--- scgi spawning local",
30173 @@ -1073,7 +1072,7 @@
30174 "\n\tmin-procs:", df->min_procs,
30175 "\n\tmax-procs:", df->max_procs);
30179 for (pno = 0; pno < df->min_procs; pno++) {
30182 @@ -1088,7 +1087,7 @@
30183 buffer_append_string(proc->socket, "-");
30184 buffer_append_long(proc->socket, pno);
30189 log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
30190 "--- scgi spawning",
30191 @@ -1096,53 +1095,53 @@
30192 "\n\tsocket", df->unixsocket,
30193 "\n\tcurrent:", pno, "/", df->min_procs);
30197 if (scgi_spawn_connection(srv, p, df, proc)) {
30198 log_error_write(srv, __FILE__, __LINE__, "s",
30199 "[ERROR]: spawning fcgi failed.");
30200 return HANDLER_ERROR;
30204 proc->next = df->first;
30205 if (df->first) df->first->prev = proc;
30214 fp = scgi_process_init();
30215 fp->id = df->num_procs++;
30217 df->active_procs++;
30218 fp->state = PROC_STATE_RUNNING;
30221 if (buffer_is_empty(df->unixsocket)) {
30222 fp->port = df->port;
30224 buffer_copy_string_buffer(fp->socket, df->unixsocket);
30236 /* if extension already exists, take it */
30237 scgi_extension_insert(s->exts, da_ext->key, df);
30244 return HANDLER_GO_ON;
30247 static int scgi_set_state(server *srv, handler_ctx *hctx, scgi_connection_state_t state) {
30248 hctx->state = state;
30249 hctx->state_timestamp = srv->cur_ts;
30255 @@ -1150,34 +1149,34 @@
30256 void scgi_connection_cleanup(server *srv, handler_ctx *hctx) {
30261 if (NULL == hctx) return;
30264 p = hctx->plugin_data;
30265 con = hctx->remote_conn;
30268 if (con->mode != p->id) {
30274 if (hctx->fd != -1) {
30275 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
30276 fdevent_unregister(srv->ev, hctx->fd);
30282 if (hctx->host && hctx->proc) {
30283 hctx->host->load--;
30286 if (hctx->got_proc) {
30287 /* after the connect the process gets a load */
30288 hctx->proc->load--;
30291 if (p->conf.debug) {
30292 log_error_write(srv, __FILE__, __LINE__, "sddb",
30296 hctx->proc->pid, hctx->proc->socket);
30298 @@ -1186,87 +1185,87 @@
30299 scgi_proclist_sort_down(srv, hctx->host, hctx->proc);
30304 handler_ctx_free(hctx);
30305 - con->plugin_ctx[p->id] = NULL;
30306 + con->plugin_ctx[p->id] = NULL;
30309 static int scgi_reconnect(server *srv, handler_ctx *hctx) {
30310 plugin_data *p = hctx->plugin_data;
30321 * connect was ok, connection was accepted
30322 * but the php accept loop checks after the accept if it should die or not.
30324 - * if yes we can only detect it at a write()
30327 + * if yes we can only detect it at a write()
30329 * next step is resetting this attemp and setup a connection again
30332 * if we have more then 5 reconnects for the same request, die
30339 * we have a connection but the child died by some other reason
30345 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
30346 fdevent_unregister(srv->ev, hctx->fd);
30351 scgi_set_state(srv, hctx, FCGI_STATE_INIT);
30354 hctx->request_id = 0;
30355 hctx->reconnects++;
30358 if (p->conf.debug) {
30359 log_error_write(srv, __FILE__, __LINE__, "sddb",
30363 hctx->proc->pid, hctx->proc->socket);
30367 hctx->proc->load--;
30368 scgi_proclist_sort_down(srv, hctx->host, hctx->proc);
30375 static handler_t scgi_connection_reset(server *srv, connection *con, void *p_d) {
30376 plugin_data *p = p_d;
30379 scgi_connection_cleanup(srv, con->plugin_ctx[p->id]);
30382 return HANDLER_GO_ON;
30386 static int scgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) {
30390 if (!key || !val) return -1;
30393 len = key_len + val_len + 2;
30396 buffer_prepare_append(env, len);
30398 - /* include the NUL */
30399 + /* include the NUL */
30400 memcpy(env->ptr + env->used, key, key_len + 1);
30401 env->used += key_len + 1;
30402 memcpy(env->ptr + env->used, val, val_len + 1);
30403 env->used += val_len + 1;
30416 @@ -1280,24 +1279,21 @@
30417 struct sockaddr_un scgi_addr_un;
30422 scgi_extension_host *host = hctx->host;
30423 scgi_proc *proc = hctx->proc;
30424 int scgi_fd = hctx->fd;
30427 memset(&scgi_addr, 0, sizeof(scgi_addr));
30430 if (!buffer_is_empty(proc->socket)) {
30431 #ifdef HAVE_SYS_UN_H
30432 /* use the unix domain socket */
30433 scgi_addr_un.sun_family = AF_UNIX;
30434 strcpy(scgi_addr_un.sun_path, proc->socket->ptr);
30437 servlen = SUN_LEN(&scgi_addr_un);
30439 - /* stevens says: */
30440 - servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
30443 scgi_addr = (struct sockaddr *) &scgi_addr_un;
30446 @@ -1305,105 +1301,105 @@
30448 scgi_addr_in.sin_family = AF_INET;
30449 if (0 == inet_aton(host->host->ptr, &(scgi_addr_in.sin_addr))) {
30450 - log_error_write(srv, __FILE__, __LINE__, "sbs",
30451 - "converting IP-adress failed for", host->host,
30452 + log_error_write(srv, __FILE__, __LINE__, "sbs",
30453 + "converting IP-adress failed for", host->host,
30454 "\nBe sure to specify an IP address here");
30459 scgi_addr_in.sin_port = htons(proc->port);
30460 servlen = sizeof(scgi_addr_in);
30463 scgi_addr = (struct sockaddr *) &scgi_addr_in;
30467 if (-1 == connect(scgi_fd, scgi_addr, servlen)) {
30468 - if (errno == EINPROGRESS ||
30469 + if (errno == EINPROGRESS ||
30470 errno == EALREADY ||
30472 if (hctx->conf.debug) {
30473 - log_error_write(srv, __FILE__, __LINE__, "sd",
30474 + log_error_write(srv, __FILE__, __LINE__, "sd",
30475 "connect delayed, will continue later:", scgi_fd);
30481 - log_error_write(srv, __FILE__, __LINE__, "sdsddb",
30482 - "connect failed:", scgi_fd,
30483 + log_error_write(srv, __FILE__, __LINE__, "sdsddb",
30484 + "connect failed:", scgi_fd,
30485 strerror(errno), errno,
30486 proc->port, proc->socket);
30488 if (errno == EAGAIN) {
30489 /* this is Linux only */
30491 - log_error_write(srv, __FILE__, __LINE__, "s",
30493 + log_error_write(srv, __FILE__, __LINE__, "s",
30494 "If this happend on Linux: You have been run out of local ports. "
30495 "Check the manual, section Performance how to handle this.");
30503 if (hctx->conf.debug > 1) {
30504 - log_error_write(srv, __FILE__, __LINE__, "sd",
30505 + log_error_write(srv, __FILE__, __LINE__, "sd",
30506 "connect succeeded: ", scgi_fd);
30515 static int scgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
30519 for (i = 0; i < con->request.headers->used; i++) {
30523 ds = (data_string *)con->request.headers->data[i];
30526 if (ds->value->used && ds->key->used) {
30528 buffer_reset(srv->tmp_buf);
30531 if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
30532 BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_");
30533 srv->tmp_buf->used--;
30537 buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
30538 for (j = 0; j < ds->key->used - 1; j++) {
30539 - srv->tmp_buf->ptr[srv->tmp_buf->used++] =
30540 - light_isalpha(ds->key->ptr[j]) ?
30541 + srv->tmp_buf->ptr[srv->tmp_buf->used++] =
30542 + light_isalpha(ds->key->ptr[j]) ?
30543 ds->key->ptr[j] & ~32 : '_';
30545 srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
30548 scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
30553 for (i = 0; i < con->environment->used; i++) {
30557 ds = (data_string *)con->environment->data[i];
30560 if (ds->value->used && ds->key->used) {
30562 buffer_reset(srv->tmp_buf);
30565 buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
30566 for (j = 0; j < ds->key->used - 1; j++) {
30567 - srv->tmp_buf->ptr[srv->tmp_buf->used++] =
30568 - isalpha((unsigned char)ds->key->ptr[j]) ?
30569 + srv->tmp_buf->ptr[srv->tmp_buf->used++] =
30570 + isalpha((unsigned char)ds->key->ptr[j]) ?
30571 toupper((unsigned char)ds->key->ptr[j]) : '_';
30573 srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
30576 scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
30584 @@ -1415,20 +1411,20 @@
30585 char b2[INET6_ADDRSTRLEN + 1];
30590 plugin_data *p = hctx->plugin_data;
30591 scgi_extension_host *host= hctx->host;
30593 connection *con = hctx->remote_conn;
30594 server_socket *srv_sock = con->srv_socket;
30597 sock_addr our_addr;
30598 socklen_t our_addr_len;
30601 buffer_prepare_copy(p->scgi_env, 1024);
30603 /* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */
30606 /* request.content_length < SSIZE_MAX, see request.c */
30607 ltostr(buf, con->request.content_length);
30608 scgi_env_add(p->scgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
30609 @@ -1436,13 +1432,13 @@
30612 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
30615 if (con->server_name->used) {
30616 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
30619 - s = inet_ntop(srv_sock->addr.plain.sa_family,
30620 - srv_sock->addr.plain.sa_family == AF_INET6 ?
30621 + s = inet_ntop(srv_sock->addr.plain.sa_family,
30622 + srv_sock->addr.plain.sa_family == AF_INET6 ?
30623 (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
30624 (const void *) &(srv_sock->addr.ipv4.sin_addr),
30626 @@ -1451,47 +1447,47 @@
30628 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
30632 scgi_env_add(p->scgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
30638 ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
30640 ntohs(srv_sock->addr.ipv4.sin_port)
30645 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
30648 /* get the server-side of the connection to the client */
30649 our_addr_len = sizeof(our_addr);
30652 if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
30653 s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
30655 s = inet_ntop_cache_get_ip(srv, &(our_addr));
30657 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
30663 ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
30665 ntohs(con->dst_addr.ipv4.sin_port)
30670 scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
30673 s = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
30674 scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
30677 if (!buffer_is_empty(con->authed_user)) {
30678 scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_USER"),
30679 CONST_BUF_LEN(con->authed_user));
30685 * SCRIPT_NAME, PATH_INFO and PATH_TRANSLATED according to
30686 @@ -1500,12 +1496,12 @@
30689 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
30692 if (!buffer_is_empty(con->request.pathinfo)) {
30693 scgi_env_add(p->scgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
30696 /* PATH_TRANSLATED is only defined if PATH_INFO is set */
30699 if (!buffer_is_empty(host->docroot)) {
30700 buffer_copy_string_buffer(p->path, host->docroot);
30702 @@ -1526,19 +1522,19 @@
30705 if (!buffer_is_empty(host->docroot)) {
30707 - * rewrite SCRIPT_FILENAME
30710 + * rewrite SCRIPT_FILENAME
30715 buffer_copy_string_buffer(p->path, host->docroot);
30716 buffer_append_string_buffer(p->path, con->uri.path);
30719 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
30720 scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot));
30722 buffer_copy_string_buffer(p->path, con->physical.path);
30725 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
30726 scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
30728 @@ -1551,30 +1547,30 @@
30730 scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
30734 s = get_http_method_name(con->request.http_method);
30735 scgi_env_add(p->scgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
30736 scgi_env_add(p->scgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */
30737 s = get_http_version_name(con->request.http_version);
30738 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
30742 if (srv_sock->is_ssl) {
30743 scgi_env_add(p->scgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
30748 scgi_env_add_request_headers(srv, con, p);
30750 b = chunkqueue_get_append_buffer(hctx->wb);
30753 buffer_append_long(b, p->scgi_env->used);
30754 buffer_append_string_len(b, CONST_STR_LEN(":"));
30755 buffer_append_string_len(b, (const char *)p->scgi_env->ptr, p->scgi_env->used);
30756 buffer_append_string_len(b, CONST_STR_LEN(","));
30758 hctx->wb->bytes_in += b->used - 1;
30761 if (con->request.content_length) {
30762 chunkqueue *req_cq = con->request_content_queue;
30764 @@ -1587,7 +1583,7 @@
30766 /* we announce toWrite octects
30767 * now take all the request_content chunk that we need to fill this request
30771 switch (req_c->type) {
30773 @@ -1615,32 +1611,32 @@
30775 req_c->offset += weHave;
30776 req_cq->bytes_out += weHave;
30779 hctx->wb->bytes_in += weHave;
30793 for (i = 0; i < hctx->write_buffer->used; i++) {
30794 fprintf(stderr, "%02x ", hctx->write_buffer->ptr[i]);
30795 if ((i+1) % 16 == 0) {
30797 for (j = i-15; j <= i; j++) {
30798 - fprintf(stderr, "%c",
30799 + fprintf(stderr, "%c",
30800 isprint((unsigned char)hctx->write_buffer->ptr[j]) ? hctx->write_buffer->ptr[j] : '.');
30802 fprintf(stderr, "\n");
30811 @@ -1648,32 +1644,32 @@
30820 buffer_copy_string_buffer(p->parse_response, in);
30822 - for (s = p->parse_response->ptr;
30823 - NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
30825 + for (s = p->parse_response->ptr;
30826 + NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
30827 s = ns + (eol == EOL_RN ? 2 : 1), line++) {
30828 const char *key, *value;
30838 0 == strncmp(s, "HTTP/1.", 7)) {
30839 /* non-parsed header ... we parse them anyway */
30842 if ((s[7] == '1' ||
30846 /* after the space should be a status code for us */
30849 status = strtol(s+9, NULL, 10);
30852 if (con->http_status >= 100 &&
30853 con->http_status < 1000) {
30854 /* we expected 3 digits and didn't got them */
30855 @@ -1682,27 +1678,27 @@
30862 if (NULL == (value = strchr(s, ':'))) {
30863 /* we expect: "<key>: <value>\r\n" */
30868 key_len = value - key;
30873 while (*value == ' ' || *value == '\t') value++;
30876 if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
30877 ds = data_response_init();
30879 buffer_copy_string_len(ds->key, key, key_len);
30880 buffer_copy_string(ds->value, value);
30883 array_insert_unique(con->response.headers, (data_unset *)ds);
30888 if (0 == strncasecmp(key, "Date", key_len)) {
30889 @@ -1737,13 +1733,13 @@
30895 /* CGI/1.1 rev 03 - 7.2.1.2 */
30896 if ((con->parsed_response & HTTP_LOCATION) &&
30897 !(con->parsed_response & HTTP_STATUS)) {
30898 con->http_status = 302;
30905 @@ -1751,10 +1747,10 @@
30906 static int scgi_demux_response(server *srv, handler_ctx *hctx) {
30907 plugin_data *p = hctx->plugin_data;
30908 connection *con = hctx->remote_conn;
30915 buffer_prepare_copy(hctx->response, 1024);
30916 if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
30917 if (errno == EAGAIN || errno == EINTR) {
30918 @@ -1765,143 +1761,143 @@
30919 log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
30925 /* read finished */
30928 con->file_finished = 1;
30931 /* send final chunk */
30932 http_chunk_append_mem(srv, con, NULL, 0);
30933 joblist_append(srv, con);
30940 hctx->response->ptr[n] = '\0';
30941 hctx->response->used = n+1;
30944 /* split header from body */
30947 if (con->file_started == 0) {
30950 int header_end = 0;
30951 int cp, eol = EOL_UNSET;
30955 buffer_append_string_buffer(hctx->response_header, hctx->response);
30958 /* nph (non-parsed headers) */
30959 if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
30962 /* search for the \r\n\r\n or \n\n in the string */
30963 for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
30964 if (*c == ':') in_header = 1;
30965 else if (*c == '\n') {
30966 if (in_header == 0) {
30967 /* got a response without a response header */
30976 if (eol == EOL_UNSET) eol = EOL_N;
30979 if (*(c+1) == '\n') {
30985 } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
30986 if (in_header == 0) {
30987 /* got a response without a response header */
30996 if (eol == EOL_UNSET) eol = EOL_RN;
31000 - *(c+2) == '\r' &&
31001 + *(c+2) == '\r' &&
31018 /* no header, but a body */
31021 if (con->request.http_version == HTTP_VERSION_1_1) {
31022 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
31026 http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
31027 joblist_append(srv, con);
31029 size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
31030 size_t blen = hctx->response_header->used - hlen - 1;
31033 /* a small hack: terminate after at the second \r */
31034 hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
31035 hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
31038 /* parse the response header */
31039 scgi_response_parse(srv, con, p, hctx->response_header, eol);
31042 /* enable chunked-transfer-encoding */
31043 if (con->request.http_version == HTTP_VERSION_1_1 &&
31044 !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
31045 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
31049 if ((hctx->response->used != hlen) && blen > 0) {
31050 http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
31051 joblist_append(srv, con);
31056 con->file_started = 1;
31059 http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
31060 joblist_append(srv, con);
31066 log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
31075 int scgi_proclist_sort_up(server *srv, scgi_extension_host *host, scgi_proc *proc) {
31081 - /* we have been the smallest of the current list
31082 - * and we want to insert the node sorted as soon
31084 + /* we have been the smallest of the current list
31085 + * and we want to insert the node sorted as soon
31098 /* nothing to sort, only one element */
31099 @@ -1909,9 +1905,9 @@
31101 for (p = proc; p->next && p->next->load < proc->load; p = p->next);
31103 - /* no need to move something
31104 + /* no need to move something
31111 @@ -1930,16 +1926,16 @@
31113 if (proc->prev) proc->prev->next = proc->next;
31114 if (proc->next) proc->next->prev = proc->prev;
31117 /* proc should be right of p */
31120 proc->next = p->next;
31122 if (p->next) p->next->prev = proc;
31125 for(p = host->first; p; p = p->next) {
31126 - log_error_write(srv, __FILE__, __LINE__, "dd",
31127 + log_error_write(srv, __FILE__, __LINE__, "dd",
31131 @@ -1951,21 +1947,21 @@
31133 int scgi_proclist_sort_down(server *srv, scgi_extension_host *host, scgi_proc *proc) {
31139 - /* we have been the smallest of the current list
31140 - * and we want to insert the node sorted as soon
31142 + /* we have been the smallest of the current list
31143 + * and we want to insert the node sorted as soon
31153 * the basic is idea is:
31154 - * - the last active scgi process should be still
31155 + * - the last active scgi process should be still
31156 * in ram and is not swapped out yet
31157 * - processes that are not reused will be killed
31158 * after some time by the trigger-handler
31159 @@ -1975,7 +1971,7 @@
31160 * ice-cold processes are propably unused since more
31161 * than 'unused-timeout', are swaped out and won't be
31162 * reused in the next seconds anyway.
31167 /* nothing to sort, only one element */
31168 @@ -1984,16 +1980,16 @@
31169 for (p = host->first; p != proc && p->load < proc->load; p = p->next);
31172 - /* no need to move something
31173 + /* no need to move something
31182 if (p == proc) return 0;
31185 /* we have to move left. If we are already the first element
31187 if (host->first == proc) return 0;
31188 @@ -2009,9 +2005,9 @@
31191 if (proc->prev == NULL) host->first = proc;
31194 for(p = host->first; p; p = p->next) {
31195 - log_error_write(srv, __FILE__, __LINE__, "dd",
31196 + log_error_write(srv, __FILE__, __LINE__, "dd",
31200 @@ -2023,41 +2019,42 @@
31202 static int scgi_restart_dead_procs(server *srv, plugin_data *p, scgi_extension_host *host) {
31206 for (proc = host->first; proc; proc = proc->next) {
31207 if (p->conf.debug) {
31208 - log_error_write(srv, __FILE__, __LINE__, "sbdbdddd",
31210 - host->host, proc->port,
31211 + log_error_write(srv, __FILE__, __LINE__, "sbdbdddd",
31213 + host->host, proc->port,
31222 if (0 == proc->is_local) {
31224 - * external servers might get disabled
31226 - * enable the server again, perhaps it is back again
31228 + * external servers might get disabled
31230 + * enable the server again, perhaps it is back again
31234 if ((proc->state == PROC_STATE_DISABLED) &&
31235 (srv->cur_ts - proc->disable_ts > host->disable_time)) {
31236 proc->state = PROC_STATE_RUNNING;
31237 host->active_procs++;
31239 - log_error_write(srv, __FILE__, __LINE__, "sbdb",
31240 - "fcgi-server re-enabled:",
31241 - host->host, host->port,
31243 + log_error_write(srv, __FILE__, __LINE__, "sbdb",
31244 + "fcgi-server re-enabled:",
31245 + host->host, host->port,
31249 /* the child should not terminate at all */
31253 if (proc->state == PROC_STATE_DIED_WAIT_FOR_PID) {
31255 switch(waitpid(proc->pid, &status, WNOHANG)) {
31257 /* child is still alive */
31258 @@ -2067,33 +2064,34 @@
31260 if (WIFEXITED(status)) {
31262 - log_error_write(srv, __FILE__, __LINE__, "sdsd",
31263 + log_error_write(srv, __FILE__, __LINE__, "sdsd",
31264 "child exited, pid:", proc->pid,
31265 "status:", WEXITSTATUS(status));
31267 } else if (WIFSIGNALED(status)) {
31268 - log_error_write(srv, __FILE__, __LINE__, "sd",
31269 - "child signaled:",
31270 + log_error_write(srv, __FILE__, __LINE__, "sd",
31271 + "child signaled:",
31274 - log_error_write(srv, __FILE__, __LINE__, "sd",
31275 - "child died somehow:",
31276 + log_error_write(srv, __FILE__, __LINE__, "sd",
31277 + "child died somehow:",
31282 proc->state = PROC_STATE_DIED;
31291 * local servers might died, but we restart them
31295 if (proc->state == PROC_STATE_DIED &&
31297 /* restart the child */
31300 if (p->conf.debug) {
31301 log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
31302 "--- scgi spawning",
31303 @@ -2101,18 +2099,18 @@
31304 "\n\tsocket", host->unixsocket,
31305 "\n\tcurrent:", 1, "/", host->min_procs);
31309 if (scgi_spawn_connection(srv, p, host, proc)) {
31310 log_error_write(srv, __FILE__, __LINE__, "s",
31311 "ERROR: spawning fcgi failed.");
31312 return HANDLER_ERROR;
31316 scgi_proclist_sort_down(srv, host, proc);
31325 @@ -2121,13 +2119,13 @@
31326 plugin_data *p = hctx->plugin_data;
31327 scgi_extension_host *host= hctx->host;
31328 connection *con = hctx->remote_conn;
31333 - /* sanity check */
31334 + /* sanity check */
31336 ((!host->host->used || !host->port) && !host->unixsocket->used)) {
31337 - log_error_write(srv, __FILE__, __LINE__, "sxddd",
31338 + log_error_write(srv, __FILE__, __LINE__, "sxddd",
31339 "write-req: error",
31342 @@ -2135,179 +2133,180 @@
31343 host->unixsocket->used);
31344 return HANDLER_ERROR;
31349 switch(hctx->state) {
31350 case FCGI_STATE_INIT:
31351 ret = host->unixsocket->used ? AF_UNIX : AF_INET;
31354 if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
31355 if (errno == EMFILE ||
31357 - log_error_write(srv, __FILE__, __LINE__, "sd",
31358 + log_error_write(srv, __FILE__, __LINE__, "sd",
31359 "wait for fd at connection:", con->fd);
31362 return HANDLER_WAIT_FOR_FD;
31365 - log_error_write(srv, __FILE__, __LINE__, "ssdd",
31367 + log_error_write(srv, __FILE__, __LINE__, "ssdd",
31368 "socket failed:", strerror(errno), srv->cur_fds, srv->max_fds);
31369 return HANDLER_ERROR;
31371 hctx->fde_ndx = -1;
31377 fdevent_register(srv->ev, hctx->fd, scgi_handle_fdevent, hctx);
31380 if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
31381 - log_error_write(srv, __FILE__, __LINE__, "ss",
31382 + log_error_write(srv, __FILE__, __LINE__, "ss",
31383 "fcntl failed: ", strerror(errno));
31386 return HANDLER_ERROR;
31391 case FCGI_STATE_CONNECT:
31392 if (hctx->state == FCGI_STATE_INIT) {
31393 - for (hctx->proc = hctx->host->first;
31394 - hctx->proc && hctx->proc->state != PROC_STATE_RUNNING;
31395 + for (hctx->proc = hctx->host->first;
31396 + hctx->proc && hctx->proc->state != PROC_STATE_RUNNING;
31397 hctx->proc = hctx->proc->next);
31400 /* all childs are dead */
31401 if (hctx->proc == NULL) {
31402 hctx->fde_ndx = -1;
31405 return HANDLER_ERROR;
31409 if (hctx->proc->is_local) {
31410 hctx->pid = hctx->proc->pid;
31414 switch (scgi_establish_connection(srv, hctx)) {
31416 scgi_set_state(srv, hctx, FCGI_STATE_CONNECT);
31419 /* connection is in progress, wait for an event and call getsockopt() below */
31422 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
31425 return HANDLER_WAIT_FOR_EVENT;
31427 /* if ECONNREFUSED choose another connection -> FIXME */
31428 hctx->fde_ndx = -1;
31431 return HANDLER_ERROR;
31433 /* everything is ok, go on */
31441 socklen_t socket_error_len = sizeof(socket_error);
31444 /* try to finish the connect() */
31445 if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
31446 - log_error_write(srv, __FILE__, __LINE__, "ss",
31447 + log_error_write(srv, __FILE__, __LINE__, "ss",
31448 "getsockopt failed:", strerror(errno));
31451 return HANDLER_ERROR;
31453 if (socket_error != 0) {
31454 if (!hctx->proc->is_local || p->conf.debug) {
31455 /* local procs get restarted */
31458 log_error_write(srv, __FILE__, __LINE__, "ss",
31459 - "establishing connection failed:", strerror(socket_error),
31460 + "establishing connection failed:", strerror(socket_error),
31461 "port:", hctx->proc->port);
31465 return HANDLER_ERROR;
31470 /* ok, we have the connection */
31473 hctx->proc->load++;
31474 hctx->proc->last_used = srv->cur_ts;
31475 hctx->got_proc = 1;
31478 if (p->conf.debug) {
31479 log_error_write(srv, __FILE__, __LINE__, "sddbdd",
31484 - hctx->proc->socket,
31486 + hctx->proc->socket,
31491 /* move the proc-list entry down the list */
31492 scgi_proclist_sort_up(srv, hctx->host, hctx->proc);
31495 scgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
31497 case FCGI_STATE_PREPARE_WRITE:
31498 scgi_create_env(srv, hctx);
31501 scgi_set_state(srv, hctx, FCGI_STATE_WRITE);
31505 case FCGI_STATE_WRITE:
31506 - ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
31507 + ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
31509 chunkqueue_remove_finished_chunks(hctx->wb);
31513 if (errno == ENOTCONN) {
31514 - /* the connection got dropped after accept()
31516 - * this is most of the time a PHP which dies
31517 + /* the connection got dropped after accept()
31519 + * this is most of the time a PHP which dies
31520 * after PHP_FCGI_MAX_REQUESTS
31525 if (hctx->wb->bytes_out == 0 &&
31526 hctx->reconnects < 5) {
31527 - usleep(10000); /* take away the load of the webserver
31528 - * to let the php a chance to restart
31530 + usleep(10000); /* take away the load of the webserver
31531 + * to let the php a chance to restart
31535 scgi_reconnect(srv, hctx);
31538 return HANDLER_WAIT_FOR_FD;
31542 /* not reconnected ... why
31545 * far@#lighttpd report this for FreeBSD
31550 - log_error_write(srv, __FILE__, __LINE__, "ssdsd",
31552 + log_error_write(srv, __FILE__, __LINE__, "ssosd",
31553 "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
31554 "write-offset:", hctx->wb->bytes_out,
31555 "reconnect attempts:", hctx->reconnects);
31558 return HANDLER_ERROR;
31562 if ((errno != EAGAIN) &&
31563 (errno != EINTR)) {
31565 - log_error_write(srv, __FILE__, __LINE__, "ssd",
31567 + log_error_write(srv, __FILE__, __LINE__, "ssd",
31568 "write failed:", strerror(errno), errno);
31571 return HANDLER_ERROR;
31573 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
31576 return HANDLER_WAIT_FOR_EVENT;
31581 if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
31582 /* we don't need the out event anymore */
31583 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
31584 @@ -2315,10 +2314,10 @@
31585 scgi_set_state(srv, hctx, FCGI_STATE_READ);
31587 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
31590 return HANDLER_WAIT_FOR_EVENT;
31595 case FCGI_STATE_READ:
31596 /* waiting for a response */
31597 @@ -2327,67 +2326,67 @@
31598 log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
31599 return HANDLER_ERROR;
31603 return HANDLER_WAIT_FOR_EVENT;
31606 SUBREQUEST_FUNC(mod_scgi_handle_subrequest) {
31607 plugin_data *p = p_d;
31610 handler_ctx *hctx = con->plugin_ctx[p->id];
31612 scgi_extension_host *host;
31615 if (NULL == hctx) return HANDLER_GO_ON;
31619 if (con->mode != p->id) return HANDLER_GO_ON;
31622 /* ok, create the request */
31623 switch(scgi_write_request(srv, hctx)) {
31624 case HANDLER_ERROR:
31631 0 == proc->is_local &&
31632 proc->state != PROC_STATE_DISABLED) {
31633 /* only disable remote servers as we don't manage them*/
31635 - log_error_write(srv, __FILE__, __LINE__, "sbdb", "fcgi-server disabled:",
31637 + log_error_write(srv, __FILE__, __LINE__, "sbdb", "fcgi-server disabled:",
31643 /* disable this server */
31644 proc->disable_ts = srv->cur_ts;
31645 proc->state = PROC_STATE_DISABLED;
31646 host->active_procs--;
31650 if (hctx->state == FCGI_STATE_INIT ||
31651 hctx->state == FCGI_STATE_CONNECT) {
31652 - /* connect() or getsockopt() failed,
31653 - * restart the request-handling
31654 + /* connect() or getsockopt() failed,
31655 + * restart the request-handling
31657 if (proc && proc->is_local) {
31659 if (p->conf.debug) {
31660 - log_error_write(srv, __FILE__, __LINE__, "sbdb", "connect() to scgi failed, restarting the request-handling:",
31661 + log_error_write(srv, __FILE__, __LINE__, "sbdb", "connect() to scgi failed, restarting the request-handling:",
31669 * several hctx might reference the same proc
31672 * Only one of them should mark the proc as dead all the other
31673 * ones should just take a new one.
31676 * If a new proc was started with the old struct this might lead
31677 * the mark a perfect proc as dead otherwise
31681 if (proc->state == PROC_STATE_RUNNING &&
31682 hctx->pid == proc->pid) {
31683 @@ -2395,25 +2394,25 @@
31686 scgi_restart_dead_procs(srv, p, host);
31689 scgi_connection_cleanup(srv, hctx);
31692 buffer_reset(con->physical.path);
31693 con->mode = DIRECT;
31694 joblist_append(srv, con);
31696 - /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
31697 - * and hope that the childs will be restarted
31700 + /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
31701 + * and hope that the childs will be restarted
31704 return HANDLER_WAIT_FOR_FD;
31706 scgi_connection_cleanup(srv, hctx);
31709 buffer_reset(con->physical.path);
31710 con->mode = DIRECT;
31711 con->http_status = 503;
31714 return HANDLER_FINISHED;
31716 case HANDLER_WAIT_FOR_EVENT:
31717 @@ -2433,23 +2432,23 @@
31718 static handler_t scgi_connection_close(server *srv, handler_ctx *hctx) {
31723 if (NULL == hctx) return HANDLER_GO_ON;
31726 p = hctx->plugin_data;
31727 con = hctx->remote_conn;
31730 if (con->mode != p->id) return HANDLER_GO_ON;
31732 - log_error_write(srv, __FILE__, __LINE__, "ssdsd",
31733 - "emergency exit: scgi:",
31735 + log_error_write(srv, __FILE__, __LINE__, "ssdsd",
31736 + "emergency exit: scgi:",
31737 "connection-fd:", con->fd,
31738 "fcgi-fd:", hctx->fd);
31745 scgi_connection_cleanup(srv, hctx);
31748 return HANDLER_FINISHED;
31751 @@ -2459,7 +2458,7 @@
31752 handler_ctx *hctx = ctx;
31753 connection *con = hctx->remote_conn;
31754 plugin_data *p = hctx->plugin_data;
31757 scgi_proc *proc = hctx->proc;
31758 scgi_extension_host *host= hctx->host;
31760 @@ -2471,15 +2470,15 @@
31763 scgi_connection_cleanup(srv, hctx);
31766 joblist_append(srv, con);
31767 return HANDLER_FINISHED;
31769 if (proc->pid && proc->state != PROC_STATE_DIED) {
31773 /* only fetch the zombie if it is not already done */
31776 switch(waitpid(proc->pid, &status, WNOHANG)) {
31778 /* child is still alive */
31779 @@ -2489,19 +2488,19 @@
31781 /* the child should not terminate at all */
31782 if (WIFEXITED(status)) {
31783 - log_error_write(srv, __FILE__, __LINE__, "sdsd",
31784 + log_error_write(srv, __FILE__, __LINE__, "sdsd",
31785 "child exited, pid:", proc->pid,
31786 "status:", WEXITSTATUS(status));
31787 } else if (WIFSIGNALED(status)) {
31788 - log_error_write(srv, __FILE__, __LINE__, "sd",
31789 - "child signaled:",
31790 + log_error_write(srv, __FILE__, __LINE__, "sd",
31791 + "child signaled:",
31794 - log_error_write(srv, __FILE__, __LINE__, "sd",
31795 - "child died somehow:",
31796 + log_error_write(srv, __FILE__, __LINE__, "sd",
31797 + "child died somehow:",
31802 if (p->conf.debug) {
31803 log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
31804 "--- scgi spawning",
31805 @@ -2509,40 +2508,41 @@
31806 "\n\tsocket", host->unixsocket,
31807 "\n\tcurrent:", 1, "/", host->min_procs);
31811 if (scgi_spawn_connection(srv, p, host, proc)) {
31813 proc->state = PROC_STATE_DIED;
31815 scgi_proclist_sort_down(srv, host, proc);
31824 if (con->file_started == 0) {
31825 /* nothing has been send out yet, try to use another child */
31828 if (hctx->wb->bytes_out == 0 &&
31829 hctx->reconnects < 5) {
31830 scgi_reconnect(srv, hctx);
31832 - log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
31834 + log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
31835 "response not sent, request not sent, reconnection.",
31836 "connection-fd:", con->fd,
31837 "fcgi-fd:", hctx->fd);
31840 return HANDLER_WAIT_FOR_FD;
31843 - log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
31845 + log_error_write(srv, __FILE__, __LINE__, "sosdsd",
31846 "response not sent, request sent:", hctx->wb->bytes_out,
31847 "connection-fd:", con->fd,
31848 "fcgi-fd:", hctx->fd);
31851 scgi_connection_cleanup(srv, hctx);
31854 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
31855 buffer_reset(con->physical.path);
31856 con->http_status = 500;
31857 @@ -2550,76 +2550,76 @@
31859 /* response might have been already started, kill the connection */
31860 scgi_connection_cleanup(srv, hctx);
31862 - log_error_write(srv, __FILE__, __LINE__, "ssdsd",
31864 + log_error_write(srv, __FILE__, __LINE__, "ssdsd",
31865 "response already sent out, termination connection",
31866 "connection-fd:", con->fd,
31867 "fcgi-fd:", hctx->fd);
31870 connection_set_state(srv, con, CON_STATE_ERROR);
31878 joblist_append(srv, con);
31879 return HANDLER_FINISHED;
31884 if (revents & FDEVENT_OUT) {
31885 if (hctx->state == FCGI_STATE_CONNECT ||
31886 hctx->state == FCGI_STATE_WRITE) {
31887 /* we are allowed to send something out
31890 * 1. in a unfinished connect() call
31891 * 2. in a unfinished write() call (long POST request)
31893 return mod_scgi_handle_subrequest(srv, con, p);
31895 - log_error_write(srv, __FILE__, __LINE__, "sd",
31896 - "got a FDEVENT_OUT and didn't know why:",
31897 + log_error_write(srv, __FILE__, __LINE__, "sd",
31898 + "got a FDEVENT_OUT and didn't know why:",
31904 /* perhaps this issue is already handled */
31905 if (revents & FDEVENT_HUP) {
31906 if (hctx->state == FCGI_STATE_CONNECT) {
31907 /* getoptsock will catch this one (right ?)
31909 - * if we are in connect we might get a EINPROGRESS
31910 - * in the first call and a FDEVENT_HUP in the
31912 + * if we are in connect we might get a EINPROGRESS
31913 + * in the first call and a FDEVENT_HUP in the
31917 * FIXME: as it is a bit ugly.
31921 return mod_scgi_handle_subrequest(srv, con, p);
31922 } else if (hctx->state == FCGI_STATE_READ &&
31923 hctx->proc->port == 0) {
31927 * ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket
31928 * even if the FCGI_FIN packet is not received yet
31931 - log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
31932 - "error: unexpected close of scgi connection for",
31933 + log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
31934 + "error: unexpected close of scgi connection for",
31936 - "(no scgi process on host: ",
31937 + "(no scgi process on host: ",
31946 connection_set_state(srv, con, CON_STATE_ERROR);
31947 scgi_connection_close(srv, hctx);
31948 joblist_append(srv, con);
31950 } else if (revents & FDEVENT_ERR) {
31951 - log_error_write(srv, __FILE__, __LINE__, "s",
31952 + log_error_write(srv, __FILE__, __LINE__, "s",
31953 "fcgi: got a FDEVENT_ERR. Don't know why.");
31954 /* kill all connections to the scgi process */
31956 @@ -2628,42 +2628,39 @@
31957 scgi_connection_close(srv, hctx);
31958 joblist_append(srv, con);
31962 return HANDLER_FINISHED;
31964 -#define PATCH(x) \
31965 - p->conf.x = s->x;
31967 static int scgi_patch_connection(server *srv, connection *con, plugin_data *p) {
31969 plugin_config *s = p->config_storage[0];
31975 + PATCH_OPTION(exts);
31976 + PATCH_OPTION(debug);
31978 /* skip the first, the global context */
31979 for (i = 1; i < srv->config_context->used; i++) {
31980 data_config *dc = (data_config *)srv->config_context->data[i];
31981 s = p->config_storage[i];
31984 /* condition didn't match */
31985 if (!config_check_cond(srv, con, dc)) continue;
31989 for (j = 0; j < dc->value->used; j++) {
31990 data_unset *du = dc->value->data[j];
31993 if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.server"))) {
31995 + PATCH_OPTION(exts);
31996 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.debug"))) {
31998 + PATCH_OPTION(debug);
32009 static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
32010 plugin_data *p = p_d;
32011 @@ -2673,30 +2670,30 @@
32014 scgi_extension *extension = NULL;
32017 /* Possibly, we processed already this request */
32018 if (con->file_started == 1) return HANDLER_GO_ON;
32021 fn = uri_path_handler ? con->uri.path : con->physical.path;
32023 if (buffer_is_empty(fn)) return HANDLER_GO_ON;
32025 s_len = fn->used - 1;
32028 scgi_patch_connection(srv, con, p);
32030 /* check if extension matches */
32031 for (k = 0; k < p->conf.exts->used; k++) {
32035 extension = p->conf.exts->exts[k];
32038 if (extension->key->used == 0) continue;
32041 ct_len = extension->key->used - 1;
32044 if (s_len < ct_len) continue;
32047 /* check extension in the form "/scgi_pattern" */
32048 if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
32050 @@ -2710,17 +2707,17 @@
32051 if (k == p->conf.exts->used) {
32052 return HANDLER_GO_ON;
32056 /* get best server */
32057 for (k = 0, ndx = -1; k < extension->used; k++) {
32058 scgi_extension_host *host = extension->hosts[k];
32061 /* we should have at least one proc that can do somthing */
32062 if (host->active_procs == 0) continue;
32064 if (used == -1 || host->load < used) {
32071 @@ -2728,12 +2725,12 @@
32072 /* found a server */
32074 scgi_extension_host *host = extension->hosts[ndx];
32077 - * if check-local is disabled, use the uri.path handler
32081 + * if check-local is disabled, use the uri.path handler
32086 /* init handler-context */
32087 if (uri_path_handler) {
32088 if (host->check_local == 0) {
32089 @@ -2741,7 +2738,7 @@
32092 hctx = handler_ctx_init();
32095 hctx->remote_conn = con;
32096 hctx->plugin_data = p;
32098 @@ -2749,45 +2746,45 @@
32100 hctx->conf.exts = p->conf.exts;
32101 hctx->conf.debug = p->conf.debug;
32104 con->plugin_ctx[p->id] = hctx;
32112 if (con->conf.log_request_handling) {
32113 log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_scgi");
32116 - /* the prefix is the SCRIPT_NAME,
32117 + /* the prefix is the SCRIPT_NAME,
32118 * everthing from start to the next slash
32119 * this is important for check-local = "disable"
32122 * if prefix = /admin.fcgi
32125 * /admin.fcgi/foo/bar
32128 * SCRIPT_NAME = /admin.fcgi
32129 * PATH_INFO = /foo/bar
32132 * if prefix = /fcgi-bin/
32135 * /fcgi-bin/foo/bar
32138 * SCRIPT_NAME = /fcgi-bin/foo
32145 /* the rewrite is only done for /prefix/? matches */
32146 if (extension->key->ptr[0] == '/' &&
32147 con->uri.path->used > extension->key->used &&
32148 NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
32149 - /* rewrite uri.path and pathinfo */
32151 + /* rewrite uri.path and pathinfo */
32153 buffer_copy_string(con->request.pathinfo, pathinfo);
32156 con->uri.path->used -= con->request.pathinfo->used - 1;
32157 con->uri.path->ptr[con->uri.path->used - 1] = '\0';
32159 @@ -2796,21 +2793,21 @@
32162 hctx = handler_ctx_init();
32165 hctx->remote_conn = con;
32166 hctx->plugin_data = p;
32171 hctx->conf.exts = p->conf.exts;
32172 hctx->conf.debug = p->conf.debug;
32175 con->plugin_ctx[p->id] = hctx;
32184 if (con->conf.log_request_handling) {
32185 log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi");
32187 @@ -2821,11 +2818,11 @@
32188 /* no handler found */
32189 buffer_reset(con->physical.path);
32190 con->http_status = 500;
32192 - log_error_write(srv, __FILE__, __LINE__, "sb",
32193 - "no fcgi-handler found for:",
32195 + log_error_write(srv, __FILE__, __LINE__, "sb",
32196 + "no fcgi-handler found for:",
32200 return HANDLER_FINISHED;
32202 return HANDLER_GO_ON;
32203 @@ -2844,19 +2841,19 @@
32204 JOBLIST_FUNC(mod_scgi_handle_joblist) {
32205 plugin_data *p = p_d;
32206 handler_ctx *hctx = con->plugin_ctx[p->id];
32209 if (hctx == NULL) return HANDLER_GO_ON;
32211 if (hctx->fd != -1) {
32212 switch (hctx->state) {
32213 case FCGI_STATE_READ:
32214 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
32218 case FCGI_STATE_CONNECT:
32219 case FCGI_STATE_WRITE:
32220 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
32224 case FCGI_STATE_INIT:
32226 @@ -2873,21 +2870,21 @@
32228 static handler_t scgi_connection_close_callback(server *srv, connection *con, void *p_d) {
32229 plugin_data *p = p_d;
32232 return scgi_connection_close(srv, con->plugin_ctx[p->id]);
32235 TRIGGER_FUNC(mod_scgi_handle_trigger) {
32236 plugin_data *p = p_d;
32242 /* perhaps we should kill a connect attempt after 10-15 seconds
32245 * currently we wait for the TCP timeout which is on Linux 180 seconds
32254 /* check all childs if they are still up */
32255 @@ -2904,47 +2901,47 @@
32256 scgi_extension *ex;
32258 ex = exts->exts[j];
32261 for (n = 0; n < ex->used; n++) {
32265 unsigned long sum_load = 0;
32266 scgi_extension_host *host;
32269 host = ex->hosts[n];
32272 scgi_restart_dead_procs(srv, p, host);
32275 for (proc = host->first; proc; proc = proc->next) {
32276 sum_load += proc->load;
32280 if (host->num_procs &&
32281 host->num_procs < host->max_procs &&
32282 (sum_load / host->num_procs) > host->max_load_per_proc) {
32283 /* overload, spawn new child */
32284 scgi_proc *fp = NULL;
32287 if (p->conf.debug) {
32288 - log_error_write(srv, __FILE__, __LINE__, "s",
32289 + log_error_write(srv, __FILE__, __LINE__, "s",
32290 "overload detected, spawning a new child");
32294 for (fp = host->unused_procs; fp && fp->pid != 0; fp = fp->next);
32298 if (fp == host->unused_procs) host->unused_procs = fp->next;
32301 if (fp->next) fp->next->prev = NULL;
32306 fp = scgi_process_init();
32307 fp->id = host->max_id++;
32314 if (buffer_is_empty(host->unixsocket)) {
32315 fp->port = host->port + fp->id;
32317 @@ -2952,13 +2949,13 @@
32318 buffer_append_string(fp->socket, "-");
32319 buffer_append_long(fp->socket, fp->id);
32323 if (scgi_spawn_connection(srv, p, host, fp)) {
32324 log_error_write(srv, __FILE__, __LINE__, "s",
32325 "ERROR: spawning fcgi failed.");
32326 return HANDLER_ERROR;
32331 fp->next = host->first;
32333 @@ -2966,56 +2963,57 @@
32339 for (proc = host->first; proc; proc = proc->next) {
32340 if (proc->load != 0) break;
32341 if (host->num_procs <= host->min_procs) break;
32342 if (proc->pid == 0) continue;
32345 if (srv->cur_ts - proc->last_used > host->idle_timeout) {
32346 /* a proc is idling for a long time now,
32350 if (p->conf.debug) {
32351 - log_error_write(srv, __FILE__, __LINE__, "ssbsd",
32352 - "idle-timeout reached, terminating child:",
32353 - "socket:", proc->socket,
32354 + log_error_write(srv, __FILE__, __LINE__, "ssbsd",
32355 + "idle-timeout reached, terminating child:",
32356 + "socket:", proc->socket,
32363 if (proc->next) proc->next->prev = proc->prev;
32364 if (proc->prev) proc->prev->next = proc->next;
32367 if (proc->prev == NULL) host->first = proc->next;
32371 proc->next = host->unused_procs;
32374 if (host->unused_procs) host->unused_procs->prev = proc;
32375 host->unused_procs = proc;
32378 kill(proc->pid, SIGTERM);
32381 proc->state = PROC_STATE_KILLED;
32383 - log_error_write(srv, __FILE__, __LINE__, "ssbsd",
32385 - "socket:", proc->socket,
32387 + log_error_write(srv, __FILE__, __LINE__, "ssbsd",
32389 + "socket:", proc->socket,
32396 /* proc is now in unused, let the next second handle the next process */
32404 for (proc = host->unused_procs; proc; proc = proc->next) {
32408 if (proc->pid == 0) continue;
32411 switch (waitpid(proc->pid, &status, WNOHANG)) {
32413 /* child still running after timeout, good */
32414 @@ -3023,10 +3021,10 @@
32416 if (errno != EINTR) {
32417 /* no PID found ? should never happen */
32418 - log_error_write(srv, __FILE__, __LINE__, "sddss",
32419 + log_error_write(srv, __FILE__, __LINE__, "sddss",
32420 "pid ", proc->pid, proc->state,
32421 "not found:", strerror(errno));
32425 if (errno == ECHILD) {
32426 /* someone else has cleaned up for us */
32427 @@ -3040,25 +3038,26 @@
32428 /* the child should not terminate at all */
32429 if (WIFEXITED(status)) {
32430 if (proc->state != PROC_STATE_KILLED) {
32431 - log_error_write(srv, __FILE__, __LINE__, "sdb",
32433 + log_error_write(srv, __FILE__, __LINE__, "sdb",
32435 WEXITSTATUS(status), proc->socket);
32437 } else if (WIFSIGNALED(status)) {
32438 if (WTERMSIG(status) != SIGTERM) {
32439 - log_error_write(srv, __FILE__, __LINE__, "sd",
32440 - "child signaled:",
32441 + log_error_write(srv, __FILE__, __LINE__, "sd",
32442 + "child signaled:",
32446 - log_error_write(srv, __FILE__, __LINE__, "sd",
32447 - "child died somehow:",
32448 + log_error_write(srv, __FILE__, __LINE__, "sd",
32449 + "child died somehow:",
32453 proc->state = PROC_STATE_UNSET;
32460 @@ -3082,8 +3081,8 @@
32461 p->handle_subrequest = mod_scgi_handle_subrequest;
32462 p->handle_joblist = mod_scgi_handle_joblist;
32463 p->handle_trigger = mod_scgi_handle_trigger;
32471 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_secure_download.c lighttpd-1.4.12/src/mod_secure_download.c
32472 --- lighttpd-1.4.11/src/mod_secure_download.c 2005-12-14 14:37:29.000000000 +0200
32473 +++ lighttpd-1.4.12/src/mod_secure_download.c 2006-07-11 21:23:39.000000000 +0300
32483 @@ -36,28 +36,28 @@
32486 buffer *uri_prefix;
32489 unsigned short timeout;
32499 plugin_config **config_storage;
32501 - plugin_config conf;
32503 + plugin_config conf;
32506 /* init the plugin data */
32507 INIT_FUNC(mod_secdownload_init) {
32511 p = calloc(1, sizeof(*p));
32514 p->md5 = buffer_init();
32520 @@ -65,27 +65,27 @@
32521 FREE_FUNC(mod_secdownload_free) {
32522 plugin_data *p = p_d;
32526 if (!p) return HANDLER_GO_ON;
32529 if (p->config_storage) {
32531 for (i = 0; i < srv->config_context->used; i++) {
32532 plugin_config *s = p->config_storage[i];
32535 buffer_free(s->secret);
32536 buffer_free(s->doc_root);
32537 buffer_free(s->uri_prefix);
32542 free(p->config_storage);
32546 buffer_free(p->md5);
32552 return HANDLER_GO_ON;
32555 @@ -94,107 +94,103 @@
32556 SETDEFAULTS_FUNC(mod_secdownload_set_defaults) {
32557 plugin_data *p = p_d;
32560 - config_values_t cv[] = {
32562 + config_values_t cv[] = {
32563 { "secdownload.secret", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
32564 { "secdownload.document-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
32565 { "secdownload.uri-prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
32566 { "secdownload.timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
32567 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
32571 if (!p) return HANDLER_ERROR;
32574 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
32577 for (i = 0; i < srv->config_context->used; i++) {
32581 s = calloc(1, sizeof(plugin_config));
32582 s->secret = buffer_init();
32583 s->doc_root = buffer_init();
32584 s->uri_prefix = buffer_init();
32588 cv[0].destination = s->secret;
32589 cv[1].destination = s->doc_root;
32590 cv[2].destination = s->uri_prefix;
32591 cv[3].destination = &(s->timeout);
32594 p->config_storage[i] = s;
32597 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
32598 return HANDLER_ERROR;
32603 return HANDLER_GO_ON;
32607 * checks if the supplied string is a MD5 string
32610 * @param str a possible MD5 string
32611 * @return if the supplied string is a valid MD5 string 1 is returned otherwise 0
32614 int is_hex_len(const char *str, size_t len) {
32618 if (NULL == str) return 0;
32621 for (i = 0; i < len && *str; i++, str++) {
32622 /* illegal characters */
32623 if (!((*str >= '0' && *str <= '9') ||
32624 (*str >= 'a' && *str <= 'f') ||
32625 - (*str >= 'A' && *str <= 'F'))
32626 + (*str >= 'A' && *str <= 'F'))
32636 -#define PATCH(x) \
32637 - p->conf.x = s->x;
32638 static int mod_secdownload_patch_connection(server *srv, connection *con, plugin_data *p) {
32640 plugin_config *s = p->config_storage[0];
32644 - PATCH(uri_prefix);
32648 + PATCH_OPTION(secret);
32649 + PATCH_OPTION(doc_root);
32650 + PATCH_OPTION(uri_prefix);
32651 + PATCH_OPTION(timeout);
32653 /* skip the first, the global context */
32654 for (i = 1; i < srv->config_context->used; i++) {
32655 data_config *dc = (data_config *)srv->config_context->data[i];
32656 s = p->config_storage[i];
32659 /* condition didn't match */
32660 if (!config_check_cond(srv, con, dc)) continue;
32664 for (j = 0; j < dc->value->used; j++) {
32665 data_unset *du = dc->value->data[j];
32668 if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.secret"))) {
32670 + PATCH_OPTION(secret);
32671 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.document-root"))) {
32673 + PATCH_OPTION(doc_root);
32674 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.uri-prefix"))) {
32675 - PATCH(uri_prefix);
32676 + PATCH_OPTION(uri_prefix);
32677 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.timeout"))) {
32679 + PATCH_OPTION(timeout);
32690 URIHANDLER_FUNC(mod_secdownload_uri_handler) {
32691 plugin_data *p = p_d;
32692 @@ -203,88 +199,88 @@
32693 const char *rel_uri, *ts_str, *md5_str;
32698 if (con->uri.path->used == 0) return HANDLER_GO_ON;
32701 mod_secdownload_patch_connection(srv, con, p);
32703 if (buffer_is_empty(p->conf.uri_prefix)) return HANDLER_GO_ON;
32706 if (buffer_is_empty(p->conf.secret)) {
32707 log_error_write(srv, __FILE__, __LINE__, "s",
32708 "secdownload.secret has to be set");
32709 return HANDLER_ERROR;
32713 if (buffer_is_empty(p->conf.doc_root)) {
32714 log_error_write(srv, __FILE__, __LINE__, "s",
32715 "secdownload.document-root has to be set");
32716 return HANDLER_ERROR;
32722 * /<uri-prefix>[a-f0-9]{32}/[a-f0-9]{8}/<rel-path>
32726 if (0 != strncmp(con->uri.path->ptr, p->conf.uri_prefix->ptr, p->conf.uri_prefix->used - 1)) return HANDLER_GO_ON;
32729 md5_str = con->uri.path->ptr + p->conf.uri_prefix->used - 1;
32732 if (!is_hex_len(md5_str, 32)) return HANDLER_GO_ON;
32733 if (*(md5_str + 32) != '/') return HANDLER_GO_ON;
32736 ts_str = md5_str + 32 + 1;
32739 if (!is_hex_len(ts_str, 8)) return HANDLER_GO_ON;
32740 if (*(ts_str + 8) != '/') return HANDLER_GO_ON;
32743 for (i = 0; i < 8; i++) {
32744 ts = (ts << 4) + hex2int(*(ts_str + i));
32749 - if (srv->cur_ts - ts > p->conf.timeout ||
32750 + if (srv->cur_ts - ts > p->conf.timeout ||
32751 srv->cur_ts - ts < -p->conf.timeout) {
32752 con->http_status = 408;
32755 return HANDLER_FINISHED;
32759 rel_uri = ts_str + 8;
32766 * <secret><rel-path><timestamp-hex>
32770 buffer_copy_string_buffer(p->md5, p->conf.secret);
32771 buffer_append_string(p->md5, rel_uri);
32772 buffer_append_string_len(p->md5, ts_str, 8);
32776 MD5_Update(&Md5Ctx, (unsigned char *)p->md5->ptr, p->md5->used - 1);
32777 MD5_Final(HA1, &Md5Ctx);
32780 buffer_copy_string_hex(p->md5, (char *)HA1, 16);
32783 if (0 != strncmp(md5_str, p->md5->ptr, 32)) {
32784 con->http_status = 403;
32786 - log_error_write(srv, __FILE__, __LINE__, "sss",
32788 + log_error_write(srv, __FILE__, __LINE__, "sss",
32790 md5_str, p->md5->ptr);
32793 return HANDLER_FINISHED;
32797 /* starting with the last / we should have relative-path to the docroot
32801 buffer_copy_string_buffer(con->physical.doc_root, p->conf.doc_root);
32802 buffer_copy_string(con->physical.rel_path, rel_uri);
32803 buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
32804 buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
32807 return HANDLER_GO_ON;
32810 @@ -293,13 +289,13 @@
32811 int mod_secdownload_plugin_init(plugin *p) {
32812 p->version = LIGHTTPD_VERSION_ID;
32813 p->name = buffer_init_string("secdownload");
32816 p->init = mod_secdownload_init;
32817 p->handle_physical = mod_secdownload_uri_handler;
32818 p->set_defaults = mod_secdownload_set_defaults;
32819 p->cleanup = mod_secdownload_free;
32827 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_setenv.c lighttpd-1.4.12/src/mod_setenv.c
32828 --- lighttpd-1.4.11/src/mod_setenv.c 2006-01-14 20:33:12.000000000 +0200
32829 +++ lighttpd-1.4.12/src/mod_setenv.c 2006-07-11 21:23:40.000000000 +0300
32830 @@ -18,25 +18,25 @@
32832 array *request_header;
32833 array *response_header;
32836 array *environment;
32843 plugin_config **config_storage;
32845 - plugin_config conf;
32847 + plugin_config conf;
32850 static handler_ctx * handler_ctx_init() {
32851 handler_ctx * hctx;
32854 hctx = calloc(1, sizeof(*hctx));
32863 @@ -48,36 +48,36 @@
32864 /* init the plugin data */
32865 INIT_FUNC(mod_setenv_init) {
32869 p = calloc(1, sizeof(*p));
32875 /* detroy the plugin data */
32876 FREE_FUNC(mod_setenv_free) {
32877 plugin_data *p = p_d;
32882 if (!p) return HANDLER_GO_ON;
32885 if (p->config_storage) {
32887 for (i = 0; i < srv->config_context->used; i++) {
32888 plugin_config *s = p->config_storage[i];
32891 array_free(s->request_header);
32892 array_free(s->response_header);
32893 array_free(s->environment);
32898 free(p->config_storage);
32905 return HANDLER_GO_ON;
32908 @@ -86,86 +86,83 @@
32909 SETDEFAULTS_FUNC(mod_setenv_set_defaults) {
32910 plugin_data *p = p_d;
32913 - config_values_t cv[] = {
32915 + config_values_t cv[] = {
32916 { "setenv.add-request-header", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
32917 { "setenv.add-response-header", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
32918 { "setenv.add-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
32919 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
32923 if (!p) return HANDLER_ERROR;
32926 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
32929 for (i = 0; i < srv->config_context->used; i++) {
32933 s = calloc(1, sizeof(plugin_config));
32934 s->request_header = array_init();
32935 s->response_header = array_init();
32936 s->environment = array_init();
32939 cv[0].destination = s->request_header;
32940 cv[1].destination = s->response_header;
32941 cv[2].destination = s->environment;
32944 p->config_storage[i] = s;
32947 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
32948 return HANDLER_ERROR;
32953 return HANDLER_GO_ON;
32956 -#define PATCH(x) \
32957 - p->conf.x = s->x;
32958 static int mod_setenv_patch_connection(server *srv, connection *con, plugin_data *p) {
32960 plugin_config *s = p->config_storage[0];
32962 - PATCH(request_header);
32963 - PATCH(response_header);
32964 - PATCH(environment);
32967 + PATCH_OPTION(request_header);
32968 + PATCH_OPTION(response_header);
32969 + PATCH_OPTION(environment);
32971 /* skip the first, the global context */
32972 for (i = 1; i < srv->config_context->used; i++) {
32973 data_config *dc = (data_config *)srv->config_context->data[i];
32974 s = p->config_storage[i];
32977 /* condition didn't match */
32978 if (!config_check_cond(srv, con, dc)) continue;
32982 for (j = 0; j < dc->value->used; j++) {
32983 data_unset *du = dc->value->data[j];
32986 if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-request-header"))) {
32987 - PATCH(request_header);
32988 + PATCH_OPTION(request_header);
32989 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-response-header"))) {
32990 - PATCH(response_header);
32991 + PATCH_OPTION(response_header);
32992 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-environment"))) {
32993 - PATCH(environment);
32994 + PATCH_OPTION(environment);
33004 URIHANDLER_FUNC(mod_setenv_uri_handler) {
33005 plugin_data *p = p_d;
33010 if (con->plugin_ctx[p->id]) {
33011 hctx = con->plugin_ctx[p->id];
33013 hctx = handler_ctx_init();
33016 con->plugin_ctx[p->id] = hctx;
33019 @@ -180,52 +177,52 @@
33020 for (k = 0; k < p->conf.request_header->used; k++) {
33021 data_string *ds = (data_string *)p->conf.request_header->data[k];
33022 data_string *ds_dst;
33025 if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
33026 ds_dst = data_string_init();
33030 buffer_copy_string_buffer(ds_dst->key, ds->key);
33031 buffer_copy_string_buffer(ds_dst->value, ds->value);
33034 array_insert_unique(con->request.headers, (data_unset *)ds_dst);
33038 for (k = 0; k < p->conf.environment->used; k++) {
33039 data_string *ds = (data_string *)p->conf.environment->data[k];
33040 data_string *ds_dst;
33043 if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
33044 ds_dst = data_string_init();
33048 buffer_copy_string_buffer(ds_dst->key, ds->key);
33049 buffer_copy_string_buffer(ds_dst->value, ds->value);
33052 array_insert_unique(con->environment, (data_unset *)ds_dst);
33056 for (k = 0; k < p->conf.response_header->used; k++) {
33057 data_string *ds = (data_string *)p->conf.response_header->data[k];
33060 response_header_insert(srv, con, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
33065 return HANDLER_GO_ON;
33068 REQUESTDONE_FUNC(mod_setenv_reset) {
33069 plugin_data *p = p_d;
33075 if (con->plugin_ctx[p->id]) {
33076 handler_ctx_free(con->plugin_ctx[p->id]);
33077 con->plugin_ctx[p->id] = NULL;
33080 - return HANDLER_GO_ON;
33081 + return HANDLER_GO_ON;
33084 /* this function is called at dlopen() time and inits the callbacks */
33085 @@ -233,15 +230,15 @@
33086 int mod_setenv_plugin_init(plugin *p) {
33087 p->version = LIGHTTPD_VERSION_ID;
33088 p->name = buffer_init_string("setenv");
33091 p->init = mod_setenv_init;
33092 p->handle_uri_clean = mod_setenv_uri_handler;
33093 p->set_defaults = mod_setenv_set_defaults;
33094 p->cleanup = mod_setenv_free;
33097 p->handle_request_done = mod_setenv_reset;
33104 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_simple_vhost.c lighttpd-1.4.12/src/mod_simple_vhost.c
33105 --- lighttpd-1.4.11/src/mod_simple_vhost.c 2005-11-18 15:16:13.000000000 +0200
33106 +++ lighttpd-1.4.12/src/mod_simple_vhost.c 2006-07-11 21:23:40.000000000 +0300
33109 #include "plugin.h"
33111 +#include "sys-files.h"
33113 #ifdef HAVE_CONFIG_H
33114 #include "config.h"
33117 buffer *server_root;
33118 buffer *default_host;
33119 buffer *document_root;
33122 buffer *docroot_cache_key;
33123 buffer *docroot_cache_value;
33124 buffer *docroot_cache_servername;
33125 @@ -28,138 +30,138 @@
33134 plugin_config **config_storage;
33135 - plugin_config conf;
33136 + plugin_config conf;
33139 INIT_FUNC(mod_simple_vhost_init) {
33143 p = calloc(1, sizeof(*p));
33146 p->doc_root = buffer_init();
33152 FREE_FUNC(mod_simple_vhost_free) {
33153 plugin_data *p = p_d;
33158 if (!p) return HANDLER_GO_ON;
33161 if (p->config_storage) {
33163 for (i = 0; i < srv->config_context->used; i++) {
33164 plugin_config *s = p->config_storage[i];
33167 buffer_free(s->document_root);
33168 buffer_free(s->default_host);
33169 buffer_free(s->server_root);
33172 buffer_free(s->docroot_cache_key);
33173 buffer_free(s->docroot_cache_value);
33174 buffer_free(s->docroot_cache_servername);
33181 free(p->config_storage);
33185 buffer_free(p->doc_root);
33191 return HANDLER_GO_ON;
33194 SETDEFAULTS_FUNC(mod_simple_vhost_set_defaults) {
33195 plugin_data *p = p_d;
33198 - config_values_t cv[] = {
33200 + config_values_t cv[] = {
33201 { "simple-vhost.server-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
33202 { "simple-vhost.default-host", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
33203 { "simple-vhost.document-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
33204 { "simple-vhost.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
33205 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
33209 if (!p) return HANDLER_ERROR;
33212 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
33215 for (i = 0; i < srv->config_context->used; i++) {
33219 s = calloc(1, sizeof(plugin_config));
33222 s->server_root = buffer_init();
33223 s->default_host = buffer_init();
33224 s->document_root = buffer_init();
33227 s->docroot_cache_key = buffer_init();
33228 s->docroot_cache_value = buffer_init();
33229 s->docroot_cache_servername = buffer_init();
33234 cv[0].destination = s->server_root;
33235 cv[1].destination = s->default_host;
33236 cv[2].destination = s->document_root;
33237 cv[3].destination = &(s->debug);
33242 p->config_storage[i] = s;
33245 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
33246 return HANDLER_ERROR;
33251 return HANDLER_GO_ON;
33254 static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *out, buffer *host) {
33255 stat_cache_entry *sce = NULL;
33258 buffer_prepare_copy(out, 128);
33260 if (p->conf.server_root->used) {
33261 buffer_copy_string_buffer(out, p->conf.server_root);
33265 /* a hostname has to start with a alpha-numerical character
33266 * and must not contain a slash "/"
33270 - BUFFER_APPEND_SLASH(out);
33273 + PATHNAME_APPEND_SLASH(out);
33275 if (NULL == (dp = strchr(host->ptr, ':'))) {
33276 buffer_append_string_buffer(out, host);
33278 buffer_append_string_len(out, host->ptr, dp - host->ptr);
33281 - BUFFER_APPEND_SLASH(out);
33283 + PATHNAME_APPEND_SLASH(out);
33285 if (p->conf.document_root->used > 2 && p->conf.document_root->ptr[0] == '/') {
33286 buffer_append_string_len(out, p->conf.document_root->ptr + 1, p->conf.document_root->used - 2);
33288 buffer_append_string_buffer(out, p->conf.document_root);
33289 - BUFFER_APPEND_SLASH(out);
33290 + PATHNAME_APPEND_SLASH(out);
33293 buffer_copy_string_buffer(out, con->conf.document_root);
33294 - BUFFER_APPEND_SLASH(out);
33295 + PATHNAME_APPEND_SLASH(out);
33299 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, out, &sce)) {
33300 if (p->conf.debug) {
33301 log_error_write(srv, __FILE__, __LINE__, "sb",
33302 @@ -169,57 +171,53 @@
33303 } else if (!S_ISDIR(sce->st.st_mode)) {
33312 -#define PATCH(x) \
33313 - p->conf.x = s->x;
33314 static int mod_simple_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
33316 plugin_config *s = p->config_storage[0];
33318 - PATCH(server_root);
33319 - PATCH(default_host);
33320 - PATCH(document_root);
33322 - PATCH(docroot_cache_key);
33323 - PATCH(docroot_cache_value);
33324 - PATCH(docroot_cache_servername);
33328 + PATCH_OPTION(server_root);
33329 + PATCH_OPTION(default_host);
33330 + PATCH_OPTION(document_root);
33332 + PATCH_OPTION(docroot_cache_key);
33333 + PATCH_OPTION(docroot_cache_value);
33334 + PATCH_OPTION(docroot_cache_servername);
33336 + PATCH_OPTION(debug);
33338 /* skip the first, the global context */
33339 for (i = 1; i < srv->config_context->used; i++) {
33340 data_config *dc = (data_config *)srv->config_context->data[i];
33341 s = p->config_storage[i];
33344 /* condition didn't match */
33345 if (!config_check_cond(srv, con, dc)) continue;
33349 for (j = 0; j < dc->value->used; j++) {
33350 data_unset *du = dc->value->data[j];
33353 if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.server-root"))) {
33354 - PATCH(server_root);
33355 - PATCH(docroot_cache_key);
33356 - PATCH(docroot_cache_value);
33357 - PATCH(docroot_cache_servername);
33358 + PATCH_OPTION(server_root);
33359 + PATCH_OPTION(docroot_cache_key);
33360 + PATCH_OPTION(docroot_cache_value);
33361 + PATCH_OPTION(docroot_cache_servername);
33362 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.default-host"))) {
33363 - PATCH(default_host);
33364 + PATCH_OPTION(default_host);
33365 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.document-root"))) {
33366 - PATCH(document_root);
33367 + PATCH_OPTION(document_root);
33368 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.debug"))) {
33370 + PATCH_OPTION(debug);
33380 static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_data) {
33381 plugin_data *p = p_data;
33382 @@ -227,12 +225,12 @@
33384 * cache the last successfull translation from hostname (authority) to docroot
33385 * - this saves us a stat() call
33391 mod_simple_vhost_patch_connection(srv, con, p);
33393 - if (p->conf.docroot_cache_key->used &&
33395 + if (p->conf.docroot_cache_key->used &&
33396 con->uri.authority->used &&
33397 buffer_is_equal(p->conf.docroot_cache_key, con->uri.authority)) {
33399 @@ -243,8 +241,8 @@
33400 if ((con->uri.authority->used == 0) ||
33401 build_doc_root(srv, con, p, p->doc_root, con->uri.authority)) {
33402 /* not found, fallback the default-host */
33403 - if (build_doc_root(srv, con, p,
33405 + if (build_doc_root(srv, con, p,
33407 p->conf.default_host)) {
33408 return HANDLER_GO_ON;
33410 @@ -253,15 +251,15 @@
33412 buffer_copy_string_buffer(con->server_name, con->uri.authority);
33416 /* copy to cache */
33417 buffer_copy_string_buffer(p->conf.docroot_cache_key, con->uri.authority);
33418 buffer_copy_string_buffer(p->conf.docroot_cache_value, p->doc_root);
33419 buffer_copy_string_buffer(p->conf.docroot_cache_servername, con->server_name);
33422 buffer_copy_string_buffer(con->physical.doc_root, p->doc_root);
33426 return HANDLER_GO_ON;
33429 @@ -269,13 +267,13 @@
33430 int mod_simple_vhost_plugin_init(plugin *p) {
33431 p->version = LIGHTTPD_VERSION_ID;
33432 p->name = buffer_init_string("simple_vhost");
33435 p->init = mod_simple_vhost_init;
33436 p->set_defaults = mod_simple_vhost_set_defaults;
33437 p->handle_docroot = mod_simple_vhost_docroot;
33438 p->cleanup = mod_simple_vhost_free;
33446 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_skeleton.c lighttpd-1.4.12/src/mod_skeleton.c
33447 --- lighttpd-1.4.11/src/mod_skeleton.c 2005-10-02 18:30:51.000000000 +0300
33448 +++ lighttpd-1.4.12/src/mod_skeleton.c 2006-07-11 21:23:40.000000000 +0300
33449 @@ -14,13 +14,13 @@
33452 * this is a skeleton for a lighttpd plugin
33455 * just replaces every occurance of 'skeleton' by your plugin name
33461 * :%s/skeleton/myhandler/
33467 @@ -33,12 +33,12 @@
33476 plugin_config **config_storage;
33478 - plugin_config conf;
33480 + plugin_config conf;
33484 @@ -47,36 +47,36 @@
33486 static handler_ctx * handler_ctx_init() {
33487 handler_ctx * hctx;
33490 hctx = calloc(1, sizeof(*hctx));
33496 static void handler_ctx_free(handler_ctx *hctx) {
33502 /* init the plugin data */
33503 INIT_FUNC(mod_skeleton_init) {
33507 p = calloc(1, sizeof(*p));
33510 p->match_buf = buffer_init();
33516 /* detroy the plugin data */
33517 FREE_FUNC(mod_skeleton_free) {
33518 plugin_data *p = p_d;
33523 if (!p) return HANDLER_GO_ON;
33526 if (p->config_storage) {
33529 @@ -84,18 +84,18 @@
33530 plugin_config *s = p->config_storage[i];
33535 array_free(s->match);
33540 free(p->config_storage);
33544 buffer_free(p->match_buf);
33550 return HANDLER_GO_ON;
33553 @@ -104,91 +104,88 @@
33554 SETDEFAULTS_FUNC(mod_skeleton_set_defaults) {
33555 plugin_data *p = p_d;
33558 - config_values_t cv[] = {
33560 + config_values_t cv[] = {
33561 { "skeleton.array", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
33562 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
33566 if (!p) return HANDLER_ERROR;
33569 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
33572 for (i = 0; i < srv->config_context->used; i++) {
33576 s = calloc(1, sizeof(plugin_config));
33577 s->match = array_init();
33580 cv[0].destination = s->match;
33583 p->config_storage[i] = s;
33586 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
33587 return HANDLER_ERROR;
33592 return HANDLER_GO_ON;
33595 -#define PATCH(x) \
33596 - p->conf.x = s->x;
33597 static int mod_skeleton_patch_connection(server *srv, connection *con, plugin_data *p) {
33599 plugin_config *s = p->config_storage[0];
33604 + PATCH_OPTION(match);
33606 /* skip the first, the global context */
33607 for (i = 1; i < srv->config_context->used; i++) {
33608 data_config *dc = (data_config *)srv->config_context->data[i];
33609 s = p->config_storage[i];
33612 /* condition didn't match */
33613 if (!config_check_cond(srv, con, dc)) continue;
33617 for (j = 0; j < dc->value->used; j++) {
33618 data_unset *du = dc->value->data[j];
33621 if (buffer_is_equal_string(du->key, CONST_STR_LEN("skeleton.array"))) {
33623 + PATCH_OPTION(match);
33633 URIHANDLER_FUNC(mod_skeleton_uri_handler) {
33634 plugin_data *p = p_d;
33641 if (con->uri.path->used == 0) return HANDLER_GO_ON;
33644 mod_skeleton_patch_connection(srv, con, p);
33646 s_len = con->uri.path->used - 1;
33649 for (k = 0; k < p->conf.match->used; k++) {
33650 data_string *ds = (data_string *)p->conf.match->data[k];
33651 int ct_len = ds->value->used - 1;
33654 if (ct_len > s_len) continue;
33655 if (ds->value->used == 0) continue;
33658 if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
33659 con->http_status = 403;
33662 return HANDLER_FINISHED;
33668 return HANDLER_GO_ON;
33670 @@ -198,13 +195,13 @@
33671 int mod_skeleton_plugin_init(plugin *p) {
33672 p->version = LIGHTTPD_VERSION_ID;
33673 p->name = buffer_init_string("skeleton");
33676 p->init = mod_skeleton_init;
33677 p->handle_uri_clean = mod_skeleton_uri_handler;
33678 p->set_defaults = mod_skeleton_set_defaults;
33679 p->cleanup = mod_skeleton_free;
33687 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_sql_vhost_core.c lighttpd-1.4.12/src/mod_sql_vhost_core.c
33688 --- lighttpd-1.4.11/src/mod_sql_vhost_core.c 1970-01-01 03:00:00.000000000 +0300
33689 +++ lighttpd-1.4.12/src/mod_sql_vhost_core.c 2006-07-11 21:23:40.000000000 +0300
33691 +#include <stdio.h>
33692 +#include <errno.h>
33693 +#include <fcntl.h>
33694 +#include <string.h>
33696 +#ifdef HAVE_CONFIG_H
33697 +#include "config.h"
33700 +#include "plugin.h"
33703 +#include "stat_cache.h"
33705 +#include "mod_sql_vhost_core.h"
33707 +#define plugin_data mod_sql_vhost_core_plugin_data
33708 +#define plugin_config mod_sql_vhost_core_plugin_config
33710 +/* init the plugin data */
33711 +INIT_FUNC(mod_sql_vhost_core_init) {
33714 + p = calloc(1, sizeof(*p));
33716 + p->docroot = buffer_init();
33717 + p->host = buffer_init();
33722 +/* cleanup the plugin data */
33723 +SERVER_FUNC(mod_sql_vhost_core_cleanup) {
33724 + plugin_data *p = p_d;
33728 + if (!p) return HANDLER_GO_ON;
33730 + if (p->config_storage) {
33732 + for (i = 0; i < srv->config_context->used; i++) {
33733 + plugin_config *s = p->config_storage[i];
33735 + if (!s) continue;
33737 + buffer_free(s->db);
33738 + buffer_free(s->user);
33739 + buffer_free(s->pass);
33740 + buffer_free(s->sock);
33741 + buffer_free(s->backend);
33745 + free(p->config_storage);
33747 + buffer_free(p->docroot);
33748 + buffer_free(p->host);
33752 + return HANDLER_GO_ON;
33755 +/* set configuration values */
33756 +SERVER_FUNC(mod_sql_vhost_core_set_defaults) {
33757 + plugin_data *p = p_d;
33761 + config_values_t cv[] = {
33762 + { "sql-vhost.db", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 0 * e.g. vhost */
33763 + { "sql-vhost.user", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 1 * lighty */
33764 + { "sql-vhost.pass", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 2 * secrect */
33765 + { "sql-vhost.sock", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 3 * /tmp/mysql.sock */
33766 + { "sql-vhost.select-vhost", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 4 * SELECT ... FROM hosts WHERE hostname = ? */
33767 + { "sql-vhost.hostname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 5 * 127.0.0.1 */
33768 + { "sql-vhost.port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 6 * 3306 */
33769 + { "sql-vhost.backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 7 * mysql */
33771 + /* backward compat */
33772 + { "mysql-vhost.db", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 8 == 0 */
33773 + { "mysql-vhost.user", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 9 == 1 */
33774 + { "mysql-vhost.pass", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 == 2 */
33775 + { "mysql-vhost.sock", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 == 3 */
33776 + { "mysql-vhost.sql", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 12 == 4 */
33777 + { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER }, /* 13 == 5 */
33778 + { "mysql-vhost.port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 14 == 6 */
33780 + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
33783 + p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
33785 + for (i = 0; i < srv->config_context->used; i++) {
33786 + plugin_config *s;
33788 + s = calloc(1, sizeof(plugin_config));
33789 + s->db = buffer_init();
33790 + s->user = buffer_init();
33791 + s->pass = buffer_init();
33792 + s->sock = buffer_init();
33793 + s->hostname = buffer_init();
33794 + s->backend = buffer_init();
33795 + s->port = 0; /* default port for mysql */
33796 + s->select_vhost = buffer_init();
33797 + s->backend_data = NULL;
33799 + cv[0].destination = s->db;
33800 + cv[1].destination = s->user;
33801 + cv[2].destination = s->pass;
33802 + cv[3].destination = s->sock;
33803 + cv[4].destination = s->select_vhost;
33804 + cv[5].destination = s->hostname;
33805 + cv[6].destination = &(s->port);
33806 + cv[7].destination = s->backend;
33808 + /* backend compat */
33809 + cv[8].destination = cv[0].destination;
33810 + cv[9].destination = cv[1].destination;
33811 + cv[10].destination = cv[2].destination;
33812 + cv[11].destination = cv[3].destination;
33813 + cv[12].destination = cv[4].destination;
33814 + cv[13].destination = cv[5].destination;
33815 + cv[14].destination = cv[6].destination;
33817 + p->config_storage[i] = s;
33819 + if (config_insert_values_global(srv,
33820 + ((data_config *)srv->config_context->data[i])->value,
33821 + cv)) return HANDLER_ERROR;
33823 + /* we only parse the config, the backend plugin will patch itself into the plugin-struct */
33826 + return HANDLER_GO_ON;
33829 +static int mod_sql_vhost_core_patch_connection(server *srv, connection *con, plugin_data *p) {
33831 + plugin_config *s = p->config_storage[0];
33833 + PATCH_OPTION(backend_data);
33834 + PATCH_OPTION(get_vhost);
33836 + /* skip the first, the global context */
33837 + for (i = 1; i < srv->config_context->used; i++) {
33838 + data_config *dc = (data_config *)srv->config_context->data[i];
33839 + s = p->config_storage[i];
33841 + /* condition didn't match */
33842 + if (!config_check_cond(srv, con, dc)) continue;
33844 + if (s->backend_data) {
33845 + PATCH_OPTION(backend_data);
33846 + PATCH_OPTION(get_vhost);
33853 +/* handle document root request */
33854 +CONNECTION_FUNC(mod_sql_vhost_core_handle_docroot) {
33855 + plugin_data *p = p_d;
33856 + stat_cache_entry *sce;
33858 + /* no host specified? */
33859 + if (!con->uri.authority->used) return HANDLER_GO_ON;
33861 + mod_sql_vhost_core_patch_connection(srv, con, p);
33863 + /* do we have backend ? */
33864 + if (!p->conf.get_vhost) return HANDLER_GO_ON;
33866 + /* ask the backend for the data */
33867 + if (0 != p->conf.get_vhost(srv, con, p->conf.backend_data, p->docroot, p->host)) {
33868 + return HANDLER_GO_ON;
33871 + if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->docroot, &sce)) {
33872 + log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->docroot);
33873 + return HANDLER_GO_ON;
33875 + if (!S_ISDIR(sce->st.st_mode)) {
33876 + log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->docroot);
33877 + return HANDLER_GO_ON;
33880 + buffer_copy_string_buffer(con->server_name, p->host);
33881 + buffer_copy_string_buffer(con->physical.doc_root, p->docroot);
33883 + return HANDLER_GO_ON;
33886 +/* this function is called at dlopen() time and inits the callbacks */
33887 +int mod_sql_vhost_core_plugin_init(plugin *p) {
33888 + p->version = LIGHTTPD_VERSION_ID;
33889 + p->name = buffer_init_string("mod_sql_vhost_core");
33891 + p->init = mod_sql_vhost_core_init;
33892 + p->cleanup = mod_sql_vhost_core_cleanup;
33894 + p->set_defaults = mod_sql_vhost_core_set_defaults;
33895 + p->handle_docroot = mod_sql_vhost_core_handle_docroot;
33900 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_sql_vhost_core.h lighttpd-1.4.12/src/mod_sql_vhost_core.h
33901 --- lighttpd-1.4.11/src/mod_sql_vhost_core.h 1970-01-01 03:00:00.000000000 +0300
33902 +++ lighttpd-1.4.12/src/mod_sql_vhost_core.h 2006-07-11 21:23:40.000000000 +0300
33904 +#ifndef _MOD_SQL_VHOST_CORE_H_
33905 +#define _MOD_SQL_VHOST_CORE_H_
33907 +#include "buffer.h"
33908 +#include "plugin.h"
33910 +#define SQLVHOST_BACKEND_GETVHOST_PARAMS \
33911 + (server *srv, connection *con, void *p_d, buffer *docroot, buffer *host)
33913 +#define SQLVHOST_BACKEND_GETVHOST_RETVAL handler_t
33915 +#define SQLVHOST_BACKEND_GETVHOST(name) \
33916 + SQLVHOST_BACKEND_GETVHOST_RETVAL name SQLVHOST_BACKEND_GETVHOST_PARAMS
33918 +#define SQLVHOST_BACKEND_GETVHOST_PTR(name) \
33919 + SQLVHOST_BACKEND_GETVHOST_RETVAL (* name)SQLVHOST_BACKEND_GETVHOST_PARAMS
33927 + buffer *hostname;
33928 + unsigned short port;
33931 + void *backend_data;
33933 + buffer *select_vhost;
33935 + SQLVHOST_BACKEND_GETVHOST_PTR(get_vhost);
33936 +} mod_sql_vhost_core_plugin_config;
33938 +/* global plugin data */
33945 + mod_sql_vhost_core_plugin_config **config_storage;
33947 + mod_sql_vhost_core_plugin_config conf;
33948 +} mod_sql_vhost_core_plugin_data;
33953 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi.c lighttpd-1.4.12/src/mod_ssi.c
33954 --- lighttpd-1.4.11/src/mod_ssi.c 2006-03-04 17:09:48.000000000 +0200
33955 +++ lighttpd-1.4.12/src/mod_ssi.c 2006-07-11 21:23:40.000000000 +0300
33957 #include <string.h>
33960 -#include <unistd.h>
33965 #include "inet_ntop_cache.h"
33967 #include "sys-socket.h"
33968 +#include "sys-strings.h"
33969 +#include "sys-files.h"
33973 @@ -39,15 +40,15 @@
33974 /* init the plugin data */
33975 INIT_FUNC(mod_ssi_init) {
33979 p = calloc(1, sizeof(*p));
33982 p->timefmt = buffer_init();
33983 p->stat_fn = buffer_init();
33986 p->ssi_vars = array_init();
33987 p->ssi_cgi_env = array_init();
33993 @@ -55,21 +56,21 @@
33994 FREE_FUNC(mod_ssi_free) {
33995 plugin_data *p = p_d;
33999 if (!p) return HANDLER_GO_ON;
34002 if (p->config_storage) {
34004 for (i = 0; i < srv->config_context->used; i++) {
34005 plugin_config *s = p->config_storage[i];
34008 array_free(s->ssi_extension);
34013 free(p->config_storage);
34017 array_free(p->ssi_vars);
34018 array_free(p->ssi_cgi_env);
34022 buffer_free(p->timefmt);
34023 buffer_free(p->stat_fn);
34029 return HANDLER_GO_ON;
34032 @@ -92,36 +93,36 @@
34033 const char *errptr;
34037 - config_values_t cv[] = {
34039 + config_values_t cv[] = {
34040 { "ssi.extension", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
34041 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
34045 if (!p) return HANDLER_ERROR;
34048 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
34051 for (i = 0; i < srv->config_context->used; i++) {
34055 s = calloc(1, sizeof(plugin_config));
34056 s->ssi_extension = array_init();
34059 cv[0].destination = s->ssi_extension;
34062 p->config_storage[i] = s;
34065 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
34066 return HANDLER_ERROR;
34072 /* allow 2 params */
34073 if (NULL == (p->ssi_regex = pcre_compile("<!--#([a-z]+)\\s+(?:([a-z]+)=\"(.*?)(?<!\\\\)\"\\s*)?(?:([a-z]+)=\"(.*?)(?<!\\\\)\"\\s*)?-->", 0, &errptr, &erroff, NULL))) {
34074 log_error_write(srv, __FILE__, __LINE__, "sds",
34078 return HANDLER_ERROR;
34080 @@ -130,52 +131,52 @@
34081 "mod_ssi: pcre support is missing, please recompile with pcre support or remove mod_ssi from the list of modules");
34082 return HANDLER_ERROR;
34086 return HANDLER_GO_ON;
34089 int ssi_env_add(array *env, const char *key, const char *val) {
34093 if (NULL == (ds = (data_string *)array_get_unused_element(env, TYPE_STRING))) {
34094 ds = data_string_init();
34096 buffer_copy_string(ds->key, key);
34097 buffer_copy_string(ds->value, val);
34100 array_insert_unique(env, (data_unset *)ds);
34108 * the next two functions are take from fcgi.c
34113 static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
34117 for (i = 0; i < con->request.headers->used; i++) {
34121 ds = (data_string *)con->request.headers->data[i];
34124 if (ds->value->used && ds->key->used) {
34126 buffer_reset(srv->tmp_buf);
34129 /* don't forward the Authorization: Header */
34130 if (0 == strcasecmp(ds->key->ptr, "AUTHORIZATION")) {
34135 if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
34136 buffer_copy_string(srv->tmp_buf, "HTTP_");
34137 srv->tmp_buf->used--;
34141 buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
34142 for (j = 0; j < ds->key->used - 1; j++) {
34144 @@ -189,33 +190,33 @@
34145 srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
34147 srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0';
34150 ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
34158 static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
34162 server_socket *srv_sock = con->srv_socket;
34166 char b2[INET6_ADDRSTRLEN + 1];
34169 #define CONST_STRING(x) \
34173 array_reset(p->ssi_cgi_env);
34176 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION);
34177 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"),
34179 - inet_ntop(srv_sock->addr.plain.sa_family,
34180 - srv_sock->addr.plain.sa_family == AF_INET6 ?
34181 + inet_ntop(srv_sock->addr.plain.sa_family,
34182 + srv_sock->addr.plain.sa_family == AF_INET6 ?
34183 (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
34184 (const void *) &(srv_sock->addr.ipv4.sin_addr),
34186 @@ -224,28 +225,28 @@
34189 ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1");
34195 ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
34197 ntohs(srv_sock->addr.ipv4.sin_port)
34202 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PORT"), buf);
34205 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_ADDR"),
34206 inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
34209 if (con->authed_user->used) {
34210 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_USER"),
34211 con->authed_user->ptr);
34215 if (con->request.content_length > 0) {
34216 /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
34219 /* request.content_length < SSIZE_MAX, see request.c */
34220 ltostr(buf, con->request.content_length);
34221 ssi_env_add(p->ssi_cgi_env, CONST_STRING("CONTENT_LENGTH"), buf);
34222 @@ -271,30 +272,30 @@
34223 if (con->request.pathinfo->used) {
34224 ssi_env_add(p->ssi_cgi_env, CONST_STRING("PATH_INFO"), con->request.pathinfo->ptr);
34228 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SCRIPT_FILENAME"), con->physical.path->ptr);
34229 ssi_env_add(p->ssi_cgi_env, CONST_STRING("DOCUMENT_ROOT"), con->physical.doc_root->ptr);
34232 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_URI"), con->request.uri->ptr);
34233 ssi_env_add(p->ssi_cgi_env, CONST_STRING("QUERY_STRING"), con->uri.query->used ? con->uri.query->ptr : "");
34234 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_METHOD"), get_http_method_name(con->request.http_method));
34235 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REDIRECT_STATUS"), "200");
34236 ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PROTOCOL"), get_http_version_name(con->request.http_version));
34239 ssi_env_add_request_headers(srv, con, p);
34245 -static int process_ssi_stmt(server *srv, connection *con, plugin_data *p,
34246 +static int process_ssi_stmt(server *srv, connection *con, plugin_data *p,
34247 const char **l, size_t n) {
34248 size_t i, ssicmd = 0;
34256 - enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD,
34257 + enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD,
34258 SSI_CONFIG, SSI_PRINTENV, SSI_SET, SSI_IF, SSI_ELIF,
34259 SSI_ELSE, SSI_ENDIF, SSI_EXEC } type;
34261 @@ -310,27 +311,27 @@
34262 { "endif", SSI_ENDIF },
34263 { "else", SSI_ELSE },
34264 { "exec", SSI_EXEC },
34267 { NULL, SSI_UNSET }
34271 for (i = 0; ssicmds[i].var; i++) {
34272 if (0 == strcmp(l[1], ssicmds[i].var)) {
34273 ssicmd = ssicmds[i].type;
34282 int var = 0, enc = 0;
34283 const char *var_val = NULL;
34284 stat_cache_entry *sce = NULL;
34290 - enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI,
34291 + enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI,
34292 SSI_ECHO_LAST_MODIFIED, SSI_ECHO_USER_NAME } type;
34294 { "DATE_GMT", SSI_ECHO_DATE_GMT },
34295 @@ -339,27 +340,27 @@
34296 { "DOCUMENT_URI", SSI_ECHO_DOCUMENT_URI },
34297 { "LAST_MODIFIED", SSI_ECHO_LAST_MODIFIED },
34298 { "USER_NAME", SSI_ECHO_USER_NAME },
34301 { NULL, SSI_ECHO_UNSET }
34308 enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type;
34310 { "url", SSI_ENC_URL },
34311 { "none", SSI_ENC_NONE },
34312 { "entity", SSI_ENC_ENTITY },
34315 { NULL, SSI_ENC_UNSET }
34319 for (i = 2; i < n; i += 2) {
34320 if (0 == strcmp(l[i], "var")) {
34327 for (j = 0; echovars[j].var; j++) {
34328 if (0 == strcmp(l[i+1], echovars[j].var)) {
34329 var = echovars[j].type;
34330 @@ -368,7 +369,7 @@
34332 } else if (0 == strcmp(l[i], "encoding")) {
34336 for (j = 0; encvars[j].var; j++) {
34337 if (0 == strcmp(l[i+1], encvars[j].var)) {
34338 enc = encvars[j].type;
34339 @@ -377,26 +378,26 @@
34342 log_error_write(srv, __FILE__, __LINE__, "sss",
34343 - "ssi: unknow attribute for ",
34344 + "ssi: unknow attribute for ",
34350 if (p->if_is_false) break;
34354 log_error_write(srv, __FILE__, __LINE__, "sss",
34357 l[1], "var is missing");
34361 stat_cache_get_entry(srv, con, con->physical.path, &sce);
34365 case SSI_ECHO_USER_NAME: {
34369 b = chunkqueue_get_append_buffer(con->write_queue);
34371 if (NULL == (pw = getpwuid(sce->st.st_uid))) {
34372 @@ -411,7 +412,7 @@
34374 case SSI_ECHO_LAST_MODIFIED: {
34375 time_t t = sce->st.st_mtime;
34378 b = chunkqueue_get_append_buffer(con->write_queue);
34379 if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
34380 buffer_copy_string(b, "(none)");
34381 @@ -422,7 +423,7 @@
34383 case SSI_ECHO_DATE_LOCAL: {
34384 time_t t = time(NULL);
34387 b = chunkqueue_get_append_buffer(con->write_queue);
34388 if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
34389 buffer_copy_string(b, "(none)");
34390 @@ -433,7 +434,7 @@
34392 case SSI_ECHO_DATE_GMT: {
34393 time_t t = time(NULL);
34396 b = chunkqueue_get_append_buffer(con->write_queue);
34397 if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) {
34398 buffer_copy_string(b, "(none)");
34399 @@ -444,7 +445,7 @@
34401 case SSI_ECHO_DOCUMENT_NAME: {
34405 b = chunkqueue_get_append_buffer(con->write_queue);
34406 if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
34407 buffer_copy_string_buffer(b, con->physical.path);
34408 @@ -461,15 +462,15 @@
34411 /* check if it is a cgi-var */
34414 b = chunkqueue_get_append_buffer(con->write_queue);
34417 if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) {
34418 buffer_copy_string_buffer(b, ds->value);
34420 buffer_copy_string(b, "(none)");
34427 @@ -481,7 +482,7 @@
34428 const char * file_path = NULL, *virt_path = NULL;
34433 for (i = 2; i < n; i += 2) {
34434 if (0 == strcmp(l[i], "file")) {
34435 file_path = l[i+1];
34436 @@ -489,28 +490,28 @@
34437 virt_path = l[i+1];
34439 log_error_write(srv, __FILE__, __LINE__, "sss",
34440 - "ssi: unknow attribute for ",
34441 + "ssi: unknow attribute for ",
34447 if (!file_path && !virt_path) {
34448 log_error_write(srv, __FILE__, __LINE__, "sss",
34451 l[1], "file or virtual are missing");
34456 if (file_path && virt_path) {
34457 log_error_write(srv, __FILE__, __LINE__, "sss",
34460 l[1], "only one of file and virtual is allowed here");
34467 if (p->if_is_false) break;
34471 /* current doc-root */
34472 if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
34473 @@ -519,46 +520,46 @@
34474 buffer_copy_string_len(p->stat_fn, con->physical.path->ptr, sl - con->physical.path->ptr + 1);
34477 - buffer_copy_string(srv->tmp_buf, file_path);
34478 + buffer_copy_string(srv->tmp_buf, file_path);
34479 buffer_urldecode_path(srv->tmp_buf);
34480 - buffer_path_simplify(srv->tmp_buf, srv->tmp_buf);
34481 - buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
34482 + buffer_path_simplify(srv->tmp_buf, srv->tmp_buf);
34483 + buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
34488 if (virt_path[0] == '/') {
34489 buffer_copy_string(p->stat_fn, virt_path);
34491 /* there is always a / */
34492 sl = strrchr(con->uri.path->ptr, '/');
34495 buffer_copy_string_len(p->stat_fn, con->uri.path->ptr, sl - con->uri.path->ptr + 1);
34496 buffer_append_string(p->stat_fn, virt_path);
34500 buffer_urldecode_path(p->stat_fn);
34501 buffer_path_simplify(srv->tmp_buf, p->stat_fn);
34504 /* we have an uri */
34507 buffer_copy_string_buffer(p->stat_fn, con->physical.doc_root);
34508 buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
34512 if (0 == stat(p->stat_fn->ptr, &st)) {
34513 time_t t = st.st_mtime;
34518 b = chunkqueue_get_append_buffer(con->write_queue);
34521 const char *abr[] = { " B", " kB", " MB", " GB", " TB", NULL };
34524 off_t s = st.st_size;
34527 for (j = 0; s > 1024 && abr[j+1]; s /= 1024, j++);
34530 buffer_copy_off_t(b, s);
34531 buffer_append_string(b, abr[j]);
34533 @@ -579,7 +580,7 @@
34536 log_error_write(srv, __FILE__, __LINE__, "sbs",
34537 - "ssi: stating failed ",
34538 + "ssi: stating failed ",
34539 p->stat_fn, strerror(errno));
34542 @@ -593,33 +594,33 @@
34545 log_error_write(srv, __FILE__, __LINE__, "sss",
34546 - "ssi: unknow attribute for ",
34547 + "ssi: unknow attribute for ",
34553 if (p->if_is_false) break;
34560 if (NULL == (ds = (data_string *)array_get_unused_element(p->ssi_vars, TYPE_STRING))) {
34561 ds = data_string_init();
34563 buffer_copy_string(ds->key, key);
34564 buffer_copy_string(ds->value, val);
34567 array_insert_unique(p->ssi_vars, (data_unset *)ds);
34569 log_error_write(srv, __FILE__, __LINE__, "sss",
34570 - "ssi: var and value have to be set in",
34571 + "ssi: var and value have to be set in",
34578 if (p->if_is_false) break;
34581 for (i = 2; i < n; i += 2) {
34582 if (0 == strcmp(l[i], "timefmt")) {
34583 buffer_copy_string(p->timefmt, l[i+1]);
34584 @@ -632,63 +633,65 @@
34585 log_error_write(srv, __FILE__, __LINE__, "sssss",
34586 "ssi: unknow value for attribute '",
34593 log_error_write(srv, __FILE__, __LINE__, "sss",
34594 - "ssi: unknow attribute for ",
34595 + "ssi: unknow attribute for ",
34601 if (p->if_is_false) break;
34604 b = chunkqueue_get_append_buffer(con->write_queue);
34605 buffer_copy_string(b, "<pre>");
34606 for (i = 0; i < p->ssi_vars->used; i++) {
34607 data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]];
34610 buffer_append_string_buffer(b, ds->key);
34611 buffer_append_string(b, ": ");
34612 buffer_append_string_buffer(b, ds->value);
34613 buffer_append_string(b, "<br />");
34617 buffer_append_string(b, "</pre>");
34624 const char *cmd = NULL;
34626 int from_exec_fds[2];
34629 for (i = 2; i < n; i += 2) {
34630 if (0 == strcmp(l[i], "cmd")) {
34633 log_error_write(srv, __FILE__, __LINE__, "sss",
34634 - "ssi: unknow attribute for ",
34635 + "ssi: unknow attribute for ",
34641 if (p->if_is_false) break;
34644 /* create a return pipe and send output to the html-page
34646 - * as exec is assumed evil it is implemented synchronously
34648 + * as exec is assumed evil it is implemented synchronously
34655 if (pipe(from_exec_fds)) {
34656 - log_error_write(srv, __FILE__, __LINE__, "ss",
34657 + log_error_write(srv, __FILE__, __LINE__, "ss",
34658 "pipe failed: ", strerror(errno));
34664 switch (pid = fork()) {
34666 @@ -698,14 +701,14 @@
34667 close(from_exec_fds[1]);
34669 close(from_exec_fds[0]);
34673 close(STDIN_FILENO);
34676 execl("/bin/sh", "sh", "-c", cmd, NULL);
34679 log_error_write(srv, __FILE__, __LINE__, "sss", "spawing exec failed:", strerror(errno), cmd);
34685 @@ -718,9 +721,9 @@
34691 close(from_exec_fds[1]);
34694 /* wait for the client to end */
34695 if (-1 == waitpid(pid, &status, 0)) {
34696 log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed:", strerror(errno));
34697 @@ -730,7 +733,7 @@
34700 if (ioctl(from_exec_fds[0], FIONREAD, &toread)) {
34701 - log_error_write(srv, __FILE__, __LINE__, "s",
34702 + log_error_write(srv, __FILE__, __LINE__, "s",
34703 "unexpected end-of-file (perhaps the ssi-exec process died)");
34706 @@ -738,10 +741,10 @@
34708 b = chunkqueue_get_append_buffer(con->write_queue);
34710 - buffer_prepare_copy(b, toread + 1);
34711 + buffer_prepare_copy(b, toread + 1);
34713 if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) {
34714 - /* read failed */
34715 + /* read failed */
34719 @@ -755,59 +758,58 @@
34720 log_error_write(srv, __FILE__, __LINE__, "s", "process exited abnormally");
34722 close(from_exec_fds[0]);
34737 const char *expr = NULL;
34740 for (i = 2; i < n; i += 2) {
34741 if (0 == strcmp(l[i], "expr")) {
34744 log_error_write(srv, __FILE__, __LINE__, "sss",
34745 - "ssi: unknow attribute for ",
34746 + "ssi: unknow attribute for ",
34753 log_error_write(srv, __FILE__, __LINE__, "sss",
34756 l[1], "expr missing");
34761 if ((!p->if_is_false) &&
34762 - ((p->if_is_false_level == 0) ||
34763 + ((p->if_is_false_level == 0) ||
34764 (p->if_level < p->if_is_false_level))) {
34765 switch (ssi_eval_expr(srv, con, p, expr)) {
34768 - p->if_is_false = 1;
34770 + p->if_is_false = 1;
34771 p->if_is_false_level = p->if_level;
34774 - p->if_is_false = 0;
34776 + p->if_is_false = 0;
34791 if (p->if_is_false) {
34792 if ((p->if_level == p->if_is_false_level) &&
34793 (p->if_is_false_endif == 0)) {
34794 @@ -815,11 +817,11 @@
34797 p->if_is_false = 1;
34800 p->if_is_false_level = p->if_level;
34807 const char *expr = NULL;
34808 @@ -828,52 +830,52 @@
34811 log_error_write(srv, __FILE__, __LINE__, "sss",
34812 - "ssi: unknow attribute for ",
34813 + "ssi: unknow attribute for ",
34820 log_error_write(srv, __FILE__, __LINE__, "sss",
34823 l[1], "expr missing");
34831 if (p->if_level == p->if_is_false_level) {
34832 if ((p->if_is_false) &&
34833 (p->if_is_false_endif == 0)) {
34834 switch (ssi_eval_expr(srv, con, p, expr)) {
34837 - p->if_is_false = 1;
34839 + p->if_is_false = 1;
34840 p->if_is_false_level = p->if_level;
34843 - p->if_is_false = 0;
34845 + p->if_is_false = 0;
34849 - p->if_is_false = 1;
34850 + p->if_is_false = 1;
34851 p->if_is_false_level = p->if_level;
34852 p->if_is_false_endif = 1;
34866 if (p->if_level == p->if_is_false_level) {
34867 p->if_is_false = 0;
34868 p->if_is_false_endif = 0;
34874 log_error_write(srv, __FILE__, __LINE__, "ss",
34875 @@ -881,41 +883,41 @@
34886 static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) {
34897 /* get a stream to the file */
34900 array_reset(p->ssi_vars);
34901 array_reset(p->ssi_cgi_env);
34902 buffer_copy_string(p->timefmt, "%a, %d %b %Y %H:%M:%S %Z");
34904 build_ssi_cgi_vars(srv, con, p);
34905 p->if_is_false = 0;
34908 if (-1 == stream_open(&s, con->physical.path)) {
34909 log_error_write(srv, __FILE__, __LINE__, "sb",
34910 "stream-open: ", con->physical.path);
34918 - * <!--#element attribute=value attribute=value ... -->
34920 + * <!--#element attribute=value attribute=value ... -->
34923 - * errmsg -- missing
34924 + * errmsg -- missing
34928 @@ -937,13 +939,13 @@
34945 @@ -951,118 +953,115 @@
34957 - * The current date in Greenwich Mean Time.
34959 - * The current date in the local time zone.
34961 - * The filename (excluding directories) of the document requested by the user.
34963 - * The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.
34965 - * The last modification date of the document requested by the user.
34968 + * The current date in Greenwich Mean Time.
34970 + * The current date in the local time zone.
34972 + * The filename (excluding directories) of the document requested by the user.
34974 + * The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.
34976 + * The last modification date of the document requested by the user.
34978 * Contains the owner of the file which included it.
34982 -#ifdef HAVE_PCRE_H
34983 +#ifdef HAVE_PCRE_H
34984 for (i = 0; (n = pcre_exec(p->ssi_regex, NULL, s.start, s.size, i, 0, ovec, N * 3)) > 0; i = ovec[1]) {
34986 /* take everything from last offset to current match pos */
34989 if (!p->if_is_false) chunkqueue_append_file(con->write_queue, con->physical.path, i, ovec[0] - i);
34992 pcre_get_substring_list(s.start, ovec, n, &l);
34993 process_ssi_stmt(srv, con, p, l, n);
34994 pcre_free_substring_list(l);
34999 case PCRE_ERROR_NOMATCH:
35000 /* copy everything/the rest */
35001 chunkqueue_append_file(con->write_queue, con->physical.path, i, s.size - i);
35006 log_error_write(srv, __FILE__, __LINE__, "sd",
35007 "execution error while matching: ", n);
35019 con->file_started = 1;
35020 con->file_finished = 1;
35023 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
35026 /* reset physical.path */
35027 buffer_reset(con->physical.path);
35033 -#define PATCH(x) \
35034 - p->conf.x = s->x;
35035 static int mod_ssi_patch_connection(server *srv, connection *con, plugin_data *p) {
35037 plugin_config *s = p->config_storage[0];
35039 - PATCH(ssi_extension);
35042 + PATCH_OPTION(ssi_extension);
35044 /* skip the first, the global context */
35045 for (i = 1; i < srv->config_context->used; i++) {
35046 data_config *dc = (data_config *)srv->config_context->data[i];
35047 s = p->config_storage[i];
35050 /* condition didn't match */
35051 if (!config_check_cond(srv, con, dc)) continue;
35055 for (j = 0; j < dc->value->used; j++) {
35056 data_unset *du = dc->value->data[j];
35059 if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) {
35060 - PATCH(ssi_extension);
35061 + PATCH_OPTION(ssi_extension);
35071 URIHANDLER_FUNC(mod_ssi_physical_path) {
35072 plugin_data *p = p_d;
35076 if (con->physical.path->used == 0) return HANDLER_GO_ON;
35079 mod_ssi_patch_connection(srv, con, p);
35082 for (k = 0; k < p->conf.ssi_extension->used; k++) {
35083 data_string *ds = (data_string *)p->conf.ssi_extension->data[k];
35086 if (ds->value->used == 0) continue;
35089 if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) {
35090 /* handle ssi-request */
35093 if (mod_ssi_handle_request(srv, con, p)) {
35095 con->http_status = 500;
35099 return HANDLER_FINISHED;
35105 return HANDLER_GO_ON;
35107 @@ -1072,13 +1071,13 @@
35108 int mod_ssi_plugin_init(plugin *p) {
35109 p->version = LIGHTTPD_VERSION_ID;
35110 p->name = buffer_init_string("ssi");
35113 p->init = mod_ssi_init;
35114 p->handle_subrequest_start = mod_ssi_physical_path;
35115 p->set_defaults = mod_ssi_set_defaults;
35116 p->cleanup = mod_ssi_free;
35124 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi.h lighttpd-1.4.12/src/mod_ssi.h
35125 --- lighttpd-1.4.11/src/mod_ssi.h 2005-08-11 01:26:39.000000000 +0300
35126 +++ lighttpd-1.4.12/src/mod_ssi.h 2006-07-11 21:23:40.000000000 +0300
35127 @@ -19,23 +19,23 @@
35132 -#ifdef HAVE_PCRE_H
35134 +#ifdef HAVE_PCRE_H
35146 array *ssi_cgi_env;
35149 int if_level, if_is_false_level, if_is_false, if_is_false_endif;
35152 plugin_config **config_storage;
35154 - plugin_config conf;
35156 + plugin_config conf;
35159 int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr);
35160 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi_expr.c lighttpd-1.4.12/src/mod_ssi_expr.c
35161 --- lighttpd-1.4.11/src/mod_ssi_expr.c 2005-08-11 01:26:48.000000000 +0300
35162 +++ lighttpd-1.4.12/src/mod_ssi_expr.c 2006-07-11 21:23:40.000000000 +0300
35175 @@ -21,15 +21,15 @@
35177 ssi_val_t *ssi_val_init() {
35181 s = calloc(1, sizeof(*s));
35187 void ssi_val_free(ssi_val_t *s) {
35188 if (s->str) buffer_free(s->str);
35194 @@ -45,175 +45,175 @@
35195 ssi_tokenizer_t *t, int *token_id, buffer *token) {
35202 for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) {
35203 char c = t->input[t->offset];
35217 buffer_copy_string(token, "(=)");
35222 if (t->input[t->offset + 1] == '=') {
35230 buffer_copy_string(token, "(>=)");
35239 buffer_copy_string(token, "(>)");
35245 if (t->input[t->offset + 1] == '=') {
35253 buffer_copy_string(token, "(<=)");
35262 buffer_copy_string(token, "(<)");
35270 if (t->input[t->offset + 1] == '=') {
35278 buffer_copy_string(token, "(!=)");
35287 buffer_copy_string(token, "(!)");
35293 if (t->input[t->offset + 1] == '&') {
35301 buffer_copy_string(token, "(&&)");
35303 - log_error_write(srv, __FILE__, __LINE__, "sds",
35304 - "pos:", t->line_pos,
35305 + log_error_write(srv, __FILE__, __LINE__, "sds",
35306 + "pos:", t->line_pos,
35307 "missing second &");
35314 if (t->input[t->offset + 1] == '|') {
35322 buffer_copy_string(token, "(||)");
35324 - log_error_write(srv, __FILE__, __LINE__, "sds",
35325 - "pos:", t->line_pos,
35326 + log_error_write(srv, __FILE__, __LINE__, "sds",
35327 + "pos:", t->line_pos,
35328 "missing second |");
35342 /* search for the terminating " */
35343 for (i = 1; t->input[t->offset + i] && t->input[t->offset + i] != '\''; i++);
35346 if (t->input[t->offset + i]) {
35350 buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
35353 t->offset += i + 1;
35354 t->line_pos += i + 1;
35358 - log_error_write(srv, __FILE__, __LINE__, "sds",
35359 - "pos:", t->line_pos,
35361 + log_error_write(srv, __FILE__, __LINE__, "sds",
35362 + "pos:", t->line_pos,
35363 "missing closing quote");
35379 buffer_copy_string(token, "(");
35389 buffer_copy_string(token, ")");
35392 if (t->input[t->offset + 1] == '{') {
35393 for (i = 2; t->input[t->offset + i] && t->input[t->offset + i] != '}'; i++);
35396 if (t->input[t->offset + i] != '}') {
35397 - log_error_write(srv, __FILE__, __LINE__, "sds",
35398 - "pos:", t->line_pos,
35399 + log_error_write(srv, __FILE__, __LINE__, "sds",
35400 + "pos:", t->line_pos,
35401 "missing closing quote");
35408 buffer_copy_string_len(token, t->input + t->offset + 2, i-3);
35410 for (i = 1; isalpha(t->input[t->offset + i]) || t->input[t->offset + i] == '_'; i++);
35413 buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
35420 if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, token->ptr))) {
35421 buffer_copy_string_buffer(token, ds->value);
35422 } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) {
35423 @@ -221,16 +221,16 @@
35425 buffer_copy_string(token, "");
35435 for (i = 0; isgraph(t->input[t->offset + i]); i++) {
35436 char d = t->input[t->offset + i];
35443 @@ -244,25 +244,25 @@
35452 buffer_copy_string_len(token, t->input + t->offset, i);
35469 } else if (t->offset < t->size) {
35470 - log_error_write(srv, __FILE__, __LINE__, "sds",
35471 - "pos:", t->line_pos,
35472 + log_error_write(srv, __FILE__, __LINE__, "sds",
35473 + "pos:", t->line_pos,
35477 @@ -275,50 +275,50 @@
35485 t.size = strlen(expr);
35498 /* default context */
35501 pParser = ssiexprparserAlloc( malloc );
35502 token = buffer_init();
35503 while((1 == (ret = ssi_expr_tokenizer(srv, con, p, &t, &token_id, token))) && context.ok) {
35504 ssiexprparser(pParser, token_id, token, &context);
35507 token = buffer_init();
35509 ssiexprparser(pParser, 0, token, &context);
35510 ssiexprparserFree(pParser, free );
35513 buffer_free(token);
35517 - log_error_write(srv, __FILE__, __LINE__, "s",
35518 + log_error_write(srv, __FILE__, __LINE__, "s",
35519 "expr parser failed");
35524 if (context.ok == 0) {
35525 - log_error_write(srv, __FILE__, __LINE__, "sds",
35526 - "pos:", t.line_pos,
35527 + log_error_write(srv, __FILE__, __LINE__, "sds",
35528 + "pos:", t.line_pos,
35529 "parser failed somehow near here");
35533 - log_error_write(srv, __FILE__, __LINE__, "ssd",
35534 + log_error_write(srv, __FILE__, __LINE__, "ssd",
35540 return context.val.bo;
35542 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi_expr.h lighttpd-1.4.12/src/mod_ssi_expr.h
35543 --- lighttpd-1.4.11/src/mod_ssi_expr.h 2005-08-11 01:26:48.000000000 +0300
35544 +++ lighttpd-1.4.12/src/mod_ssi_expr.h 2006-07-11 21:23:40.000000000 +0300
35548 enum { SSI_TYPE_UNSET, SSI_TYPE_BOOL, SSI_TYPE_STRING } type;
35565 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_ssi_exprparser.c lighttpd-1.4.12/src/mod_ssi_exprparser.c
35566 --- lighttpd-1.4.11/src/mod_ssi_exprparser.c 2005-10-03 00:40:25.000000000 +0300
35567 +++ lighttpd-1.4.12/src/mod_ssi_exprparser.c 2006-07-11 21:49:18.000000000 +0300
35568 @@ -18,10 +18,10 @@
35569 /* Next is all token values, in a form suitable for use by makeheaders.
35570 ** This section will be null unless lemon is run with the -m switch.
35574 ** These constants (all generated automatically by the parser generator)
35575 ** specify the various kinds of tokens (terminals) that the parser
35579 ** Each symbol here is a terminal symbol in the grammar.
35582 ** and nonterminals. "int" is used otherwise.
35583 ** YYNOCODE is a number of type YYCODETYPE which corresponds
35584 ** to no legal terminal or nonterminal number. This
35585 -** number is used to fill in empty slots of the hash
35586 +** number is used to fill in empty slots of the hash
35588 ** YYFALLBACK If defined, this indicates that one or more tokens
35589 ** have fall-back values which should be used if the
35591 ** and nonterminal numbers. "unsigned char" is
35592 ** used if there are fewer than 250 rules and
35593 ** states combined. "int" is used otherwise.
35594 -** ssiexprparserTOKENTYPE is the data type used for minor tokens given
35595 +** ssiexprparserTOKENTYPE is the data type used for minor tokens given
35596 ** directly to the parser from the tokenizer.
35597 ** YYMINORTYPE is the data type used for all minor tokens.
35598 ** This is typically a union of many types, one of
35600 /* Next are that tables used to determine what action to take based on the
35601 ** current state and lookahead token. These tables are used to implement
35602 ** functions that take a state number and lookahead value and return an
35603 -** action integer.
35604 +** action integer.
35606 ** Suppose the action integer is N. Then the action is determined as
35608 @@ -116,7 +116,7 @@
35609 ** If the index value yy_shift_ofst[S]+X is out of range or if the value
35610 ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
35611 ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
35612 -** and that yy_default[S] should be used instead.
35613 +** and that yy_default[S] should be used instead.
35615 ** The formula above is for computing the action when the lookahead is
35616 ** a terminal symbol. If the lookahead is a non-terminal (as occurs after
35617 @@ -168,7 +168,7 @@
35619 /* The next table maps tokens into fallback tokens. If a construct
35620 ** like the following:
35623 ** %fallback ID X Y Z.
35625 ** appears in the grammer, then ID becomes a fallback token for X, Y,
35626 @@ -219,10 +219,10 @@
35627 #endif /* NDEBUG */
35632 ** Turn parser tracing on by giving a stream to which to write the trace
35633 ** and a prompt to preface each trace message. Tracing is turned off
35634 -** by making either argument NULL
35635 +** by making either argument NULL
35639 @@ -247,7 +247,7 @@
35641 /* For tracing shifts, the names of all terminals and nonterminals
35642 ** are required. The following table supplies these names */
35643 -static const char *yyTokenName[] = {
35644 +static const char *yyTokenName[] = {
35645 "$", "AND", "OR", "EQ",
35646 "NE", "GT", "GE", "LT",
35647 "LE", "NOT", "LPARAN", "RPARAN",
35648 @@ -295,7 +295,7 @@
35654 ** This function allocates a new parser.
35655 ** The only argument is a pointer to a function which works like
35657 @@ -326,7 +326,7 @@
35658 /* Here is inserted the actions which take place when a
35659 ** terminal or non-terminal is destroyed. This can happen
35660 ** when the symbol is popped from the stack during a
35661 - ** reduce or during error processing or when a parser is
35662 + ** reduce or during error processing or when a parser is
35663 ** being destroyed before it is finished parsing.
35665 ** Note: during a reduce, the only symbols destroyed are those
35666 @@ -379,7 +379,7 @@
35672 ** Deallocate and destroy a parser. Destructors are all called for
35673 ** all stack elements before shutting the parser down.
35675 @@ -415,7 +415,7 @@
35678 int stateno = pParser->yystack[pParser->yyidx].stateno;
35681 /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */
35682 i = yy_shift_ofst[stateno];
35683 if( i==YY_SHIFT_USE_DFLT ){
35684 @@ -459,7 +459,7 @@
35687 int stateno = pParser->yystack[pParser->yyidx].stateno;
35690 i = yy_reduce_ofst[stateno];
35691 if( i==YY_REDUCE_USE_DFLT ){
35692 return yy_default[stateno];
35693 @@ -559,7 +559,7 @@
35694 ssiexprparserARG_FETCH;
35695 yymsp = &yypParser->yystack[yypParser->yyidx];
35697 - if( yyTraceFILE && yyruleno>=0
35698 + if( yyTraceFILE && yyruleno>=0
35699 && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
35700 fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
35701 yyRuleName[yyruleno]);
35702 @@ -872,7 +872,7 @@
35703 #ifdef YYERRORSYMBOL
35704 /* A syntax error has occurred.
35705 ** The response to an error depends upon whether or not the
35706 - ** grammar defines an error token "ERROR".
35707 + ** grammar defines an error token "ERROR".
35709 ** This is what we do if the grammar does define ERROR:
35711 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_staticfile.c lighttpd-1.4.12/src/mod_staticfile.c
35712 --- lighttpd-1.4.11/src/mod_staticfile.c 2006-02-15 14:31:14.000000000 +0200
35713 +++ lighttpd-1.4.12/src/mod_staticfile.c 2006-07-11 21:23:39.000000000 +0300
35715 #include "http_chunk.h"
35716 #include "response.h"
35718 +#include "sys-files.h"
35719 +#include "sys-strings.h"
35721 * this is a staticfile for a lighttpd plugin
35727 @@ -29,48 +31,48 @@
35736 plugin_config **config_storage;
35738 - plugin_config conf;
35740 + plugin_config conf;
35743 /* init the plugin data */
35744 INIT_FUNC(mod_staticfile_init) {
35748 p = calloc(1, sizeof(*p));
35751 p->range_buf = buffer_init();
35757 -/* detroy the plugin data */
35758 +/* destroy the plugin data */
35759 FREE_FUNC(mod_staticfile_free) {
35760 plugin_data *p = p_d;
35765 if (!p) return HANDLER_GO_ON;
35768 if (p->config_storage) {
35770 for (i = 0; i < srv->config_context->used; i++) {
35771 plugin_config *s = p->config_storage[i];
35774 array_free(s->exclude_ext);
35779 free(p->config_storage);
35781 buffer_free(p->range_buf);
35787 return HANDLER_GO_ON;
35790 @@ -79,63 +81,60 @@
35791 SETDEFAULTS_FUNC(mod_staticfile_set_defaults) {
35792 plugin_data *p = p_d;
35795 - config_values_t cv[] = {
35797 + config_values_t cv[] = {
35798 { "static-file.exclude-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
35799 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
35803 if (!p) return HANDLER_ERROR;
35806 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
35809 for (i = 0; i < srv->config_context->used; i++) {
35813 s = calloc(1, sizeof(plugin_config));
35814 s->exclude_ext = array_init();
35817 cv[0].destination = s->exclude_ext;
35820 p->config_storage[i] = s;
35823 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
35824 return HANDLER_ERROR;
35829 return HANDLER_GO_ON;
35832 -#define PATCH(x) \
35833 - p->conf.x = s->x;
35834 static int mod_staticfile_patch_connection(server *srv, connection *con, plugin_data *p) {
35836 plugin_config *s = p->config_storage[0];
35838 - PATCH(exclude_ext);
35841 + PATCH_OPTION(exclude_ext);
35843 /* skip the first, the global context */
35844 for (i = 1; i < srv->config_context->used; i++) {
35845 data_config *dc = (data_config *)srv->config_context->data[i];
35846 s = p->config_storage[i];
35849 /* condition didn't match */
35850 if (!config_check_cond(srv, con, dc)) continue;
35854 for (j = 0; j < dc->value->used; j++) {
35855 data_unset *du = dc->value->data[j];
35858 if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.exclude-extensions"))) {
35859 - PATCH(exclude_ext);
35860 + PATCH_OPTION(exclude_ext);
35870 static int http_response_parse_range(server *srv, connection *con, plugin_data *p) {
35872 @@ -146,69 +145,69 @@
35874 stat_cache_entry *sce = NULL;
35875 buffer *content_type = NULL;
35878 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
35884 end = sce->st.st_size - 1;
35887 con->response.content_length = 0;
35890 if (NULL != (ds = (data_string *)array_get_element(con->response.headers, "Content-Type"))) {
35891 content_type = ds->value;
35895 for (s = con->request.http_range, error = 0;
35896 !error && *s && NULL != (minus = strchr(s, '-')); ) {
35905 le = strtoll(s, &err, 10);
35909 /* RFC 2616 - 14.35.1 */
35912 con->http_status = 416;
35914 } else if (*err == '\0') {
35919 end = sce->st.st_size - 1;
35920 start = sce->st.st_size + le;
35921 } else if (*err == ',') {
35926 end = sce->st.st_size - 1;
35927 start = sce->st.st_size + le;
35933 } else if (*(minus+1) == '\0' || *(minus+1) == ',') {
35937 la = strtoll(s, &err, 10);
35940 if (err == minus) {
35944 if (*(err + 1) == '\0') {
35948 end = sce->st.st_size - 1;
35952 } else if (*(err + 1) == ',') {
35957 end = sce->st.st_size - 1;
35960 @@ -220,64 +219,64 @@
35963 /* <start>-<stop> */
35966 la = strtoll(s, &err, 10);
35969 if (err == minus) {
35970 le = strtoll(minus+1, &err, 10);
35973 /* RFC 2616 - 14.35.1 */
35979 if (*err == '\0') {
35986 } else if (*err == ',') {
36009 if (start < 0) start = 0;
36012 /* RFC 2616 - 14.35.1 */
36013 if (end > sce->st.st_size - 1) end = sce->st.st_size - 1;
36016 if (start > sce->st.st_size - 1) {
36020 con->http_status = 416;
36027 /* write boundary-header */
36031 b = chunkqueue_get_append_buffer(con->write_queue);
36034 buffer_copy_string(b, "\r\n--");
36035 buffer_append_string(b, boundary);
36038 /* write Content-Range */
36039 buffer_append_string(b, "\r\nContent-Range: bytes ");
36040 buffer_append_off_t(b, start);
36041 @@ -285,54 +284,54 @@
36042 buffer_append_off_t(b, end);
36043 buffer_append_string(b, "/");
36044 buffer_append_off_t(b, sce->st.st_size);
36047 buffer_append_string(b, "\r\nContent-Type: ");
36048 buffer_append_string_buffer(b, content_type);
36051 /* write END-OF-HEADER */
36052 buffer_append_string(b, "\r\n\r\n");
36055 con->response.content_length += b->used - 1;
36061 chunkqueue_append_file(con->write_queue, con->physical.path, start, end - start + 1);
36062 con->response.content_length += end - start + 1;
36067 /* something went wrong */
36068 if (error) return -1;
36072 /* add boundary end */
36076 b = chunkqueue_get_append_buffer(con->write_queue);
36079 buffer_copy_string_len(b, "\r\n--", 4);
36080 buffer_append_string(b, boundary);
36081 buffer_append_string_len(b, "--\r\n", 4);
36084 con->response.content_length += b->used - 1;
36087 /* set header-fields */
36090 buffer_copy_string(p->range_buf, "multipart/byteranges; boundary=");
36091 buffer_append_string(p->range_buf, boundary);
36094 /* overwrite content-type */
36095 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->range_buf));
36097 /* add Content-Range-header */
36100 buffer_copy_string(p->range_buf, "bytes ");
36101 buffer_append_off_t(p->range_buf, start);
36102 buffer_append_string(p->range_buf, "-");
36103 buffer_append_off_t(p->range_buf, end);
36104 buffer_append_string(p->range_buf, "/");
36105 buffer_append_off_t(p->range_buf, sce->st.st_size);
36108 response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(p->range_buf));
36111 @@ -347,12 +346,12 @@
36112 stat_cache_entry *sce = NULL;
36117 /* someone else has done a decision for us */
36118 if (con->http_status != 0) return HANDLER_GO_ON;
36119 if (con->uri.path->used == 0) return HANDLER_GO_ON;
36120 if (con->physical.path->used == 0) return HANDLER_GO_ON;
36123 /* someone else has handled this request */
36124 if (con->mode != DIRECT) return HANDLER_GO_ON;
36126 @@ -365,52 +364,52 @@
36128 return HANDLER_GO_ON;
36132 mod_staticfile_patch_connection(srv, con, p);
36135 s_len = con->uri.path->used - 1;
36138 /* ignore certain extensions */
36139 for (k = 0; k < p->conf.exclude_ext->used; k++) {
36140 - ds = (data_string *)p->conf.exclude_ext->data[k];
36142 + ds = (data_string *)p->conf.exclude_ext->data[k];
36144 if (ds->value->used == 0) continue;
36146 if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) {
36147 return HANDLER_GO_ON;
36153 if (con->conf.log_request_handling) {
36154 log_error_write(srv, __FILE__, __LINE__, "s", "-- handling file as static file");
36158 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
36159 con->http_status = 403;
36162 log_error_write(srv, __FILE__, __LINE__, "sbsb",
36163 "not a regular file:", con->uri.path,
36164 "->", con->physical.path);
36167 return HANDLER_FINISHED;
36170 - /* we only handline regular files */
36172 + /* we only handle regular files */
36173 if (!S_ISREG(sce->st.st_mode)) {
36174 con->http_status = 404;
36177 if (con->conf.log_file_not_found) {
36178 log_error_write(srv, __FILE__, __LINE__, "sbsb",
36179 "not a regular file:", con->uri.path,
36184 return HANDLER_FINISHED;
36187 - /* mod_compress might set several data directly, don't overwrite them */
36189 + /* mod_compress might set several parameters directly; don't overwrite them */
36191 /* set response content-type, if not set already */
36193 if (NULL == array_get_element(con->response.headers, "Content-Type")) {
36194 @@ -420,15 +419,15 @@
36195 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
36200 if (NULL == array_get_element(con->response.headers, "ETag")) {
36201 /* generate e-tag */
36202 etag_mutate(con->physical.etag, sce->etag);
36205 response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
36207 response_header_overwrite(srv, con, CONST_STR_LEN("Accept-Ranges"), CONST_STR_LEN("bytes"));
36210 /* prepare header */
36211 if (NULL == (ds = (data_string *)array_get_element(con->response.headers, "Last-Modified"))) {
36212 mtime = strftime_cache_get(srv, sce->st.st_mtime);
36213 @@ -444,34 +443,34 @@
36214 /* check if we have a conditional GET */
36216 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If-Range"))) {
36217 - /* if the value is the same as our ETag, we do a Range-request,
36218 + /* if the value is the same as our ETag, we do a Range-request,
36219 * otherwise a full 200 */
36221 if (!buffer_is_equal(ds->value, con->physical.etag)) {
36222 do_range_request = 0;
36227 if (do_range_request) {
36228 /* content prepared, I'm done */
36229 con->file_finished = 1;
36232 if (0 == http_response_parse_range(srv, con, p)) {
36233 con->http_status = 206;
36235 return HANDLER_FINISHED;
36240 /* if we are still here, prepare body */
36242 - /* we add it here for all requests
36243 - * the HEAD request will drop it afterwards again
36245 + /* we add it here for all requests
36246 + * the HEAD request will drop it afterwards again
36248 http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size);
36251 con->file_finished = 1;
36254 return HANDLER_FINISHED;
36257 @@ -480,13 +479,13 @@
36258 int mod_staticfile_plugin_init(plugin *p) {
36259 p->version = LIGHTTPD_VERSION_ID;
36260 p->name = buffer_init_string("staticfile");
36263 p->init = mod_staticfile_init;
36264 p->handle_subrequest_start = mod_staticfile_subrequest;
36265 p->set_defaults = mod_staticfile_set_defaults;
36266 p->cleanup = mod_staticfile_free;
36274 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_status.c lighttpd-1.4.12/src/mod_status.c
36275 --- lighttpd-1.4.11/src/mod_status.c 2006-01-10 21:45:32.000000000 +0200
36276 +++ lighttpd-1.4.12/src/mod_status.c 2006-07-11 21:23:40.000000000 +0300
36279 #include <stdlib.h>
36280 #include <string.h>
36281 -#include <unistd.h>
36285 @@ -29,114 +28,114 @@
36291 double traffic_out;
36295 double mod_5s_traffic_out[5];
36296 double mod_5s_requests[5];
36300 double rel_traffic_out;
36301 double rel_requests;
36304 double abs_traffic_out;
36305 double abs_requests;
36308 double bytes_written;
36311 buffer *module_list;
36314 plugin_config **config_storage;
36316 - plugin_config conf;
36318 + plugin_config conf;
36321 INIT_FUNC(mod_status_init) {
36326 p = calloc(1, sizeof(*p));
36329 p->traffic_out = p->requests = 0;
36330 p->rel_traffic_out = p->rel_requests = 0;
36331 p->abs_traffic_out = p->abs_requests = 0;
36332 p->bytes_written = 0;
36333 p->module_list = buffer_init();
36336 for (i = 0; i < 5; i++) {
36337 p->mod_5s_traffic_out[i] = p->mod_5s_requests[i] = 0;
36344 FREE_FUNC(mod_status_free) {
36345 plugin_data *p = p_d;
36350 if (!p) return HANDLER_GO_ON;
36353 buffer_free(p->module_list);
36356 if (p->config_storage) {
36358 for (i = 0; i < srv->config_context->used; i++) {
36359 plugin_config *s = p->config_storage[i];
36362 buffer_free(s->status_url);
36363 buffer_free(s->statistics_url);
36364 buffer_free(s->config_url);
36369 free(p->config_storage);
36378 return HANDLER_GO_ON;
36381 SETDEFAULTS_FUNC(mod_status_set_defaults) {
36382 plugin_data *p = p_d;
36385 - config_values_t cv[] = {
36387 + config_values_t cv[] = {
36388 { "status.status-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
36389 { "status.config-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
36390 { "status.enable-sort", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
36391 { "status.statistics-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
36392 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
36396 if (!p) return HANDLER_ERROR;
36399 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
36402 for (i = 0; i < srv->config_context->used; i++) {
36406 s = calloc(1, sizeof(plugin_config));
36407 s->config_url = buffer_init();
36408 s->status_url = buffer_init();
36410 s->statistics_url = buffer_init();
36413 cv[0].destination = s->status_url;
36414 cv[1].destination = s->config_url;
36415 cv[2].destination = &(s->sort);
36416 cv[3].destination = s->statistics_url;
36419 p->config_storage[i] = s;
36422 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
36423 return HANDLER_ERROR;
36428 return HANDLER_GO_ON;
36431 @@ -151,7 +150,7 @@
36432 buffer_append_string(b, value);
36433 BUFFER_APPEND_STRING_CONST(b, "</td>\n");
36434 BUFFER_APPEND_STRING_CONST(b, " </tr>\n");
36440 @@ -161,13 +160,13 @@
36441 buffer_append_string(b, key);
36442 BUFFER_APPEND_STRING_CONST(b, "</th>\n");
36443 BUFFER_APPEND_STRING_CONST(b, " </tr>\n");
36449 static int mod_status_header_append_sort(buffer *b, void *p_d, const char* key) {
36450 plugin_data *p = p_d;
36453 if (p->conf.sort) {
36454 BUFFER_APPEND_STRING_CONST(b, "<th class=\"status\"><a href=\"#\" class=\"sortheader\" onclick=\"resort(this);return false;\">");
36455 buffer_append_string(b, key);
36456 @@ -177,13 +176,13 @@
36457 buffer_append_string(b, key);
36458 BUFFER_APPEND_STRING_CONST(b, "</th>\n");
36465 static int mod_status_get_multiplier(double *avg, char *multiplier, int size) {
36469 if (*avg > size) { *avg /= size; *multiplier = 'k'; }
36470 if (*avg > size) { *avg /= size; *multiplier = 'M'; }
36471 if (*avg > size) { *avg /= size; *multiplier = 'G'; }
36472 @@ -202,21 +201,21 @@
36475 char multiplier = '\0';
36481 int days, hours, mins, seconds;
36484 b = chunkqueue_get_append_buffer(con->write_queue);
36486 - BUFFER_COPY_STRING_CONST(b,
36487 + BUFFER_COPY_STRING_CONST(b,
36488 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
36489 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
36490 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
36491 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
36493 " <title>Status</title>\n");
36496 BUFFER_APPEND_STRING_CONST(b,
36497 " <style type=\"text/css\">\n"
36498 " table.status { border: black solid thin; }\n"
36499 @@ -226,14 +225,14 @@
36500 " a.sortheader { background-color: black; color: white; font-weight: bold; text-decoration: none; display: block; }\n"
36501 " span.sortarrow { color: white; text-decoration: none; }\n"
36505 if (p->conf.sort) {
36506 BUFFER_APPEND_STRING_CONST(b,
36507 "<script type=\"text/javascript\">\n"
36509 "var sort_column;\n"
36510 "var prev_span = null;\n");
36513 BUFFER_APPEND_STRING_CONST(b,
36514 "function get_inner_text(el) {\n"
36515 " if((typeof el == 'string')||(typeof el == 'undefined'))\n"
36516 @@ -251,7 +250,7 @@
36522 BUFFER_APPEND_STRING_CONST(b,
36523 "function sortfn(a,b) {\n"
36524 " var at = get_inner_text(a.cells[sort_column]);\n"
36525 @@ -266,7 +265,7 @@
36526 " else return 1;\n"
36531 BUFFER_APPEND_STRING_CONST(b,
36532 "function resort(lnk) {\n"
36533 " var span = lnk.childNodes[1];\n"
36534 @@ -276,7 +275,7 @@
36535 " rows[j-1] = table.rows[j];\n"
36536 " sort_column = lnk.parentNode.cellIndex;\n"
36537 " rows.sort(sortfn);\n");
36540 BUFFER_APPEND_STRING_CONST(b,
36541 " if (prev_span != null) prev_span.innerHTML = '';\n"
36542 " if (span.getAttribute('sortdir')=='down') {\n"
36543 @@ -294,175 +293,175 @@
36548 - BUFFER_APPEND_STRING_CONST(b,
36550 + BUFFER_APPEND_STRING_CONST(b,
36559 /* connection listing */
36560 BUFFER_APPEND_STRING_CONST(b, "<h1>Server-Status</h1>");
36562 - BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">");
36563 - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\">");
36565 + BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" id=\"status\" summary=\"Server Status\">");
36566 + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\"><span id=\"host_addr\">");
36567 buffer_append_string_buffer(b, con->uri.authority);
36568 - BUFFER_APPEND_STRING_CONST(b, " (");
36569 + BUFFER_APPEND_STRING_CONST(b, "</span> (<span id=\"host_name\">");
36570 buffer_append_string_buffer(b, con->server_name);
36571 - BUFFER_APPEND_STRING_CONST(b, ")</td></tr>\n");
36572 - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\">");
36574 + BUFFER_APPEND_STRING_CONST(b, "</span>)</td></tr>\n");
36575 + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\" id=\"uptime\">");
36577 ts = srv->cur_ts - srv->startup_ts;
36580 days = ts / (60 * 60 * 24);
36581 ts %= (60 * 60 * 24);
36584 hours = ts / (60 * 60);
36596 buffer_append_long(b, days);
36597 BUFFER_APPEND_STRING_CONST(b, " days ");
36602 buffer_append_long(b, hours);
36603 BUFFER_APPEND_STRING_CONST(b, " hours ");
36608 buffer_append_long(b, mins);
36609 BUFFER_APPEND_STRING_CONST(b, " min ");
36613 buffer_append_long(b, seconds);
36614 BUFFER_APPEND_STRING_CONST(b, " s");
36617 BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
36618 BUFFER_APPEND_STRING_CONST(b, "<tr><td>Started at</td><td class=\"string\">");
36621 ts = srv->startup_ts;
36623 - strftime(buf, sizeof(buf) - 1, "%Y-%m-%d %H:%M:%S", localtime(&ts));
36625 + strftime(buf, sizeof(buf) - 1, "<span id=\"start_date\">%Y-%m-%d</span> <span id=\"start_time\">%H:%M:%S</span>", localtime(&ts));
36626 buffer_append_string(b, buf);
36627 BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
36632 BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">absolute (since start)</th></tr>\n");
36634 - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
36636 + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\" ><span id=\"requests\">");
36637 avg = p->abs_requests;
36639 mod_status_get_multiplier(&avg, &multiplier, 1000);
36642 buffer_append_long(b, avg);
36643 - BUFFER_APPEND_STRING_CONST(b, " ");
36644 + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_mult\">");
36645 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
36646 - BUFFER_APPEND_STRING_CONST(b, "req</td></tr>\n");
36648 - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
36649 + BUFFER_APPEND_STRING_CONST(b, "</span>req</td></tr>\n");
36651 + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic\">");
36652 avg = p->abs_traffic_out;
36654 mod_status_get_multiplier(&avg, &multiplier, 1024);
36656 sprintf(buf, "%.2f", avg);
36657 buffer_append_string(b, buf);
36658 - BUFFER_APPEND_STRING_CONST(b, " ");
36659 + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"traffic_mult\">");
36660 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
36661 - BUFFER_APPEND_STRING_CONST(b, "byte</td></tr>\n");
36662 + BUFFER_APPEND_STRING_CONST(b, "</span>byte</td></tr>\n");
36666 BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (since start)</th></tr>\n");
36668 - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
36670 + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_avg\">");
36671 avg = p->abs_requests / (srv->cur_ts - srv->startup_ts);
36673 mod_status_get_multiplier(&avg, &multiplier, 1000);
36675 buffer_append_long(b, avg);
36676 - BUFFER_APPEND_STRING_CONST(b, " ");
36677 + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_avg_mult\">");
36678 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
36679 - BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
36681 - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
36682 + BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n");
36684 + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic_avg\">");
36685 avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts);
36687 mod_status_get_multiplier(&avg, &multiplier, 1024);
36689 sprintf(buf, "%.2f", avg);
36690 buffer_append_string(b, buf);
36691 - BUFFER_APPEND_STRING_CONST(b, " ");
36692 + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"traffic_avg_mult\">");
36693 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
36694 - BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
36695 + BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n");
36701 BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (5s sliding average)</th></tr>\n");
36702 for (j = 0, avg = 0; j < 5; j++) {
36703 avg += p->mod_5s_requests[j];
36709 - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
36711 + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_sliding_avg\">");
36713 mod_status_get_multiplier(&avg, &multiplier, 1000);
36715 buffer_append_long(b, avg);
36716 - BUFFER_APPEND_STRING_CONST(b, " ");
36717 + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_avg_mult\">");
36718 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
36720 - BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
36723 + BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n");
36725 for (j = 0, avg = 0; j < 5; j++) {
36726 avg += p->mod_5s_traffic_out[j];
36732 - BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
36734 + BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"requests_sliding_traffic\">");
36736 mod_status_get_multiplier(&avg, &multiplier, 1024);
36738 sprintf(buf, "%.2f", avg);
36739 buffer_append_string(b, buf);
36740 - BUFFER_APPEND_STRING_CONST(b, " ");
36741 + BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_traffic_mult\">");
36742 if (multiplier) buffer_append_string_len(b, &multiplier, 1);
36743 - BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
36745 + BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n");
36747 BUFFER_APPEND_STRING_CONST(b, "</table>\n");
36752 BUFFER_APPEND_STRING_CONST(b, "<hr />\n<pre><b>legend</b>\n");
36753 BUFFER_APPEND_STRING_CONST(b, ". = connect, C = close, E = hard error\n");
36754 BUFFER_APPEND_STRING_CONST(b, "r = read, R = read-POST, W = write, h = handle-request\n");
36755 BUFFER_APPEND_STRING_CONST(b, "q = request-start, Q = request-end\n");
36756 BUFFER_APPEND_STRING_CONST(b, "s = response-start, S = response-end\n");
36758 - BUFFER_APPEND_STRING_CONST(b, "<b>");
36760 + BUFFER_APPEND_STRING_CONST(b, "<strong><span id=\"connections\">");
36761 buffer_append_long(b, srv->conns->used);
36762 - BUFFER_APPEND_STRING_CONST(b, " connections</b>\n");
36764 + BUFFER_APPEND_STRING_CONST(b, "</span> connections</strong>\n");
36766 for (j = 0; j < srv->conns->used; j++) {
36767 connection *c = srv->conns->ptr[j];
36768 const char *state = connection_get_short_state(c->state);
36771 buffer_append_string_len(b, state, 1);
36774 if (((j + 1) % 50) == 0) {
36775 BUFFER_APPEND_STRING_CONST(b, "\n");
36780 BUFFER_APPEND_STRING_CONST(b, "\n</pre><hr />\n<h2>Connections</h2>\n");
36782 - BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">\n");
36784 + BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" summary=\"Current connections\" id=\"clients\">\n");
36785 BUFFER_APPEND_STRING_CONST(b, "<tr>");
36786 mod_status_header_append_sort(b, p_d, "Client IP");
36787 mod_status_header_append_sort(b, p_d, "Read");
36788 @@ -473,16 +472,16 @@
36789 mod_status_header_append_sort(b, p_d, "URI");
36790 mod_status_header_append_sort(b, p_d, "File");
36791 BUFFER_APPEND_STRING_CONST(b, "</tr>\n");
36794 for (j = 0; j < srv->conns->used; j++) {
36795 connection *c = srv->conns->ptr[j];
36797 - BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string\">");
36800 + BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string ip\">");
36802 buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(c->dst_addr)));
36804 - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
36807 + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_read\">");
36809 if (con->request.content_length) {
36810 buffer_append_long(b, c->request_content_queue->bytes_in);
36811 BUFFER_APPEND_STRING_CONST(b, "/");
36812 @@ -490,55 +489,55 @@
36814 BUFFER_APPEND_STRING_CONST(b, "0/0");
36817 - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
36820 + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_written\">");
36822 buffer_append_off_t(b, chunkqueue_written(c->write_queue));
36823 BUFFER_APPEND_STRING_CONST(b, "/");
36824 buffer_append_off_t(b, chunkqueue_length(c->write_queue));
36826 - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
36829 + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string state\">");
36831 buffer_append_string(b, connection_get_state(c->state));
36833 - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
36836 + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int time\">");
36838 buffer_append_long(b, srv->cur_ts - c->request_start);
36840 - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
36843 + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string host\">");
36845 if (buffer_is_empty(c->server_name)) {
36846 buffer_append_string_buffer(b, c->uri.authority);
36849 buffer_append_string_buffer(b, c->server_name);
36852 - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
36855 + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string uri\">");
36857 if (!buffer_is_empty(c->uri.path)) {
36858 buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
36861 - BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
36864 + BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string file\">");
36866 buffer_append_string_buffer(b, c->physical.path);
36869 BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
36873 - BUFFER_APPEND_STRING_CONST(b,
36876 + BUFFER_APPEND_STRING_CONST(b,
36880 - BUFFER_APPEND_STRING_CONST(b,
36883 + BUFFER_APPEND_STRING_CONST(b,
36889 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
36895 @@ -548,7 +547,7 @@
36901 b = chunkqueue_get_append_buffer(con->write_queue);
36903 /* output total number of requests */
36904 @@ -556,19 +555,19 @@
36905 avg = p->abs_requests;
36906 buffer_append_long(b, avg);
36907 BUFFER_APPEND_STRING_CONST(b, "\n");
36910 /* output total traffic out in kbytes */
36911 BUFFER_APPEND_STRING_CONST(b, "Total kBytes: ");
36912 avg = p->abs_traffic_out / 1024;
36913 buffer_append_long(b, avg);
36914 BUFFER_APPEND_STRING_CONST(b, "\n");
36917 /* output uptime */
36918 BUFFER_APPEND_STRING_CONST(b, "Uptime: ");
36919 ts = srv->cur_ts - srv->startup_ts;
36920 buffer_append_long(b, ts);
36921 BUFFER_APPEND_STRING_CONST(b, "\n");
36924 /* output busy servers */
36925 BUFFER_APPEND_STRING_CONST(b, "BusyServers: ");
36926 buffer_append_long(b, srv->conns->used);
36927 @@ -577,7 +576,7 @@
36928 /* set text/plain output */
36930 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
36936 @@ -591,10 +590,10 @@
36937 /* we have nothing to send */
36938 con->http_status = 204;
36939 con->file_finished = 1;
36942 return HANDLER_FINISHED;
36946 b = chunkqueue_get_append_buffer(con->write_queue);
36948 for (i = 0; i < st->used; i++) {
36949 @@ -605,27 +604,27 @@
36950 buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value);
36951 buffer_append_string(b, "\n");
36955 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
36958 con->http_status = 200;
36959 con->file_finished = 1;
36962 return HANDLER_FINISHED;
36966 static handler_t mod_status_handle_server_status(server *srv, connection *con, void *p_d) {
36969 if (buffer_is_equal_string(con->uri.query, CONST_STR_LEN("auto"))) {
36970 mod_status_handle_server_status_text(srv, con, p_d);
36972 mod_status_handle_server_status_html(srv, con, p_d);
36976 con->http_status = 200;
36977 con->file_finished = 1;
36980 return HANDLER_FINISHED;
36983 @@ -634,9 +633,9 @@
36984 plugin_data *p = p_d;
36985 buffer *b, *m = p->module_list;
36988 - struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
36991 + struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
36993 /* - poll is most reliable
36994 * - select works everywhere
36995 * - linux-* are experimental
36996 @@ -661,10 +660,10 @@
36998 { FDEVENT_HANDLER_UNSET, NULL }
37002 b = chunkqueue_get_append_buffer(con->write_queue);
37004 - BUFFER_COPY_STRING_CONST(b,
37006 + BUFFER_COPY_STRING_CONST(b,
37007 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
37008 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
37009 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
37010 @@ -675,7 +674,7 @@
37012 " <h1>" PACKAGE_NAME " " PACKAGE_VERSION "</h1>\n"
37013 " <table border=\"1\">\n");
37016 mod_status_header_append(b, "Server-Features");
37018 mod_status_row_append(b, "RegEx Conditionals", "enabled");
37019 @@ -683,21 +682,21 @@
37020 mod_status_row_append(b, "RegEx Conditionals", "disabled - pcre missing");
37022 mod_status_header_append(b, "Network Engine");
37025 for (i = 0; event_handlers[i].name; i++) {
37026 if (event_handlers[i].et == srv->event_handler) {
37027 mod_status_row_append(b, "fd-Event-Handler", event_handlers[i].name);
37033 mod_status_header_append(b, "Config-File-Settings");
37036 for (i = 0; i < srv->plugins.used; i++) {
37037 plugin **ps = srv->plugins.ptr;
37040 plugin *pl = ps[i];
37044 buffer_copy_string_buffer(m, pl->name);
37046 @@ -705,137 +704,135 @@
37047 buffer_append_string_buffer(m, pl->name);
37052 mod_status_row_append(b, "Loaded Modules", m->ptr);
37055 BUFFER_APPEND_STRING_CONST(b, " </table>\n");
37057 - BUFFER_APPEND_STRING_CONST(b,
37059 + BUFFER_APPEND_STRING_CONST(b,
37065 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
37068 con->http_status = 200;
37069 con->file_finished = 1;
37072 return HANDLER_FINISHED;
37075 -#define PATCH(x) \
37076 - p->conf.x = s->x;
37077 static int mod_status_patch_connection(server *srv, connection *con, plugin_data *p) {
37079 plugin_config *s = p->config_storage[0];
37081 - PATCH(status_url);
37082 - PATCH(config_url);
37084 - PATCH(statistics_url);
37087 + PATCH_OPTION(status_url);
37088 + PATCH_OPTION(config_url);
37089 + PATCH_OPTION(sort);
37090 + PATCH_OPTION(statistics_url);
37092 /* skip the first, the global context */
37093 for (i = 1; i < srv->config_context->used; i++) {
37094 data_config *dc = (data_config *)srv->config_context->data[i];
37095 s = p->config_storage[i];
37098 /* condition didn't match */
37099 if (!config_check_cond(srv, con, dc)) continue;
37103 for (j = 0; j < dc->value->used; j++) {
37104 data_unset *du = dc->value->data[j];
37107 if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.status-url"))) {
37108 - PATCH(status_url);
37109 + PATCH_OPTION(status_url);
37110 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.config-url"))) {
37111 - PATCH(config_url);
37112 + PATCH_OPTION(config_url);
37113 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.enable-sort"))) {
37115 + PATCH_OPTION(sort);
37116 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.statistics-url"))) {
37117 - PATCH(statistics_url);
37119 + PATCH_OPTION(statistics_url);
37128 static handler_t mod_status_handler(server *srv, connection *con, void *p_d) {
37129 plugin_data *p = p_d;
37132 mod_status_patch_connection(srv, con, p);
37134 - if (!buffer_is_empty(p->conf.status_url) &&
37136 + if (!buffer_is_empty(p->conf.status_url) &&
37137 buffer_is_equal(p->conf.status_url, con->uri.path)) {
37138 return mod_status_handle_server_status(srv, con, p_d);
37139 - } else if (!buffer_is_empty(p->conf.config_url) &&
37140 + } else if (!buffer_is_empty(p->conf.config_url) &&
37141 buffer_is_equal(p->conf.config_url, con->uri.path)) {
37142 return mod_status_handle_server_config(srv, con, p_d);
37143 - } else if (!buffer_is_empty(p->conf.statistics_url) &&
37144 + } else if (!buffer_is_empty(p->conf.statistics_url) &&
37145 buffer_is_equal(p->conf.statistics_url, con->uri.path)) {
37146 return mod_status_handle_server_statistics(srv, con, p_d);
37150 return HANDLER_GO_ON;
37153 TRIGGER_FUNC(mod_status_trigger) {
37154 plugin_data *p = p_d;
37158 /* check all connections */
37159 for (i = 0; i < srv->conns->used; i++) {
37160 connection *c = srv->conns->ptr[i];
37163 p->bytes_written += c->bytes_written_cur_second;
37167 /* a sliding average */
37168 p->mod_5s_traffic_out[p->mod_5s_ndx] = p->bytes_written;
37169 p->mod_5s_requests [p->mod_5s_ndx] = p->requests;
37172 p->mod_5s_ndx = (p->mod_5s_ndx+1) % 5;
37175 p->abs_traffic_out += p->bytes_written;
37176 p->rel_traffic_out += p->bytes_written;
37179 p->bytes_written = 0;
37182 /* reset storage - second */
37183 p->traffic_out = 0;
37187 return HANDLER_GO_ON;
37190 REQUESTDONE_FUNC(mod_status_account) {
37191 plugin_data *p = p_d;
37201 p->bytes_written += con->bytes_written_cur_second;
37204 return HANDLER_GO_ON;
37207 int mod_status_plugin_init(plugin *p) {
37208 p->version = LIGHTTPD_VERSION_ID;
37209 p->name = buffer_init_string("status");
37212 p->init = mod_status_init;
37213 p->cleanup = mod_status_free;
37214 p->set_defaults= mod_status_set_defaults;
37217 p->handle_uri_clean = mod_status_handler;
37218 p->handle_trigger = mod_status_trigger;
37219 p->handle_request_done = mod_status_account;
37227 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_trigger_b4_dl.c lighttpd-1.4.12/src/mod_trigger_b4_dl.c
37228 --- lighttpd-1.4.11/src/mod_trigger_b4_dl.c 2005-09-23 22:53:55.000000000 +0300
37229 +++ lighttpd-1.4.12/src/mod_trigger_b4_dl.c 2006-07-11 21:23:39.000000000 +0300
37230 @@ -24,18 +24,18 @@
37233 * this is a trigger_b4_dl for a lighttpd plugin
37238 /* plugin config for all request/connections */
37241 buffer *db_filename;
37244 buffer *trigger_url;
37245 buffer *download_url;
37250 buffer *mc_namespace;
37251 #if defined(HAVE_PCRE_H)
37252 @@ -46,58 +46,58 @@
37256 -#if defined(HAVE_MEMCACHE_H)
37257 +#if defined(HAVE_MEMCACHE_H)
37258 struct memcache *mc;
37262 unsigned short trigger_timeout;
37263 unsigned short debug;
37273 plugin_config **config_storage;
37275 - plugin_config conf;
37277 + plugin_config conf;
37280 /* init the plugin data */
37281 INIT_FUNC(mod_trigger_b4_dl_init) {
37285 p = calloc(1, sizeof(*p));
37288 p->tmp_buf = buffer_init();
37294 /* detroy the plugin data */
37295 FREE_FUNC(mod_trigger_b4_dl_free) {
37296 plugin_data *p = p_d;
37301 if (!p) return HANDLER_GO_ON;
37304 if (p->config_storage) {
37306 for (i = 0; i < srv->config_context->used; i++) {
37307 plugin_config *s = p->config_storage[i];
37312 buffer_free(s->db_filename);
37313 buffer_free(s->download_url);
37314 buffer_free(s->trigger_url);
37315 buffer_free(s->deny_url);
37318 buffer_free(s->mc_namespace);
37319 array_free(s->mc_hosts);
37322 #if defined(HAVE_PCRE_H)
37323 if (s->trigger_regex) pcre_free(s->trigger_regex);
37324 if (s->download_regex) pcre_free(s->download_regex);
37325 @@ -108,16 +108,16 @@
37326 #if defined(HAVE_MEMCACHE_H)
37327 if (s->mc) mc_free(s->mc);
37333 free(p->config_storage);
37337 buffer_free(p->tmp_buf);
37343 return HANDLER_GO_ON;
37346 @@ -126,9 +126,9 @@
37347 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
37348 plugin_data *p = p_d;
37352 - config_values_t cv[] = {
37355 + config_values_t cv[] = {
37356 { "trigger-before-download.gdbm-filename", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
37357 { "trigger-before-download.trigger-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
37358 { "trigger-before-download.download-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
37359 @@ -139,18 +139,18 @@
37360 { "trigger-before-download.debug", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
37361 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
37365 if (!p) return HANDLER_ERROR;
37368 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
37371 for (i = 0; i < srv->config_context->used; i++) {
37373 #if defined(HAVE_PCRE_H)
37374 const char *errptr;
37379 s = calloc(1, sizeof(plugin_config));
37380 s->db_filename = buffer_init();
37381 s->download_url = buffer_init();
37382 @@ -158,7 +158,7 @@
37383 s->deny_url = buffer_init();
37384 s->mc_hosts = array_init();
37385 s->mc_namespace = buffer_init();
37388 cv[0].destination = s->db_filename;
37389 cv[1].destination = s->trigger_url;
37390 cv[2].destination = s->download_url;
37391 @@ -167,41 +167,41 @@
37392 cv[5].destination = s->mc_hosts;
37393 cv[6].destination = s->mc_namespace;
37394 cv[7].destination = &(s->debug);
37397 p->config_storage[i] = s;
37400 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
37401 return HANDLER_ERROR;
37403 #if defined(HAVE_GDBM_H)
37404 if (!buffer_is_empty(s->db_filename)) {
37405 if (NULL == (s->db = gdbm_open(s->db_filename->ptr, 4096, GDBM_WRCREAT | GDBM_NOLOCK, S_IRUSR | S_IWUSR, 0))) {
37406 - log_error_write(srv, __FILE__, __LINE__, "s",
37407 + log_error_write(srv, __FILE__, __LINE__, "s",
37408 "gdbm-open failed");
37409 return HANDLER_ERROR;
37413 -#if defined(HAVE_PCRE_H)
37414 +#if defined(HAVE_PCRE_H)
37415 if (!buffer_is_empty(s->download_url)) {
37416 if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr,
37417 0, &errptr, &erroff, NULL))) {
37419 - log_error_write(srv, __FILE__, __LINE__, "sbss",
37420 - "compiling regex for download-url failed:",
37422 + log_error_write(srv, __FILE__, __LINE__, "sbss",
37423 + "compiling regex for download-url failed:",
37424 s->download_url, "pos:", erroff);
37425 return HANDLER_ERROR;
37430 if (!buffer_is_empty(s->trigger_url)) {
37431 if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr,
37432 0, &errptr, &erroff, NULL))) {
37434 - log_error_write(srv, __FILE__, __LINE__, "sbss",
37435 - "compiling regex for trigger-url failed:",
37437 + log_error_write(srv, __FILE__, __LINE__, "sbss",
37438 + "compiling regex for trigger-url failed:",
37439 s->trigger_url, "pos:", erroff);
37442 return HANDLER_ERROR;
37445 @@ -211,100 +211,97 @@
37446 #if defined(HAVE_MEMCACHE_H)
37451 for (k = 0; k < s->mc_hosts->used; k++) {
37452 data_string *ds = (data_string *)s->mc_hosts->data[k];
37455 if (0 != mc_server_add4(s->mc, ds->value->ptr)) {
37456 - log_error_write(srv, __FILE__, __LINE__, "sb",
37457 - "connection to host failed:",
37458 + log_error_write(srv, __FILE__, __LINE__, "sb",
37459 + "connection to host failed:",
37463 return HANDLER_ERROR;
37467 - log_error_write(srv, __FILE__, __LINE__, "s",
37468 + log_error_write(srv, __FILE__, __LINE__, "s",
37469 "memcache support is not compiled in but trigger-before-download.memcache-hosts is set, aborting");
37470 return HANDLER_ERROR;
37476 #if (!defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)) || !defined(HAVE_PCRE_H)
37477 - log_error_write(srv, __FILE__, __LINE__, "s",
37478 + log_error_write(srv, __FILE__, __LINE__, "s",
37479 "(either gdbm or libmemcache) and pcre are require, but were not found, aborting");
37480 return HANDLER_ERROR;
37485 return HANDLER_GO_ON;
37488 -#define PATCH(x) \
37489 - p->conf.x = s->x;
37490 static int mod_trigger_b4_dl_patch_connection(server *srv, connection *con, plugin_data *p) {
37492 plugin_config *s = p->config_storage[0];
37495 #if defined(HAVE_GDBM)
37498 + PATCH_OPTION(db);
37500 #if defined(HAVE_PCRE_H)
37501 - PATCH(download_regex);
37502 - PATCH(trigger_regex);
37504 - PATCH(trigger_timeout);
37506 - PATCH(mc_namespace);
37508 + PATCH_OPTION(download_regex);
37509 + PATCH_OPTION(trigger_regex);
37511 + PATCH_OPTION(trigger_timeout);
37512 + PATCH_OPTION(deny_url);
37513 + PATCH_OPTION(mc_namespace);
37514 + PATCH_OPTION(debug);
37515 #if defined(HAVE_MEMCACHE_H)
37517 + PATCH_OPTION(mc);
37521 /* skip the first, the global context */
37522 for (i = 1; i < srv->config_context->used; i++) {
37523 data_config *dc = (data_config *)srv->config_context->data[i];
37524 s = p->config_storage[i];
37527 /* condition didn't match */
37528 if (!config_check_cond(srv, con, dc)) continue;
37532 for (j = 0; j < dc->value->used; j++) {
37533 data_unset *du = dc->value->data[j];
37535 if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.download-url"))) {
37536 #if defined(HAVE_PCRE_H)
37537 - PATCH(download_regex);
37538 + PATCH_OPTION(download_regex);
37540 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-url"))) {
37541 # if defined(HAVE_PCRE_H)
37542 - PATCH(trigger_regex);
37543 + PATCH_OPTION(trigger_regex);
37545 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.gdbm-filename"))) {
37546 #if defined(HAVE_GDBM_H)
37548 + PATCH_OPTION(db);
37550 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-timeout"))) {
37551 - PATCH(trigger_timeout);
37552 + PATCH_OPTION(trigger_timeout);
37553 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.debug"))) {
37555 + PATCH_OPTION(debug);
37556 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.deny-url"))) {
37558 + PATCH_OPTION(deny_url);
37559 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-namespace"))) {
37560 - PATCH(mc_namespace);
37561 + PATCH_OPTION(mc_namespace);
37562 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-hosts"))) {
37563 #if defined(HAVE_MEMCACHE_H)
37565 + PATCH_OPTION(mc);
37576 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
37577 plugin_data *p = p_d;
37578 @@ -315,20 +312,20 @@
37584 if (con->uri.path->used == 0) return HANDLER_GO_ON;
37587 mod_trigger_b4_dl_patch_connection(srv, con, p);
37590 if (!p->conf.trigger_regex || !p->conf.download_regex) return HANDLER_GO_ON;
37593 # if !defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)
37594 return HANDLER_GO_ON;
37595 # elif defined(HAVE_GDBM_H) && defined(HAVE_MEMCACHE_H)
37596 if (!p->conf.db && !p->conf.mc) return HANDLER_GO_ON;
37597 if (p->conf.db && p->conf.mc) {
37598 /* can't decide which one */
37601 return HANDLER_GO_ON;
37603 # elif defined(HAVE_GDBM_H)
37604 @@ -336,12 +333,12 @@
37606 if (!p->conf.mc) return HANDLER_GO_ON;
37610 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "X-Forwarded-For"))) {
37611 /* X-Forwarded-For contains the ip behind the proxy */
37614 remote_ip = ds->value->ptr;
37617 /* memcache can't handle spaces */
37619 remote_ip = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
37620 @@ -350,13 +347,13 @@
37621 if (p->conf.debug) {
37622 log_error_write(srv, __FILE__, __LINE__, "ss", "(debug) remote-ip:", remote_ip);
37626 /* check if URL is a trigger -> insert IP into DB */
37627 if ((n = pcre_exec(p->conf.trigger_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) {
37628 if (n != PCRE_ERROR_NOMATCH) {
37629 log_error_write(srv, __FILE__, __LINE__, "sd",
37630 "execution error while matching:", n);
37633 return HANDLER_ERROR;
37636 @@ -364,34 +361,34 @@
37638 /* the trigger matched */
37642 key.dptr = (char *)remote_ip;
37643 key.dsize = strlen(remote_ip);
37646 val.dptr = (char *)&(srv->cur_ts);
37647 val.dsize = sizeof(srv->cur_ts);
37650 if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) {
37651 log_error_write(srv, __FILE__, __LINE__, "s",
37656 -# if defined(HAVE_MEMCACHE_H)
37657 +# if defined(HAVE_MEMCACHE_H)
37660 buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
37661 buffer_append_string(p->tmp_buf, remote_ip);
37664 for (i = 0; i < p->tmp_buf->used - 1; i++) {
37665 if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-';
37669 if (p->conf.debug) {
37670 log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) triggered IP:", p->tmp_buf);
37673 - if (0 != mc_set(p->conf.mc,
37674 + if (0 != mc_set(p->conf.mc,
37675 CONST_BUF_LEN(p->tmp_buf),
37676 (char *)&(srv->cur_ts), sizeof(srv->cur_ts),
37677 p->conf.trigger_timeout, 0)) {
37678 @@ -401,7 +398,7 @@
37684 /* check if URL is a download -> check IP in DB, update timestamp */
37685 if ((n = pcre_exec(p->conf.download_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) {
37686 if (n != PCRE_ERROR_NOMATCH) {
37687 @@ -411,93 +408,93 @@
37690 /* the download uri matched */
37691 -# if defined(HAVE_GDBM_H)
37692 +# if defined(HAVE_GDBM_H)
37698 key.dptr = (char *)remote_ip;
37699 key.dsize = strlen(remote_ip);
37702 val = gdbm_fetch(p->conf.db, key);
37705 if (val.dptr == NULL) {
37706 /* not found, redirect */
37709 response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
37712 con->http_status = 307;
37715 return HANDLER_FINISHED;
37719 last_hit = *(time_t *)(val.dptr);
37725 if (srv->cur_ts - last_hit > p->conf.trigger_timeout) {
37726 /* found, but timeout, redirect */
37729 response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
37730 con->http_status = 307;
37734 if (0 != gdbm_delete(p->conf.db, key)) {
37735 log_error_write(srv, __FILE__, __LINE__, "s",
37741 return HANDLER_FINISHED;
37745 val.dptr = (char *)&(srv->cur_ts);
37746 val.dsize = sizeof(srv->cur_ts);
37749 if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) {
37750 log_error_write(srv, __FILE__, __LINE__, "s",
37756 -# if defined(HAVE_MEMCACHE_H)
37758 +# if defined(HAVE_MEMCACHE_H)
37764 buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
37765 buffer_append_string(p->tmp_buf, remote_ip);
37768 for (i = 0; i < p->tmp_buf->used - 1; i++) {
37769 if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-';
37773 if (p->conf.debug) {
37774 log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) checking IP:", p->tmp_buf);
37780 * memcached is do expiration for us, as long as we can fetch it every thing is ok
37781 - * and the timestamp is updated
37783 + * and the timestamp is updated
37786 - if (NULL == (r = mc_aget(p->conf.mc,
37787 + if (NULL == (r = mc_aget(p->conf.mc,
37788 CONST_BUF_LEN(p->tmp_buf)
37792 response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
37795 con->http_status = 307;
37798 return HANDLER_FINISHED;
37805 /* set a new timeout */
37806 - if (0 != mc_set(p->conf.mc,
37807 + if (0 != mc_set(p->conf.mc,
37808 CONST_BUF_LEN(p->tmp_buf),
37809 (char *)&(srv->cur_ts), sizeof(srv->cur_ts),
37810 p->conf.trigger_timeout, 0)) {
37811 @@ -507,13 +504,13 @@
37824 return HANDLER_GO_ON;
37827 @@ -521,21 +518,21 @@
37828 TRIGGER_FUNC(mod_trigger_b4_dl_handle_trigger) {
37829 plugin_data *p = p_d;
37833 /* check DB each minute */
37834 if (srv->cur_ts % 60 != 0) return HANDLER_GO_ON;
37838 for (i = 0; i < srv->config_context->used; i++) {
37839 plugin_config *s = p->config_storage[i];
37840 datum key, val, okey;
37843 if (!s->db) continue;
37848 - /* according to the manual this loop + delete does delete all entries on its way
37851 + /* according to the manual this loop + delete does delete all entries on its way
37853 * we don't care as the next round will remove them. We don't have to perfect here.
37855 for (key = gdbm_firstkey(s->db); key.dptr; key = gdbm_nextkey(s->db, okey)) {
37856 @@ -544,21 +541,21 @@
37862 val = gdbm_fetch(s->db, key);
37865 last_hit = *(time_t *)(val.dptr);
37871 if (srv->cur_ts - last_hit > s->trigger_timeout) {
37872 gdbm_delete(s->db, key);
37878 if (okey.dptr) free(okey.dptr);
37881 /* reorg once a day */
37882 if ((srv->cur_ts % (60 * 60 * 24) != 0)) gdbm_reorganize(s->db);
37884 @@ -571,7 +568,7 @@
37885 int mod_trigger_b4_dl_plugin_init(plugin *p) {
37886 p->version = LIGHTTPD_VERSION_ID;
37887 p->name = buffer_init_string("trigger_b4_dl");
37890 p->init = mod_trigger_b4_dl_init;
37891 p->handle_uri_clean = mod_trigger_b4_dl_uri_handler;
37892 p->set_defaults = mod_trigger_b4_dl_set_defaults;
37893 @@ -579,8 +576,8 @@
37894 p->handle_trigger = mod_trigger_b4_dl_handle_trigger;
37896 p->cleanup = mod_trigger_b4_dl_free;
37904 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_userdir.c lighttpd-1.4.12/src/mod_userdir.c
37905 --- lighttpd-1.4.11/src/mod_userdir.c 2005-10-28 16:48:28.000000000 +0300
37906 +++ lighttpd-1.4.12/src/mod_userdir.c 2006-07-11 21:23:40.000000000 +0300
37908 #include "response.h"
37910 #include "plugin.h"
37911 +#include "sys-files.h"
37915 @@ -25,54 +26,54 @@
37925 plugin_config **config_storage;
37927 - plugin_config conf;
37929 + plugin_config conf;
37932 /* init the plugin data */
37933 INIT_FUNC(mod_userdir_init) {
37937 p = calloc(1, sizeof(*p));
37940 p->username = buffer_init();
37941 p->temp_path = buffer_init();
37947 /* detroy the plugin data */
37948 FREE_FUNC(mod_userdir_free) {
37949 plugin_data *p = p_d;
37952 if (!p) return HANDLER_GO_ON;
37955 if (p->config_storage) {
37959 for (i = 0; i < srv->config_context->used; i++) {
37960 plugin_config *s = p->config_storage[i];
37963 array_free(s->include_user);
37964 array_free(s->exclude_user);
37965 buffer_free(s->path);
37966 buffer_free(s->basepath);
37971 free(p->config_storage);
37975 buffer_free(p->username);
37976 buffer_free(p->temp_path);
37982 return HANDLER_GO_ON;
37985 @@ -81,81 +82,78 @@
37986 SETDEFAULTS_FUNC(mod_userdir_set_defaults) {
37987 plugin_data *p = p_d;
37990 - config_values_t cv[] = {
37992 + config_values_t cv[] = {
37993 { "userdir.path", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
37994 { "userdir.exclude-user", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
37995 { "userdir.include-user", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
37996 { "userdir.basepath", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
37997 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
38001 if (!p) return HANDLER_ERROR;
38004 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
38007 for (i = 0; i < srv->config_context->used; i++) {
38011 s = calloc(1, sizeof(plugin_config));
38012 s->exclude_user = array_init();
38013 s->include_user = array_init();
38014 s->path = buffer_init();
38015 s->basepath = buffer_init();
38018 cv[0].destination = s->path;
38019 cv[1].destination = s->exclude_user;
38020 cv[2].destination = s->include_user;
38021 cv[3].destination = s->basepath;
38024 p->config_storage[i] = s;
38027 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
38028 return HANDLER_ERROR;
38033 return HANDLER_GO_ON;
38036 -#define PATCH(x) \
38037 - p->conf.x = s->x;
38038 static int mod_userdir_patch_connection(server *srv, connection *con, plugin_data *p) {
38040 plugin_config *s = p->config_storage[0];
38043 - PATCH(exclude_user);
38044 - PATCH(include_user);
38048 + PATCH_OPTION(path);
38049 + PATCH_OPTION(exclude_user);
38050 + PATCH_OPTION(include_user);
38051 + PATCH_OPTION(basepath);
38053 /* skip the first, the global context */
38054 for (i = 1; i < srv->config_context->used; i++) {
38055 data_config *dc = (data_config *)srv->config_context->data[i];
38056 s = p->config_storage[i];
38059 /* condition didn't match */
38060 if (!config_check_cond(srv, con, dc)) continue;
38064 for (j = 0; j < dc->value->used; j++) {
38065 data_unset *du = dc->value->data[j];
38068 if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.path"))) {
38070 + PATCH_OPTION(path);
38071 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.exclude-user"))) {
38072 - PATCH(exclude_user);
38073 + PATCH_OPTION(exclude_user);
38074 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.include-user"))) {
38075 - PATCH(include_user);
38076 + PATCH_OPTION(include_user);
38077 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.basepath"))) {
38079 + PATCH_OPTION(basepath);
38089 URIHANDLER_FUNC(mod_userdir_docroot_handler) {
38090 plugin_data *p = p_d;
38091 @@ -169,18 +167,18 @@
38092 if (con->uri.path->used == 0) return HANDLER_GO_ON;
38094 mod_userdir_patch_connection(srv, con, p);
38097 uri_len = con->uri.path->used - 1;
38100 /* /~user/foo.html -> /home/user/public_html/foo.html */
38103 if (con->uri.path->ptr[0] != '/' ||
38104 con->uri.path->ptr[1] != '~') return HANDLER_GO_ON;
38107 if (NULL == (rel_url = strchr(con->uri.path->ptr + 2, '/'))) {
38108 /* / is missing -> redirect to .../ as we are a user - DIRECTORY ! :) */
38109 http_response_redirect_to_directory(srv, con);
38112 return HANDLER_FINISHED;
38115 @@ -188,10 +186,10 @@
38116 if (0 == rel_url - (con->uri.path->ptr + 2)) {
38117 return HANDLER_GO_ON;
38121 buffer_copy_string_len(p->username, con->uri.path->ptr + 2, rel_url - (con->uri.path->ptr + 2));
38123 - if (buffer_is_empty(p->conf.basepath)
38125 + if (buffer_is_empty(p->conf.basepath)
38127 && NULL == (pwd = getpwnam(p->username->ptr))
38129 @@ -200,31 +198,31 @@
38130 return HANDLER_GO_ON;
38135 for (k = 0; k < p->conf.exclude_user->used; k++) {
38136 data_string *ds = (data_string *)p->conf.exclude_user->data[k];
38139 if (buffer_is_equal(ds->value, p->username)) {
38140 /* user in exclude list */
38141 return HANDLER_GO_ON;
38146 if (p->conf.include_user->used) {
38147 int found_user = 0;
38148 for (k = 0; k < p->conf.include_user->used; k++) {
38149 data_string *ds = (data_string *)p->conf.include_user->data[k];
38152 if (buffer_is_equal(ds->value, p->username)) {
38153 /* user in include list */
38160 if (!found_user) return HANDLER_GO_ON;
38164 /* we build the physical path */
38166 if (buffer_is_empty(p->conf.basepath)) {
38167 @@ -252,23 +250,23 @@
38170 buffer_copy_string_buffer(p->temp_path, p->conf.basepath);
38171 - BUFFER_APPEND_SLASH(p->temp_path);
38172 + PATHNAME_APPEND_SLASH(p->temp_path);
38173 buffer_append_string_buffer(p->temp_path, p->username);
38175 - BUFFER_APPEND_SLASH(p->temp_path);
38176 - buffer_append_string_buffer(p->temp_path, p->conf.path);
38177 + PATHNAME_APPEND_SLASH(p->temp_path);
38178 + buffer_append_string_buffer(p->temp_path, p->conf.path);
38180 if (buffer_is_empty(p->conf.basepath)) {
38185 ret = stat(p->temp_path->ptr, &st);
38186 if (ret < 0 || S_ISDIR(st.st_mode) != 1) {
38187 return HANDLER_GO_ON;
38192 - BUFFER_APPEND_SLASH(p->temp_path);
38193 + PATHNAME_APPEND_SLASH(p->temp_path);
38194 buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */
38195 buffer_copy_string_buffer(con->physical.path, p->temp_path);
38197 @@ -282,13 +280,13 @@
38198 int mod_userdir_plugin_init(plugin *p) {
38199 p->version = LIGHTTPD_VERSION_ID;
38200 p->name = buffer_init_string("userdir");
38203 p->init = mod_userdir_init;
38204 p->handle_physical = mod_userdir_docroot_handler;
38205 p->set_defaults = mod_userdir_set_defaults;
38206 p->cleanup = mod_userdir_free;
38214 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_usertrack.c lighttpd-1.4.12/src/mod_usertrack.c
38215 --- lighttpd-1.4.11/src/mod_usertrack.c 2006-01-31 15:01:20.000000000 +0200
38216 +++ lighttpd-1.4.12/src/mod_usertrack.c 2006-07-11 21:23:40.000000000 +0300
38217 @@ -24,44 +24,44 @@
38223 plugin_config **config_storage;
38225 - plugin_config conf;
38227 + plugin_config conf;
38230 /* init the plugin data */
38231 INIT_FUNC(mod_usertrack_init) {
38235 p = calloc(1, sizeof(*p));
38241 /* detroy the plugin data */
38242 FREE_FUNC(mod_usertrack_free) {
38243 plugin_data *p = p_d;
38249 if (!p) return HANDLER_GO_ON;
38252 if (p->config_storage) {
38254 for (i = 0; i < srv->config_context->used; i++) {
38255 plugin_config *s = p->config_storage[i];
38258 buffer_free(s->cookie_name);
38259 buffer_free(s->cookie_domain);
38264 free(p->config_storage);
38271 return HANDLER_GO_ON;
38274 @@ -70,38 +70,38 @@
38275 SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
38276 plugin_data *p = p_d;
38279 - config_values_t cv[] = {
38281 + config_values_t cv[] = {
38282 { "usertrack.cookie-name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
38283 { "usertrack.cookie-max-age", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
38284 { "usertrack.cookie-domain", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
38286 - { "usertrack.cookiename", NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION },
38288 + { "usertrack.cookiename", NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION },
38289 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
38293 if (!p) return HANDLER_ERROR;
38296 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
38299 for (i = 0; i < srv->config_context->used; i++) {
38303 s = calloc(1, sizeof(plugin_config));
38304 s->cookie_name = buffer_init();
38305 s->cookie_domain = buffer_init();
38306 s->cookie_max_age = 0;
38309 cv[0].destination = s->cookie_name;
38310 cv[1].destination = &(s->cookie_max_age);
38311 cv[2].destination = s->cookie_domain;
38314 p->config_storage[i] = s;
38317 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
38318 return HANDLER_ERROR;
38322 if (buffer_is_empty(s->cookie_name)) {
38323 buffer_copy_string(s->cookie_name, "TRACKID");
38325 @@ -109,68 +109,65 @@
38326 for (j = 0; j < s->cookie_name->used - 1; j++) {
38327 char c = s->cookie_name->ptr[j] | 32;
38328 if (c < 'a' || c > 'z') {
38329 - log_error_write(srv, __FILE__, __LINE__, "sb",
38330 - "invalid character in usertrack.cookie-name:",
38331 + log_error_write(srv, __FILE__, __LINE__, "sb",
38332 + "invalid character in usertrack.cookie-name:",
38336 return HANDLER_ERROR;
38342 if (!buffer_is_empty(s->cookie_domain)) {
38344 for (j = 0; j < s->cookie_domain->used - 1; j++) {
38345 char c = s->cookie_domain->ptr[j];
38346 if (c <= 32 || c >= 127 || c == '"' || c == '\\') {
38347 - log_error_write(srv, __FILE__, __LINE__, "sb",
38348 - "invalid character in usertrack.cookie-domain:",
38349 + log_error_write(srv, __FILE__, __LINE__, "sb",
38350 + "invalid character in usertrack.cookie-domain:",
38354 return HANDLER_ERROR;
38361 return HANDLER_GO_ON;
38364 -#define PATCH(x) \
38365 - p->conf.x = s->x;
38366 static int mod_usertrack_patch_connection(server *srv, connection *con, plugin_data *p) {
38368 plugin_config *s = p->config_storage[0];
38370 - PATCH(cookie_name);
38371 - PATCH(cookie_domain);
38372 - PATCH(cookie_max_age);
38375 + PATCH_OPTION(cookie_name);
38376 + PATCH_OPTION(cookie_domain);
38377 + PATCH_OPTION(cookie_max_age);
38379 /* skip the first, the global context */
38380 for (i = 1; i < srv->config_context->used; i++) {
38381 data_config *dc = (data_config *)srv->config_context->data[i];
38382 s = p->config_storage[i];
38385 /* condition didn't match */
38386 if (!config_check_cond(srv, con, dc)) continue;
38390 for (j = 0; j < dc->value->used; j++) {
38391 data_unset *du = dc->value->data[j];
38394 if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-name"))) {
38395 - PATCH(cookie_name);
38396 + PATCH_OPTION(cookie_name);
38397 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-max-age"))) {
38398 - PATCH(cookie_max_age);
38399 + PATCH_OPTION(cookie_max_age);
38400 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-domain"))) {
38401 - PATCH(cookie_domain);
38402 + PATCH_OPTION(cookie_domain);
38412 URIHANDLER_FUNC(mod_usertrack_uri_handler) {
38413 plugin_data *p = p_d;
38414 @@ -178,38 +175,38 @@
38415 unsigned char h[16];
38420 if (con->uri.path->used == 0) return HANDLER_GO_ON;
38423 mod_usertrack_patch_connection(srv, con, p);
38426 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) {
38428 /* we have a cookie, does it contain a valid name ? */
38430 - /* parse the cookie
38433 + /* parse the cookie
38435 * check for cookiename + (WS | '=')
38441 if (NULL != (g = strstr(ds->value->ptr, p->conf.cookie_name->ptr))) {
38446 for (nc = g + p->conf.cookie_name->used-1; *nc == ' ' || *nc == '\t'; nc++);
38450 /* ok, found the key of our own cookie */
38453 if (strlen(nc) > 32) {
38455 return HANDLER_GO_ON;
38464 if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
38465 ds = data_response_init();
38466 @@ -217,39 +214,39 @@
38467 buffer_copy_string(ds->key, "Set-Cookie");
38468 buffer_copy_string_buffer(ds->value, p->conf.cookie_name);
38469 buffer_append_string(ds->value, "=");
38473 /* taken from mod_auth.c */
38476 /* generate shared-secret */
38478 MD5_Update(&Md5Ctx, (unsigned char *)con->uri.path->ptr, con->uri.path->used - 1);
38479 MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
38482 /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
38483 ltostr(hh, srv->cur_ts);
38484 MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
38485 ltostr(hh, rand());
38486 MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
38489 MD5_Final(h, &Md5Ctx);
38492 buffer_append_string_encoded(ds->value, (char *)h, 16, ENCODING_HEX);
38493 buffer_append_string(ds->value, "; Path=/");
38494 buffer_append_string(ds->value, "; Version=1");
38497 if (!buffer_is_empty(p->conf.cookie_domain)) {
38498 buffer_append_string(ds->value, "; Domain=");
38499 buffer_append_string_encoded(ds->value, CONST_BUF_LEN(p->conf.cookie_domain), ENCODING_REL_URI);
38503 if (p->conf.cookie_max_age) {
38504 buffer_append_string(ds->value, "; max-age=");
38505 buffer_append_long(ds->value, p->conf.cookie_max_age);
38509 array_insert_unique(con->response.headers, (data_unset *)ds);
38512 return HANDLER_GO_ON;
38515 @@ -258,13 +255,13 @@
38516 int mod_usertrack_plugin_init(plugin *p) {
38517 p->version = LIGHTTPD_VERSION_ID;
38518 p->name = buffer_init_string("usertrack");
38521 p->init = mod_usertrack_init;
38522 p->handle_uri_clean = mod_usertrack_uri_handler;
38523 p->set_defaults = mod_usertrack_set_defaults;
38524 p->cleanup = mod_usertrack_free;
38532 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/mod_webdav.c lighttpd-1.4.12/src/mod_webdav.c
38533 --- lighttpd-1.4.11/src/mod_webdav.c 2006-03-03 01:28:58.000000000 +0200
38534 +++ lighttpd-1.4.12/src/mod_webdav.c 2006-07-11 21:23:40.000000000 +0300
38537 #include <stdlib.h>
38538 #include <string.h>
38539 -#include <dirent.h>
38541 -#include <unistd.h>
38544 #include <assert.h>
38545 -#include <sys/mman.h>
38547 #ifdef HAVE_CONFIG_H
38548 #include "config.h"
38550 #include <sqlite3.h>
38553 +#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H) && defined(HAVE_UUID_H)
38555 +#include <uuid/uuid.h>
38560 #include "buffer.h"
38561 @@ -33,13 +35,16 @@
38562 #include "stream.h"
38563 #include "stat_cache.h"
38565 +#include "sys-files.h"
38566 +#include "sys-mmap.h"
38567 +#include "sys-strings.h"
38570 * this is a webdav for a lighttpd plugin
38572 - * at least a very basic one.
38573 + * at least a very basic one.
38574 * - for now it is read-only and we only support PROPFIND
38580 @@ -58,64 +63,70 @@
38581 sqlite3_stmt *stmt_delete_prop;
38582 sqlite3_stmt *stmt_select_prop;
38583 sqlite3_stmt *stmt_select_propnames;
38586 sqlite3_stmt *stmt_delete_uri;
38587 sqlite3_stmt *stmt_move_uri;
38588 sqlite3_stmt *stmt_copy_uri;
38590 + sqlite3_stmt *stmt_remove_lock;
38591 + sqlite3_stmt *stmt_create_lock;
38592 + sqlite3_stmt *stmt_read_lock;
38593 + sqlite3_stmt *stmt_read_lock_by_uri;
38594 + sqlite3_stmt *stmt_refresh_lock;
38606 plugin_config **config_storage;
38608 - plugin_config conf;
38610 + plugin_config conf;
38613 /* init the plugin data */
38614 INIT_FUNC(mod_webdav_init) {
38618 p = calloc(1, sizeof(*p));
38621 p->tmp_buf = buffer_init();
38623 p->uri.scheme = buffer_init();
38624 p->uri.path_raw = buffer_init();
38625 p->uri.path = buffer_init();
38626 p->uri.authority = buffer_init();
38629 p->physical.path = buffer_init();
38630 p->physical.rel_path = buffer_init();
38631 p->physical.doc_root = buffer_init();
38632 p->physical.basedir = buffer_init();
38638 /* detroy the plugin data */
38639 FREE_FUNC(mod_webdav_free) {
38640 plugin_data *p = p_d;
38645 if (!p) return HANDLER_GO_ON;
38648 if (p->config_storage) {
38650 for (i = 0; i < srv->config_context->used; i++) {
38651 plugin_config *s = p->config_storage[i];
38656 buffer_free(s->sqlite_db_name);
38657 #ifdef USE_PROPPATCH
38660 sqlite3_finalize(s->stmt_delete_prop);
38661 sqlite3_finalize(s->stmt_delete_uri);
38662 sqlite3_finalize(s->stmt_copy_uri);
38663 @@ -123,9 +134,15 @@
38664 sqlite3_finalize(s->stmt_update_prop);
38665 sqlite3_finalize(s->stmt_select_prop);
38666 sqlite3_finalize(s->stmt_select_propnames);
38668 + sqlite3_finalize(s->stmt_read_lock);
38669 + sqlite3_finalize(s->stmt_read_lock_by_uri);
38670 + sqlite3_finalize(s->stmt_create_lock);
38671 + sqlite3_finalize(s->stmt_remove_lock);
38672 + sqlite3_finalize(s->stmt_refresh_lock);
38673 sqlite3_close(s->sql);
38679 free(p->config_storage);
38680 @@ -135,16 +152,16 @@
38681 buffer_free(p->uri.path_raw);
38682 buffer_free(p->uri.path);
38683 buffer_free(p->uri.authority);
38686 buffer_free(p->physical.path);
38687 buffer_free(p->physical.rel_path);
38688 buffer_free(p->physical.doc_root);
38689 buffer_free(p->physical.basedir);
38692 buffer_free(p->tmp_buf);
38698 return HANDLER_GO_ON;
38701 @@ -153,32 +170,32 @@
38702 SETDEFAULTS_FUNC(mod_webdav_set_defaults) {
38703 plugin_data *p = p_d;
38706 - config_values_t cv[] = {
38708 + config_values_t cv[] = {
38709 { "webdav.activate", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
38710 { "webdav.is-readonly", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
38711 { "webdav.sqlite-db-name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
38712 { "webdav.log-xml", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
38713 { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
38717 if (!p) return HANDLER_ERROR;
38720 p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
38723 for (i = 0; i < srv->config_context->used; i++) {
38727 s = calloc(1, sizeof(plugin_config));
38728 s->sqlite_db_name = buffer_init();
38731 cv[0].destination = &(s->enabled);
38732 cv[1].destination = &(s->is_readonly);
38733 cv[2].destination = s->sqlite_db_name;
38734 cv[3].destination = &(s->log_xml);
38737 p->config_storage[i] = s;
38740 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
38741 return HANDLER_ERROR;
38743 @@ -193,8 +210,26 @@
38744 return HANDLER_ERROR;
38747 - if (SQLITE_OK != sqlite3_prepare(s->sql,
38748 - CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
38749 + if (SQLITE_OK != sqlite3_exec(s->sql,
38750 + "CREATE TABLE properties ("
38751 + " resource TEXT NOT NULL,"
38752 + " prop TEXT NOT NULL,"
38753 + " ns TEXT NOT NULL,"
38754 + " value TEXT NOT NULL,"
38755 + " PRIMARY KEY(resource, prop, ns))",
38756 + NULL, NULL, &err)) {
38758 + if (0 != strcmp(err, "table properties already exists")) {
38759 + log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
38760 + sqlite3_free(err);
38762 + return HANDLER_ERROR;
38764 + sqlite3_free(err);
38767 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38768 + CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
38769 &(s->stmt_select_prop), &next_stmt)) {
38770 /* prepare failed */
38772 @@ -202,8 +237,8 @@
38773 return HANDLER_ERROR;
38776 - if (SQLITE_OK != sqlite3_prepare(s->sql,
38777 - CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"),
38778 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38779 + CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"),
38780 &(s->stmt_select_propnames), &next_stmt)) {
38781 /* prepare failed */
38783 @@ -211,16 +246,67 @@
38784 return HANDLER_ERROR;
38787 - if (SQLITE_OK != sqlite3_exec(s->sql,
38788 - "CREATE TABLE properties ("
38790 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38791 + CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"),
38792 + &(s->stmt_update_prop), &next_stmt)) {
38793 + /* prepare failed */
38795 + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
38796 + return HANDLER_ERROR;
38799 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38800 + CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
38801 + &(s->stmt_delete_prop), &next_stmt)) {
38802 + /* prepare failed */
38803 + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38805 + return HANDLER_ERROR;
38808 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38809 + CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"),
38810 + &(s->stmt_delete_uri), &next_stmt)) {
38811 + /* prepare failed */
38812 + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38814 + return HANDLER_ERROR;
38817 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38818 + CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"),
38819 + &(s->stmt_copy_uri), &next_stmt)) {
38820 + /* prepare failed */
38821 + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38823 + return HANDLER_ERROR;
38826 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38827 + CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"),
38828 + &(s->stmt_move_uri), &next_stmt)) {
38829 + /* prepare failed */
38830 + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38832 + return HANDLER_ERROR;
38837 + if (SQLITE_OK != sqlite3_exec(s->sql,
38838 + "CREATE TABLE locks ("
38839 + " locktoken TEXT NOT NULL,"
38840 " resource TEXT NOT NULL,"
38841 - " prop TEXT NOT NULL,"
38842 - " ns TEXT NOT NULL,"
38843 - " value TEXT NOT NULL,"
38844 - " PRIMARY KEY(resource, prop, ns))",
38845 + " lockscope TEXT NOT NULL,"
38846 + " locktype TEXT NOT NULL,"
38847 + " owner TEXT NOT NULL,"
38848 + " depth INT NOT NULL,"
38849 + " timeout TIMESTAMP NOT NULL,"
38850 + " PRIMARY KEY(locktoken))",
38851 NULL, NULL, &err)) {
38853 - if (0 != strcmp(err, "table properties already exists")) {
38854 + if (0 != strcmp(err, "table locks already exists")) {
38855 log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
38858 @@ -228,127 +314,138 @@
38863 - if (SQLITE_OK != sqlite3_prepare(s->sql,
38864 - CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"),
38865 - &(s->stmt_update_prop), &next_stmt)) {
38867 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38868 + CONST_STR_LEN("INSERT INTO locks (locktoken, resource, lockscope, locktype, owner, depth, timeout) VALUES (?,?,?,?,?,?, CURRENT_TIME + 600)"),
38869 + &(s->stmt_create_lock), &next_stmt)) {
38870 /* prepare failed */
38871 + log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38873 - log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
38874 return HANDLER_ERROR;
38877 - if (SQLITE_OK != sqlite3_prepare(s->sql,
38878 - CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
38879 - &(s->stmt_delete_prop), &next_stmt)) {
38880 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38881 + CONST_STR_LEN("DELETE FROM locks WHERE locktoken = ?"),
38882 + &(s->stmt_remove_lock), &next_stmt)) {
38883 /* prepare failed */
38884 log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38886 return HANDLER_ERROR;
38889 - if (SQLITE_OK != sqlite3_prepare(s->sql,
38890 - CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"),
38891 - &(s->stmt_delete_uri), &next_stmt)) {
38892 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38893 + CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE locktoken = ?"),
38894 + &(s->stmt_read_lock), &next_stmt)) {
38895 /* prepare failed */
38896 log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38898 return HANDLER_ERROR;
38901 - if (SQLITE_OK != sqlite3_prepare(s->sql,
38902 - CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"),
38903 - &(s->stmt_copy_uri), &next_stmt)) {
38904 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38905 + CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE resource = ?"),
38906 + &(s->stmt_read_lock_by_uri), &next_stmt)) {
38907 /* prepare failed */
38908 log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38910 return HANDLER_ERROR;
38913 - if (SQLITE_OK != sqlite3_prepare(s->sql,
38914 - CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"),
38915 - &(s->stmt_move_uri), &next_stmt)) {
38916 + if (SQLITE_OK != sqlite3_prepare(s->sql,
38917 + CONST_STR_LEN("UPDATE locks SET timeout = CURRENT_TIME + 600 WHERE locktoken = ?"),
38918 + &(s->stmt_refresh_lock), &next_stmt)) {
38919 /* prepare failed */
38920 log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
38922 return HANDLER_ERROR;
38927 log_error_write(srv, __FILE__, __LINE__, "s", "Sorry, no sqlite3 and libxml2 support include, compile with --with-webdav-props");
38928 return HANDLER_ERROR;
38934 return HANDLER_GO_ON;
38937 -#define PATCH(x) \
38938 - p->conf.x = s->x;
38939 static int mod_webdav_patch_connection(server *srv, connection *con, plugin_data *p) {
38941 plugin_config *s = p->config_storage[0];
38944 - PATCH(is_readonly);
38948 + PATCH_OPTION(enabled);
38949 + PATCH_OPTION(is_readonly);
38950 + PATCH_OPTION(log_xml);
38952 #ifdef USE_PROPPATCH
38954 - PATCH(stmt_update_prop);
38955 - PATCH(stmt_delete_prop);
38956 - PATCH(stmt_select_prop);
38957 - PATCH(stmt_select_propnames);
38959 - PATCH(stmt_delete_uri);
38960 - PATCH(stmt_move_uri);
38961 - PATCH(stmt_copy_uri);
38962 + PATCH_OPTION(sql);
38963 + PATCH_OPTION(stmt_update_prop);
38964 + PATCH_OPTION(stmt_delete_prop);
38965 + PATCH_OPTION(stmt_select_prop);
38966 + PATCH_OPTION(stmt_select_propnames);
38968 + PATCH_OPTION(stmt_delete_uri);
38969 + PATCH_OPTION(stmt_move_uri);
38970 + PATCH_OPTION(stmt_copy_uri);
38972 + PATCH_OPTION(stmt_remove_lock);
38973 + PATCH_OPTION(stmt_refresh_lock);
38974 + PATCH_OPTION(stmt_create_lock);
38975 + PATCH_OPTION(stmt_read_lock);
38976 + PATCH_OPTION(stmt_read_lock_by_uri);
38978 /* skip the first, the global context */
38979 for (i = 1; i < srv->config_context->used; i++) {
38980 data_config *dc = (data_config *)srv->config_context->data[i];
38981 s = p->config_storage[i];
38984 /* condition didn't match */
38985 if (!config_check_cond(srv, con, dc)) continue;
38989 for (j = 0; j < dc->value->used; j++) {
38990 data_unset *du = dc->value->data[j];
38993 if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.activate"))) {
38995 + PATCH_OPTION(enabled);
38996 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.is-readonly"))) {
38997 - PATCH(is_readonly);
38998 + PATCH_OPTION(is_readonly);
38999 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.log-xml"))) {
39001 + PATCH_OPTION(log_xml);
39002 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.sqlite-db-name"))) {
39003 #ifdef USE_PROPPATCH
39005 - PATCH(stmt_update_prop);
39006 - PATCH(stmt_delete_prop);
39007 - PATCH(stmt_select_prop);
39008 - PATCH(stmt_select_propnames);
39010 - PATCH(stmt_delete_uri);
39011 - PATCH(stmt_move_uri);
39012 - PATCH(stmt_copy_uri);
39013 + PATCH_OPTION(sql);
39014 + PATCH_OPTION(stmt_update_prop);
39015 + PATCH_OPTION(stmt_delete_prop);
39016 + PATCH_OPTION(stmt_select_prop);
39017 + PATCH_OPTION(stmt_select_propnames);
39019 + PATCH_OPTION(stmt_delete_uri);
39020 + PATCH_OPTION(stmt_move_uri);
39021 + PATCH_OPTION(stmt_copy_uri);
39023 + PATCH_OPTION(stmt_remove_lock);
39024 + PATCH_OPTION(stmt_refresh_lock);
39025 + PATCH_OPTION(stmt_create_lock);
39026 + PATCH_OPTION(stmt_read_lock);
39027 + PATCH_OPTION(stmt_read_lock_by_uri);
39038 URIHANDLER_FUNC(mod_webdav_uri_handler) {
39039 plugin_data *p = p_d;
39044 if (con->uri.path->used == 0) return HANDLER_GO_ON;
39047 mod_webdav_patch_connection(srv, con, p);
39049 if (!p->conf.enabled) return HANDLER_GO_ON;
39050 @@ -362,20 +459,20 @@
39051 if (p->conf.is_readonly) {
39052 response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND"));
39054 - response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH"));
39055 + response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK"));
39064 return HANDLER_GO_ON;
39066 -static int webdav_gen_prop_tag(server *srv, connection *con,
39070 +static int webdav_gen_prop_tag(server *srv, connection *con,
39077 @@ -414,7 +511,7 @@
39078 buffer_append_string_buffer(b, dst->rel_path);
39079 buffer_append_string(b,"</D:href>\n");
39080 buffer_append_string(b,"<D:status>\n");
39083 if (con->request.http_version == HTTP_VERSION_1_1) {
39084 BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
39086 @@ -458,11 +555,11 @@
39088 /* bind the values to the insert */
39090 - sqlite3_bind_text(stmt, 1,
39091 - dst->rel_path->ptr,
39092 + sqlite3_bind_text(stmt, 1,
39093 + dst->rel_path->ptr,
39094 dst->rel_path->used - 1,
39098 if (SQLITE_DONE != sqlite3_step(stmt)) {
39101 @@ -493,14 +590,14 @@
39102 (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
39104 /* ignore the parent dir */
39108 buffer_copy_string_buffer(d.path, dst->path);
39109 - BUFFER_APPEND_SLASH(d.path);
39110 + PATHNAME_APPEND_SLASH(d.path);
39111 buffer_append_string(d.path, de->d_name);
39114 buffer_copy_string_buffer(d.rel_path, dst->rel_path);
39115 - BUFFER_APPEND_SLASH(d.rel_path);
39116 + PATHNAME_APPEND_SLASH(d.rel_path);
39117 buffer_append_string(d.rel_path, de->d_name);
39119 /* stat and unlink afterwards */
39120 @@ -508,7 +605,7 @@
39121 /* don't about it yet, rmdir will fail too */
39122 } else if (S_ISDIR(st.st_mode)) {
39123 have_multi_status = webdav_delete_dir(srv, con, p, &d, b);
39126 /* try to unlink it */
39127 if (-1 == rmdir(d.path->ptr)) {
39129 @@ -535,11 +632,11 @@
39131 /* bind the values to the insert */
39133 - sqlite3_bind_text(stmt, 1,
39135 + sqlite3_bind_text(stmt, 1,
39137 d.rel_path->used - 1,
39141 if (SQLITE_DONE != sqlite3_step(stmt)) {
39144 @@ -569,7 +666,7 @@
39145 if (stream_open(&s, src->path)) {
39150 if (-1 == (ofd = open(dst->path->ptr, O_WRONLY|O_TRUNC|O_CREAT|(overwrite ? 0 : O_EXCL), 0600))) {
39151 /* opening the destination failed for some reason */
39153 @@ -601,7 +698,7 @@
39162 @@ -614,16 +711,16 @@
39163 sqlite3_reset(stmt);
39165 /* bind the values to the insert */
39166 - sqlite3_bind_text(stmt, 1,
39167 - dst->rel_path->ptr,
39168 + sqlite3_bind_text(stmt, 1,
39169 + dst->rel_path->ptr,
39170 dst->rel_path->used - 1,
39173 - sqlite3_bind_text(stmt, 2,
39174 - src->rel_path->ptr,
39175 + sqlite3_bind_text(stmt, 2,
39176 + src->rel_path->ptr,
39177 src->rel_path->used - 1,
39181 if (SQLITE_DONE != sqlite3_step(stmt)) {
39184 @@ -655,21 +752,21 @@
39185 (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
39190 buffer_copy_string_buffer(s.path, src->path);
39191 - BUFFER_APPEND_SLASH(s.path);
39192 + PATHNAME_APPEND_SLASH(s.path);
39193 buffer_append_string(s.path, de->d_name);
39195 buffer_copy_string_buffer(d.path, dst->path);
39196 - BUFFER_APPEND_SLASH(d.path);
39197 + PATHNAME_APPEND_SLASH(d.path);
39198 buffer_append_string(d.path, de->d_name);
39200 buffer_copy_string_buffer(s.rel_path, src->rel_path);
39201 - BUFFER_APPEND_SLASH(s.rel_path);
39202 + PATHNAME_APPEND_SLASH(s.rel_path);
39203 buffer_append_string(s.rel_path, de->d_name);
39205 buffer_copy_string_buffer(d.rel_path, dst->rel_path);
39206 - BUFFER_APPEND_SLASH(d.rel_path);
39207 + PATHNAME_APPEND_SLASH(d.rel_path);
39208 buffer_append_string(d.rel_path, de->d_name);
39210 if (-1 == stat(s.path->ptr, &st)) {
39211 @@ -692,16 +789,16 @@
39212 sqlite3_reset(stmt);
39214 /* bind the values to the insert */
39215 - sqlite3_bind_text(stmt, 1,
39216 - dst->rel_path->ptr,
39217 + sqlite3_bind_text(stmt, 1,
39218 + dst->rel_path->ptr,
39219 dst->rel_path->used - 1,
39222 - sqlite3_bind_text(stmt, 2,
39223 - src->rel_path->ptr,
39224 + sqlite3_bind_text(stmt, 2,
39225 + src->rel_path->ptr,
39226 src->rel_path->used - 1,
39230 if (SQLITE_DONE != sqlite3_step(stmt)) {
39233 @@ -721,7 +818,7 @@
39234 buffer_free(s.rel_path);
39235 buffer_free(d.path);
39236 buffer_free(d.rel_path);
39242 @@ -748,12 +845,12 @@
39243 if (S_ISDIR(sce->st.st_mode)) {
39244 buffer_append_string(b, "<D:getcontenttype>httpd/unix-directory</D:getcontenttype>");
39246 - } else if(S_ISREG(sce->st.st_mode)) {
39247 + } else if(S_ISREG(sce->st.st_mode)) {
39248 for (k = 0; k < con->conf.mimetypes->used; k++) {
39249 data_string *ds = (data_string *)con->conf.mimetypes->data[k];
39252 if (ds->key->used == 0) continue;
39255 if (buffer_is_equal_right_len(dst->path, ds->key, ds->key->used - 1)) {
39256 buffer_append_string(b,"<D:getcontenttype>");
39257 buffer_append_string_buffer(b, ds->value);
39258 @@ -807,23 +904,23 @@
39260 /* bind the values to the insert */
39262 - sqlite3_bind_text(stmt, 1,
39263 - dst->rel_path->ptr,
39264 + sqlite3_bind_text(stmt, 1,
39265 + dst->rel_path->ptr,
39266 dst->rel_path->used - 1,
39268 - sqlite3_bind_text(stmt, 2,
39269 + sqlite3_bind_text(stmt, 2,
39273 - sqlite3_bind_text(stmt, 3,
39274 + sqlite3_bind_text(stmt, 3,
39280 - while (SQLITE_ROW == sqlite3_step(p->conf.stmt_select_prop)) {
39281 + while (SQLITE_ROW == sqlite3_step(stmt)) {
39282 /* there is a row for us, we only expect a single col 'value' */
39283 - webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(p->conf.stmt_select_prop, 0), b);
39284 + webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(stmt, 0), b);
39288 @@ -840,7 +937,7 @@
39292 -webdav_property live_properties[] = {
39293 +webdav_property live_properties[] = {
39294 { "DAV:", "creationdate" },
39295 { "DAV:", "displayname" },
39296 { "DAV:", "getcontentlanguage" },
39297 @@ -871,8 +968,8 @@
39298 webdav_property *prop;
39300 prop = props->ptr[i];
39302 - if (0 != webdav_get_property(srv, con, p,
39304 + if (0 != webdav_get_property(srv, con, p,
39305 dst, prop->prop, prop->ns, b_200)) {
39306 webdav_gen_prop_tag(srv, con, prop->prop, prop->ns, NULL, b_404);
39308 @@ -916,12 +1013,12 @@
39309 if (-1 == c->file.fd && /* open the file if not already open */
39310 -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
39311 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
39318 if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
39319 - log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
39320 + log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
39321 strerror(errno), c->file.name, c->file.fd);
39324 @@ -938,7 +1035,7 @@
39325 if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->file.mmap.start + c->offset, weHave, 0))) {
39326 log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
39330 c->offset += weHave;
39331 cq->bytes_out += weHave;
39333 @@ -956,7 +1053,7 @@
39334 if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->mem->ptr + c->offset, weHave, 0))) {
39335 log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
39339 c->offset += weHave;
39340 cq->bytes_out += weHave;
39342 @@ -991,6 +1088,113 @@
39346 +int webdav_lockdiscovery(server *srv, connection *con,
39347 + buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
39351 + response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken));
39353 + response_header_overwrite(srv, con,
39354 + CONST_STR_LEN("Content-Type"),
39355 + CONST_STR_LEN("text/xml; charset=\"utf-8\""));
39357 + b = chunkqueue_get_append_buffer(con->write_queue);
39359 + buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
39361 + buffer_append_string(b,"<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n");
39362 + buffer_append_string(b,"<D:lockdiscovery>\n");
39363 + buffer_append_string(b,"<D:activelock>\n");
39365 + buffer_append_string(b,"<D:lockscope>");
39366 + buffer_append_string(b,"<D:");
39367 + buffer_append_string(b, lockscope);
39368 + buffer_append_string(b, "/>");
39369 + buffer_append_string(b,"</D:lockscope>\n");
39371 + buffer_append_string(b,"<D:locktype>");
39372 + buffer_append_string(b,"<D:");
39373 + buffer_append_string(b, locktype);
39374 + buffer_append_string(b, "/>");
39375 + buffer_append_string(b,"</D:locktype>\n");
39377 + buffer_append_string(b,"<D:depth>");
39378 + buffer_append_string(b, depth == 0 ? "0" : "infinity");
39379 + buffer_append_string(b,"</D:depth>\n");
39381 + buffer_append_string(b,"<D:timeout>");
39382 + buffer_append_string(b, "Second-600");
39383 + buffer_append_string(b,"</D:timeout>\n");
39385 + buffer_append_string(b,"<D:owner>");
39386 + buffer_append_string(b,"</D:owner>\n");
39388 + buffer_append_string(b,"<D:locktoken>");
39389 + buffer_append_string(b, "<D:href>");
39390 + buffer_append_string_buffer(b, locktoken);
39391 + buffer_append_string(b, "</D:href>");
39392 + buffer_append_string(b,"</D:locktoken>\n");
39394 + buffer_append_string(b,"</D:activelock>\n");
39395 + buffer_append_string(b,"</D:lockdiscovery>\n");
39396 + buffer_append_string(b,"</D:prop>\n");
39401 + * check if resource is having the right locks to access to resource
39406 +int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
39407 + int has_lock = 1;
39417 + * there is NOT, AND and OR
39418 + * and a list can be tagged
39420 + * (<lock-token>) is untagged
39421 + * <tag> (<lock-token>) is tagged
39423 + * as long as we don't handle collections it is simple. :)
39425 + * X-Litmus: locks: 11 (owner_modify)
39426 + * If: <http://127.0.0.1:1025/dav/litmus/lockme> (<opaquelocktoken:2165478d-0611-49c4-be92-e790d68a38f1>)
39428 + * X-Litmus: locks: 16 (fail_cond_put)
39429 + * If: (<DAV:no-lock> ["-1622396671"])
39431 + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
39433 + /* we didn't provided a lock-token -> */
39434 + /* if the resource is locked -> 423 */
39436 + sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
39438 + sqlite3_reset(stmt);
39440 + sqlite3_bind_text(stmt, 1,
39441 + CONST_BUF_LEN(uri),
39442 + SQLITE_TRANSIENT);
39444 + while (SQLITE_ROW == sqlite3_step(stmt)) {
39453 URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
39454 plugin_data *p = p_d;
39456 @@ -1001,7 +1205,8 @@
39459 webdav_properties *req_props;
39461 + stat_cache_entry *sce = NULL;
39465 if (!p->conf.enabled) return HANDLER_GO_ON;
39466 @@ -1019,7 +1224,19 @@
39469 /* is there a content-body ? */
39472 + switch (stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
39473 + case HANDLER_ERROR:
39474 + if (errno == ENOENT) {
39475 + con->http_status = 404;
39476 + return HANDLER_FINISHED;
39484 #ifdef USE_PROPPATCH
39485 /* any special requests or just allprop ? */
39486 if (con->request.content_length) {
39487 @@ -1087,12 +1304,12 @@
39488 /* get all property names (EMPTY) */
39489 sqlite3_reset(stmt);
39490 /* bind the values to the insert */
39492 - sqlite3_bind_text(stmt, 1,
39493 - con->uri.path->ptr,
39495 + sqlite3_bind_text(stmt, 1,
39496 + con->uri.path->ptr,
39497 con->uri.path->used - 1,
39501 if (SQLITE_DONE != sqlite3_step(stmt)) {
39504 @@ -1115,13 +1332,13 @@
39505 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
39507 b = chunkqueue_get_append_buffer(con->write_queue);
39510 buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
39512 buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n");
39517 prop_200 = buffer_init();
39518 prop_404 = buffer_init();
39520 @@ -1129,7 +1346,7 @@
39523 webdav_get_props(srv, con, p, &(con->physical), req_props, prop_200, prop_404);
39526 buffer_append_string(b,"<D:response>\n");
39527 buffer_append_string(b,"<D:href>");
39528 buffer_append_string_buffer(b, con->uri.scheme);
39529 @@ -1145,9 +1362,9 @@
39530 buffer_append_string_buffer(b, prop_200);
39532 buffer_append_string(b,"</D:prop>\n");
39535 buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n");
39538 buffer_append_string(b,"</D:propstat>\n");
39540 if (!buffer_is_empty(prop_404)) {
39541 @@ -1157,16 +1374,16 @@
39542 buffer_append_string_buffer(b, prop_404);
39544 buffer_append_string(b,"</D:prop>\n");
39547 buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n");
39550 buffer_append_string(b,"</D:propstat>\n");
39553 buffer_append_string(b,"</D:response>\n");
39558 if (NULL != (dir = opendir(con->physical.path->ptr))) {
39561 @@ -1179,16 +1396,16 @@
39562 if (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0') {
39564 /* ignore the parent dir */
39568 buffer_copy_string_buffer(d.path, dst->path);
39569 - BUFFER_APPEND_SLASH(d.path);
39570 + PATHNAME_APPEND_SLASH(d.path);
39572 buffer_copy_string_buffer(d.rel_path, dst->rel_path);
39573 - BUFFER_APPEND_SLASH(d.rel_path);
39574 + PATHNAME_APPEND_SLASH(d.rel_path);
39576 if (de->d_name[0] == '.' && de->d_name[1] == '\0') {
39577 - /* don't append the . */
39578 + /* don't append the . */
39580 buffer_append_string(d.path, de->d_name);
39581 buffer_append_string(d.rel_path, de->d_name);
39582 @@ -1198,7 +1415,7 @@
39583 buffer_reset(prop_404);
39585 webdav_get_props(srv, con, p, &d, req_props, prop_200, prop_404);
39588 buffer_append_string(b,"<D:response>\n");
39589 buffer_append_string(b,"<D:href>");
39590 buffer_append_string_buffer(b, con->uri.scheme);
39591 @@ -1214,9 +1431,9 @@
39592 buffer_append_string_buffer(b, prop_200);
39594 buffer_append_string(b,"</D:prop>\n");
39597 buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n");
39600 buffer_append_string(b,"</D:propstat>\n");
39602 if (!buffer_is_empty(prop_404)) {
39603 @@ -1226,9 +1443,9 @@
39604 buffer_append_string_buffer(b, prop_404);
39606 buffer_append_string(b,"</D:prop>\n");
39609 buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n");
39612 buffer_append_string(b,"</D:propstat>\n");
39615 @@ -1275,7 +1492,7 @@
39617 return HANDLER_FINISHED;
39621 /* let's create the directory */
39623 if (-1 == mkdir(con->physical.path->ptr, 0700)) {
39624 @@ -1303,7 +1520,13 @@
39625 con->http_status = 403;
39626 return HANDLER_FINISHED;
39630 + /* does the client have a lock for this connection ? */
39631 + if (!webdav_has_lock(srv, con, p, con->uri.path)) {
39632 + con->http_status = 423;
39633 + return HANDLER_FINISHED;
39636 /* stat and unlink afterwards */
39637 if (-1 == stat(con->physical.path->ptr, &st)) {
39638 /* don't about it yet, unlink will fail too */
39639 @@ -1323,7 +1546,7 @@
39640 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
39642 b = chunkqueue_get_append_buffer(con->write_queue);
39645 buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
39647 buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\">\n");
39648 @@ -1331,7 +1554,7 @@
39649 buffer_append_string_buffer(b, multi_status_resp);
39651 buffer_append_string(b,"</D:multistatus>\n");
39654 if (p->conf.log_xml) {
39655 log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
39657 @@ -1340,7 +1563,7 @@
39658 con->file_finished = 1;
39660 /* everything went fine, remove the directory */
39663 if (-1 == rmdir(con->physical.path->ptr)) {
39666 @@ -1375,97 +1598,174 @@
39667 case HTTP_METHOD_PUT: {
39669 chunkqueue *cq = con->request_content_queue;
39671 + data_string *ds_range;
39673 if (p->conf.is_readonly) {
39674 con->http_status = 403;
39675 return HANDLER_FINISHED;
39678 + /* is a exclusive lock set on the source */
39679 + if (!webdav_has_lock(srv, con, p, con->uri.path)) {
39680 + con->http_status = 423;
39681 + return HANDLER_FINISHED;
39685 assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
39687 - /* taken what we have in the request-body and write it to a file */
39688 - if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC, 0600))) {
39689 - /* we can't open the file */
39690 - con->http_status = 403;
39693 + /* RFC2616 Section 9.6 PUT requires us to send 501 on all Content-* we don't support
39694 + * - most important Content-Range
39697 + * Example: Content-Range: bytes 100-1037/1038 */
39699 - con->http_status = 201; /* created */
39700 - con->file_finished = 1;
39701 + if (NULL != (ds_range = (data_string *)array_get_element(con->request.headers, "Content-Range"))) {
39702 + const char *num = ds_range->value->ptr;
39704 + char *err = NULL;
39706 - for (c = cq->first; c; c = cq->first) {
39708 + if (0 != strncmp(num, "bytes ", 6)) {
39709 + con->http_status = 501; /* not implemented */
39711 - /* copy all chunks */
39712 - switch(c->type) {
39715 - if (c->file.mmap.start == MAP_FAILED) {
39716 - if (-1 == c->file.fd && /* open the file if not already open */
39717 - -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
39718 - log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
39723 - if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
39724 - log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
39725 - strerror(errno), c->file.name, c->file.fd);
39726 + return HANDLER_FINISHED;
39731 + /* we only support <num>- ... */
39733 - c->file.mmap.length = c->file.length;
39736 - close(c->file.fd);
39739 - /* chunk_reset() or chunk_free() will cleanup for us */
39742 - if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) {
39745 - con->http_status = 507;
39749 - con->http_status = 403;
39755 - if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
39758 - con->http_status = 507;
39762 - con->http_status = 403;
39767 + while (*num == ' ' || *num == '\t') num++;
39769 + if (*num == '\0') {
39770 + con->http_status = 501; /* not implemented */
39772 + return HANDLER_FINISHED;
39775 + offset = strtoll(num, &err, 10);
39777 + if (*err != '-' || offset < 0) {
39778 + con->http_status = 501; /* not implemented */
39780 + return HANDLER_FINISHED;
39783 + if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY, 0600))) {
39786 + con->http_status = 404; /* not found */
39788 - case UNUSED_CHUNK:
39790 + con->http_status = 403; /* not found */
39793 + return HANDLER_FINISHED;
39796 + if (-1 == lseek(fd, offset, SEEK_SET)) {
39797 + con->http_status = 501; /* not implemented */
39801 + return HANDLER_FINISHED;
39803 + con->http_status = 200; /* modified */
39805 + /* take what we have in the request-body and write it to a file */
39807 + /* if the file doesn't exist, create it */
39808 + if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_TRUNC, 0600))) {
39809 + if (errno == ENOENT &&
39810 + -1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0600))) {
39811 + /* we can't open the file */
39812 + con->http_status = 403;
39816 - cq->bytes_out += r;
39817 + return HANDLER_FINISHED;
39820 + con->http_status = 201; /* created */
39823 + con->http_status = 200; /* modified */
39827 + con->file_finished = 1;
39829 + for (c = cq->first; c; c = cq->first) {
39832 + /* copy all chunks */
39833 + switch(c->type) {
39836 + if (c->file.mmap.start == MAP_FAILED) {
39837 + if (-1 == c->file.fd && /* open the file if not already open */
39838 + -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
39839 + log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
39844 + if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
39845 + log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
39846 + strerror(errno), c->file.name, c->file.fd);
39851 + c->file.mmap.length = c->file.length;
39853 + close(c->file.fd);
39856 + /* chunk_reset() or chunk_free() will cleanup for us */
39859 + if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) {
39862 + con->http_status = 507;
39866 + con->http_status = 403;
39870 - chunkqueue_remove_finished_chunks(cq);
39873 + if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
39876 + con->http_status = 507;
39880 + con->http_status = 403;
39885 + case UNUSED_CHUNK:
39892 + cq->bytes_out += r;
39896 + chunkqueue_remove_finished_chunks(cq);
39900 return HANDLER_FINISHED;
39902 - case HTTP_METHOD_MOVE:
39903 + case HTTP_METHOD_MOVE:
39904 case HTTP_METHOD_COPY: {
39905 buffer *destination = NULL;
39907 @@ -1475,7 +1775,15 @@
39908 con->http_status = 403;
39909 return HANDLER_FINISHED;
39913 + /* is a exclusive lock set on the source */
39914 + if (con->request.http_method == HTTP_METHOD_MOVE) {
39915 + if (!webdav_has_lock(srv, con, p, con->uri.path)) {
39916 + con->http_status = 423;
39917 + return HANDLER_FINISHED;
39921 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Destination"))) {
39922 destination = ds->value;
39924 @@ -1549,10 +1857,10 @@
39927 buffer_copy_string_buffer(p->physical.path, p->physical.doc_root);
39928 - BUFFER_APPEND_SLASH(p->physical.path);
39929 + PATHNAME_APPEND_SLASH(p->physical.path);
39930 buffer_copy_string_buffer(p->physical.basedir, p->physical.path);
39932 - /* don't add a second / */
39933 + /* don't add a second / */
39934 if (p->physical.rel_path->ptr[0] == '/') {
39935 buffer_append_string_len(p->physical.path, p->physical.rel_path->ptr + 1, p->physical.rel_path->used - 2);
39937 @@ -1613,6 +1921,12 @@
39938 /* it is just a file, good */
39941 + /* does the client have a lock for this connection ? */
39942 + if (!webdav_has_lock(srv, con, p, p->uri.path)) {
39943 + con->http_status = 423;
39944 + return HANDLER_FINISHED;
39947 /* destination exists */
39948 if (0 == (r = stat(p->physical.path->ptr, &st))) {
39949 if (S_ISDIR(st.st_mode)) {
39950 @@ -1636,7 +1950,7 @@
39951 return HANDLER_FINISHED;
39953 } else if (overwrite == 0) {
39954 - /* destination exists, but overwrite is not set */
39955 + /* destination exists, but overwrite is not set */
39956 con->http_status = 412;
39957 return HANDLER_FINISHED;
39959 @@ -1655,16 +1969,16 @@
39960 sqlite3_reset(stmt);
39962 /* bind the values to the insert */
39963 - sqlite3_bind_text(stmt, 1,
39964 - p->uri.path->ptr,
39965 + sqlite3_bind_text(stmt, 1,
39966 + p->uri.path->ptr,
39967 p->uri.path->used - 1,
39970 - sqlite3_bind_text(stmt, 2,
39971 - con->uri.path->ptr,
39972 + sqlite3_bind_text(stmt, 2,
39973 + con->uri.path->ptr,
39974 con->uri.path->used - 1,
39978 if (SQLITE_DONE != sqlite3_step(stmt)) {
39979 log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move failed:", sqlite3_errmsg(p->conf.sql));
39981 @@ -1691,12 +2005,17 @@
39983 return HANDLER_FINISHED;
39985 - case HTTP_METHOD_PROPPATCH: {
39986 + case HTTP_METHOD_PROPPATCH:
39987 if (p->conf.is_readonly) {
39988 con->http_status = 403;
39989 return HANDLER_FINISHED;
39992 + if (!webdav_has_lock(srv, con, p, con->uri.path)) {
39993 + con->http_status = 423;
39994 + return HANDLER_FINISHED;
39997 /* check if destination exists */
39998 if (-1 == stat(con->physical.path->ptr, &st)) {
40000 @@ -1737,7 +2056,7 @@
40002 sqlite3_stmt *stmt;
40004 - stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ?
40005 + stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ?
40006 p->conf.stmt_delete_prop : p->conf.stmt_update_prop;
40008 for (props = cmd->children; props; props = props->next) {
40009 @@ -1762,34 +2081,35 @@
40011 /* bind the values to the insert */
40013 - sqlite3_bind_text(stmt, 1,
40014 - con->uri.path->ptr,
40015 + sqlite3_bind_text(stmt, 1,
40016 + con->uri.path->ptr,
40017 con->uri.path->used - 1,
40019 - sqlite3_bind_text(stmt, 2,
40020 + sqlite3_bind_text(stmt, 2,
40021 (char *)prop->name,
40022 strlen((char *)prop->name),
40025 - sqlite3_bind_text(stmt, 3,
40026 + sqlite3_bind_text(stmt, 3,
40027 (char *)prop->ns->href,
40028 strlen((char *)prop->ns->href),
40031 - sqlite3_bind_text(stmt, 3,
40032 + sqlite3_bind_text(stmt, 3,
40037 if (stmt == p->conf.stmt_update_prop) {
40038 - sqlite3_bind_text(stmt, 4,
40039 + sqlite3_bind_text(stmt, 4,
40040 (char *)xmlNodeGetContent(prop),
40041 strlen((char *)xmlNodeGetContent(prop)),
40046 if (SQLITE_DONE != (r = sqlite3_step(stmt))) {
40047 - log_error_write(srv, __FILE__, __LINE__, "ss", "sql-set failed:", sqlite3_errmsg(p->conf.sql));
40048 + log_error_write(srv, __FILE__, __LINE__, "ss",
40049 + "sql-set failed:", sqlite3_errmsg(p->conf.sql));
40053 @@ -1804,7 +2124,7 @@
40055 goto propmatch_cleanup;
40059 con->http_status = 400;
40061 if (SQLITE_OK != sqlite3_exec(p->conf.sql, "COMMIT", NULL, NULL, &err)) {
40062 @@ -1821,6 +2141,7 @@
40069 con->http_status = 400;
40070 @@ -1830,11 +2151,307 @@
40072 con->http_status = 501;
40073 return HANDLER_FINISHED;
40075 + case HTTP_METHOD_LOCK:
40077 + * a mac wants to write
40079 + * LOCK /dav/expire.txt HTTP/1.1\r\n
40080 + * User-Agent: WebDAVFS/1.3 (01308000) Darwin/8.1.0 (Power Macintosh)\r\n
40081 + * Accept: * / *\r\n
40083 + * Timeout: Second-600\r\n
40084 + * Content-Type: text/xml; charset=\"utf-8\"\r\n
40085 + * Content-Length: 229\r\n
40086 + * Connection: keep-alive\r\n
40087 + * Host: 192.168.178.23:1025\r\n
40089 + * <?xml version=\"1.0\" encoding=\"utf-8\"?>\n
40090 + * <D:lockinfo xmlns:D=\"DAV:\">\n
40091 + * <D:lockscope><D:exclusive/></D:lockscope>\n
40092 + * <D:locktype><D:write/></D:locktype>\n
40094 + * <D:href>http://www.apple.com/webdav_fs/</D:href>\n
40096 + * </D:lockinfo>\n
40099 + if (depth != 0 && depth != -1) {
40100 + con->http_status = 400;
40102 + return HANDLER_FINISHED;
40106 + if (con->request.content_length) {
40108 + buffer *hdr_if = NULL;
40110 + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
40111 + hdr_if = ds->value;
40114 + /* we don't support Depth: Infinity on locks */
40115 + if (hdr_if == NULL && depth == -1) {
40116 + con->http_status = 409; /* Conflict */
40118 + return HANDLER_FINISHED;
40121 + if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
40122 + xmlNode *rootnode = xmlDocGetRootElement(xml);
40124 + assert(rootnode);
40126 + if (0 == xmlStrcmp(rootnode->name, BAD_CAST "lockinfo")) {
40127 + xmlNode *lockinfo;
40128 + const xmlChar *lockscope = NULL, *locktype = NULL, *owner = NULL;
40130 + for (lockinfo = rootnode->children; lockinfo; lockinfo = lockinfo->next) {
40131 + if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "lockscope")) {
40133 + for (value = lockinfo->children; value; value = value->next) {
40134 + if ((0 == xmlStrcmp(value->name, BAD_CAST "exclusive")) ||
40135 + (0 == xmlStrcmp(value->name, BAD_CAST "shared"))) {
40136 + lockscope = value->name;
40138 + con->http_status = 400;
40141 + return HANDLER_FINISHED;
40144 + } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "locktype")) {
40146 + for (value = lockinfo->children; value; value = value->next) {
40147 + if ((0 == xmlStrcmp(value->name, BAD_CAST "write"))) {
40148 + locktype = value->name;
40150 + con->http_status = 400;
40153 + return HANDLER_FINISHED;
40157 + } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "owner")) {
40161 + if (lockscope && locktype) {
40162 + sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
40164 + /* is this resourse already locked ? */
40166 + /* SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout
40168 + * WHERE resource = ? */
40172 + sqlite3_reset(stmt);
40174 + sqlite3_bind_text(stmt, 1,
40175 + p->uri.path->ptr,
40176 + p->uri.path->used - 1,
40177 + SQLITE_TRANSIENT);
40179 + /* it is the PK */
40180 + while (SQLITE_ROW == sqlite3_step(stmt)) {
40181 + /* we found a lock
40182 + * 1. is it compatible ?
40183 + * 2. is it ours */
40184 + char *sql_lockscope = (char *)sqlite3_column_text(stmt, 2);
40186 + if (strcmp(sql_lockscope, "exclusive")) {
40187 + con->http_status = 423;
40188 + } else if (0 == xmlStrcmp(lockscope, BAD_CAST "exclusive")) {
40189 + /* resourse is locked with a shared lock
40190 + * client wants exclusive */
40191 + con->http_status = 423;
40194 + if (con->http_status == 423) {
40196 + return HANDLER_FINISHED;
40200 + stmt = p->conf.stmt_create_lock;
40202 + /* create a lock-token */
40204 + char uuid[37] /* 36 + \0 */;
40206 + uuid_generate(id);
40207 + uuid_unparse(id, uuid);
40209 + buffer_copy_string(p->tmp_buf, "opaquelocktoken:");
40210 + buffer_append_string(p->tmp_buf, uuid);
40212 + /* "CREATE TABLE locks ("
40213 + * " locktoken TEXT NOT NULL,"
40214 + * " resource TEXT NOT NULL,"
40215 + * " lockscope TEXT NOT NULL,"
40216 + * " locktype TEXT NOT NULL,"
40217 + * " owner TEXT NOT NULL,"
40218 + * " depth INT NOT NULL,"
40221 + sqlite3_reset(stmt);
40223 + sqlite3_bind_text(stmt, 1,
40224 + CONST_BUF_LEN(p->tmp_buf),
40225 + SQLITE_TRANSIENT);
40227 + sqlite3_bind_text(stmt, 2,
40228 + CONST_BUF_LEN(con->uri.path),
40229 + SQLITE_TRANSIENT);
40231 + sqlite3_bind_text(stmt, 3,
40233 + xmlStrlen(lockscope),
40234 + SQLITE_TRANSIENT);
40236 + sqlite3_bind_text(stmt, 4,
40238 + xmlStrlen(locktype),
40239 + SQLITE_TRANSIENT);
40242 + sqlite3_bind_text(stmt, 5,
40245 + SQLITE_TRANSIENT);
40248 + sqlite3_bind_int(stmt, 6,
40252 + if (SQLITE_DONE != sqlite3_step(stmt)) {
40253 + log_error_write(srv, __FILE__, __LINE__, "ss",
40254 + "create lock:", sqlite3_errmsg(p->conf.sql));
40257 + /* looks like we survived */
40258 + webdav_lockdiscovery(srv, con, p->tmp_buf, lockscope, locktype, depth);
40260 + con->http_status = 201;
40261 + con->file_finished = 1;
40267 + return HANDLER_FINISHED;
40269 + con->http_status = 400;
40270 + return HANDLER_FINISHED;
40274 + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
40275 + buffer *locktoken = ds->value;
40276 + sqlite3_stmt *stmt = p->conf.stmt_refresh_lock;
40278 + /* remove the < > around the token */
40279 + if (locktoken->used < 6) {
40280 + con->http_status = 400;
40282 + return HANDLER_FINISHED;
40285 + buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, locktoken->used - 5);
40287 + sqlite3_reset(stmt);
40289 + sqlite3_bind_text(stmt, 1,
40290 + CONST_BUF_LEN(p->tmp_buf),
40291 + SQLITE_TRANSIENT);
40293 + if (SQLITE_DONE != sqlite3_step(stmt)) {
40294 + log_error_write(srv, __FILE__, __LINE__, "ss",
40295 + "refresh lock:", sqlite3_errmsg(p->conf.sql));
40298 + webdav_lockdiscovery(srv, con, p->tmp_buf, "exclusive", "write", 0);
40300 + con->http_status = 200;
40301 + con->file_finished = 1;
40302 + return HANDLER_FINISHED;
40304 + /* we need a lock-token to refresh */
40305 + con->http_status = 400;
40307 + return HANDLER_FINISHED;
40312 + con->http_status = 501;
40313 + return HANDLER_FINISHED;
40315 + case HTTP_METHOD_UNLOCK:
40317 + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Lock-Token"))) {
40318 + buffer *locktoken = ds->value;
40319 + sqlite3_stmt *stmt = p->conf.stmt_remove_lock;
40321 + /* remove the < > around the token */
40322 + if (locktoken->used < 4) {
40323 + con->http_status = 400;
40325 + return HANDLER_FINISHED;
40331 + * if the resourse is locked:
40332 + * - by us: unlock
40333 + * - by someone else: 401
40334 + * if the resource is not locked:
40338 + buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, locktoken->used - 3);
40340 + sqlite3_reset(stmt);
40342 + sqlite3_bind_text(stmt, 1,
40343 + CONST_BUF_LEN(p->tmp_buf),
40344 + SQLITE_TRANSIENT);
40346 + sqlite3_bind_text(stmt, 2,
40347 + CONST_BUF_LEN(con->uri.path),
40348 + SQLITE_TRANSIENT);
40350 + if (SQLITE_DONE != sqlite3_step(stmt)) {
40351 + log_error_write(srv, __FILE__, __LINE__, "ss",
40352 + "remove lock:", sqlite3_errmsg(p->conf.sql));
40355 + if (0 == sqlite3_changes(p->conf.sql)) {
40356 + con->http_status = 401;
40358 + con->http_status = 204;
40360 + return HANDLER_FINISHED;
40362 + /* we need a lock-token to unlock */
40363 + con->http_status = 400;
40365 + return HANDLER_FINISHED;
40369 + con->http_status = 501;
40370 + return HANDLER_FINISHED;
40378 return HANDLER_GO_ON;
40380 @@ -1845,14 +2462,14 @@
40381 int mod_webdav_plugin_init(plugin *p) {
40382 p->version = LIGHTTPD_VERSION_ID;
40383 p->name = buffer_init_string("webdav");
40386 p->init = mod_webdav_init;
40387 p->handle_uri_clean = mod_webdav_uri_handler;
40388 p->handle_physical = mod_webdav_subrequest_handler;
40389 p->set_defaults = mod_webdav_set_defaults;
40390 p->cleanup = mod_webdav_free;
40398 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network.c lighttpd-1.4.12/src/network.c
40399 --- lighttpd-1.4.11/src/network.c 2006-03-04 16:45:46.000000000 +0200
40400 +++ lighttpd-1.4.12/src/network.c 2006-07-11 21:23:39.000000000 +0300
40402 #include <sys/types.h>
40403 #include <sys/stat.h>
40404 -#include <sys/time.h>
40408 -#include <unistd.h>
40409 #include <string.h>
40410 #include <stdlib.h>
40411 #include <assert.h>
40413 +#include <stdio.h>
40415 #include "network.h"
40416 #include "fdevent.h"
40418 @@ -19,11 +19,12 @@
40419 #include "network_backends.h"
40420 #include "sys-mmap.h"
40421 #include "sys-socket.h"
40422 +#include "sys-files.h"
40425 -# include <openssl/ssl.h>
40426 -# include <openssl/err.h>
40427 -# include <openssl/rand.h>
40428 +# include <openssl/ssl.h>
40429 +# include <openssl/err.h>
40430 +# include <openssl/rand.h>
40433 handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
40434 @@ -31,11 +32,11 @@
40435 server_socket *srv_socket = (server_socket *)context;
40443 if (revents != FDEVENT_IN) {
40444 - log_error_write(srv, __FILE__, __LINE__, "sdd",
40445 + log_error_write(srv, __FILE__, __LINE__, "sdd",
40446 "strange event for server socket",
40449 @@ -44,12 +45,12 @@
40451 /* accept()s at most 100 connections directly
40453 - * we jump out after 100 to give the waiting connections a chance */
40454 + * we jump out after 100 to give the waiting connections a chance */
40455 for (loops = 0; loops < 100 && NULL != (con = connection_accept(srv, srv_socket)); loops++) {
40459 connection_state_machine(srv, con);
40462 switch(r = plugins_call_handle_joblist(srv, con)) {
40463 case HANDLER_FINISHED:
40464 case HANDLER_GO_ON:
40465 @@ -72,18 +73,18 @@
40467 int is_unix_domain_socket = 0;
40471 #ifdef SO_ACCEPTFILTER
40472 struct accept_filter_arg afa;
40477 WORD wVersionRequested;
40482 wVersionRequested = MAKEWORD( 2, 2 );
40485 err = WSAStartup( wVersionRequested, &wsaData );
40487 /* Tell the user that we could not find a usable */
40488 @@ -91,37 +92,37 @@
40494 srv_socket = calloc(1, sizeof(*srv_socket));
40495 srv_socket->fd = -1;
40498 srv_socket->srv_token = buffer_init();
40499 buffer_copy_string_buffer(srv_socket->srv_token, host_token);
40503 buffer_copy_string_buffer(b, host_token);
40510 if (NULL == (sp = strrchr(b->ptr, ':'))) {
40511 log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b);
40521 /* check for [ and ] */
40522 if (b->ptr[0] == '[' && *(sp-1) == ']') {
40534 port = strtol(sp, NULL, 10);
40536 if (host[0] == '/') {
40537 @@ -129,17 +130,17 @@
40538 is_unix_domain_socket = 1;
40539 } else if (port == 0 || port > 65535) {
40540 log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port);
40547 if (*host == '\0') host = NULL;
40549 if (is_unix_domain_socket) {
40550 #ifdef HAVE_SYS_UN_H
40552 srv_socket->addr.plain.sa_family = AF_UNIX;
40555 if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
40556 log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
40558 @@ -154,7 +155,7 @@
40561 srv_socket->addr.plain.sa_family = AF_INET6;
40564 if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
40565 log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
40567 @@ -162,7 +163,7 @@
40568 srv_socket->use_ipv6 = 1;
40573 if (srv_socket->fd == -1) {
40574 srv_socket->addr.plain.sa_family = AF_INET;
40575 if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
40576 @@ -170,16 +171,16 @@
40583 srv->cur_fds = srv_socket->fd;
40587 if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
40588 log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno));
40593 switch(srv_socket->addr.plain.sa_family) {
40596 @@ -190,23 +191,23 @@
40598 struct addrinfo hints, *res;
40602 memset(&hints, 0, sizeof(hints));
40605 hints.ai_family = AF_INET6;
40606 hints.ai_socktype = SOCK_STREAM;
40607 hints.ai_protocol = IPPROTO_TCP;
40610 if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) {
40611 - log_error_write(srv, __FILE__, __LINE__,
40612 - "sssss", "getaddrinfo failed: ",
40613 + log_error_write(srv, __FILE__, __LINE__,
40614 + "sssss", "getaddrinfo failed: ",
40615 gai_strerror(r), "'", host, "'");
40622 memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen);
40627 srv_socket->addr.ipv6.sin6_port = htons(port);
40628 @@ -221,33 +222,34 @@
40630 struct hostent *he;
40631 if (NULL == (he = gethostbyname(host))) {
40632 - log_error_write(srv, __FILE__, __LINE__,
40633 - "sds", "gethostbyname failed: ",
40634 + log_error_write(srv, __FILE__, __LINE__,
40635 + "sds", "gethostbyname failed: ",
40641 if (he->h_addrtype != AF_INET) {
40642 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
40647 if (he->h_length != sizeof(struct in_addr)) {
40648 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
40653 memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
40655 srv_socket->addr.ipv4.sin_port = htons(port);
40658 addr_len = sizeof(struct sockaddr_in);
40664 srv_socket->addr.un.sun_family = AF_UNIX;
40665 strcpy(srv_socket->addr.un.sun_path, host);
40669 addr_len = SUN_LEN(&srv_socket->addr.un);
40671 @@ -259,8 +261,8 @@
40672 if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
40675 - log_error_write(srv, __FILE__, __LINE__, "ss",
40676 - "server socket is still in use:",
40677 + log_error_write(srv, __FILE__, __LINE__, "ss",
40678 + "server socket is still in use:",
40682 @@ -275,88 +277,89 @@
40686 - log_error_write(srv, __FILE__, __LINE__, "sds",
40687 - "testing socket failed:",
40688 + log_error_write(srv, __FILE__, __LINE__, "sds",
40689 + "testing socket failed:",
40690 host, strerror(errno));
40705 if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
40706 switch(srv_socket->addr.plain.sa_family) {
40708 - log_error_write(srv, __FILE__, __LINE__, "sds",
40709 - "can't bind to socket:",
40710 + log_error_write(srv, __FILE__, __LINE__, "sds",
40711 + "can't bind to socket:",
40712 host, strerror(errno));
40715 - log_error_write(srv, __FILE__, __LINE__, "ssds",
40716 - "can't bind to port:",
40717 + log_error_write(srv, __FILE__, __LINE__, "ssds",
40718 + "can't bind to port:",
40719 host, port, strerror(errno));
40726 if (-1 == listen(srv_socket->fd, 128 * 8)) {
40727 log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno));
40734 if (srv->ssl_is_init == 0) {
40735 SSL_load_error_strings();
40736 SSL_library_init();
40737 srv->ssl_is_init = 1;
40740 if (0 == RAND_status()) {
40741 - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
40742 + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
40743 "not enough entropy in the pool");
40749 if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
40750 - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
40751 + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
40752 ERR_error_string(ERR_get_error(), NULL));
40757 if (buffer_is_empty(s->ssl_pemfile)) {
40758 log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
40763 if (!buffer_is_empty(s->ssl_ca_file)) {
40764 if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
40765 - log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
40766 + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
40767 ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
40773 if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
40774 - log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
40775 + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
40776 ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
40781 if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
40782 - log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
40783 + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
40784 ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
40789 if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
40790 - log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
40791 + log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
40792 "Private key does not match the certificate public key, reason:",
40793 ERR_error_string(ERR_get_error(), NULL),
40795 @@ -364,15 +367,15 @@
40797 srv_socket->ssl_ctx = s->ssl_ctx;
40801 buffer_free(srv_socket->srv_token);
40807 - log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
40809 + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
40810 "ssl requested but openssl support is not compiled in");
40816 @@ -390,10 +393,10 @@
40822 srv_socket->is_ssl = s->is_ssl;
40823 srv_socket->fde_ndx = -1;
40826 if (srv->srv_sockets.size == 0) {
40827 srv->srv_sockets.size = 4;
40828 srv->srv_sockets.used = 0;
40829 @@ -402,11 +405,10 @@
40830 srv->srv_sockets.size += 4;
40831 srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket));
40835 srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket;
40843 @@ -414,45 +416,58 @@
40845 for (i = 0; i < srv->srv_sockets.used; i++) {
40846 server_socket *srv_socket = srv->srv_sockets.ptr[i];
40849 if (srv_socket->fd != -1) {
40850 /* check if server fd are already registered */
40851 if (srv_socket->fde_ndx != -1) {
40852 fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
40853 fdevent_unregister(srv->ev, srv_socket->fd);
40857 close(srv_socket->fd);
40861 + if (srv_socket->is_ssl) {
40862 +#ifdef USE_OPENSSL
40863 + SSL_CTX_free(srv_socket->ssl_ctx);
40867 buffer_free(srv_socket->srv_token);
40874 +#ifdef USE_OPENSSL
40875 + ERR_free_strings();
40877 free(srv->srv_sockets.ptr);
40884 NETWORK_BACKEND_UNSET,
40886 NETWORK_BACKEND_WRITE,
40887 NETWORK_BACKEND_WRITEV,
40888 NETWORK_BACKEND_LINUX_SENDFILE,
40889 NETWORK_BACKEND_FREEBSD_SENDFILE,
40890 - NETWORK_BACKEND_SOLARIS_SENDFILEV
40891 + NETWORK_BACKEND_SOLARIS_SENDFILEV,
40893 + NETWORK_BACKEND_WIN32_SEND,
40894 + NETWORK_BACKEND_WIN32_TRANSMITFILE,
40895 } network_backend_t;
40897 int network_init(server *srv) {
40900 network_backend_t backend;
40903 - network_backend_t nb;
40904 - const char *name;
40905 - } network_backends[] = {
40908 + network_backend_t nb;
40909 + const char *name;
40910 + } network_backends[] = {
40911 /* lowest id wins */
40912 #if defined USE_LINUX_SENDFILE
40913 { NETWORK_BACKEND_LINUX_SENDFILE, "linux-sendfile" },
40914 @@ -466,21 +481,30 @@
40915 #if defined USE_WRITEV
40916 { NETWORK_BACKEND_WRITEV, "writev" },
40918 +#if defined USE_WRITE
40919 { NETWORK_BACKEND_WRITE, "write" },
40921 +#if defined USE_WIN32_TRANSMITFILE
40922 + { NETWORK_BACKEND_WIN32_TRANSMITFILE, "win32-transmitfile" },
40924 +#if defined USE_WIN32_SEND
40925 + { NETWORK_BACKEND_WIN32_SEND, "win32-send" },
40928 { NETWORK_BACKEND_UNSET, NULL }
40935 buffer_copy_string_buffer(b, srv->srvconf.bindhost);
40936 buffer_append_string(b, ":");
40937 buffer_append_long(b, srv->srvconf.port);
40940 if (0 != network_server_init(srv, b, srv->config_storage[0])) {
40947 srv->network_ssl_backend_write = network_write_chunkqueue_openssl;
40949 @@ -500,54 +524,80 @@
40950 if (NULL == network_backends[i].name) {
40951 /* we don't know it */
40953 - log_error_write(srv, __FILE__, __LINE__, "sb",
40954 - "server.network-backend has a unknown value:",
40955 + log_error_write(srv, __FILE__, __LINE__, "sb",
40956 + "server.network-backend has a unknown value:",
40957 srv->srvconf.network_backend);
40963 +#define SET_NETWORK_BACKEND(read, write) \
40964 + srv->network_backend_write = network_write_chunkqueue_##write;\
40965 + srv->network_backend_read = network_read_chunkqueue_##read
40967 +#define SET_NETWORK_BACKEND_SSL(read, write) \
40968 + srv->network_ssl_backend_write = network_write_chunkqueue_##write;\
40969 + srv->network_ssl_backend_read = network_read_chunkqueue_##read
40973 +#ifdef USE_WIN32_SEND
40974 + case NETWORK_BACKEND_WIN32_SEND:
40975 + SET_NETWORK_BACKEND(win32recv, win32send);
40977 +#ifdef USE_WIN32_TRANSMITFILE
40978 + case NETWORK_BACKEND_WIN32_TRANSMITFILE:
40979 + SET_NETWORK_BACKEND(win32recv, win32transmitfile);
40985 case NETWORK_BACKEND_WRITE:
40986 - srv->network_backend_write = network_write_chunkqueue_write;
40987 + SET_NETWORK_BACKEND(read, write);
40991 case NETWORK_BACKEND_WRITEV:
40992 - srv->network_backend_write = network_write_chunkqueue_writev;
40993 + SET_NETWORK_BACKEND(read, writev);
40996 #ifdef USE_LINUX_SENDFILE
40997 case NETWORK_BACKEND_LINUX_SENDFILE:
40998 - srv->network_backend_write = network_write_chunkqueue_linuxsendfile;
40999 + SET_NETWORK_BACKEND(read, linuxsendfile);
41002 #ifdef USE_FREEBSD_SENDFILE
41003 case NETWORK_BACKEND_FREEBSD_SENDFILE:
41004 - srv->network_backend_write = network_write_chunkqueue_freebsdsendfile;
41005 + SET_NETWORK_BACKEND(read, freebsdsendfile);
41008 #ifdef USE_SOLARIS_SENDFILEV
41009 case NETWORK_BACKEND_SOLARIS_SENDFILEV:
41010 - srv->network_backend_write = network_write_chunkqueue_solarissendfilev;
41011 + SET_NETWORK_BACKEND(read, solarissendfilev);
41018 +#ifdef USE_OPENSSL
41019 + SET_NETWORK_BACKEND_SSL(openssl, openssl);
41022 /* check for $SERVER["socket"] */
41023 for (i = 1; i < srv->config_context->used; i++) {
41024 data_config *dc = (data_config *)srv->config_context->data[i];
41025 specific_config *s = srv->config_storage[i];
41029 /* not our stage */
41030 if (COMP_SERVER_SOCKET != dc->comp) continue;
41033 if (dc->cond != CONFIG_COND_EQ) {
41034 log_error_write(srv, __FILE__, __LINE__, "s", "only == is allowed for $SERVER[\"socket\"].");
41040 @@ -558,36 +608,47 @@
41046 if (j == srv->srv_sockets.used) {
41047 if (0 != network_server_init(srv, dc->string, s)) return -1;
41055 int network_register_fdevents(server *srv) {
41058 if (-1 == fdevent_reset(srv->ev)) {
41062 /* register fdevents after reset */
41063 for (i = 0; i < srv->srv_sockets.used; i++) {
41064 server_socket *srv_socket = srv->srv_sockets.ptr[i];
41066 fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
41067 fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
41072 -int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
41074 +network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
41075 + server_socket *srv_socket = con->srv_socket;
41077 + if (srv_socket->is_ssl) {
41078 +#ifdef USE_OPENSSL
41079 + return srv->network_ssl_backend_read(srv, con, con->ssl, cq);
41081 + return NETWORK_STATUS_FATAL_ERROR;
41084 + return srv->network_backend_read(srv, con, con->fd, cq);
41088 +network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
41089 + network_status_t ret = NETWORK_STATUS_UNSET;
41095 server_socket *srv_socket = con->srv_socket;
41096 @@ -600,11 +661,11 @@
41097 joblist_append(srv, con);
41103 written = cq->bytes_out;
41107 /* Linux: put a cork into the socket as we want to combine the write() calls
41108 * but only if we really have multiple chunks
41110 @@ -613,7 +674,7 @@
41111 setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
41116 if (srv_socket->is_ssl) {
41118 ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq);
41119 @@ -621,12 +682,17 @@
41121 ret = srv->network_backend_write(srv, con, con->fd, cq);
41127 + case NETWORK_STATUS_WAIT_FOR_EVENT:
41128 + case NETWORK_STATUS_SUCCESS:
41129 chunkqueue_remove_finished_chunks(cq);
41130 - ret = chunkqueue_is_empty(cq) ? 0 : 1;
41141 @@ -639,13 +705,13 @@
41142 con->bytes_written_cur_second += written;
41144 *(con->conf.global_bytes_per_second_cnt_ptr) += written;
41147 if (con->conf.kbytes_per_second &&
41148 (con->bytes_written_cur_second > con->conf.kbytes_per_second * 1024)) {
41149 /* we reached the traffic limit */
41151 con->traffic_limit_reached = 1;
41152 joblist_append(srv, con);
41157 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network.h lighttpd-1.4.12/src/network.h
41158 --- lighttpd-1.4.11/src/network.h 2005-08-11 01:26:42.000000000 +0300
41159 +++ lighttpd-1.4.12/src/network.h 2006-07-11 21:23:39.000000000 +0300
41162 #include "server.h"
41164 -int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c);
41165 +network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *c);
41166 +network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *c);
41168 int network_init(server *srv);
41169 int network_close(server *srv);
41170 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_backends.h lighttpd-1.4.12/src/network_backends.h
41171 --- lighttpd-1.4.11/src/network_backends.h 2005-10-24 15:13:51.000000000 +0300
41172 +++ lighttpd-1.4.12/src/network_backends.h 2006-07-11 21:23:40.000000000 +0300
41173 @@ -43,16 +43,52 @@
41174 # define USE_AIX_SENDFILE
41178 +* unix can use read/write or recv/send on sockets
41179 +* win32 only recv/send
41182 +# define USE_WIN32_SEND
41183 +/* wait for async-io support
41184 +# define USE_WIN32_TRANSMITFILE
41187 +# define USE_WRITE
41191 +#include "network.h"
41193 +#define NETWORK_BACKEND_WRITE_CHUNK(x) \
41194 + network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq, chunk *c)
41196 +#define NETWORK_BACKEND_WRITE(x) \
41197 + network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
41198 +#define NETWORK_BACKEND_READ(x) \
41199 + network_status_t network_read_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
41201 +NETWORK_BACKEND_WRITE_CHUNK(writev_mem);
41203 +NETWORK_BACKEND_WRITE(write);
41204 +NETWORK_BACKEND_WRITE(writev);
41205 +NETWORK_BACKEND_WRITE(linuxsendfile);
41206 +NETWORK_BACKEND_WRITE(freebsdsendfile);
41207 +NETWORK_BACKEND_WRITE(solarissendfilev);
41209 +NETWORK_BACKEND_WRITE(win32transmitfile);
41210 +NETWORK_BACKEND_WRITE(win32send);
41212 +NETWORK_BACKEND_READ(read);
41213 +NETWORK_BACKEND_READ(win32recv);
41215 -int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq);
41216 -int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq);
41217 -int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq);
41218 -int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq);
41219 -int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq);
41221 -int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq);
41222 +#define NETWORK_BACKEND_WRITE_SSL(x) \
41223 + network_status_t network_write_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
41224 +#define NETWORK_BACKEND_READ_SSL(x) \
41225 + network_status_t network_read_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
41227 +NETWORK_BACKEND_WRITE_SSL(openssl);
41228 +NETWORK_BACKEND_READ_SSL(openssl);
41232 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_freebsd_sendfile.c lighttpd-1.4.12/src/network_freebsd_sendfile.c
41233 --- lighttpd-1.4.11/src/network_freebsd_sendfile.c 2005-10-22 12:28:18.000000000 +0300
41234 +++ lighttpd-1.4.12/src/network_freebsd_sendfile.c 2006-07-11 21:23:40.000000000 +0300
41235 @@ -26,142 +26,61 @@
41238 # ifdef __FreeBSD__
41239 -/* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */
41240 +/* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */
41241 # define UIO_MAXIOV 1024
41245 -int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq) {
41246 +NETWORK_BACKEND_WRITE(freebsdsendfile) {
41248 size_t chunks_written = 0;
41251 for(c = cq->first; c; c = c->next, chunks_written++) {
41252 int chunk_finished = 0;
41254 + network_status_t ret;
41257 - case MEM_CHUNK: {
41262 - size_t num_chunks, i;
41263 - struct iovec chunks[UIO_MAXIOV];
41265 - size_t num_bytes = 0;
41267 - /* we can't send more then SSIZE_MAX bytes in one chunk */
41269 - /* build writev list
41271 - * 1. limit: num_chunks < UIO_MAXIOV
41272 - * 2. limit: num_bytes < SSIZE_MAX
41274 - for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
41276 - for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
41277 - if (tc->mem->used == 0) {
41278 - chunks[i].iov_base = tc->mem->ptr;
41279 - chunks[i].iov_len = 0;
41281 - offset = tc->mem->ptr + tc->offset;
41282 - toSend = tc->mem->used - 1 - tc->offset;
41284 - chunks[i].iov_base = offset;
41286 - /* protect the return value of writev() */
41287 - if (toSend > SSIZE_MAX ||
41288 - num_bytes + toSend > SSIZE_MAX) {
41289 - chunks[i].iov_len = SSIZE_MAX - num_bytes;
41291 - num_chunks = i + 1;
41294 - chunks[i].iov_len = toSend;
41297 - num_bytes += toSend;
41301 - if ((r = writev(fd, chunks, num_chunks)) < 0) {
41311 - log_error_write(srv, __FILE__, __LINE__, "ssd",
41312 - "writev failed:", strerror(errno), fd);
41317 + ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
41322 - /* check which chunks have been written */
41323 - cq->bytes_out += r;
41325 - for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
41326 - if (r >= (ssize_t)chunks[i].iov_len) {
41328 - r -= chunks[i].iov_len;
41329 - tc->offset += chunks[i].iov_len;
41331 - if (chunk_finished) {
41332 - /* skip the chunks from further touches */
41333 - chunks_written++;
41336 - /* chunks_written + c = c->next is done in the for()*/
41337 - chunk_finished++;
41340 - /* partially written */
41343 - chunk_finished = 0;
41347 + if (ret != NETWORK_STATUS_SUCCESS) {
41352 + chunk_finished = 1;
41359 stat_cache_entry *sce = NULL;
41363 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
41364 log_error_write(srv, __FILE__, __LINE__, "sb",
41365 strerror(errno), c->file.name);
41367 + return NETWORK_STATUS_FATAL_ERROR;
41371 offset = c->file.start + c->offset;
41372 /* limit the toSend to 2^31-1 bytes in a chunk */
41373 - toSend = c->file.length - c->offset > ((1 << 30) - 1) ?
41374 + toSend = c->file.length - c->offset > ((1 << 30) - 1) ?
41375 ((1 << 30) - 1) : c->file.length - c->offset;
41378 if (offset > sce->st.st_size) {
41379 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
41383 + return NETWORK_STATUS_FATAL_ERROR;
41387 if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
41388 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
41392 + return NETWORK_STATUS_FATAL_ERROR;
41399 /* FreeBSD sendfile() */
41400 if (-1 == sendfile(ifd, fd, offset, toSend, NULL, &r, 0)) {
41402 @@ -169,39 +88,39 @@
41407 + return NETWORK_STATUS_CONNECTION_CLOSE;
41409 log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
41412 + return NETWORK_STATUS_FATAL_ERROR;
41419 cq->bytes_out += r;
41422 if (c->offset == c->file.length) {
41423 chunk_finished = 1;
41432 log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
41439 if (!chunk_finished) {
41440 /* not finished yet */
41447 - return chunks_written;
41448 + return NETWORK_STATUS_SUCCESS;
41452 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_linux_sendfile.c lighttpd-1.4.12/src/network_linux_sendfile.c
41453 --- lighttpd-1.4.11/src/network_linux_sendfile.c 2006-02-15 20:02:36.000000000 +0200
41454 +++ lighttpd-1.4.12/src/network_linux_sendfile.c 2006-07-11 21:23:40.000000000 +0300
41455 @@ -26,122 +26,54 @@
41456 /* on linux 2.4.29 + debian/ubuntu we have crashes if this is enabled */
41457 #undef HAVE_POSIX_FADVISE
41459 -int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq) {
41461 +NETWORK_BACKEND_WRITE(linuxsendfile) {
41463 size_t chunks_written = 0;
41466 for(c = cq->first; c; c = c->next, chunks_written++) {
41467 int chunk_finished = 0;
41469 + network_status_t ret;
41472 - case MEM_CHUNK: {
41477 - size_t num_chunks, i;
41478 - struct iovec chunks[UIO_MAXIOV];
41480 - size_t num_bytes = 0;
41482 - /* we can't send more then SSIZE_MAX bytes in one chunk */
41484 - /* build writev list
41486 - * 1. limit: num_chunks < UIO_MAXIOV
41487 - * 2. limit: num_bytes < SSIZE_MAX
41489 - for (num_chunks = 0, tc = c;
41490 - tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV;
41491 - tc = tc->next, num_chunks++);
41493 - for (tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
41494 - if (tc->mem->used == 0) {
41495 - chunks[i].iov_base = tc->mem->ptr;
41496 - chunks[i].iov_len = 0;
41498 - offset = tc->mem->ptr + tc->offset;
41499 - toSend = tc->mem->used - 1 - tc->offset;
41501 - chunks[i].iov_base = offset;
41503 - /* protect the return value of writev() */
41504 - if (toSend > SSIZE_MAX ||
41505 - num_bytes + toSend > SSIZE_MAX) {
41506 - chunks[i].iov_len = SSIZE_MAX - num_bytes;
41508 - num_chunks = i + 1;
41511 - chunks[i].iov_len = toSend;
41514 - num_bytes += toSend;
41518 - if ((r = writev(fd, chunks, num_chunks)) < 0) {
41528 - log_error_write(srv, __FILE__, __LINE__, "ssd",
41529 - "writev failed:", strerror(errno), fd);
41535 - /* check which chunks have been written */
41536 - cq->bytes_out += r;
41538 + ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
41540 - for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
41541 - if (r >= (ssize_t)chunks[i].iov_len) {
41543 - r -= chunks[i].iov_len;
41544 - tc->offset += chunks[i].iov_len;
41546 + /* check which chunks are finished now */
41547 + for (tc = c; tc; tc = tc->next) {
41548 + /* finished the chunk */
41549 + if (tc->offset == tc->mem->used - 1) {
41550 + /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
41551 if (chunk_finished) {
41552 - /* skip the chunks from further touches */
41553 - chunks_written++;
41556 - /* chunks_written + c = c->next is done in the for()*/
41557 - chunk_finished++;
41558 + chunk_finished = 1;
41561 - /* partially written */
41564 - chunk_finished = 0;
41571 + if (ret != NETWORK_STATUS_SUCCESS) {
41581 stat_cache_entry *sce = NULL;
41584 offset = c->file.start + c->offset;
41585 /* limit the toSend to 2^31-1 bytes in a chunk */
41586 - toSend = c->file.length - c->offset > ((1 << 30) - 1) ?
41587 + toSend = c->file.length - c->offset > ((1 << 30) - 1) ?
41588 ((1 << 30) - 1) : c->file.length - c->offset;
41590 - /* open file if not already opened */
41592 + /* open file if not already opened */
41593 if (-1 == c->file.fd) {
41594 if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
41595 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
41602 /* tell the kernel that we want to stream the file */
41603 if (-1 == posix_fadvise(c->file.fd, 0, 0, POSIX_FADV_SEQUENTIAL)) {
41604 if (ENOSYS != errno) {
41605 - log_error_write(srv, __FILE__, __LINE__, "ssd",
41606 + log_error_write(srv, __FILE__, __LINE__, "ssd",
41607 "posix_fadvise failed:", strerror(errno), c->file.fd);
41610 @@ -168,7 +100,7 @@
41614 - log_error_write(srv, __FILE__, __LINE__, "ssd",
41615 + log_error_write(srv, __FILE__, __LINE__, "ssd",
41616 "sendfile failed:", strerror(errno), fd);
41619 @@ -179,7 +111,7 @@
41621 * - the file shrinked -> error
41622 * - the remote side closed inbetween -> remote-close */
41625 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
41626 /* file is gone ? */
41628 @@ -196,22 +128,22 @@
41629 #ifdef HAVE_POSIX_FADVISE
41632 -#define M * 1024 K
41633 +#define M * 1024 K
41634 #define READ_AHEAD 4 M
41635 /* check if we need a new chunk */
41636 if ((c->offset & ~(READ_AHEAD - 1)) != ((c->offset + r) & ~(READ_AHEAD - 1))) {
41637 /* tell the kernel that we want to stream the file */
41638 if (-1 == posix_fadvise(c->file.fd, (c->offset + r) & ~(READ_AHEAD - 1), READ_AHEAD, POSIX_FADV_NOREUSE)) {
41639 - log_error_write(srv, __FILE__, __LINE__, "ssd",
41640 + log_error_write(srv, __FILE__, __LINE__, "ssd",
41641 "posix_fadvise failed:", strerror(errno), c->file.fd);
41649 cq->bytes_out += r;
41652 if (c->offset == c->file.length) {
41653 chunk_finished = 1;
41655 @@ -222,19 +154,19 @@
41666 log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
41673 if (!chunk_finished) {
41674 /* not finished yet */
41680 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_openssl.c lighttpd-1.4.12/src/network_openssl.c
41681 --- lighttpd-1.4.11/src/network_openssl.c 2005-11-17 14:53:29.000000000 +0200
41682 +++ lighttpd-1.4.12/src/network_openssl.c 2006-07-11 21:23:40.000000000 +0300
41683 @@ -23,17 +23,87 @@
41685 #include "stat_cache.h"
41687 -# include <openssl/ssl.h>
41688 -# include <openssl/err.h>
41689 +# include <openssl/ssl.h>
41690 +# include <openssl/err.h>
41692 -int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) {
41693 +NETWORK_BACKEND_READ_SSL(openssl) {
41697 + b = chunkqueue_get_append_buffer(cq);
41698 + buffer_prepare_copy(b, 8192);
41699 + len = SSL_read(ssl, b->ptr, b->size - 1);
41701 + log_error_write(srv, __FILE__, __LINE__, "so", "SSL:", len);
41706 + switch ((r = SSL_get_error(con->ssl, len))) {
41707 + case SSL_ERROR_WANT_READ:
41708 + return NETWORK_STATUS_WAIT_FOR_EVENT;
41709 + case SSL_ERROR_SYSCALL:
41711 + * man SSL_get_error()
41713 + * SSL_ERROR_SYSCALL
41714 + * Some I/O error occurred. The OpenSSL error queue may contain more
41715 + * information on the error. If the error queue is empty (i.e.
41716 + * ERR_get_error() returns 0), ret can be used to find out more about
41717 + * the error: If ret == 0, an EOF was observed that violates the
41718 + * protocol. If ret == -1, the underlying BIO reported an I/O error
41719 + * (for socket I/O on Unix systems, consult errno for details).
41722 + while((ssl_err = ERR_get_error())) {
41723 + /* get all errors from the error-queue */
41724 + log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
41725 + r, ERR_error_string(ssl_err, NULL));
41730 + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
41732 + strerror(errno));
41737 + case SSL_ERROR_ZERO_RETURN:
41738 + /* clean shutdown on the remote side */
41741 + /* FIXME: later */
41744 + /* fall thourgh */
41746 + while((ssl_err = ERR_get_error())) {
41747 + /* get all errors from the error-queue */
41748 + log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
41749 + r, ERR_error_string(ssl_err, NULL));
41757 + b->ptr[b->used - 1] = '\0';
41759 + return NETWORK_STATUS_SUCCESS;
41763 +NETWORK_BACKEND_WRITE_SSL(openssl) {
41766 size_t chunks_written = 0;
41768 /* this is a 64k sendbuffer
41770 - * it has to stay at the same location all the time to satisfy the needs
41771 + * it has to stay at the same location all the time to satisfy the needs
41772 * of SSL_write to pass the SAME parameter in case of a _WANT_WRITE
41774 * the buffer is allocated once, is NOT realloced and is NOT freed at shutdown
41775 @@ -43,14 +113,14 @@
41776 * In reality we would like to use mmap() but we don't have a guarantee that
41777 * we get the same mmap() address for each call. On openbsd the mmap() address
41779 - * That means either we keep the mmap() open or we do a read() into a
41780 - * constant buffer
41781 + * That means either we keep the mmap() open or we do a read() into a
41782 + * constant buffer
41784 #define LOCAL_SEND_BUFSIZE (64 * 1024)
41785 static char *local_send_buffer = NULL;
41787 /* the remote side closed the connection before without shutdown request
41791 * if keep-alive is disabled */
41793 @@ -60,32 +130,34 @@
41795 for(c = cq->first; c; c = c->next) {
41796 int chunk_finished = 0;
41807 if (c->mem->used == 0) {
41808 chunk_finished = 1;
41813 offset = c->mem->ptr + c->offset;
41814 toSend = c->mem->used - 1 - c->offset;
41818 * SSL_write man-page
41822 * When an SSL_write() operation has to be repeated because of
41823 * SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be
41824 * repeated with the same arguments.
41827 + * SSL_write(..., 0) return 0 which is handle as an error (Success)
41828 + * checking toSend and not calling SSL_write() is simpler
41831 - if ((r = SSL_write(ssl, offset, toSend)) <= 0) {
41833 + if (toSend != 0 && (r = SSL_write(ssl, offset, toSend)) <= 0) {
41836 switch ((ssl_r = SSL_get_error(ssl, r))) {
41838 /* perhaps we have error waiting in our error-queue */
41839 if (0 != (err = ERR_get_error())) {
41841 - log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
41842 + log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
41844 ERR_error_string(err, NULL));
41845 } while((err = ERR_get_error()));
41846 @@ -105,43 +177,43 @@
41850 - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
41851 + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
41857 /* neither error-queue nor errno ? */
41858 - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
41859 + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
41866 case SSL_ERROR_ZERO_RETURN:
41867 /* clean shutdown on the remote side */
41870 if (r == 0) return -2;
41875 while((err = ERR_get_error())) {
41876 - log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
41877 + log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
41879 ERR_error_string(err, NULL));
41887 cq->bytes_out += r;
41891 if (c->offset == (off_t)c->mem->used - 1) {
41892 chunk_finished = 1;
41899 @@ -150,7 +222,7 @@
41900 stat_cache_entry *sce = NULL;
41902 int write_wait = 0;
41905 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
41906 log_error_write(srv, __FILE__, __LINE__, "sb",
41907 strerror(errno), c->file.name);
41908 @@ -164,13 +236,13 @@
41911 off_t offset = c->file.start + c->offset;
41912 - off_t toSend = c->file.length - c->offset;
41913 + off_t toSend = c->file.length - c->offset;
41915 if (toSend > LOCAL_SEND_BUFSIZE) toSend = LOCAL_SEND_BUFSIZE;
41918 if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
41919 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed:", strerror(errno));
41925 @@ -183,9 +255,9 @@
41928 s = local_send_buffer;
41934 if ((r = SSL_write(ssl, s, toSend)) <= 0) {
41937 @@ -197,7 +269,7 @@
41938 /* perhaps we have error waiting in our error-queue */
41939 if (0 != (err = ERR_get_error())) {
41941 - log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
41942 + log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
41944 ERR_error_string(err, NULL));
41945 } while((err = ERR_get_error()));
41946 @@ -207,58 +279,58 @@
41950 - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
41951 + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
41957 /* neither error-queue nor errno ? */
41958 - log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
41959 + log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
41966 case SSL_ERROR_ZERO_RETURN:
41967 /* clean shutdown on the remote side */
41970 if (r == 0) return -2;
41975 while((err = ERR_get_error())) {
41976 - log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
41977 + log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
41979 ERR_error_string(err, NULL));
41987 cq->bytes_out += r;
41991 if (c->offset == c->file.length) {
41992 chunk_finished = 1;
41994 } while(!chunk_finished && !write_wait);
42000 log_error_write(srv, __FILE__, __LINE__, "s", "type not known");
42007 if (!chunk_finished) {
42008 /* not finished yet */
42018 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_solaris_sendfilev.c lighttpd-1.4.12/src/network_solaris_sendfilev.c
42019 --- lighttpd-1.4.11/src/network_solaris_sendfilev.c 2005-10-22 12:28:27.000000000 +0300
42020 +++ lighttpd-1.4.12/src/network_solaris_sendfilev.c 2006-07-11 21:23:40.000000000 +0300
42021 @@ -29,114 +29,34 @@
42025 - * a very simple sendfilev() interface for solaris which can be optimised a lot more
42026 + * a very simple sendfilev() interface for solaris which can be optimised a lot more
42027 * as solaris sendfilev() supports 'sending everythin in one syscall()'
42029 - * If you want such an interface and need the performance, just give me an account on
42032 + * If you want such an interface and need the performance, just give me an account on
42034 * - jan@kneschke.de
42038 -int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq) {
42039 +NETWORK_BACKEND_WRITE(solarissendfilev) {
42041 size_t chunks_written = 0;
42044 for(c = cq->first; c; c = c->next, chunks_written++) {
42045 int chunk_finished = 0;
42047 + network_status_t ret;
42050 - case MEM_CHUNK: {
42055 - size_t num_chunks, i;
42056 - struct iovec chunks[UIO_MAXIOV];
42059 - size_t num_bytes = 0;
42061 - /* we can't send more then SSIZE_MAX bytes in one chunk */
42063 - /* build writev list
42065 - * 1. limit: num_chunks < UIO_MAXIOV
42066 - * 2. limit: num_bytes < SSIZE_MAX
42068 - for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
42070 - for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
42071 - if (tc->mem->used == 0) {
42072 - chunks[i].iov_base = tc->mem->ptr;
42073 - chunks[i].iov_len = 0;
42075 - offset = tc->mem->ptr + tc->offset;
42076 - toSend = tc->mem->used - 1 - tc->offset;
42078 - chunks[i].iov_base = offset;
42080 - /* protect the return value of writev() */
42081 - if (toSend > SSIZE_MAX ||
42082 - num_bytes + toSend > SSIZE_MAX) {
42083 - chunks[i].iov_len = SSIZE_MAX - num_bytes;
42085 - num_chunks = i + 1;
42088 - chunks[i].iov_len = toSend;
42091 - num_bytes += toSend;
42095 - if ((r = writev(fd, chunks, num_chunks)) < 0) {
42105 - log_error_write(srv, __FILE__, __LINE__, "ssd",
42106 - "writev failed:", strerror(errno), fd);
42112 - /* check which chunks have been written */
42113 - cq->bytes_out += r;
42115 - for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
42116 - if (r >= (ssize_t)chunks[i].iov_len) {
42118 - r -= chunks[i].iov_len;
42119 - tc->offset += chunks[i].iov_len;
42121 - if (chunk_finished) {
42122 - /* skip the chunks from further touches */
42123 - chunks_written++;
42126 - /* chunks_written + c = c->next is done in the for()*/
42127 - chunk_finished++;
42130 - /* partially written */
42133 - chunk_finished = 0;
42138 + ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
42140 + if (ret != NETWORK_STATUS_SUCCESS) {
42145 + chunk_finished = 1;
42152 @@ -144,25 +64,25 @@
42153 sendfilevec_t fvec;
42154 stat_cache_entry *sce = NULL;
42158 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
42159 log_error_write(srv, __FILE__, __LINE__, "sb",
42160 strerror(errno), c->file.name);
42165 offset = c->file.start + c->offset;
42166 toSend = c->file.length - c->offset;
42169 if (offset > sce->st.st_size) {
42170 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
42176 if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
42177 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
42183 @@ -170,44 +90,43 @@
42185 fvec.sfv_off = offset;
42186 fvec.sfv_len = toSend;
42189 /* Solaris sendfilev() */
42190 if (-1 == (r = sendfilev(fd, &fvec, 1, &written))) {
42191 if (errno != EAGAIN) {
42192 log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
42197 + return NETWORK_STATUS_FATAL_ERROR;
42206 c->offset += written;
42207 cq->bytes_out += written;
42210 if (c->offset == c->file.length) {
42211 chunk_finished = 1;
42219 log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
42223 + return NETWORK_STATUS_FATAL_ERROR;
42227 if (!chunk_finished) {
42228 /* not finished yet */
42235 - return chunks_written;
42236 + return NETWORK_STATUS_SUCCESS;
42240 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_write.c lighttpd-1.4.12/src/network_write.c
42241 --- lighttpd-1.4.11/src/network_write.c 2005-10-22 12:27:56.000000000 +0300
42242 +++ lighttpd-1.4.12/src/network_write.c 2006-07-11 21:23:39.000000000 +0300
42244 #include <sys/types.h>
42245 #include <sys/stat.h>
42246 -#include <sys/time.h>
42250 -#include <unistd.h>
42251 #include <string.h>
42252 #include <stdlib.h>
42253 +#include <assert.h>
42255 #include "network.h"
42256 #include "fdevent.h"
42258 #include "stat_cache.h"
42260 #include "sys-socket.h"
42261 +#include "sys-files.h"
42263 #include "network_backends.h"
42267 #ifdef HAVE_SYS_FILIO_H
42268 # include <sys/filio.h>
42270 @@ -24,47 +27,86 @@
42271 #include <sys/resource.h>
42274 -int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq) {
42276 +* fill the chunkqueue will all the data that we can get
42278 +* this might be optimized into a readv() which uses the chunks
42281 +NETWORK_BACKEND_READ(read) {
42286 + /* check how much we have to read */
42287 + if (ioctl(fd, FIONREAD, &toread)) {
42288 + log_error_write(srv, __FILE__, __LINE__, "sd",
42289 + "ioctl failed: ",
42291 + return NETWORK_STATUS_FATAL_ERROR;
42294 + if (toread == 0) return NETWORK_STATUS_WAIT_FOR_EVENT;
42297 + * our chunk queue is quiet large already
42299 + * let's buffer it to disk
42302 + b = chunkqueue_get_append_buffer(cq);
42304 + buffer_prepare_copy(b, toread);
42306 + if (-1 == (r = read(fd, b->ptr, toread))) {
42307 + log_error_write(srv, __FILE__, __LINE__, "sds",
42308 + "unexpected end-of-file (perhaps the proxy process died):",
42309 + fd, strerror(errno));
42310 + return NETWORK_STATUS_FATAL_ERROR;
42313 + /* this should be catched by the b > 0 above */
42315 + b->used += r + 1;
42316 + b->ptr[b->used - 1] = '\0';
42318 + return NETWORK_STATUS_SUCCESS;
42321 +NETWORK_BACKEND_WRITE(write) {
42323 size_t chunks_written = 0;
42326 for(c = cq->first; c; c = c->next) {
42327 int chunk_finished = 0;
42337 if (c->mem->used == 0) {
42338 chunk_finished = 1;
42343 offset = c->mem->ptr + c->offset;
42344 toSend = c->mem->used - 1 - c->offset;
42346 - if ((r = send(fd, offset, toSend, 0)) < 0) {
42347 - log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
42353 if ((r = write(fd, offset, toSend)) < 0) {
42354 log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
42358 + return NETWORK_STATUS_FATAL_ERROR;
42364 cq->bytes_out += r;
42367 if (c->offset == (off_t)c->mem->used - 1) {
42368 chunk_finished = 1;
42375 @@ -76,93 +118,89 @@
42377 stat_cache_entry *sce = NULL;
42381 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
42382 log_error_write(srv, __FILE__, __LINE__, "sb",
42383 strerror(errno), c->file.name);
42385 + return NETWORK_STATUS_FATAL_ERROR;
42389 offset = c->file.start + c->offset;
42390 toSend = c->file.length - c->offset;
42393 if (offset > sce->st.st_size) {
42394 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
42398 + return NETWORK_STATUS_FATAL_ERROR;
42401 if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
42402 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
42406 + return NETWORK_STATUS_FATAL_ERROR;
42410 #if defined USE_MMAP
42411 if (MAP_FAILED == (p = mmap(0, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
42412 log_error_write(srv, __FILE__, __LINE__, "ss", "mmap failed: ", strerror(errno));
42418 + return NETWORK_STATUS_FATAL_ERROR;
42422 if ((r = write(fd, p + offset, toSend)) <= 0) {
42423 log_error_write(srv, __FILE__, __LINE__, "ss", "write failed: ", strerror(errno));
42424 munmap(p, sce->st.st_size);
42426 + return NETWORK_STATUS_FATAL_ERROR;
42430 munmap(p, sce->st.st_size);
42432 buffer_prepare_copy(srv->tmp_buf, toSend);
42435 lseek(ifd, offset, SEEK_SET);
42436 if (-1 == (toSend = read(ifd, srv->tmp_buf->ptr, toSend))) {
42437 log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno));
42442 + return NETWORK_STATUS_FATAL_ERROR;
42446 if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) {
42447 log_error_write(srv, __FILE__, __LINE__, "ss", "write: ", strerror(errno));
42451 + return NETWORK_STATUS_FATAL_ERROR;
42455 cq->bytes_out += r;
42458 if (c->offset == c->file.length) {
42459 chunk_finished = 1;
42468 log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
42472 + return NETWORK_STATUS_FATAL_ERROR;
42476 if (!chunk_finished) {
42477 /* not finished yet */
42487 - return chunks_written;
42488 + return NETWORK_STATUS_SUCCESS;
42492 -network_write_init(void) {
42493 - p->write = network_write_write_chunkset;
42496 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/network_writev.c lighttpd-1.4.12/src/network_writev.c
42497 --- lighttpd-1.4.11/src/network_writev.c 2006-02-15 01:02:36.000000000 +0200
42498 +++ lighttpd-1.4.12/src/network_writev.c 2006-07-11 21:23:40.000000000 +0300
42499 @@ -28,10 +28,10 @@
42502 # if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__)
42503 -/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */
42504 +/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */
42505 # define UIO_MAXIOV 1024
42506 # elif defined(__sgi)
42507 -/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */
42508 +/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */
42509 # define UIO_MAXIOV 512
42510 # elif defined(__sun)
42511 /* Solaris (and SunOS?) defines IOV_MAX instead */
42512 @@ -51,105 +51,119 @@
42513 #define LOCAL_BUFFERING 1
42516 -int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq) {
42518 +NETWORK_BACKEND_WRITE_CHUNK(writev_mem) {
42523 + size_t num_chunks, i;
42524 + struct iovec chunks[UIO_MAXIOV];
42525 + chunk *tc; /* transfer chunks */
42526 + size_t num_bytes = 0;
42528 + /* we can't send more then SSIZE_MAX bytes in one chunk */
42530 + /* build writev list
42532 + * 1. limit: num_chunks < UIO_MAXIOV
42533 + * 2. limit: num_bytes < SSIZE_MAX
42535 + for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
42537 + for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
42538 + if (tc->mem->used == 0) {
42539 + chunks[i].iov_base = tc->mem->ptr;
42540 + chunks[i].iov_len = 0;
42542 + offset = tc->mem->ptr + tc->offset;
42543 + toSend = tc->mem->used - 1 - tc->offset;
42545 + chunks[i].iov_base = offset;
42547 + /* protect the return value of writev() */
42548 + if (toSend > SSIZE_MAX ||
42549 + num_bytes + toSend > SSIZE_MAX) {
42550 + chunks[i].iov_len = SSIZE_MAX - num_bytes;
42552 + num_chunks = i + 1;
42555 + chunks[i].iov_len = toSend;
42558 + num_bytes += toSend;
42562 + if ((r = writev(fd, chunks, num_chunks)) < 0) {
42570 + return NETWORK_STATUS_CONNECTION_CLOSE;
42572 + log_error_write(srv, __FILE__, __LINE__, "ssd",
42573 + "writev failed:", strerror(errno), fd);
42575 + return NETWORK_STATUS_FATAL_ERROR;
42579 + cq->bytes_out += r;
42581 + /* check which chunks have been written */
42583 + for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
42584 + if (r >= (ssize_t)chunks[i].iov_len) {
42586 + r -= chunks[i].iov_len;
42587 + tc->offset += chunks[i].iov_len;
42589 + /* partially written */
42596 + return NETWORK_STATUS_SUCCESS;
42599 +NETWORK_BACKEND_WRITE(writev) {
42601 size_t chunks_written = 0;
42604 for(c = cq->first; c; c = c->next) {
42605 int chunk_finished = 0;
42607 + network_status_t ret;
42610 - case MEM_CHUNK: {
42615 - size_t num_chunks, i;
42616 - struct iovec chunks[UIO_MAXIOV];
42618 - size_t num_bytes = 0;
42620 - /* we can't send more then SSIZE_MAX bytes in one chunk */
42622 - /* build writev list
42624 - * 1. limit: num_chunks < UIO_MAXIOV
42625 - * 2. limit: num_bytes < SSIZE_MAX
42627 - for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
42629 - for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
42630 - if (tc->mem->used == 0) {
42631 - chunks[i].iov_base = tc->mem->ptr;
42632 - chunks[i].iov_len = 0;
42634 - offset = tc->mem->ptr + tc->offset;
42635 - toSend = tc->mem->used - 1 - tc->offset;
42637 - chunks[i].iov_base = offset;
42639 - /* protect the return value of writev() */
42640 - if (toSend > SSIZE_MAX ||
42641 - num_bytes + toSend > SSIZE_MAX) {
42642 - chunks[i].iov_len = SSIZE_MAX - num_bytes;
42644 - num_chunks = i + 1;
42647 - chunks[i].iov_len = toSend;
42650 - num_bytes += toSend;
42654 - if ((r = writev(fd, chunks, num_chunks)) < 0) {
42664 - log_error_write(srv, __FILE__, __LINE__, "ssd",
42665 - "writev failed:", strerror(errno), fd);
42671 - cq->bytes_out += r;
42673 + ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
42675 - /* check which chunks have been written */
42677 - for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
42678 - if (r >= (ssize_t)chunks[i].iov_len) {
42680 - r -= chunks[i].iov_len;
42681 - tc->offset += chunks[i].iov_len;
42683 + /* check which chunks are finished now */
42684 + for (tc = c; tc; tc = tc->next) {
42685 + /* finished the chunk */
42686 + if (tc->offset == tc->mem->used - 1) {
42687 + /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
42688 if (chunk_finished) {
42689 - /* skip the chunks from further touches */
42690 - chunks_written++;
42693 - /* chunks_written + c = c->next is done in the for()*/
42694 - chunk_finished++;
42695 + chunk_finished = 1;
42698 - /* partially written */
42701 - chunk_finished = 0;
42708 + if (ret != NETWORK_STATUS_SUCCESS) {
42717 @@ -159,26 +173,26 @@
42718 #define KByte * 1024
42719 #define MByte * 1024 KByte
42720 #define GByte * 1024 MByte
42721 - const off_t we_want_to_mmap = 512 KByte;
42722 + const off_t we_want_to_mmap = 512 KByte;
42723 char *start = NULL;
42725 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
42726 log_error_write(srv, __FILE__, __LINE__, "sb",
42727 strerror(errno), c->file.name);
42729 + return NETWORK_STATUS_FATAL_ERROR;
42732 abs_offset = c->file.start + c->offset;
42735 if (abs_offset > sce->st.st_size) {
42736 - log_error_write(srv, __FILE__, __LINE__, "sb",
42737 + log_error_write(srv, __FILE__, __LINE__, "sb",
42738 "file was shrinked:", c->file.name);
42742 + return NETWORK_STATUS_FATAL_ERROR;
42745 - /* mmap the buffer
42747 + /* mmap the buffer
42749 * - new mmap as the we are at the end of the last one */
42750 if (c->file.mmap.start == MAP_FAILED ||
42751 abs_offset == (off_t)(c->file.mmap.offset + c->file.mmap.length)) {
42752 @@ -188,7 +202,7 @@
42753 * adaptive mem-mapping
42755 * we mmap() the whole file. If someone has alot large files and 32bit
42756 - * machine the virtual address area will be unrun and we will have a failing
42757 + * machine the virtual address area will be unrun and we will have a failing
42760 * only mmap 16M in one chunk and move the window as soon as we have finished
42761 @@ -234,8 +248,8 @@
42762 if (-1 == c->file.fd) { /* open the file if not already open */
42763 if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
42764 log_error_write(srv, __FILE__, __LINE__, "sbs", "open failed for:", c->file.name, strerror(errno));
42768 + return NETWORK_STATUS_FATAL_ERROR;
42771 fcntl(c->file.fd, F_SETFD, FD_CLOEXEC);
42772 @@ -245,10 +259,10 @@
42773 if (MAP_FAILED == (c->file.mmap.start = mmap(0, to_mmap, PROT_READ, MAP_SHARED, c->file.fd, c->file.mmap.offset))) {
42774 /* close it here, otherwise we'd have to set FD_CLOEXEC */
42776 - log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:",
42777 + log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:",
42778 strerror(errno), c->file.name, c->file.fd);
42781 + return NETWORK_STATUS_FATAL_ERROR;
42784 c->file.mmap.length = to_mmap;
42785 @@ -258,7 +272,7 @@
42786 #ifdef HAVE_MADVISE
42787 /* don't advise files < 64Kb */
42788 if (c->file.mmap.length > (64 KByte)) {
42789 - /* darwin 7 is returning EINVAL all the time and I don't know how to
42790 + /* darwin 7 is returning EINVAL all the time and I don't know how to
42791 * detect this at runtime.i
42793 * ignore the return value for now */
42794 @@ -274,12 +288,12 @@
42795 toSend = (c->file.mmap.offset + c->file.mmap.length) - (abs_offset);
42798 - log_error_write(srv, __FILE__, __LINE__, "soooo",
42799 + log_error_write(srv, __FILE__, __LINE__, "soooo",
42800 "toSend is negative:",
42802 c->file.mmap.length,
42804 - c->file.mmap.offset);
42805 + c->file.mmap.offset);
42806 assert(toSend < 0);
42809 @@ -297,18 +311,18 @@
42814 + return NETWORK_STATUS_CONNECTION_CLOSE;
42816 - log_error_write(srv, __FILE__, __LINE__, "ssd",
42817 + log_error_write(srv, __FILE__, __LINE__, "ssd",
42818 "write failed:", strerror(errno), fd);
42822 + return NETWORK_STATUS_FATAL_ERROR;
42828 cq->bytes_out += r;
42831 if (c->offset == c->file.length) {
42832 chunk_finished = 1;
42834 @@ -318,26 +332,26 @@
42835 c->file.mmap.start = MAP_FAILED;
42845 log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
42849 + return NETWORK_STATUS_FATAL_ERROR;
42853 if (!chunk_finished) {
42854 /* not finished yet */
42864 - return chunks_written;
42865 + return NETWORK_STATUS_SUCCESS;
42869 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/plugin.c lighttpd-1.4.12/src/plugin.c
42870 --- lighttpd-1.4.11/src/plugin.c 2006-02-08 14:00:54.000000000 +0200
42871 +++ lighttpd-1.4.12/src/plugin.c 2006-07-11 21:23:40.000000000 +0300
42872 @@ -13,27 +13,27 @@
42873 #include <valgrind/valgrind.h>
42883 * if you change this enum to add a new callback, be sure
42884 * - that PLUGIN_FUNC_SIZEOF is the last entry
42885 * - that you add PLUGIN_TO_SLOT twice:
42886 - * 1. as callback-dispatcher
42887 + * 1. as callback-dispatcher
42888 * 2. in plugins_call_init()
42900 - PLUGIN_FUNC_HANDLE_URI_CLEAN,
42901 - PLUGIN_FUNC_HANDLE_URI_RAW,
42902 + PLUGIN_FUNC_HANDLE_URI_CLEAN,
42903 + PLUGIN_FUNC_HANDLE_URI_RAW,
42904 PLUGIN_FUNC_HANDLE_REQUEST_DONE,
42905 PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE,
42906 PLUGIN_FUNC_HANDLE_TRIGGER,
42907 @@ -44,38 +44,42 @@
42908 PLUGIN_FUNC_HANDLE_DOCROOT,
42909 PLUGIN_FUNC_HANDLE_PHYSICAL,
42910 PLUGIN_FUNC_CONNECTION_RESET,
42911 - PLUGIN_FUNC_INIT,
42912 + PLUGIN_FUNC_INIT,
42913 PLUGIN_FUNC_CLEANUP,
42914 PLUGIN_FUNC_SET_DEFAULTS,
42920 static plugin *plugin_init(void) {
42924 p = calloc(1, sizeof(*p));
42927 + p->required_plugins = array_init();
42932 static void plugin_free(plugin *p) {
42933 int use_dlclose = 1;
42934 if (p->name) buffer_free(p->name);
42936 + array_free(p->required_plugins);
42937 #ifdef HAVE_VALGRIND_VALGRIND_H
42938 /*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/
42941 #ifndef LIGHTTPD_STATIC
42942 - if (use_dlclose && p->lib) {
42944 + if (use_dlclose && p->lib) {
42946 FreeLibrary(p->lib);
42957 @@ -89,17 +93,17 @@
42958 srv->plugins.size += 4;
42959 srv->plugins.ptr = realloc(srv->plugins.ptr, srv->plugins.size * sizeof(*ps));
42963 ps = srv->plugins.ptr;
42964 ps[srv->plugins.used++] = p;
42979 #ifdef LIGHTTPD_STATIC
42980 @@ -121,30 +125,35 @@
42982 int plugins_load(server *srv) {
42987 int (*init)(plugin *pl);
42995 for (i = 0; i < srv->srvconf.modules->used; i++) {
42996 data_string *d = (data_string *)srv->srvconf.modules->data[i];
42997 char *modules = d->value->ptr;
43000 buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir);
43002 buffer_append_string(srv->tmp_buf, "/");
43003 buffer_append_string(srv->tmp_buf, modules);
43004 -#if defined(__WIN32) || defined(__CYGWIN__)
43005 +#if defined(_WIN32) || defined(__CYGWIN__)
43006 buffer_append_string(srv->tmp_buf, ".dll");
43008 buffer_append_string(srv->tmp_buf, ".so");
43015 if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) {
43018 - FORMAT_MESSAGE_ALLOCATE_BUFFER |
43019 + FORMAT_MESSAGE_ALLOCATE_BUFFER |
43020 FORMAT_MESSAGE_FROM_SYSTEM,
43023 @@ -152,36 +161,36 @@
43024 (LPTSTR) &lpMsgBuf,
43027 - log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed",
43028 + log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed",
43029 lpMsgBuf, srv->tmp_buf);
43040 if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_LAZY))) {
43041 - log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:",
43042 + log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:",
43043 srv->tmp_buf, dlerror());
43054 buffer_reset(srv->tmp_buf);
43055 buffer_copy_string(srv->tmp_buf, modules);
43056 buffer_append_string(srv->tmp_buf, "_plugin_init");
43060 init = GetProcAddress(p->lib, srv->tmp_buf->ptr);
43062 if (init == NULL) {
43065 - FORMAT_MESSAGE_ALLOCATE_BUFFER |
43066 + FORMAT_MESSAGE_ALLOCATE_BUFFER |
43067 FORMAT_MESSAGE_FROM_SYSTEM,
43070 @@ -190,7 +199,7 @@
43073 log_error_write(srv, __FILE__, __LINE__, "sbs", "getprocaddress failed:", srv->tmp_buf, lpMsgBuf);
43079 @@ -203,24 +212,43 @@
43081 if ((error = dlerror()) != NULL) {
43082 log_error_write(srv, __FILE__, __LINE__, "s", error);
43092 log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin init failed" );
43099 log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin loaded" );
43101 + /* check if the required plugin is loaded */
43102 + for (k = 0; k < p->required_plugins->used; k++) {
43103 + data_string *req = (data_string *)p->required_plugins->data[k];
43105 + for (j = 0; j < i; j++) {
43106 + data_string *mod = (data_string *)srv->srvconf.modules->data[j];
43108 + if (buffer_is_equal(req->value, mod->value)) break;
43113 + log_error_write(srv, __FILE__, __LINE__, "ssbs", modules, "failed to load. required plugin", req->value, "was not loaded" );
43120 plugins_register(srv, p);
43127 @@ -253,8 +281,8 @@
43131 - * plugins that use
43133 + * plugins that use
43136 * - connection *con
43137 * - void *p_d (plugin_data *)
43138 @@ -301,12 +329,12 @@
43142 - * plugins that use
43144 + * plugins that use
43147 * - void *p_d (plugin_data *)
43151 PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger)
43152 PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup)
43153 PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup)
43154 @@ -314,18 +342,18 @@
43156 #undef PLUGIN_TO_SLOT
43167 handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) {
43172 ps = srv->plugins.ptr;
43175 for (i = 0; i < srv->plugins.used; i++) {
43177 if (p->handle_fdevent) {
43178 @@ -344,34 +372,34 @@
43184 return HANDLER_GO_ON;
43190 * - call init function of all plugins to init the plugin-internals
43191 * - added each plugin that supports has callback to the corresponding slot
43194 * - is only called once.
43197 handler_t plugins_call_init(server *srv) {
43202 ps = srv->plugins.ptr;
43208 srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps));
43211 for (i = 0; i < srv->plugins.used; i++) {
43213 /* check which calls are supported */
43219 #define PLUGIN_TO_SLOT(x, y) \
43221 plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \
43222 @@ -384,11 +412,11 @@
43229 - PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean);
43230 - PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw);
43234 + PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean);
43235 + PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw);
43236 PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done);
43237 PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close);
43238 PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger);
43239 @@ -402,19 +430,19 @@
43240 PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup);
43241 PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults);
43242 #undef PLUGIN_TO_SLOT
43246 if (NULL == (p->data = p->init())) {
43247 - log_error_write(srv, __FILE__, __LINE__, "sb",
43248 + log_error_write(srv, __FILE__, __LINE__, "sb",
43249 "plugin-init failed for module", p->name);
43250 return HANDLER_ERROR;
43254 /* used for con->mode, DIRECT == 0, plugins above that */
43255 ((plugin_data *)(p->data))->id = i + 1;
43258 if (p->version != LIGHTTPD_VERSION_ID) {
43259 - log_error_write(srv, __FILE__, __LINE__, "sb",
43260 + log_error_write(srv, __FILE__, __LINE__, "sb",
43261 "plugin-version doesn't match lighttpd-version for", p->name);
43262 return HANDLER_ERROR;
43264 @@ -422,29 +450,46 @@
43270 return HANDLER_GO_ON;
43274 + * get the config-storage of the named plugin
43276 +void *plugin_get_config(server *srv, const char *name) {
43279 + for (i = 0; i < srv->plugins.used; i++) {
43280 + plugin *p = ((plugin **)srv->plugins.ptr)[i];
43282 + if (buffer_is_equal_string(p->name, name, strlen(name))) {
43290 void plugins_free(server *srv) {
43292 plugins_call_cleanup(srv);
43295 for (i = 0; i < srv->plugins.used; i++) {
43296 plugin *p = ((plugin **)srv->plugins.ptr)[i];
43303 for (i = 0; srv->plugin_slots && i < PLUGIN_FUNC_SIZEOF; i++) {
43304 plugin **slot = ((plugin ***)(srv->plugin_slots))[i];
43307 if (slot) free(slot);
43311 free(srv->plugin_slots);
43312 srv->plugin_slots = NULL;
43315 free(srv->plugins.ptr);
43316 srv->plugins.ptr = NULL;
43317 srv->plugins.used = 0;
43318 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/plugin.h lighttpd-1.4.12/src/plugin.h
43319 --- lighttpd-1.4.11/src/plugin.h 2005-08-15 12:28:56.000000000 +0300
43320 +++ lighttpd-1.4.12/src/plugin.h 2006-07-11 21:23:40.000000000 +0300
43323 #define INIT_FUNC(x) \
43326 + * The PATCH_OPTION() macro is used in the patch_connection() functions
43327 + * of the modules to update the config object for the current request.
43329 +#define PATCH_OPTION(x) \
43332 #define FREE_FUNC SERVER_FUNC
43333 #define TRIGGER_FUNC SERVER_FUNC
43334 @@ -25,19 +31,19 @@
43335 #define URIHANDLER_FUNC CONNECTION_FUNC
43337 #define PLUGIN_DATA size_t id
43344 buffer *name; /* name of the plugin */
43348 handler_t (* set_defaults) (server *srv, void *p_d);
43349 handler_t (* cleanup) (server *srv, void *p_d);
43350 /* is called ... */
43351 handler_t (* handle_trigger) (server *srv, void *p_d); /* once a second */
43352 handler_t (* handle_sighup) (server *srv, void *p_d); /* at a signup */
43355 handler_t (* handle_uri_raw) (server *srv, connection *con, void *p_d); /* after uri_raw is set */
43356 handler_t (* handle_uri_clean) (server *srv, connection *con, void *p_d); /* after uri is set */
43357 handler_t (* handle_docroot) (server *srv, connection *con, void *p_d); /* getting the document-root */
43358 @@ -45,20 +51,22 @@
43359 handler_t (* handle_request_done) (server *srv, connection *con, void *p_d); /* at the end of a request */
43360 handler_t (* handle_connection_close)(server *srv, connection *con, void *p_d); /* at the end of a connection */
43361 handler_t (* handle_joblist) (server *srv, connection *con, void *p_d); /* after all events are handled */
43365 - handler_t (* handle_subrequest_start)(server *srv, connection *con, void *p_d);
43367 - /* when a handler for the request
43371 + handler_t (* handle_subrequest_start)(server *srv, connection *con, void *p_d);
43373 + /* when a handler for the request
43376 handler_t (* handle_subrequest) (server *srv, connection *con, void *p_d); /* */
43377 handler_t (* connection_reset) (server *srv, connection *con, void *p_d); /* */
43381 /* dlopen handle */
43384 + array *required_plugins;
43387 int plugins_load(server *srv);
43389 int config_patch_connection(server *srv, connection *con, comp_key_t comp);
43390 int config_check_cond(server *srv, connection *con, data_config *dc);
43391 int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n);
43392 +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result);
43394 +void *plugin_get_config(server *srv, const char *name);
43397 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/proc_open.c lighttpd-1.4.12/src/proc_open.c
43398 --- lighttpd-1.4.11/src/proc_open.c 2005-08-11 01:26:39.000000000 +0300
43399 +++ lighttpd-1.4.12/src/proc_open.c 2006-07-11 21:23:40.000000000 +0300
43400 @@ -13,13 +13,13 @@
43406 /* {{{ win32 stuff */
43407 # define SHELLENV "ComSpec"
43408 # define SECURITY_DC , SECURITY_ATTRIBUTES *security
43409 # define SECURITY_CC , security
43410 # define pipe(pair) (CreatePipe(&pair[0], &pair[1], security, 2048L) ? 0 : -1)
43411 -static inline HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig)
43412 +static HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig)
43414 HANDLE copy, self = GetCurrentProcess();
43416 @@ -148,11 +148,14 @@
43419 SECURITY_ATTRIBUTES security;
43420 - const char *shell;
43421 + const char *shell = NULL;
43422 + const char *windir = NULL;
43425 - if (NULL == (shell = getenv(SHELLENV))) {
43426 - fprintf(stderr, "env %s is required", SHELLENV);
43427 + if (NULL == (shell = getenv(SHELLENV)) &&
43428 + NULL == (windir = getenv("SystemRoot")) &&
43429 + NULL == (windir = getenv("windir"))) {
43430 + fprintf(stderr, "One of %s,%%SystemRoot,%%windir is required", SHELLENV);
43434 @@ -177,17 +180,23 @@
43435 memset(&pi, 0, sizeof(pi));
43437 cmdline = buffer_init();
43438 - buffer_append_string(cmdline, shell);
43440 + buffer_append_string(cmdline, shell);
43442 + buffer_append_string(cmdline, windir);
43443 + buffer_append_string(cmdline, "\\system32\\cmd.exe");
43445 buffer_append_string_len(cmdline, CONST_STR_LEN(" /c "));
43446 buffer_append_string(cmdline, command);
43447 procok = CreateProcess(NULL, cmdline->ptr, &security, &security, TRUE,
43448 NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
43449 - buffer_free(cmdline);
43451 if (FALSE == procok) {
43452 - fprintf(stderr, "failed to CreateProcess");
43453 + fprintf(stderr, "failed to CreateProcess: %s", cmdline->ptr);
43454 + buffer_free(cmdline);
43457 + buffer_free(cmdline);
43459 proc->child = pi.hProcess;
43460 CloseHandle(pi.hThread);
43461 @@ -226,8 +235,7 @@
43464 if (NULL == (shell = getenv(SHELLENV))) {
43465 - fprintf(stderr, "env %s is required", SHELLENV);
43467 + shell = "/bin/sh";
43470 if (proc_open_pipes(proc) != 0) {
43471 @@ -262,11 +270,11 @@
43475 -#endif /* WIN32 */
43476 +#endif /* _WIN32 */
43478 /* {{{ proc_read_fd_to_buffer */
43479 static void proc_read_fd_to_buffer(int fd, buffer *b) {
43481 + int s; /* win32 has not ssize_t */
43484 buffer_prepare_append(b, 512);
43485 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/proc_open.h lighttpd-1.4.12/src/proc_open.h
43486 --- lighttpd-1.4.11/src/proc_open.h 2005-08-11 01:26:39.000000000 +0300
43487 +++ lighttpd-1.4.12/src/proc_open.h 2006-07-11 21:23:40.000000000 +0300
43490 #include "buffer.h"
43494 #include <windows.h>
43495 typedef HANDLE descriptor_t;
43496 typedef HANDLE proc_pid_t;
43497 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/request.c lighttpd-1.4.12/src/request.c
43498 --- lighttpd-1.4.11/src/request.c 2006-03-05 11:58:09.000000000 +0200
43499 +++ lighttpd-1.4.12/src/request.c 2006-07-11 21:23:40.000000000 +0300
43500 @@ -10,15 +10,17 @@
43501 #include "keyvalue.h"
43504 +#include "sys-strings.h"
43506 static int request_check_hostname(server *srv, connection *con, buffer *host) {
43507 enum { DOMAINLABEL, TOPLABEL } stage = TOPLABEL;
43512 - int is_ip = -1; /* -1 don't know yet, 0 no, 1 yes */
43513 + int is_ip = -1; /* -1 don't know yet, 0 no, 1 yes */
43520 @@ -32,17 +34,17 @@
43521 * IPv6address = "[" ... "]"
43527 if (!host || host->used == 0) return 0;
43530 host_len = host->used - 1;
43534 if (host->ptr[0] == '[') {
43535 char *c = host->ptr + 1;
43539 /* check portnumber */
43540 for (; *c && *c != ']'; c++) {
43542 @@ -53,12 +55,12 @@
43555 if (*(c+1) == ':') {
43556 for (c += 2; *c; c++) {
43557 @@ -69,39 +71,39 @@
43563 if (NULL != (colon = memchr(host->ptr, ':', host_len))) {
43564 char *c = colon + 1;
43567 /* check portnumber */
43569 if (!light_isdigit(*c)) return -1;
43573 /* remove the port from the host-len */
43574 host_len = colon - host->ptr;
43578 /* Host is empty */
43579 if (host_len == 0) return -1;
43582 /* scan from the right and skip the \0 */
43583 for (i = host_len - 1; i + 1 > 0; i--) {
43584 const char c = host->ptr[i];
43590 /* only switch stage, if this is not the last character */
43591 if (i != host_len - 1) {
43592 if (label_len == 0) {
43597 /* check the first character at right of the dot */
43599 if (!light_isalpha(host->ptr[i+1])) {
43603 } else if (!light_isdigit(host->ptr[i+1])) {
43605 @@ -111,9 +113,9 @@
43611 stage = DOMAINLABEL;
43616 } else if (i == 0) {
43617 @@ -135,7 +137,7 @@
43626 @@ -143,7 +145,7 @@
43627 if (label_len == 0) {
43634 } else if (!light_isdigit(c)) {
43635 @@ -156,12 +158,12 @@
43636 if (label_len == 0) {
43641 /* c is either - or alphanum here */
43642 if ('-' == host->ptr[i+1]) {
43649 } else if (i == 0) {
43650 @@ -176,20 +178,20 @@
43661 /* a IP has to consist of 4 parts */
43662 if (is_ip == 1 && level != 3) {
43667 if (label_len == 0) {
43675 @@ -201,53 +203,53 @@
43685 * val1, val2, val3, val4
43688 * into a array (more or less a explode() incl. striping of whitespaces
43692 if (b->used == 0) return 0;
43698 for (i =0; i < b->used - 1; ) {
43699 char *start = NULL, *end = NULL;
43708 for (; (*s == ' ' || *s == '\t') && i < b->used - 1; i++, s++);
43715 case 1: /* value */
43719 for (; *s != ',' && i < b->used - 1; i++, s++);
43723 for (; (*end == ' ' || *end == '\t') && end > start; end--);
43726 if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) {
43727 ds = data_string_init();
43730 buffer_copy_string_len(ds->value, start, end-start+1);
43731 array_insert_unique(vals, (data_unset *)ds);
43739 /* end of string */
43745 @@ -263,7 +265,7 @@
43746 if (c <= 32) return 0;
43747 if (c == 127) return 0;
43748 if (c == 255) return 0;
43754 @@ -271,28 +273,28 @@
43755 char *uri = NULL, *proto = NULL, *method = NULL, con_length_set;
43756 int is_key = 1, key_len = 0, is_ws_after_key = 0, in_folding;
43757 char *value = NULL, *key = NULL;
43760 enum { HTTP_CONNECTION_UNSET, HTTP_CONNECTION_KEEPALIVE, HTTP_CONNECTION_CLOSE } keep_alive_set = HTTP_CONNECTION_UNSET;
43766 int request_line_stage = 0;
43773 data_string *ds = NULL;
43776 - * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$"
43777 - * Option : "^([-a-zA-Z]+): (.+)$"
43780 + * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$"
43781 + * Option : "^([-a-zA-Z]+): (.+)$"
43785 if (con->conf.log_request_header) {
43786 - log_error_write(srv, __FILE__, __LINE__, "sdsdSb",
43788 - "request-len:", con->request.request->used,
43789 + log_error_write(srv, __FILE__, __LINE__, "sdsdSb",
43791 + "request-len:", con->request.request->used,
43792 "\n", con->request.request);
43795 @@ -300,13 +302,13 @@
43796 con->request.request->ptr[0] == '\r' &&
43797 con->request.request->ptr[1] == '\n') {
43798 /* we are in keep-alive and might get \r\n after a previous POST request.*/
43801 buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, con->request.request->used - 1 - 2);
43803 /* fill the local request buffer */
43804 buffer_copy_string_buffer(con->parse_request, con->request.request);
43808 keep_alive_set = 0;
43809 con_length_set = 0;
43811 @@ -318,25 +320,25 @@
43813 for (i = 0, first = 0; i < con->parse_request->used && line == 0; i++) {
43814 char *cur = con->parse_request->ptr + i;
43820 if (con->parse_request->ptr[i+1] == '\n') {
43827 con->parse_request->ptr[i] = '\0';
43828 con->parse_request->ptr[i+1] = '\0';
43831 buffer_copy_string_len(con->request.request_line, con->parse_request->ptr, i);
43834 if (request_line_stage != 2) {
43835 con->http_status = 400;
43836 con->response.keep_alive = 0;
43837 con->keep_alive = 0;
43840 if (srv->srvconf.log_request_header_on_error) {
43841 log_error_write(srv, __FILE__, __LINE__, "s", "incomplete request line -> 400");
43842 log_error_write(srv, __FILE__, __LINE__, "Sb",
43843 @@ -345,36 +347,36 @@
43849 proto = con->parse_request->ptr + first;
43853 *(proto - 1) = '\0';
43856 /* we got the first one :) */
43857 if (-1 == (r = get_http_method_key(method))) {
43858 con->http_status = 501;
43859 con->response.keep_alive = 0;
43860 con->keep_alive = 0;
43863 if (srv->srvconf.log_request_header_on_error) {
43864 log_error_write(srv, __FILE__, __LINE__, "s", "unknown http-method -> 501");
43865 log_error_write(srv, __FILE__, __LINE__, "Sb",
43866 "request-header:\n",
43867 con->request.request);
43875 con->request.http_method = r;
43882 * HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
43886 if (0 == strncmp(proto, "HTTP/", sizeof("HTTP/") - 1)) {
43887 char * major = proto + sizeof("HTTP/") - 1;
43888 char * minor = strchr(major, '.');
43889 @@ -413,10 +415,10 @@
43892 if (major_num == 1 && minor_num == 1) {
43893 - con->request.http_version = con->conf.allow_http11 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0;
43894 + con->request.http_version = HTTP_VERSION_1_1;
43895 } else if (major_num == 1 && minor_num == 0) {
43896 con->request.http_version = HTTP_VERSION_1_0;
43899 con->http_status = 505;
43901 if (srv->srvconf.log_request_header_on_error) {
43902 @@ -439,30 +441,30 @@
43908 if (0 == strncmp(uri, "http://", 7) &&
43909 NULL != (nuri = strchr(uri + 7, '/'))) {
43910 /* ignore the host-part */
43913 buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1);
43915 /* everything looks good so far */
43916 buffer_copy_string_len(con->request.uri, uri, proto - uri - 1);
43920 /* check uri for invalid characters */
43921 for (j = 0; j < con->request.uri->used - 1; j++) {
43922 if (!request_uri_is_valid_char(con->request.uri->ptr[j])) {
43923 unsigned char buf[2];
43924 con->http_status = 400;
43925 con->keep_alive = 0;
43928 if (srv->srvconf.log_request_header_on_error) {
43929 buf[0] = con->request.uri->ptr[j];
43933 if (con->request.uri->ptr[j] > 32 &&
43934 - con->request.uri->ptr[j] != 127) {
43935 + con->request.uri->ptr[j] != 127) {
43936 /* the character is printable -> print it */
43937 log_error_write(srv, __FILE__, __LINE__, "ss",
43938 "invalid character in URI -> 400",
43939 @@ -473,20 +475,20 @@
43940 "invalid character in URI -> 400",
43941 con->request.uri->ptr[j]);
43945 log_error_write(srv, __FILE__, __LINE__, "Sb",
43946 "request-header:\n",
43947 con->request.request);
43956 buffer_copy_string_buffer(con->request.orig_uri, con->request.uri);
43959 con->http_status = 0;
43965 @@ -494,14 +496,14 @@
43968 switch(request_line_stage) {
43972 - method = con->parse_request->ptr + first;
43973 + method = con->parse_request->ptr + first;
43978 - uri = con->parse_request->ptr + first;
43979 + uri = con->parse_request->ptr + first;
43983 @@ -509,7 +511,7 @@
43984 con->http_status = 400;
43985 con->response.keep_alive = 0;
43986 con->keep_alive = 0;
43989 if (srv->srvconf.log_request_header_on_error) {
43990 log_error_write(srv, __FILE__, __LINE__, "s", "overlong request line -> 400");
43991 log_error_write(srv, __FILE__, __LINE__, "Sb",
43992 @@ -518,12 +520,12 @@
43998 request_line_stage++;
44006 if (con->request.uri->used == 1) {
44007 @@ -540,30 +542,30 @@
44013 for (; i < con->parse_request->used && !done; i++) {
44014 char *cur = con->parse_request->ptr + i;
44023 * 1*<any CHAR except CTLs or separators>
44024 * CTLs == 0-31 + 127
44036 if (is_ws_after_key == 0) {
44037 key_len = i - first;
44039 is_ws_after_key = 0;
44045 @@ -584,8 +586,8 @@
44046 con->http_status = 400;
44047 con->keep_alive = 0;
44048 con->response.keep_alive = 0;
44050 - log_error_write(srv, __FILE__, __LINE__, "sbsds",
44052 + log_error_write(srv, __FILE__, __LINE__, "sbsds",
44053 "invalid character in key", con->request.request, cur, *cur, "-> 400");
44056 @@ -594,13 +596,13 @@
44068 key_len = i - first;
44071 /* skip every thing up to the : */
44072 for (j = 1; !got_colon; j++) {
44073 switch(con->parse_request->ptr[j + i]) {
44074 @@ -610,40 +612,40 @@
44089 if (srv->srvconf.log_request_header_on_error) {
44090 log_error_write(srv, __FILE__, __LINE__, "s", "WS character in key -> 400");
44091 log_error_write(srv, __FILE__, __LINE__, "Sb",
44092 "request-header:\n",
44093 con->request.request);
44097 con->http_status = 400;
44098 con->response.keep_alive = 0;
44099 con->keep_alive = 0;
44109 if (con->parse_request->ptr[i+1] == '\n' && i == first) {
44110 /* End of Header */
44111 con->parse_request->ptr[i] = '\0';
44112 con->parse_request->ptr[i+1] = '\0';
44123 if (srv->srvconf.log_request_header_on_error) {
44124 @@ -652,7 +654,7 @@
44125 "request-header:\n",
44126 con->request.request);
44130 con->http_status = 400;
44131 con->keep_alive = 0;
44132 con->response.keep_alive = 0;
44133 @@ -693,16 +695,16 @@
44134 con->http_status = 400;
44135 con->keep_alive = 0;
44136 con->response.keep_alive = 0;
44139 if (srv->srvconf.log_request_header_on_error) {
44140 - log_error_write(srv, __FILE__, __LINE__, "sbsds",
44141 + log_error_write(srv, __FILE__, __LINE__, "sbsds",
44142 "CTL character in key", con->request.request, cur, *cur, "-> 400");
44144 log_error_write(srv, __FILE__, __LINE__, "Sb",
44145 "request-header:\n",
44146 con->request.request);
44153 @@ -710,25 +712,25 @@
44159 if (con->parse_request->ptr[i+1] == '\n') {
44160 /* End of Headerline */
44161 con->parse_request->ptr[i] = '\0';
44162 con->parse_request->ptr[i+1] = '\0';
44170 if (srv->srvconf.log_request_header_on_error) {
44171 log_error_write(srv, __FILE__, __LINE__, "s", "WS at the start of first line -> 400");
44174 log_error_write(srv, __FILE__, __LINE__, "Sb",
44175 "request-header:\n",
44176 con->request.request);
44181 con->http_status = 400;
44182 con->keep_alive = 0;
44183 con->response.keep_alive = 0;
44184 @@ -738,9 +740,9 @@
44187 key = con->parse_request->ptr + first;
44190 s_len = cur - value;
44195 if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
44196 @@ -748,86 +750,87 @@
44198 buffer_copy_string_len(ds->key, key, key_len);
44199 buffer_copy_string_len(ds->value, value, s_len);
44201 - /* retreive values
44205 + /* retreive values
44208 * the list of options is sorted to simplify the search
44212 if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) {
44220 vals = srv->split_vals;
44225 http_request_split_value(vals, ds->value);
44228 for (vi = 0; vi < vals->used; vi++) {
44229 data_string *dsv = (data_string *)vals->data[vi];
44232 if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) {
44233 keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
44237 } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) {
44238 keep_alive_set = HTTP_CONNECTION_CLOSE;
44246 } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) {
44248 unsigned long int r;
44252 if (con_length_set) {
44253 con->http_status = 400;
44254 con->keep_alive = 0;
44257 if (srv->srvconf.log_request_header_on_error) {
44258 - log_error_write(srv, __FILE__, __LINE__, "s",
44259 + log_error_write(srv, __FILE__, __LINE__, "s",
44260 "duplicate Content-Length-header -> 400");
44261 log_error_write(srv, __FILE__, __LINE__, "Sb",
44262 "request-header:\n",
44263 con->request.request);
44265 + ds->free((data_unset *) ds);
44270 if (ds->value->used == 0) SEGFAULT();
44273 for (j = 0; j < ds->value->used - 1; j++) {
44274 char c = ds->value->ptr[j];
44275 if (!isdigit((unsigned char)c)) {
44276 - log_error_write(srv, __FILE__, __LINE__, "sbs",
44277 + log_error_write(srv, __FILE__, __LINE__, "sbs",
44278 "content-length broken:", ds->value, "-> 400");
44281 con->http_status = 400;
44282 con->keep_alive = 0;
44285 array_insert_unique(con->request.headers, (data_unset *)ds);
44291 r = strtoul(ds->value->ptr, &err, 10);
44294 if (*err == '\0') {
44295 con_length_set = 1;
44296 con->request.content_length = r;
44298 - log_error_write(srv, __FILE__, __LINE__, "sbs",
44299 + log_error_write(srv, __FILE__, __LINE__, "sbs",
44300 "content-length broken:", ds->value, "-> 400");
44303 con->http_status = 400;
44304 con->keep_alive = 0;
44307 array_insert_unique(con->request.headers, (data_unset *)ds);
44310 @@ -838,23 +841,24 @@
44312 con->http_status = 400;
44313 con->keep_alive = 0;
44316 if (srv->srvconf.log_request_header_on_error) {
44317 - log_error_write(srv, __FILE__, __LINE__, "s",
44318 + log_error_write(srv, __FILE__, __LINE__, "s",
44319 "duplicate Content-Type-header -> 400");
44320 log_error_write(srv, __FILE__, __LINE__, "Sb",
44321 "request-header:\n",
44322 con->request.request);
44324 + ds->free((data_unset *) ds);
44327 } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) {
44328 - /* HTTP 2616 8.2.3
44329 + /* HTTP 2616 8.2.3
44330 * Expect: 100-continue
44333 * -> (10.1.1) 100 (read content, process request, send final status-code)
44334 * -> (10.4.18) 417 (close)
44337 * (not handled at all yet, we always send 417 here)
44339 * What has to be added ?
44340 @@ -863,10 +867,10 @@
44346 con->http_status = 417;
44347 con->keep_alive = 0;
44350 array_insert_unique(con->request.headers, (data_unset *)ds);
44352 } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) {
44353 @@ -875,14 +879,15 @@
44355 con->http_status = 400;
44356 con->keep_alive = 0;
44359 if (srv->srvconf.log_request_header_on_error) {
44360 - log_error_write(srv, __FILE__, __LINE__, "s",
44361 + log_error_write(srv, __FILE__, __LINE__, "s",
44362 "duplicate Host-header -> 400");
44363 log_error_write(srv, __FILE__, __LINE__, "Sb",
44364 "request-header:\n",
44365 con->request.request);
44367 + ds->free((data_unset *) ds);
44370 } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
44371 @@ -897,14 +902,15 @@
44373 con->http_status = 400;
44374 con->keep_alive = 0;
44377 if (srv->srvconf.log_request_header_on_error) {
44378 - log_error_write(srv, __FILE__, __LINE__, "s",
44379 + log_error_write(srv, __FILE__, __LINE__, "s",
44380 "duplicate If-Modified-Since header -> 400");
44381 log_error_write(srv, __FILE__, __LINE__, "Sb",
44382 "request-header:\n",
44383 con->request.request);
44385 + ds->free((data_unset *) ds);
44388 } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
44389 @@ -914,47 +920,49 @@
44391 con->http_status = 400;
44392 con->keep_alive = 0;
44395 if (srv->srvconf.log_request_header_on_error) {
44396 - log_error_write(srv, __FILE__, __LINE__, "s",
44397 + log_error_write(srv, __FILE__, __LINE__, "s",
44398 "duplicate If-None-Match-header -> 400");
44399 log_error_write(srv, __FILE__, __LINE__, "Sb",
44400 "request-header:\n",
44401 con->request.request);
44403 + ds->free((data_unset *) ds);
44406 } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
44407 if (!con->request.http_range) {
44411 if (0 == strncasecmp(ds->value->ptr, "bytes=", 6) &&
44412 NULL != strchr(ds->value->ptr+6, '-')) {
44415 /* if dup, only the first one will survive */
44416 con->request.http_range = ds->value->ptr + 6;
44419 con->http_status = 400;
44420 con->keep_alive = 0;
44423 if (srv->srvconf.log_request_header_on_error) {
44424 - log_error_write(srv, __FILE__, __LINE__, "s",
44425 + log_error_write(srv, __FILE__, __LINE__, "s",
44426 "duplicate Range-header -> 400");
44427 log_error_write(srv, __FILE__, __LINE__, "Sb",
44428 "request-header:\n",
44429 con->request.request);
44431 + ds->free((data_unset *) ds);
44437 array_insert_unique(con->request.headers, (data_unset *)ds);
44439 /* empty header-fields are not allowed by HTTP-RFC, we just ignore them */
44447 @@ -963,10 +971,10 @@
44450 if (srv->srvconf.log_request_header_on_error) {
44451 - log_error_write(srv, __FILE__, __LINE__, "sbs",
44452 + log_error_write(srv, __FILE__, __LINE__, "sbs",
44453 "CR without LF", con->request.request, "-> 400");
44457 con->http_status = 400;
44458 con->keep_alive = 0;
44459 con->response.keep_alive = 0;
44460 @@ -982,28 +990,28 @@
44466 con->header_len = i;
44469 /* do some post-processing */
44471 if (con->request.http_version == HTTP_VERSION_1_1) {
44472 if (keep_alive_set != HTTP_CONNECTION_CLOSE) {
44473 /* no Connection-Header sent */
44476 /* HTTP/1.1 -> keep-alive default TRUE */
44477 con->keep_alive = 1;
44479 con->keep_alive = 0;
44483 /* RFC 2616, 14.23 */
44484 if (con->request.http_host == NULL ||
44485 buffer_is_empty(con->request.http_host)) {
44486 con->http_status = 400;
44487 con->response.keep_alive = 0;
44488 con->keep_alive = 0;
44491 if (srv->srvconf.log_request_header_on_error) {
44492 log_error_write(srv, __FILE__, __LINE__, "s", "HTTP/1.1 but Host missing -> 400");
44493 log_error_write(srv, __FILE__, __LINE__, "Sb",
44494 @@ -1015,18 +1023,18 @@
44496 if (keep_alive_set == HTTP_CONNECTION_KEEPALIVE) {
44497 /* no Connection-Header sent */
44500 /* HTTP/1.0 -> keep-alive default FALSE */
44501 con->keep_alive = 1;
44503 con->keep_alive = 0;
44508 /* check hostname field if it is set */
44509 if (NULL != con->request.http_host &&
44510 0 != request_check_hostname(srv, con, con->request.http_host)) {
44513 if (srv->srvconf.log_request_header_on_error) {
44514 log_error_write(srv, __FILE__, __LINE__, "s",
44515 "Invalid Hostname -> 400");
44516 @@ -1038,7 +1046,7 @@
44517 con->http_status = 400;
44518 con->response.keep_alive = 0;
44519 con->keep_alive = 0;
44525 @@ -1048,7 +1056,7 @@
44526 /* content-length is forbidden for those */
44527 if (con_length_set && con->request.content_length != 0) {
44528 /* content-length is missing */
44529 - log_error_write(srv, __FILE__, __LINE__, "s",
44530 + log_error_write(srv, __FILE__, __LINE__, "s",
44531 "GET/HEAD with content-length -> 400");
44533 con->keep_alive = 0;
44534 @@ -1060,7 +1068,7 @@
44535 /* content-length is required for them */
44536 if (!con_length_set) {
44537 /* content-length is missing */
44538 - log_error_write(srv, __FILE__, __LINE__, "s",
44539 + log_error_write(srv, __FILE__, __LINE__, "s",
44540 "POST-request, but content-length missing -> 411");
44542 con->keep_alive = 0;
44543 @@ -1073,16 +1081,16 @@
44544 /* the may have a content-length */
44551 /* check if we have read post data */
44552 if (con_length_set) {
44553 /* don't handle more the SSIZE_MAX bytes in content-length */
44554 if (con->request.content_length > SSIZE_MAX) {
44555 - con->http_status = 413;
44556 + con->http_status = 413;
44557 con->keep_alive = 0;
44559 - log_error_write(srv, __FILE__, __LINE__, "sds",
44560 + log_error_write(srv, __FILE__, __LINE__, "sds",
44561 "request-size too long:", con->request.content_length, "-> 413");
44564 @@ -1090,25 +1098,25 @@
44565 /* divide by 1024 as srvconf.max_request_size is in kBytes */
44566 if (srv->srvconf.max_request_size != 0 &&
44567 (con->request.content_length >> 10) > srv->srvconf.max_request_size) {
44568 - /* the request body itself is larger then
44569 + /* the request body itself is larger then
44570 * our our max_request_size
44574 con->http_status = 413;
44575 con->keep_alive = 0;
44577 - log_error_write(srv, __FILE__, __LINE__, "sds",
44579 + log_error_write(srv, __FILE__, __LINE__, "sds",
44580 "request-size too long:", con->request.content_length, "-> 413");
44587 /* we have content */
44588 if (con->request.content_length != 0) {
44597 @@ -1116,9 +1124,9 @@
44600 if (con->request.request->used < 5) return 0;
44603 if (0 == memcmp(con->request.request->ptr + con->request.request->used - 5, "\r\n\r\n", 4)) return 1;
44604 if (NULL != strstr(con->request.request->ptr, "\r\n\r\n")) return 1;
44609 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/response.c lighttpd-1.4.12/src/response.c
44610 --- lighttpd-1.4.11/src/response.c 2006-03-04 16:41:39.000000000 +0200
44611 +++ lighttpd-1.4.12/src/response.c 2006-07-11 21:23:40.000000000 +0300
44613 #include <stdlib.h>
44614 #include <string.h>
44616 -#include <unistd.h>
44618 #include <assert.h>
44620 @@ -24,15 +23,17 @@
44621 #include "plugin.h"
44623 #include "sys-socket.h"
44624 +#include "sys-files.h"
44625 +#include "sys-strings.h"
44627 int http_response_write_header(server *srv, connection *con) {
44631 int have_server = 0;
44634 b = chunkqueue_get_prepend_buffer(con->write_queue);
44637 if (con->request.http_version == HTTP_VERSION_1_1) {
44638 BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
44640 @@ -41,25 +42,26 @@
44641 buffer_append_long(b, con->http_status);
44642 BUFFER_APPEND_STRING_CONST(b, " ");
44643 buffer_append_string(b, get_http_status_name(con->http_status));
44646 if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) {
44647 BUFFER_APPEND_STRING_CONST(b, "\r\nConnection: ");
44648 buffer_append_string(b, con->keep_alive ? "keep-alive" : "close");
44652 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
44653 BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked");
44659 /* add all headers */
44660 for (i = 0; i < con->response.headers->used; i++) {
44664 ds = (data_string *)con->response.headers->data[i];
44667 if (ds->value->used && ds->key->used &&
44668 - 0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1)) {
44669 + 0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1) &&
44670 + 0 != strcasecmp(ds->key->ptr, "X-Sendfile")) {
44671 if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Date"))) have_date = 1;
44672 if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Server"))) have_server = 1;
44674 @@ -68,28 +70,28 @@
44675 BUFFER_APPEND_STRING_CONST(b, ": ");
44676 buffer_append_string_buffer(b, ds->value);
44678 - log_error_write(srv, __FILE__, __LINE__, "bb",
44679 + log_error_write(srv, __FILE__, __LINE__, "bb",
44680 ds->key, ds->value);
44687 /* HTTP/1.1 requires a Date: header */
44688 BUFFER_APPEND_STRING_CONST(b, "\r\nDate: ");
44691 /* cache the generated timestamp */
44692 if (srv->cur_ts != srv->last_generated_date_ts) {
44693 buffer_prepare_copy(srv->ts_date_str, 255);
44695 - strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
44697 + strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
44698 "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
44701 srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1;
44704 srv->last_generated_date_ts = srv->cur_ts;
44708 buffer_append_string_buffer(b, srv->ts_date_str);
44711 @@ -101,16 +103,16 @@
44712 buffer_append_string_buffer(b, con->conf.server_tag);
44717 BUFFER_APPEND_STRING_CONST(b, "\r\n\r\n");
44722 con->bytes_header = b->used - 1;
44725 if (con->conf.log_response_header) {
44726 log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b);
44733 @@ -118,71 +120,71 @@
44735 handler_t http_response_prepare(server *srv, connection *con) {
44738 - /* looks like someone has already done a decision */
44739 - if (con->mode == DIRECT &&
44741 + /* looks like someone has already made a decision */
44742 + if (con->mode == DIRECT &&
44743 (con->http_status != 0 && con->http_status != 200)) {
44744 /* remove a packets in the queue */
44745 if (con->file_finished == 0) {
44746 chunkqueue_reset(con->write_queue);
44750 return HANDLER_FINISHED;
44754 /* no decision yet, build conf->filename */
44755 if (con->mode == DIRECT && con->physical.path->used == 0) {
44758 - /* we only come here when we have the parse the full request again
44760 - * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a
44761 + /* we only come here when we have to parse the full request again
44763 + * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a
44764 * problem here as mod_setenv might get called multiple times
44766 * fastcgi-auth might lead to a COMEBACK too
44767 * fastcgi again dead server too
44769 * mod_compress might add headers twice too
44775 if (con->conf.log_condition_handling) {
44776 log_error_write(srv, __FILE__, __LINE__, "s", "run condition");
44778 config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */
44787 * - uri.path (secure)
44796 * Name according to RFC 2396
44805 * (scheme)://(authority)(path)?(query)
44813 buffer_copy_string(con->uri.scheme, con->conf.is_ssl ? "https" : "http");
44814 buffer_copy_string_buffer(con->uri.authority, con->request.http_host);
44815 buffer_to_lower(con->uri.authority);
44818 config_patch_connection(srv, con, COMP_HTTP_HOST); /* Host: */
44819 config_patch_connection(srv, con, COMP_HTTP_REMOTEIP); /* Client-IP */
44820 config_patch_connection(srv, con, COMP_HTTP_REFERER); /* Referer: */
44821 config_patch_connection(srv, con, COMP_HTTP_USERAGENT); /* User-Agent: */
44822 config_patch_connection(srv, con, COMP_HTTP_COOKIE); /* Cookie: */
44825 /** extract query string from request.uri */
44826 if (NULL != (qstr = strchr(con->request.uri->ptr, '?'))) {
44827 buffer_copy_string (con->uri.query, qstr + 1);
44828 @@ -200,22 +202,22 @@
44829 log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path : ", con->uri.path_raw);
44830 log_error_write(srv, __FILE__, __LINE__, "sb", "URI-query : ", con->uri.query);
44834 /* disable keep-alive if requested */
44837 if (con->request_count > con->conf.max_keep_alive_requests) {
44838 con->keep_alive = 0;
44851 * - based on the raw URL
44857 switch(r = plugins_call_handle_uri_raw(srv, con)) {
44858 case HANDLER_GO_ON:
44860 @@ -229,14 +231,14 @@
44864 - /* build filename
44865 + /* build filename
44867 * - decode url-encodings (e.g. %20 -> ' ')
44868 * - remove path-modifiers (e.g. /../)
44876 if (con->request.http_method == HTTP_METHOD_OPTIONS &&
44877 con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
44878 /* OPTIONS * ... */
44879 @@ -253,15 +255,20 @@
44889 * - based on the clean URL
44895 config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */
44898 + /* do we have to downgrade to 1.0 ? */
44899 + if (!con->conf.allow_http11) {
44900 + con->request.http_version = HTTP_VERSION_1_0;
44903 switch(r = plugins_call_handle_uri_clean(srv, con)) {
44904 case HANDLER_GO_ON:
44906 @@ -274,11 +281,11 @@
44907 log_error_write(srv, __FILE__, __LINE__, "");
44912 if (con->request.http_method == HTTP_METHOD_OPTIONS &&
44913 con->uri.path->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
44914 - /* option requests are handled directly without checking of the path */
44916 + /* option requests are handled directly without checking the path */
44918 response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
44920 con->http_status = 200;
44921 @@ -288,46 +295,47 @@
44931 * logical filename (URI) becomes a physical filename here
44948 * ... ISREG() -> ok, go on
44949 * ... ISDIR() -> index-file -> redirect
44964 * SEARCH DOCUMENT ROOT
44968 /* set a default */
44971 buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root);
44972 buffer_copy_string_buffer(con->physical.rel_path, con->uri.path);
44974 -#if defined(__WIN32) || defined(__CYGWIN__)
44975 - /* strip dots from the end and spaces
44977 + filename_unix2local(con->physical.rel_path);
44978 +#if defined(_WIN32) || defined(__CYGWIN__)
44979 + /* strip dots and spaces from the end
44981 * windows/dos handle those filenames as the same file
44983 * foo == foo. == foo..... == "foo... " == "foo.. ./"
44985 - * This will affect in some cases PATHINFO
44986 + * This will affect PATHINFO in some cases
44988 * on native windows we could prepend the filename with \\?\ to circumvent
44989 * this behaviour. I have no idea how to push this through cygwin
44990 @@ -377,36 +385,41 @@
44991 log_error_write(srv, __FILE__, __LINE__, "");
44995 - /* MacOS X and Windows can't distiguish between upper and lower-case
44997 - * convert to lower-case
44999 + /* The default Mac OS X and Windows filesystems can't distiguish between
45000 + * upper- and lowercase, so convert to lowercase
45002 if (con->conf.force_lowercase_filenames) {
45003 buffer_to_lower(con->physical.rel_path);
45006 - /* the docroot plugins might set the servername, if they don't we take http-host */
45007 + /* the docroot plugins might set the servername; if they don't we take http-host */
45008 if (buffer_is_empty(con->server_name)) {
45009 buffer_copy_string_buffer(con->server_name, con->uri.authority);
45013 - * create physical filename
45016 + * create physical filename
45017 * -> physical.path = docroot + rel_path
45023 buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
45024 - BUFFER_APPEND_SLASH(con->physical.path);
45025 + PATHNAME_APPEND_SLASH(con->physical.path);
45026 buffer_copy_string_buffer(con->physical.basedir, con->physical.path);
45027 if (con->physical.rel_path->used &&
45028 - con->physical.rel_path->ptr[0] == '/') {
45029 + con->physical.rel_path->ptr[0] == DIR_SEPERATOR) {
45030 buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
45032 buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
45035 + /* win32: directories can't have a trailing slash */
45036 + if (con->physical.path->ptr[con->physical.path->used - 2] == DIR_SEPERATOR) {
45037 + con->physical.path->ptr[con->physical.path->used - 2] = '\0';
45038 + con->physical.path->used--;
45041 if (con->conf.log_request_handling) {
45042 log_error_write(srv, __FILE__, __LINE__, "s", "-- after doc_root");
45043 log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root);
45044 @@ -426,7 +439,7 @@
45045 log_error_write(srv, __FILE__, __LINE__, "");
45050 if (con->conf.log_request_handling) {
45051 log_error_write(srv, __FILE__, __LINE__, "s", "-- logical -> physical");
45052 log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root);
45053 @@ -434,38 +447,38 @@
45054 log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
45059 - * Noone catched away the file from normal path of execution yet (like mod_access)
45063 + * No one took the file away from the normal path of execution yet (like mod_access)
45065 * Go on and check of the file exists at all
45069 if (con->mode == DIRECT) {
45070 char *slash = NULL;
45071 char *pathinfo = NULL;
45073 stat_cache_entry *sce = NULL;
45076 if (con->conf.log_request_handling) {
45077 log_error_write(srv, __FILE__, __LINE__, "s", "-- handling physical path");
45078 log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
45082 if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
45086 if (con->conf.log_request_handling) {
45087 log_error_write(srv, __FILE__, __LINE__, "s", "-- file found");
45088 log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
45092 if (S_ISDIR(sce->st.st_mode)) {
45093 - if (con->physical.path->ptr[con->physical.path->used - 2] != '/') {
45094 + if (con->uri.path->ptr[con->uri.path->used - 2] != '/') {
45095 /* redirect to .../ */
45098 http_response_redirect_to_directory(srv, con);
45101 return HANDLER_FINISHED;
45103 } else if (!S_ISREG(sce->st.st_mode)) {
45104 @@ -477,12 +490,12 @@
45107 con->http_status = 403;
45110 if (con->conf.log_request_handling) {
45111 log_error_write(srv, __FILE__, __LINE__, "s", "-- access denied");
45112 log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
45116 buffer_reset(con->physical.path);
45117 return HANDLER_FINISHED;
45119 @@ -499,77 +512,77 @@
45120 /* PATH_INFO ! :) */
45123 - /* we have no idea what happend. let's tell the user so. */
45124 + /* we have no idea what happened, so tell the user. */
45125 con->http_status = 500;
45126 buffer_reset(con->physical.path);
45129 log_error_write(srv, __FILE__, __LINE__, "ssbsb",
45130 "file not found ... or so: ", strerror(errno),
45132 "->", con->physical.path);
45135 return HANDLER_FINISHED;
45139 /* not found, perhaps PATHINFO */
45142 buffer_copy_string_buffer(srv->tmp_buf, con->physical.path);
45150 buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
45152 buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
45156 if (0 == stat(con->physical.path->ptr, &(st)) &&
45157 S_ISREG(st.st_mode)) {
45163 if (pathinfo != NULL) {
45166 slash = strrchr(srv->tmp_buf->ptr, '/');
45169 if (pathinfo != NULL) {
45175 if (slash) pathinfo = slash;
45176 } while ((found == 0) && (slash != NULL) && (slash - srv->tmp_buf->ptr > con->physical.basedir->used - 2));
45180 - /* no it really doesn't exists */
45181 + /* no, it really doesn't exists */
45182 con->http_status = 404;
45185 if (con->conf.log_file_not_found) {
45186 log_error_write(srv, __FILE__, __LINE__, "sbsb",
45187 "file not found:", con->uri.path,
45188 "->", con->physical.path);
45192 buffer_reset(con->physical.path);
45195 return HANDLER_FINISHED;
45199 /* we have a PATHINFO */
45201 buffer_copy_string(con->request.pathinfo, pathinfo);
45209 con->uri.path->used -= strlen(pathinfo);
45210 con->uri.path->ptr[con->uri.path->used - 1] = '\0';
45214 if (con->conf.log_request_handling) {
45215 log_error_write(srv, __FILE__, __LINE__, "s", "-- after pathinfo check");
45216 log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
45217 @@ -577,12 +590,12 @@
45218 log_error_write(srv, __FILE__, __LINE__, "sb", "Pathinfo :", con->request.pathinfo);
45223 if (con->conf.log_request_handling) {
45224 log_error_write(srv, __FILE__, __LINE__, "s", "-- handling subrequest");
45225 log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path);
45229 /* call the handlers */
45230 switch(r = plugins_call_handle_subrequest_start(srv, con)) {
45231 case HANDLER_GO_ON:
45232 @@ -593,32 +606,32 @@
45233 if (con->conf.log_request_handling) {
45234 log_error_write(srv, __FILE__, __LINE__, "s", "-- subrequest finished");
45237 - /* something strange happend */
45239 + /* something strange happened */
45243 - /* if we are still here, no one wanted the file, status 403 is ok I think */
45246 + /* if we are still here, no one wanted the file; status 403 is ok I think */
45248 if (con->mode == DIRECT) {
45249 con->http_status = 403;
45252 return HANDLER_FINISHED;
45259 switch(r = plugins_call_handle_subrequest(srv, con)) {
45260 case HANDLER_GO_ON:
45261 - /* request was not handled, looks like we are done */
45262 + /* request was not handled; looks like we are done */
45263 return HANDLER_FINISHED;
45264 case HANDLER_FINISHED:
45265 /* request is finished */
45267 - /* something strange happend */
45268 + /* something strange happened */
45274 return HANDLER_COMEBACK;
45276 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/server.c lighttpd-1.4.12/src/server.c
45277 --- lighttpd-1.4.11/src/server.c 2006-03-04 19:12:17.000000000 +0200
45278 +++ lighttpd-1.4.12/src/server.c 2006-07-11 21:23:40.000000000 +0300
45280 #include <sys/types.h>
45281 -#include <sys/time.h>
45282 #include <sys/stat.h>
45284 #include <string.h>
45287 -#include <unistd.h>
45288 #include <stdlib.h>
45290 #include <signal.h>
45292 #include "plugin.h"
45293 #include "joblist.h"
45294 #include "network_backends.h"
45297 +/* use local getopt implementation */
45298 +# undef HAVE_GETOPT_H
45300 #ifdef HAVE_GETOPT_H
45301 #include <getopt.h>
45303 +#include "getopt.h"
45306 #ifdef HAVE_VALGRIND_VALGRIND_H
45308 /* #define USE_ALARM */
45312 +#undef HAVE_SIGNAL
45315 +#include "sys-files.h"
45316 +#include "sys-process.h"
45318 static volatile sig_atomic_t srv_shutdown = 0;
45319 static volatile sig_atomic_t graceful_shutdown = 0;
45320 +static volatile sig_atomic_t graceful_restart = 0;
45321 static volatile sig_atomic_t handle_sig_alarm = 1;
45322 static volatile sig_atomic_t handle_sig_hup = 0;
45327 case SIGTERM: srv_shutdown = 1; break;
45330 if (graceful_shutdown) srv_shutdown = 1;
45331 - else graceful_shutdown = 1;
45332 + else graceful_shutdown = 1;
45335 case SIGALRM: handle_sig_alarm = 1; break;
45337 static void signal_handler(int sig) {
45339 case SIGTERM: srv_shutdown = 1; break;
45342 if (graceful_shutdown) srv_shutdown = 1;
45343 - else graceful_shutdown = 1;
45344 + else graceful_shutdown = 1;
45347 case SIGALRM: handle_sig_alarm = 1; break;
45348 @@ -110,25 +121,26 @@
45349 signal(SIGTSTP, SIG_IGN);
45351 if (0 != fork()) exit(0);
45354 if (-1 == setsid()) exit(0);
45356 signal(SIGHUP, SIG_IGN);
45358 if (0 != fork()) exit(0);
45361 if (0 != chdir("/")) exit(0);
45365 static server *server_init(void) {
45369 server *srv = calloc(1, sizeof(*srv));
45371 + srv->max_fds = 1024;
45373 srv->x = buffer_init();
45376 CLEAN(response_header);
45377 CLEAN(parse_full_path);
45378 CLEAN(ts_debug_str);
45379 @@ -138,7 +150,7 @@
45381 srv->empty_string = buffer_init_string("");
45382 CLEAN(cond_check_buf);
45385 CLEAN(srvconf.errorlog_file);
45386 CLEAN(srvconf.groupname);
45387 CLEAN(srvconf.username);
45388 @@ -146,58 +158,58 @@
45389 CLEAN(srvconf.bindhost);
45390 CLEAN(srvconf.event_handler);
45391 CLEAN(srvconf.pid_file);
45394 CLEAN(tmp_chunk_len);
45399 srv->x = array_init();
45402 CLEAN(config_context);
45403 CLEAN(config_touched);
45408 for (i = 0; i < FILE_CACHE_MAX; i++) {
45409 srv->mtime_cache[i].str = buffer_init();
45413 srv->cur_ts = time(NULL);
45414 srv->startup_ts = srv->cur_ts;
45417 srv->conns = calloc(1, sizeof(*srv->conns));
45418 assert(srv->conns);
45421 srv->joblist = calloc(1, sizeof(*srv->joblist));
45422 assert(srv->joblist);
45425 srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
45426 assert(srv->fdwaitqueue);
45429 srv->srvconf.modules = array_init();
45430 srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
45431 srv->srvconf.network_backend = buffer_init();
45432 srv->srvconf.upload_tempdirs = array_init();
45436 srv->errorlog_fd = -1;
45437 srv->errorlog_mode = ERRORLOG_STDERR;
45439 srv->split_vals = array_init();
45445 static void server_free(server *srv) {
45449 for (i = 0; i < FILE_CACHE_MAX; i++) {
45450 buffer_free(srv->mtime_cache[i].str);
45455 buffer_free(srv->x);
45458 CLEAN(response_header);
45459 CLEAN(parse_full_path);
45460 CLEAN(ts_debug_str);
45461 @@ -207,7 +219,7 @@
45463 CLEAN(empty_string);
45464 CLEAN(cond_check_buf);
45467 CLEAN(srvconf.errorlog_file);
45468 CLEAN(srvconf.groupname);
45469 CLEAN(srvconf.username);
45470 @@ -217,7 +229,7 @@
45471 CLEAN(srvconf.pid_file);
45472 CLEAN(srvconf.modules_dir);
45473 CLEAN(srvconf.network_backend);
45476 CLEAN(tmp_chunk_len);
45479 @@ -225,15 +237,15 @@
45480 fdevent_unregister(srv->ev, srv->fd);
45482 fdevent_free(srv->ev);
45488 if (srv->config_storage) {
45489 for (i = 0; i < srv->config_context->used; i++) {
45490 specific_config *s = srv->config_storage[i];
45495 buffer_free(s->document_root);
45496 buffer_free(s->server_name);
45497 buffer_free(s->server_tag);
45498 @@ -242,32 +254,32 @@
45499 buffer_free(s->error_handler);
45500 buffer_free(s->errorfile_prefix);
45501 array_free(s->mimetypes);
45506 free(srv->config_storage);
45507 srv->config_storage = NULL;
45512 array_free(srv->x);
45515 CLEAN(config_context);
45516 CLEAN(config_touched);
45518 CLEAN(srvconf.upload_tempdirs);
45522 joblist_free(srv, srv->joblist);
45523 fdwaitqueue_free(srv, srv->fdwaitqueue);
45526 if (srv->stat_cache) {
45527 stat_cache_free(srv->stat_cache);
45530 array_free(srv->srvconf.modules);
45531 array_free(srv->split_vals);
45537 @@ -281,14 +293,12 @@
45538 " - a light and fast webserver\n" \
45539 "Build-Date: " __DATE__ " " __TIME__ "\n";
45543 write(STDOUT_FILENO, b, strlen(b));
45546 static void show_features (void) {
45548 - printf("\nEvent Handlers:\n\n%s",
45550 + const char *s = ""
45552 "\t+ select (generic)\n"
45554 @@ -355,11 +365,6 @@
45556 "\t- crypt support\n"
45559 - "\t+ PAM support\n"
45561 - "\t- PAM support\n"
45564 "\t+ SSL Support\n"
45566 @@ -371,9 +376,9 @@
45567 "\t- PCRE support\n"
45570 - "\t+ mySQL support\n"
45571 + "\t+ MySQL support\n"
45573 - "\t- mySQL support\n"
45574 + "\t- MySQL support\n"
45576 #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
45577 "\t+ LDAP support\n"
45578 @@ -410,8 +415,11 @@
45580 "\t- GDBM support\n"
45588 + printf("\nEvent Handlers:\n\n%s", s);
45591 static void show_help (void) {
45592 @@ -433,12 +441,12 @@
45593 " -h show this help\n" \
45599 write(STDOUT_FILENO, b, strlen(b));
45602 -int main (int argc, char **argv) {
45603 +int main (int argc, char **argv, char **envp) {
45604 server *srv = NULL;
45605 int print_config = 0;
45606 int test_config = 0;
45607 @@ -447,33 +455,37 @@
45608 int num_childs = 0;
45609 int pid_fd = -1, fd;
45612 + char *optarg = NULL;
45615 #ifdef HAVE_SIGACTION
45616 struct sigaction act;
45618 #ifdef HAVE_GETRLIMIT
45619 struct rlimit rlim;
45624 struct itimerval interval;
45627 interval.it_interval.tv_sec = 1;
45628 interval.it_interval.tv_usec = 0;
45629 interval.it_value.tv_sec = 1;
45630 interval.it_value.tv_usec = 0;
45636 /* for nice %b handling in strfime() */
45637 setlocale(LC_TIME, "C");
45640 if (NULL == (srv = server_init())) {
45641 fprintf(stderr, "did this really happen?\n");
45646 /* init structs done */
45649 srv->srvconf.port = 0;
45651 i_am_root = (getuid() == 0);
45652 @@ -481,14 +493,19 @@
45655 srv->srvconf.dont_daemonize = 0;
45658 while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
45661 - if (config_read(srv, optarg)) {
45664 + /* evil HACK for windows, optarg is not set */
45665 + optarg = argv[optind-1];
45667 + if (config_read(srv, optarg)) {
45674 buffer_copy_string(srv->srvconf.modules_dir, optarg);
45675 @@ -497,23 +514,23 @@
45676 case 't': test_config = 1; break;
45677 case 'D': srv->srvconf.dont_daemonize = 1; break;
45678 case 'v': show_version(); return 0;
45679 - case 'V': show_features(); return 0;
45680 + case 'V': show_features(); return 0;
45681 case 'h': show_help(); return 0;
45691 if (!srv->config_storage) {
45692 log_error_write(srv, __FILE__, __LINE__, "s",
45693 "No configuration available. Try using -f option.");
45701 if (print_config) {
45702 data_unset *dc = srv->config_context->data[0];
45704 @@ -533,7 +550,7 @@
45710 /* close stdin and stdout, as they are not needed */
45711 /* move stdin to /dev/null */
45712 if (-1 != (fd = open("/dev/null", O_RDONLY))) {
45713 @@ -541,54 +558,55 @@
45714 dup2(fd, STDIN_FILENO);
45719 /* move stdout to /dev/null */
45720 if (-1 != (fd = open("/dev/null", O_WRONLY))) {
45721 close(STDOUT_FILENO);
45722 dup2(fd, STDOUT_FILENO);
45727 if (0 != config_set_defaults(srv)) {
45728 - log_error_write(srv, __FILE__, __LINE__, "s",
45729 + log_error_write(srv, __FILE__, __LINE__, "s",
45730 "setting default values failed");
45738 if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
45739 /* we are setuid-root */
45741 - log_error_write(srv, __FILE__, __LINE__, "s",
45743 + log_error_write(srv, __FILE__, __LINE__, "s",
45744 "Are you nuts ? Don't apply a SUID bit to this binary");
45753 /* check document-root */
45754 if (srv->config_storage[0]->document_root->used <= 1) {
45755 - log_error_write(srv, __FILE__, __LINE__, "s",
45756 + log_error_write(srv, __FILE__, __LINE__, "s",
45757 "document-root is not set\n");
45767 if (plugins_load(srv)) {
45768 log_error_write(srv, __FILE__, __LINE__, "s",
45769 "loading plugins finally failed");
45781 /* open pid file BEFORE chroot */
45782 if (srv->srvconf.pid_file->used) {
45783 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))) {
45784 @@ -598,18 +616,18 @@
45785 "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
45790 if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
45791 log_error_write(srv, __FILE__, __LINE__, "sbs",
45792 "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
45796 if (!S_ISREG(st.st_mode)) {
45797 log_error_write(srv, __FILE__, __LINE__, "sb",
45798 "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
45803 if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
45804 log_error_write(srv, __FILE__, __LINE__, "sbs",
45805 "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
45806 @@ -617,13 +635,14 @@
45812 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
45813 /* select limits itself
45815 * as it is a hard limit and will lead to a segfault we add some safety
45817 - srv->max_fds = FD_SETSIZE - 200;
45818 + fprintf(stderr, "%s.%d: max parallel connections: %d\r\n", __FILE__, __LINE__, FD_SETSIZE);
45819 + srv->max_fds = FD_SETSIZE - 4;
45821 srv->max_fds = 4096;
45823 @@ -636,7 +655,7 @@
45824 #ifdef HAVE_VALGRIND_VALGRIND_H
45825 if (RUNNING_ON_VALGRIND) use_rlimit = 0;
45829 #ifdef HAVE_GETRLIMIT
45830 if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
45831 log_error_write(srv, __FILE__, __LINE__,
45832 @@ -644,13 +663,13 @@
45838 if (use_rlimit && srv->srvconf.max_fds) {
45842 rlim.rlim_cur = srv->srvconf.max_fds;
45843 rlim.rlim_max = srv->srvconf.max_fds;
45846 if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
45847 log_error_write(srv, __FILE__, __LINE__,
45848 "ss", "couldn't set 'max filedescriptors'",
45849 @@ -659,7 +678,7 @@
45853 - /* #372: solaris need some fds extra for devpoll */
45854 + /* #372: solaris need some fds extra for devpoll */
45855 if (rlim.rlim_cur > 10) rlim.rlim_cur -= 10;
45857 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
45858 @@ -677,33 +696,33 @@
45859 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
45860 /* don't raise the limit above FD_SET_SIZE */
45861 if (srv->max_fds > FD_SETSIZE - 200) {
45862 - log_error_write(srv, __FILE__, __LINE__, "sd",
45863 + log_error_write(srv, __FILE__, __LINE__, "sd",
45864 "can't raise max filedescriptors above", FD_SETSIZE - 200,
45865 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
45873 /* set user and group */
45874 if (srv->srvconf.username->used) {
45875 if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
45876 - log_error_write(srv, __FILE__, __LINE__, "sb",
45877 + log_error_write(srv, __FILE__, __LINE__, "sb",
45878 "can't find username", srv->srvconf.username);
45883 if (pwd->pw_uid == 0) {
45884 log_error_write(srv, __FILE__, __LINE__, "s",
45885 "I will not set uid to 0\n");
45891 if (srv->srvconf.groupname->used) {
45892 if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
45893 - log_error_write(srv, __FILE__, __LINE__, "sb",
45894 + log_error_write(srv, __FILE__, __LINE__, "sb",
45895 "can't find groupname", srv->srvconf.groupname);
45898 @@ -713,15 +732,15 @@
45904 /* we need root-perms for port < 1024 */
45905 if (0 != network_init(srv)) {
45912 -#ifdef HAVE_CHROOT
45913 +#ifdef HAVE_CHROOT
45914 if (srv->srvconf.changeroot->used) {
45917 @@ -761,7 +780,7 @@
45920 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
45921 - srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
45922 + srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 4 ? rlim.rlim_cur : FD_SETSIZE - 4;
45924 srv->max_fds = rlim.rlim_cur;
45926 @@ -775,18 +794,18 @@
45928 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
45929 /* don't raise the limit above FD_SET_SIZE */
45930 - if (srv->max_fds > FD_SETSIZE - 200) {
45931 - log_error_write(srv, __FILE__, __LINE__, "sd",
45932 - "can't raise max filedescriptors above", FD_SETSIZE - 200,
45933 + if (srv->max_fds > FD_SETSIZE - 4) {
45934 + log_error_write(srv, __FILE__, __LINE__, "sd",
45935 + "can't raise max filedescriptors above", FD_SETSIZE - 4,
45936 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
45942 if (0 != network_init(srv)) {
45950 @@ -802,25 +821,27 @@
45951 /* or use the default */
45952 srv->max_conns = srv->max_fds;
45956 if (HANDLER_GO_ON != plugins_call_init(srv)) {
45957 log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
45961 network_close(srv);
45970 /* network is up, let's deamonize ourself */
45971 if (srv->srvconf.dont_daemonize == 0) daemonize();
45975 srv->gid = getgid();
45976 srv->uid = getuid();
45980 /* write pid file */
45981 if (pid_fd != -1) {
45982 buffer_copy_long(srv->tmp_buf, getpid());
45983 @@ -829,17 +850,17 @@
45989 if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
45990 log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
45994 network_close(srv);
46002 /* dump unused config-keys */
46003 for (i = 0; i < srv->config_context->used; i++) {
46004 array *config = ((data_config *)srv->config_context->data[i])->value;
46005 @@ -847,43 +868,42 @@
46007 for (j = 0; config && j < config->used; j++) {
46008 data_unset *du = config->data[j];
46011 /* all var.* is known as user defined variable */
46012 if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
46016 if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
46017 - log_error_write(srv, __FILE__, __LINE__, "sbs",
46018 + log_error_write(srv, __FILE__, __LINE__, "sbs",
46019 "WARNING: unknown config-key:",
46027 if (srv->config_deprecated) {
46028 - log_error_write(srv, __FILE__, __LINE__, "s",
46029 + log_error_write(srv, __FILE__, __LINE__, "s",
46030 "Configuration contains deprecated keys. Going down.");
46034 network_close(srv);
46042 if (-1 == log_error_open(srv)) {
46043 - log_error_write(srv, __FILE__, __LINE__, "s",
46044 + log_error_write(srv, __FILE__, __LINE__, "s",
46045 "opening errorlog failed, dying");
46049 network_close(srv);
46056 #ifdef HAVE_SIGACTION
46057 memset(&act, 0, sizeof(act));
46058 act.sa_handler = SIG_IGN;
46059 @@ -903,7 +923,7 @@
46060 sigaction(SIGHUP, &act, NULL);
46061 sigaction(SIGALRM, &act, NULL);
46062 sigaction(SIGCHLD, &act, NULL);
46065 #elif defined(HAVE_SIGNAL)
46066 /* ignore the SIGPIPE from sendfile() */
46067 signal(SIGPIPE, SIG_IGN);
46068 @@ -914,20 +934,20 @@
46069 signal(SIGCHLD, signal_handler);
46070 signal(SIGINT, signal_handler);
46075 signal(SIGALRM, signal_handler);
46078 /* setup periodic timer (1 second) */
46079 if (setitimer(ITIMER_REAL, &interval, NULL)) {
46080 log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
46085 getitimer(ITIMER_REAL, &interval);
46090 /* start watcher and workers */
46091 num_childs = srv->srvconf.max_worker;
46092 if (num_childs > 0) {
46093 @@ -957,13 +977,13 @@
46097 - if (NULL == (srv->ev = fdevent_init(srv->max_fds + 1, srv->event_handler))) {
46098 + if (NULL == (srv->ev = fdevent_init(/*srv->max_fds + 1*/ 4096, srv->event_handler))) {
46099 log_error_write(srv, __FILE__, __LINE__,
46100 "s", "fdevent_init failed");
46104 - * kqueue() is called here, select resets its internals,
46106 + * kqueue() is called here, select resets its internals,
46107 * all server sockets get their handlers
46110 @@ -971,7 +991,7 @@
46112 network_close(srv);
46119 @@ -986,7 +1006,7 @@
46121 if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
46122 if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
46123 - log_error_write(srv, __FILE__, __LINE__, "s",
46124 + log_error_write(srv, __FILE__, __LINE__, "s",
46125 "could not open a fam connection, dieing.");
46128 @@ -1018,16 +1038,40 @@
46134 if (handle_sig_hup) {
46138 /* reset notification */
46139 handle_sig_hup = 0;
46146 + /* send the old process into a graceful-shutdown and start a
46147 + * new process right away
46150 + * - if webserver is running on port < 1024 (e.g. 80, 433)
46151 + * we don't have the permissions to bind to that port anymore
46155 + if (0 == (pid = fork())) {
46156 + execve(argv[0], argv, envp);
46159 + } else if (pid == -1) {
46164 + graceful_shutdown = 1; /* shutdown without killing running connections */
46165 + graceful_restart = 1; /* don't delete pid file */
46168 /* cycle logfiles */
46171 switch(r = plugins_call_handle_sighup(srv)) {
46172 case HANDLER_GO_ON:
46174 @@ -1035,30 +1079,31 @@
46175 log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
46180 if (-1 == log_error_cycle(srv)) {
46181 log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
46190 if (handle_sig_alarm) {
46195 /* reset notification */
46196 handle_sig_alarm = 0;
46200 /* get current time */
46201 min_ts = time(NULL);
46204 if (min_ts != srv->cur_ts) {
46206 connections *conns = srv->conns;
46210 switch(r = plugins_call_handle_trigger(srv)) {
46211 case HANDLER_GO_ON:
46213 @@ -1069,21 +1114,21 @@
46214 log_error_write(srv, __FILE__, __LINE__, "d", r);
46219 /* trigger waitpid */
46220 srv->cur_ts = min_ts;
46222 - /* cleanup stat-cache */
46224 + /* cleanup stat-cache */
46225 stat_cache_trigger_cleanup(srv);
46227 - * check all connections for timeouts
46229 + * check all connections for timeouts
46232 for (ndx = 0; ndx < conns->used; ndx++) {
46238 con = conns->ptr[ndx];
46240 if (con->state == CON_STATE_READ ||
46241 @@ -1092,7 +1137,7 @@
46242 if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
46245 - log_error_write(srv, __FILE__, __LINE__, "sd",
46246 + log_error_write(srv, __FILE__, __LINE__, "sd",
46247 "connection closed - read-timeout:", con->fd);
46249 connection_set_state(srv, con, CON_STATE_ERROR);
46250 @@ -1102,7 +1147,7 @@
46251 if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) {
46254 - log_error_write(srv, __FILE__, __LINE__, "sd",
46255 + log_error_write(srv, __FILE__, __LINE__, "sd",
46256 "connection closed - read-timeout:", con->fd);
46258 connection_set_state(srv, con, CON_STATE_ERROR);
46259 @@ -1110,20 +1155,20 @@
46265 if ((con->state == CON_STATE_WRITE) &&
46266 - (con->write_request_ts != 0)) {
46267 + (con->write_request_ts != 0)) {
46269 if (srv->cur_ts - con->write_request_ts > 60) {
46270 - log_error_write(srv, __FILE__, __LINE__, "sdd",
46271 + log_error_write(srv, __FILE__, __LINE__, "sdd",
46272 "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
46277 if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
46280 - log_error_write(srv, __FILE__, __LINE__, "sbsosds",
46281 + log_error_write(srv, __FILE__, __LINE__, "sbsosds",
46282 "NOTE: a request for",
46284 "timed out after writing",
46285 @@ -1138,35 +1183,35 @@
46287 /* we don't like div by zero */
46288 if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
46290 - if (con->traffic_limit_reached &&
46291 - (con->conf.kbytes_per_second == 0 ||
46293 + if (con->traffic_limit_reached &&
46294 + (con->conf.kbytes_per_second == 0 ||
46295 ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
46296 /* enable connection again */
46297 con->traffic_limit_reached = 0;
46305 connection_state_machine(srv, con);
46307 con->bytes_written_cur_second = 0;
46308 *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
46313 fprintf(stderr, "connection-state: ");
46318 fprintf(stderr, "c[%d,%d]: %s ",
46321 connection_get_state(con->state));
46326 if (cs == 1) fprintf(stderr, "\n");
46329 @@ -1181,18 +1226,18 @@
46330 server_socket *srv_socket = srv->srv_sockets.ptr[i];
46331 fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
46335 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
46338 srv->sockets_disabled = 0;
46341 if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
46342 (srv->conns->used > srv->max_conns) || /* out of connections */
46343 - (graceful_shutdown)) { /* graceful_shutdown */
46344 + (graceful_shutdown)) { /* graceful_shutdown */
46346 /* disable server-fds */
46349 for (i = 0; i < srv->srv_sockets.used; i++) {
46350 server_socket *srv_socket = srv->srv_sockets.ptr[i];
46351 fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
46352 @@ -1211,7 +1256,7 @@
46353 /* network_close() will cleanup after us */
46358 if (graceful_shutdown) {
46359 log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
46360 } else if (srv->conns->used > srv->max_conns) {
46361 @@ -1219,7 +1264,7 @@
46363 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
46367 srv->sockets_disabled = 1;
46370 @@ -1229,16 +1274,16 @@
46371 * we are ready to terminate without harming anyone */
46376 /* we still have some fds to share */
46377 - if (srv->want_fds) {
46378 + if (srv->want_fds) {
46379 /* check the fdwaitqueue for waiting fds */
46380 int free_fds = srv->max_fds - srv->cur_fds - 16;
46384 for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
46385 connection_state_machine(srv, con);
46391 @@ -1249,27 +1294,27 @@
46395 - log_error_write(srv, __FILE__, __LINE__, "sd",
46396 + log_error_write(srv, __FILE__, __LINE__, "sd",
46403 fdevent_handler handler;
46408 fd_ndx = fdevent_event_next_fdndx (srv->ev, fd_ndx);
46409 revents = fdevent_event_get_revent (srv->ev, fd_ndx);
46410 fd = fdevent_event_get_fd (srv->ev, fd_ndx);
46411 handler = fdevent_get_handler(srv->ev, fd);
46412 context = fdevent_get_context(srv->ev, fd);
46415 /* connection_handle_fdevent needs a joblist_append */
46417 - log_error_write(srv, __FILE__, __LINE__, "sdd",
46418 + log_error_write(srv, __FILE__, __LINE__, "sdd",
46419 "event for", fd, revents);
46422 switch (r = (*handler)(srv, context, revents)) {
46423 case HANDLER_FINISHED:
46424 case HANDLER_GO_ON:
46425 @@ -1286,17 +1331,17 @@
46428 } else if (n < 0 && errno != EINTR) {
46429 - log_error_write(srv, __FILE__, __LINE__, "ss",
46430 - "fdevent_poll failed:",
46431 + log_error_write(srv, __FILE__, __LINE__, "ss",
46432 + "fdevent_poll failed:",
46437 for (ndx = 0; ndx < srv->joblist->used; ndx++) {
46438 connection *con = srv->joblist->ptr[ndx];
46442 connection_state_machine(srv, con);
46445 switch(r = plugins_call_handle_joblist(srv, con)) {
46446 case HANDLER_FINISHED:
46447 case HANDLER_GO_ON:
46448 @@ -1305,32 +1350,33 @@
46449 log_error_write(srv, __FILE__, __LINE__, "d", r);
46454 con->in_joblist = 0;
46458 srv->joblist->used = 0;
46461 - if (srv->srvconf.pid_file->used &&
46463 + if (0 == graceful_restart &&
46464 + srv->srvconf.pid_file->used &&
46465 srv->srvconf.changeroot->used == 0) {
46466 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
46467 if (errno != EACCES && errno != EPERM) {
46468 - log_error_write(srv, __FILE__, __LINE__, "sbds",
46469 - "unlink failed for:",
46470 + log_error_write(srv, __FILE__, __LINE__, "sbds",
46471 + "unlink failed for:",
46472 srv->srvconf.pid_file,
46481 log_error_close(srv);
46482 network_close(srv);
46483 connections_free(srv);
46490 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/settings.h lighttpd-1.4.12/src/settings.h
46491 --- lighttpd-1.4.11/src/settings.h 2005-08-11 01:26:41.000000000 +0300
46492 +++ lighttpd-1.4.12/src/settings.h 2006-07-11 21:23:40.000000000 +0300
46495 * max size of a buffer which will just be reset
46496 * to ->used = 0 instead of really freeing the buffer
46499 * 64kB (no real reason, just a guess)
46501 #define BUFFER_MAX_REUSE_SIZE (4 * 1024)
46504 * max size of the HTTP request header
46507 * 32k should be enough for everything (just a guess)
46511 #define MAX_HTTP_REQUEST_HEADER (32 * 1024)
46513 -typedef enum { HANDLER_UNSET,
46515 +typedef enum { HANDLER_UNSET,
46518 - HANDLER_COMEBACK,
46519 - HANDLER_WAIT_FOR_EVENT,
46520 + HANDLER_COMEBACK,
46521 + HANDLER_WAIT_FOR_EVENT,
46523 HANDLER_WAIT_FOR_FD
46525 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/spawn-fcgi.c lighttpd-1.4.12/src/spawn-fcgi.c
46526 --- lighttpd-1.4.11/src/spawn-fcgi.c 2006-03-07 14:18:10.000000000 +0200
46527 +++ lighttpd-1.4.12/src/spawn-fcgi.c 2006-07-11 21:23:40.000000000 +0300
46529 #include <sys/types.h>
46530 -#include <sys/time.h>
46531 #include <sys/stat.h>
46533 #include <stdlib.h>
46534 #include <string.h>
46537 -#include <unistd.h>
46541 #ifdef HAVE_CONFIG_H
46542 #include "config.h"
46552 #include "sys-socket.h"
46553 +#include "sys-files.h"
46555 #ifdef HAVE_SYS_WAIT_H
46556 #include <sys/wait.h>
46557 @@ -45,28 +43,28 @@
46559 int socket_type, status;
46560 struct timeval tv = { 0, 100 * 1000 };
46563 struct sockaddr_un fcgi_addr_un;
46564 struct sockaddr_in fcgi_addr_in;
46565 struct sockaddr *fcgi_addr;
46571 if (child_count < 2) {
46576 if (child_count > 256) {
46584 memset(&fcgi_addr, 0, sizeof(fcgi_addr));
46587 fcgi_addr_un.sun_family = AF_UNIX;
46588 strcpy(fcgi_addr_un.sun_path, unixsocket);
46592 servlen = SUN_LEN(&fcgi_addr_un);
46594 @@ -84,50 +82,50 @@
46596 fcgi_addr_in.sin_port = htons(port);
46597 servlen = sizeof(fcgi_addr_in);
46600 socket_type = AF_INET;
46601 fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
46605 if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
46606 - fprintf(stderr, "%s.%d\n",
46607 + fprintf(stderr, "%s.%d\n",
46608 __FILE__, __LINE__);
46613 if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
46614 /* server is not up, spawn in */
46619 if (unixsocket) unlink(unixsocket);
46625 /* reopen socket */
46626 if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
46627 - fprintf(stderr, "%s.%d\n",
46628 + fprintf(stderr, "%s.%d\n",
46629 __FILE__, __LINE__);
46634 if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
46635 - fprintf(stderr, "%s.%d\n",
46636 + fprintf(stderr, "%s.%d\n",
46637 __FILE__, __LINE__);
46641 /* create socket */
46642 if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
46643 - fprintf(stderr, "%s.%d: bind failed: %s\n",
46644 + fprintf(stderr, "%s.%d: bind failed: %s\n",
46645 __FILE__, __LINE__,
46651 if (-1 == listen(fcgi_fd, 1024)) {
46652 - fprintf(stderr, "%s.%d: fd = -1\n",
46653 + fprintf(stderr, "%s.%d: fd = -1\n",
46654 __FILE__, __LINE__);
46657 @@ -137,42 +135,45 @@
46665 char cgi_childs[64];
46672 + /* loose control terminal */
46675 /* is save as we limit to 256 childs */
46676 sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count);
46679 if(fcgi_fd != FCGI_LISTENSOCK_FILENO) {
46680 close(FCGI_LISTENSOCK_FILENO);
46681 dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
46686 /* we don't need the client socket */
46687 for (i = 3; i < 256; i++) {
46692 /* create environment */
46695 putenv(cgi_childs);
46698 /* fork and replace shell */
46699 b = malloc(strlen("exec ") + strlen(appPath) + 1);
46700 strcpy(b, "exec ");
46701 strcat(b, appPath);
46705 execl("/bin/sh", "sh", "-c", b, NULL);
46714 @@ -180,47 +181,47 @@
46721 select(0, NULL, NULL, NULL, &tv);
46724 switch (waitpid(child, &status, WNOHANG)) {
46726 - fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n",
46727 + fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n",
46728 __FILE__, __LINE__,
46732 /* write pid file */
46733 if (pid_fd != -1) {
46734 /* assume a 32bit pid_t */
46738 snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child);
46741 write(pid_fd, pidbuf, strlen(pidbuf));
46751 if (WIFEXITED(status)) {
46752 - fprintf(stderr, "%s.%d: child exited with: %d, %s\n",
46753 + fprintf(stderr, "%s.%d: child exited with: %d, %s\n",
46754 __FILE__, __LINE__,
46755 WEXITSTATUS(status), strerror(WEXITSTATUS(status)));
46756 } else if (WIFSIGNALED(status)) {
46757 - fprintf(stderr, "%s.%d: child signaled: %d\n",
46758 + fprintf(stderr, "%s.%d: child signaled: %d\n",
46759 __FILE__, __LINE__,
46762 - fprintf(stderr, "%s.%d: child died somehow: %d\n",
46763 + fprintf(stderr, "%s.%d: child died somehow: %d\n",
46764 __FILE__, __LINE__,
46773 @@ -228,16 +229,16 @@
46774 __FILE__, __LINE__);
46786 void show_version () {
46787 char *b = "spawn-fcgi" "-" PACKAGE_VERSION \
46788 -" - spawns fastcgi processes\n"
46789 +" - spawns fastcgi processes\n"
46791 write(1, b, strlen(b));
46793 @@ -265,7 +266,7 @@
46796 int main(int argc, char **argv) {
46797 - char *fcgi_app = NULL, *changeroot = NULL, *username = NULL,
46798 + char *fcgi_app = NULL, *changeroot = NULL, *username = NULL,
46799 *groupname = NULL, *unixsocket = NULL, *pid_file = NULL,
46801 unsigned short port = 0;
46802 @@ -273,9 +274,9 @@
46808 i_am_root = (getuid() == 0);
46811 while(-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:s:P:"))) {
46813 case 'f': fcgi_app = optarg; break;
46814 @@ -290,137 +291,137 @@
46815 case 'P': pid_file = optarg; /* PID file */ break;
46816 case 'v': show_version(); return 0;
46817 case 'h': show_help(); return 0;
46826 if (fcgi_app == NULL || (port == 0 && unixsocket == NULL)) {
46832 if (unixsocket && port) {
46833 - fprintf(stderr, "%s.%d: %s\n",
46834 + fprintf(stderr, "%s.%d: %s\n",
46835 __FILE__, __LINE__,
46836 "either a unix domain socket or a tcp-port, but not both\n");
46843 if (unixsocket && strlen(unixsocket) > UNIX_PATH_MAX - 1) {
46844 - fprintf(stderr, "%s.%d: %s\n",
46845 + fprintf(stderr, "%s.%d: %s\n",
46846 __FILE__, __LINE__,
46847 "path of the unix socket is too long\n");
46854 if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
46855 /* we are setuid-root */
46857 - fprintf(stderr, "%s.%d: %s\n",
46859 + fprintf(stderr, "%s.%d: %s\n",
46860 __FILE__, __LINE__,
46861 "Are you nuts ? Don't apply a SUID bit to this binary\n");
46870 (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) {
46872 if (errno != EEXIST) {
46873 - fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
46874 + fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
46875 __FILE__, __LINE__,
46876 pid_file, strerror(errno));
46883 /* ok, file exists */
46886 if (0 != stat(pid_file, &st)) {
46887 - fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n",
46888 + fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n",
46889 __FILE__, __LINE__,
46890 pid_file, strerror(errno));
46897 /* is it a regular file ? */
46900 if (!S_ISREG(st.st_mode)) {
46901 - fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n",
46902 + fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n",
46903 __FILE__, __LINE__,
46911 if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
46912 - fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
46913 + fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
46914 __FILE__, __LINE__,
46915 pid_file, strerror(errno));
46924 struct group *grp = NULL;
46925 struct passwd *pwd = NULL;
46928 /* set user and group */
46932 if (NULL == (pwd = getpwnam(username))) {
46933 - fprintf(stderr, "%s.%d: %s, %s\n",
46934 + fprintf(stderr, "%s.%d: %s, %s\n",
46935 __FILE__, __LINE__,
46936 "can't find username", username);
46941 if (pwd->pw_uid == 0) {
46942 - fprintf(stderr, "%s.%d: %s\n",
46943 + fprintf(stderr, "%s.%d: %s\n",
46944 __FILE__, __LINE__,
46945 "I will not set uid to 0\n");
46952 if (NULL == (grp = getgrnam(groupname))) {
46953 - fprintf(stderr, "%s.%d: %s %s\n",
46954 + fprintf(stderr, "%s.%d: %s %s\n",
46955 __FILE__, __LINE__,
46956 - "can't find groupname",
46957 + "can't find groupname",
46961 if (grp->gr_gid == 0) {
46962 - fprintf(stderr, "%s.%d: %s\n",
46963 + fprintf(stderr, "%s.%d: %s\n",
46964 __FILE__, __LINE__,
46965 "I will not set gid to 0\n");
46972 if (-1 == chroot(changeroot)) {
46973 - fprintf(stderr, "%s.%d: %s %s\n",
46974 + fprintf(stderr, "%s.%d: %s %s\n",
46975 __FILE__, __LINE__,
46976 "chroot failed: ", strerror(errno));
46979 if (-1 == chdir("/")) {
46980 - fprintf(stderr, "%s.%d: %s %s\n",
46981 + fprintf(stderr, "%s.%d: %s %s\n",
46982 __FILE__, __LINE__,
46983 "chdir failed: ", strerror(errno));
46989 /* drop root privs */
46991 setgid(grp->gr_gid);
46992 @@ -428,7 +429,7 @@
46994 if (username) setuid(pwd->pw_uid);
46998 return fcgi_spawn_connection(fcgi_app, addr, port, unixsocket, child_count, pid_fd, nofork);
47001 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/splaytree.c lighttpd-1.4.12/src/splaytree.c
47002 --- lighttpd-1.4.11/src/splaytree.c 2005-09-12 21:51:28.000000000 +0300
47003 +++ lighttpd-1.4.12/src/splaytree.c 2006-07-11 21:23:39.000000000 +0300
47004 @@ -56,19 +56,19 @@
47006 #define node_size splaytree_size
47008 -/* Splay using the key i (which may or may not be in the tree.)
47009 - * The starting root is t, and the tree used is defined by rat
47010 +/* Splay using the key i (which may or may not be in the tree.)
47011 + * The starting root is t, and the tree used is defined by rat
47012 * size fields are maintained */
47013 splay_tree * splaytree_splay (splay_tree *t, int i) {
47014 splay_tree N, *l, *r, *y;
47015 int comp, root_size, l_size, r_size;
47018 if (t == NULL) return t;
47019 N.left = N.right = NULL;
47021 root_size = node_size(t);
47022 l_size = r_size = 0;
47026 comp = compare(i, t->key);
47028 @@ -120,7 +120,7 @@
47030 r_size -= 1+node_size(y->right);
47034 l->right = t->left; /* assemble */
47035 r->left = t->right;
47037 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/splaytree.h lighttpd-1.4.12/src/splaytree.h
47038 --- lighttpd-1.4.11/src/splaytree.h 2005-09-12 21:51:13.000000000 +0300
47039 +++ lighttpd-1.4.12/src/splaytree.h 2006-07-11 21:23:40.000000000 +0300
47041 /* This macro returns the size of a node. Unlike "x->size", */
47042 /* it works even if x=NULL. The test could be avoided by using */
47043 /* a special version of NULL which was a real node with size 0. */
47048 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/stat_cache.c lighttpd-1.4.12/src/stat_cache.c
47049 --- lighttpd-1.4.11/src/stat_cache.c 2005-11-22 15:23:51.000000000 +0200
47050 +++ lighttpd-1.4.12/src/stat_cache.c 2006-07-11 21:23:40.000000000 +0300
47052 #include <stdlib.h>
47053 #include <string.h>
47055 -#include <unistd.h>
47058 #include <assert.h>
47062 #include "sys-mmap.h"
47064 -/* NetBSD 1.3.x needs it */
47065 -#ifndef MAP_FAILED
47066 -# define MAP_FAILED -1
47069 -#ifndef O_LARGEFILE
47070 -# define O_LARGEFILE 0
47073 -#ifndef HAVE_LSTAT
47074 -#define lstat stat
47076 +#include "sys-files.h"
47077 +#include "sys-strings.h"
47080 /* enables debug code for testing if all nodes in the stat-cache as accessable */
47083 * if we get a change-event from FAM, we increment the version in the FAM->dir mapping
47085 - * if the stat()-cache is queried we check if the version id for the directory is the
47086 - * same and return immediatly.
47087 + * if the stat()-cache is queried we check if the version id for the directory is the
47088 + * same and return immediatly.
47092 @@ -62,17 +50,17 @@
47093 * - for each FAMRequest we have to find the version in the directory cache (index as userdata)
47095 * stat <<-> directory <-> FAMRequest
47097 - * if file is deleted, directory is dirty, file is rechecked ...
47099 + * if file is deleted, directory is dirty, file is rechecked ...
47100 * if directory is deleted, directory mapping is removed
47114 @@ -83,16 +71,16 @@
47116 * - the hash-key is used as sorting criteria for a tree
47117 * - a splay-tree is used as we can use the caching effect of it
47121 /* we want to cleanup the stat-cache every few seconds, let's say 10
47123 * - remove entries which are outdated since 30s
47124 * - remove entries which are fresh but havn't been used since 60s
47125 * - if we don't have a stat-cache entry for a directory, release it from the monitor
47129 -#ifdef DEBUG_STAT_CACHE
47130 +#ifdef DEBUG_STAT_CACHE
47134 @@ -105,15 +93,15 @@
47136 stat_cache *stat_cache_init(void) {
47137 stat_cache *fc = NULL;
47140 fc = calloc(1, sizeof(*fc));
47143 fc->dir_name = buffer_init();
47145 fc->fam = calloc(1, sizeof(*fc->fam));
47148 -#ifdef DEBUG_STAT_CACHE
47149 +#ifdef DEBUG_STAT_CACHE
47153 @@ -122,24 +110,24 @@
47155 static stat_cache_entry * stat_cache_entry_init(void) {
47156 stat_cache_entry *sce = NULL;
47159 sce = calloc(1, sizeof(*sce));
47162 sce->name = buffer_init();
47163 sce->etag = buffer_init();
47164 sce->content_type = buffer_init();
47170 static void stat_cache_entry_free(void *data) {
47171 stat_cache_entry *sce = data;
47175 buffer_free(sce->etag);
47176 buffer_free(sce->name);
47177 buffer_free(sce->content_type);
47183 @@ -148,22 +136,22 @@
47184 fam_dir_entry *fam_dir = NULL;
47186 fam_dir = calloc(1, sizeof(*fam_dir));
47189 fam_dir->name = buffer_init();
47195 static void fam_dir_entry_free(void *data) {
47196 fam_dir_entry *fam_dir = data;
47199 if (!fam_dir) return;
47202 FAMCancelMonitor(fam_dir->fc, fam_dir->req);
47205 buffer_free(fam_dir->name);
47206 free(fam_dir->req);
47212 @@ -174,7 +162,7 @@
47213 splay_tree *node = sc->files;
47215 osize = sc->files->size;
47218 stat_cache_entry_free(node->data);
47219 sc->files = splaytree_delete(sc->files, node->key);
47221 @@ -187,12 +175,12 @@
47224 splay_tree *node = sc->dirs;
47227 osize = sc->dirs->size;
47229 fam_dir_entry_free(node->data);
47230 sc->dirs = splaytree_delete(sc->dirs, node->key);
47234 assert(NULL == sc->dirs);
47236 @@ -212,7 +200,7 @@
47237 static int stat_cache_attr_get(buffer *buf, char *name) {
47243 buffer_prepare_copy(buf, attrlen);
47245 @@ -251,15 +239,15 @@
47248 events = FAMPending(sc->fam);
47251 for (i = 0; i < events; i++) {
47253 fam_dir_entry *fam_dir;
47258 FAMNextEvent(sc->fam, &fe);
47264 @@ -280,7 +268,7 @@
47266 sc->dirs = splaytree_splay(sc->dirs, ndx);
47270 if (node && (node->key == ndx)) {
47271 int osize = splaytree_size(sc->dirs);
47273 @@ -308,7 +296,7 @@
47279 return HANDLER_GO_ON;
47282 @@ -332,7 +320,7 @@
47288 * - HANDLER_FINISHED on cache-miss (don't forget to reopen the file)
47289 * - HANDLER_ERROR on stat() failed -> see errno for problem
47291 @@ -348,16 +336,16 @@
47295 -#ifdef DEBUG_STAT_CACHE
47296 +#ifdef DEBUG_STAT_CACHE
47301 splay_tree *file_node = NULL;
47308 * check if the directory for this file has changed
47311 @@ -366,23 +354,23 @@
47312 file_ndx = hashme(name);
47313 sc->files = splaytree_splay(sc->files, file_ndx);
47315 -#ifdef DEBUG_STAT_CACHE
47316 +#ifdef DEBUG_STAT_CACHE
47317 for (i = 0; i < ctrl.used; i++) {
47318 if (ctrl.ptr[i] == file_ndx) break;
47322 if (sc->files && (sc->files->key == file_ndx)) {
47323 -#ifdef DEBUG_STAT_CACHE
47324 +#ifdef DEBUG_STAT_CACHE
47325 /* it was in the cache */
47326 assert(i < ctrl.used);
47329 - /* we have seen this file already and
47331 + /* we have seen this file already and
47332 * don't stat() it again in the same second */
47334 file_node = sc->files;
47337 sce = file_node->data;
47339 /* check if the name is the same, we might have a collision */
47340 @@ -390,7 +378,7 @@
47341 if (buffer_is_equal(name, sce->name)) {
47342 if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_SIMPLE) {
47343 if (sce->stat_ts == srv->cur_ts) {
47346 return HANDLER_GO_ON;
47349 @@ -400,15 +388,15 @@
47350 * file_node is used by the FAM check below to see if we know this file
47351 * and if we can save a stat().
47353 - * BUT, the sce is not reset here as the entry into the cache is ok, we
47354 + * BUT, the sce is not reset here as the entry into the cache is ok, we
47355 * it is just not pointing to our requested file.
47363 -#ifdef DEBUG_STAT_CACHE
47364 +#ifdef DEBUG_STAT_CACHE
47365 if (i != ctrl.used) {
47366 fprintf(stderr, "%s.%d: %08x was already inserted but not found in cache, %s\n", __FILE__, __LINE__, file_ndx, name->ptr);
47368 @@ -424,23 +412,23 @@
47371 dir_ndx = hashme(sc->dir_name);
47374 sc->dirs = splaytree_splay(sc->dirs, dir_ndx);
47377 if (sc->dirs && (sc->dirs->key == dir_ndx)) {
47378 dir_node = sc->dirs;
47382 if (dir_node && file_node) {
47383 /* we found a file */
47386 sce = file_node->data;
47387 fam_dir = dir_node->data;
47390 if (fam_dir->version == sce->dir_version) {
47391 /* the stat()-cache entry is still ok */
47396 return HANDLER_GO_ON;
47399 @@ -448,7 +436,7 @@
47405 * - open() + fstat() on a named-pipe results in a (intended) hang.
47406 * - stat() if regualar file + open() to see if we can read from it is better
47408 @@ -469,16 +457,16 @@
47415 osize = sc->files->size;
47418 sce = stat_cache_entry_init();
47419 buffer_copy_string_buffer(sce->name, name);
47421 - sc->files = splaytree_insert(sc->files, file_ndx, sce);
47422 -#ifdef DEBUG_STAT_CACHE
47424 + sc->files = splaytree_insert(sc->files, file_ndx, sce);
47425 +#ifdef DEBUG_STAT_CACHE
47426 if (ctrl.size == 0) {
47429 @@ -499,29 +487,29 @@
47431 sce->stat_ts = srv->cur_ts;
47433 - /* catch the obvious symlinks
47434 + /* catch the obvious symlinks
47436 * this is not a secure check as we still have a race-condition between
47437 - * the stat() and the open. We can only solve this by
47438 + * the stat() and the open. We can only solve this by
47439 * 1. open() the file
47440 * 2. fstat() the fd
47442 * and keeping the file open for the rest of the time. But this can
47443 * only be done at network level.
47447 if (S_ISLNK(st.st_mode) && !con->conf.follow_symlink) {
47448 return HANDLER_ERROR;
47451 - if (S_ISREG(st.st_mode)) {
47452 + if (S_ISREG(st.st_mode)) {
47453 /* determine mimetype */
47454 buffer_reset(sce->content_type);
47457 for (k = 0; k < con->conf.mimetypes->used; k++) {
47458 data_string *ds = (data_string *)con->conf.mimetypes->data[k];
47459 buffer *type = ds->key;
47462 if (type->used == 0) continue;
47464 /* check if the right side is the same */
47465 @@ -539,7 +527,7 @@
47473 (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM)) {
47474 @@ -549,19 +537,19 @@
47475 fam_dir->fc = sc->fam;
47477 buffer_copy_string_buffer(fam_dir->name, sc->dir_name);
47480 fam_dir->version = 1;
47483 fam_dir->req = calloc(1, sizeof(FAMRequest));
47485 - if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr,
47487 + if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr,
47488 fam_dir->req, fam_dir)) {
47490 - log_error_write(srv, __FILE__, __LINE__, "sbs",
47491 - "monitoring dir failed:",
47494 + log_error_write(srv, __FILE__, __LINE__, "sbs",
47495 + "monitoring dir failed:",
47497 FamErrlist[FAMErrno]);
47500 fam_dir_entry_free(fam_dir);
47503 @@ -570,7 +558,7 @@
47504 osize = sc->dirs->size;
47507 - sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir);
47508 + sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir);
47510 assert(sc->dirs->data == fam_dir);
47511 assert(osize == (sc->dirs->size - 1));
47512 @@ -578,9 +566,9 @@
47514 fam_dir = dir_node->data;
47518 /* bind the fam_fc to the stat() cache entry */
47522 sce->dir_version = fam_dir->version;
47523 sce->dir_ndx = dir_ndx;
47524 @@ -594,11 +582,11 @@
47528 - * remove stat() from cache which havn't been stat()ed for
47529 + * remove stat() from cache which havn't been stat()ed for
47530 * more than 10 seconds
47533 - * walk though the stat-cache, collect the ids which are too old
47535 + * walk though the stat-cache, collect the ids which are too old
47536 * and remove them in a second loop
47539 @@ -639,9 +627,9 @@
47540 sc->files = splaytree_splay(sc->files, ndx);
47545 if (node && (node->key == ndx)) {
47546 -#ifdef DEBUG_STAT_CACHE
47547 +#ifdef DEBUG_STAT_CACHE
47549 int osize = splaytree_size(sc->files);
47550 stat_cache_entry *sce = node->data;
47551 @@ -649,7 +637,7 @@
47552 stat_cache_entry_free(node->data);
47553 sc->files = splaytree_delete(sc->files, ndx);
47555 -#ifdef DEBUG_STAT_CACHE
47556 +#ifdef DEBUG_STAT_CACHE
47557 for (j = 0; j < ctrl.used; j++) {
47558 if (ctrl.ptr[j] == ndx) {
47559 ctrl.ptr[j] = ctrl.ptr[--ctrl.used];
47560 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/stream.c lighttpd-1.4.12/src/stream.c
47561 --- lighttpd-1.4.11/src/stream.c 2005-09-23 21:50:15.000000000 +0300
47562 +++ lighttpd-1.4.12/src/stream.c 2006-07-11 21:23:40.000000000 +0300
47564 #include <sys/types.h>
47565 #include <sys/stat.h>
47567 -#include <unistd.h>
47570 #include "stream.h"
47574 #include "sys-mmap.h"
47575 +#include "sys-files.h"
47578 # define O_BINARY 0
47579 @@ -19,39 +19,39 @@
47583 -#elif defined __WIN32
47584 +#elif defined _WIN32
47592 if (-1 == stat(fn->ptr, &st)) {
47597 f->size = st.st_size;
47600 if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY))) {
47605 f->start = mmap(0, f->size, PROT_READ, MAP_SHARED, fd, 0);
47611 if (MAP_FAILED == f->start) {
47615 -#elif defined __WIN32
47616 - fh = CreateFile(fn->ptr,
47621 - FILE_ATTRIBUTE_READONLY,
47622 +#elif defined _WIN32
47623 + fh = CreateFile(fn->ptr,
47628 + FILE_ATTRIBUTE_READONLY,
47631 if (!fh) return -1;
47636 - FORMAT_MESSAGE_ALLOCATE_BUFFER |
47637 + FORMAT_MESSAGE_ALLOCATE_BUFFER |
47638 FORMAT_MESSAGE_FROM_SYSTEM,
47647 p = MapViewOfFile(mh,
47654 -# error no mmap found
47655 +# error no mmap found
47662 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/sys-mmap.h lighttpd-1.4.12/src/sys-mmap.h
47663 --- lighttpd-1.4.11/src/sys-mmap.h 2005-08-11 01:26:34.000000000 +0300
47664 +++ lighttpd-1.4.12/src/sys-mmap.h 2006-07-11 21:23:40.000000000 +0300
47666 #ifndef WIN32_MMAP_H
47667 #define WIN32_MMAP_H
47672 #define MAP_FAILED -1
47673 #define PROT_SHARED 0
47674 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/src/sys-socket.h lighttpd-1.4.12/src/sys-socket.h
47675 --- lighttpd-1.4.11/src/sys-socket.h 2005-08-11 01:26:39.000000000 +0300
47676 +++ lighttpd-1.4.12/src/sys-socket.h 2006-07-11 21:23:40.000000000 +0300
47678 #ifndef WIN32_SOCKET_H
47679 #define WIN32_SOCKET_H
47684 #include <winsock2.h>
47686 #define ECONNRESET WSAECONNRESET
47687 #define EINPROGRESS WSAEINPROGRESS
47688 #define EALREADY WSAEALREADY
47689 +#define ENOTCONN WSAENOTCONN
47690 +#define EWOULDBLOCK WSAEWOULDBLOCK
47691 #define ioctl ioctlsocket
47692 #define hstrerror(x) ""
47693 +#define STDIN_FILENO 0
47694 +#define STDOUT_FILENO 1
47695 +#define STDERR_FILENO 2
47696 +#define ssize_t int
47698 +int inet_aton(const char *cp, struct in_addr *inp);
47699 +#define HAVE_INET_ADDR
47700 +#undef HAVE_INET_ATON
47703 #include <sys/socket.h>
47704 #include <sys/ioctl.h>
47706 #include <sys/un.h>
47707 #include <arpa/inet.h>
47710 +#define SUN_LEN(su) \
47711 + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
47717 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/LightyTest.pm lighttpd-1.4.12/tests/LightyTest.pm
47718 --- lighttpd-1.4.11/tests/LightyTest.pm 2006-01-14 20:32:31.000000000 +0200
47719 +++ lighttpd-1.4.12/tests/LightyTest.pm 2006-07-11 21:23:42.000000000 +0300
47720 @@ -87,14 +87,14 @@
47721 # pre-process configfile if necessary
47724 - unlink($self->{TESTDIR}."/tmp/cfg.file");
47725 - system("cat ".$self->{SRCDIR}."/".$self->{CONFIGFILE}.' | perl -pe "s#\@SRCDIR\@#'.$self->{BASEDIR}.'/tests/#" > '.$self->{TESTDIR}.'/tmp/cfg.file');
47726 + $ENV{'SRCDIR'} = $self->{BASEDIR}.'/tests';
47727 + $ENV{'PORT'} = $self->{PORT};
47729 unlink($self->{LIGHTTPD_PIDFILE});
47731 - system($self->{LIGHTTPD_PATH}." -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH});
47732 + system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH});
47734 - system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --logfile=foo ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH}." &");
47735 + system("valgrind --tool=memcheck --show-reachable=yes --leak-check=yes --logfile=foo ".$self->{LIGHTTPD_PATH}." -D -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH}." &");
47738 select(undef, undef, undef, 0.1);
47739 @@ -184,7 +184,7 @@
47740 (my $h = $1) =~ tr/[A-Z]/[a-z]/;
47742 if (defined $resp_hdr{$h}) {
47743 - diag(sprintf("header %s is duplicated: %s and %s\n",
47744 + diag(sprintf("header '%s' is duplicated: '%s' and '%s'\n",
47745 $h, $resp_hdr{$h}, $2));
47747 $resp_hdr{$h} = $2;
47748 @@ -196,6 +196,9 @@
47752 + $t->{etag} = $resp_hdr{'etag'};
47753 + $t->{date} = $resp_hdr{'date'};
47756 if (defined $resp_hdr{"content-length"}) {
47757 $resp_body = substr($lines, 0, $resp_hdr{"content-length"});
47758 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/Makefile.am lighttpd-1.4.12/tests/Makefile.am
47759 --- lighttpd-1.4.11/tests/Makefile.am 2005-09-16 15:48:40.000000000 +0300
47760 +++ lighttpd-1.4.12/tests/Makefile.am 2006-07-11 21:23:42.000000000 +0300
47761 @@ -39,10 +39,15 @@
47777 TESTS_ENVIRONMENT=$(srcdir)/wrapper.sh $(srcdir) $(top_builddir)
47778 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/Makefile.in lighttpd-1.4.12/tests/Makefile.in
47779 --- lighttpd-1.4.11/tests/Makefile.in 2006-03-07 14:21:03.000000000 +0200
47780 +++ lighttpd-1.4.12/tests/Makefile.in 2006-07-11 21:48:14.000000000 +0300
47782 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
47783 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
47784 # @configure_input@
47786 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
47788 # PARTICULAR PURPOSE.
47791 -SOURCES = $(fcgi_auth_SOURCES) $(fcgi_responder_SOURCES)
47794 top_srcdir = @top_srcdir@
47797 am__aclocal_m4_deps = $(top_srcdir)/configure.in
47798 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
47800 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
47801 +mkinstalldirs = $(install_sh) -d
47802 CONFIG_HEADER = $(top_builddir)/config.h
47803 CONFIG_CLEAN_FILES =
47804 am__fcgi_auth_SOURCES_DIST = fcgi-auth.c
47806 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
47807 $(AM_CFLAGS) $(CFLAGS)
47809 -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
47810 - $(AM_LDFLAGS) $(LDFLAGS) -o $@
47811 +LINK = $(LIBTOOL) --tag=CC --mode=link "$(CCLD)" $(AM_CFLAGS) \
47812 + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
47813 SOURCES = $(fcgi_auth_SOURCES) $(fcgi_responder_SOURCES)
47814 DIST_SOURCES = $(am__fcgi_auth_SOURCES_DIST) \
47815 $(am__fcgi_responder_SOURCES_DIST)
47816 @@ -134,7 +132,6 @@
47817 LIBTOOL = @LIBTOOL@
47819 LTLIBOBJS = @LTLIBOBJS@
47820 -LUACONFIG = @LUACONFIG@
47821 LUA_CFLAGS = @LUA_CFLAGS@
47822 LUA_LIBS = @LUA_LIBS@
47824 @@ -177,6 +174,7 @@
47825 ac_ct_F77 = @ac_ct_F77@
47826 ac_ct_RANLIB = @ac_ct_RANLIB@
47827 ac_ct_STRIP = @ac_ct_STRIP@
47828 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
47829 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
47830 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
47831 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
47832 @@ -253,10 +251,15 @@
47847 TESTS_ENVIRONMENT = $(srcdir)/wrapper.sh $(srcdir) $(top_builddir)
47848 EXTRA_DIST = wrapper.sh lighttpd.conf \
47849 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/bug-06.conf lighttpd-1.4.12/tests/bug-06.conf
47850 --- lighttpd-1.4.11/tests/bug-06.conf 2005-08-27 17:44:19.000000000 +0300
47851 +++ lighttpd-1.4.12/tests/bug-06.conf 2006-07-11 21:23:41.000000000 +0300
47853 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47854 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
47855 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47856 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
47858 ## bind to port (default: 80)
47862 ## bind to localhost (default: all interfaces)
47863 server.bind = "localhost"
47864 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
47865 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
47866 server.name = "www.example.org"
47867 server.tag = "Apache 1.3.29"
47870 ######################## MODULE CONFIG ############################
47873 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
47874 +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
47876 mimetype.assign = ( ".png" => "image/png",
47877 ".jpg" => "image/jpeg",
47879 ".c" => "text/plain",
47880 ".conf" => "text/plain" )
47882 -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/"
47883 +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
47884 compress.filetype = ("text/plain", "text/html")
47886 setenv.add-environment = ( "TRAC_ENV" => "foo")
47888 "host" => "127.0.0.1",
47890 # "mode" => "authorizer",
47891 -# "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
47892 +# "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
47896 @@ -106,7 +106,7 @@
47897 ssl.pemfile = "server.pem"
47899 auth.backend = "plain"
47900 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
47901 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
47902 auth.backend.plain.groupfile = "lighttpd.group"
47904 auth.backend.ldap.hostname = "localhost"
47905 @@ -149,15 +149,15 @@
47906 status.config-url = "/server-config"
47908 simple-vhost.document-root = "pages"
47909 -simple-vhost.server-root = "@SRCDIR@/tmp/lighttpd/servers/"
47910 +simple-vhost.server-root = env.SRCDIR + "/tmp/lighttpd/servers/"
47911 simple-vhost.default-host = "www.example.org"
47913 $HTTP["host"] == "vvv.example.org" {
47914 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47915 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47918 $HTTP["host"] == "zzz.example.org" {
47919 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47920 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47921 server.name = "zzz.example.org"
47924 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/bug-12.conf lighttpd-1.4.12/tests/bug-12.conf
47925 --- lighttpd-1.4.11/tests/bug-12.conf 2005-08-27 17:44:19.000000000 +0300
47926 +++ lighttpd-1.4.12/tests/bug-12.conf 2006-07-11 21:23:41.000000000 +0300
47928 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47929 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
47930 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47931 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
47933 ## bind to port (default: 80)
47937 ## bind to localhost (default: all interfaces)
47938 server.bind = "localhost"
47939 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
47940 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
47941 server.name = "www.example.org"
47942 server.tag = "Apache 1.3.29"
47945 ######################## MODULE CONFIG ############################
47948 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
47949 +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
47951 mimetype.assign = ( ".png" => "image/png",
47952 ".jpg" => "image/jpeg",
47954 ".c" => "text/plain",
47955 ".conf" => "text/plain" )
47957 -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/"
47958 +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
47959 compress.filetype = ("text/plain", "text/html")
47961 setenv.add-environment = ( "TRAC_ENV" => "foo")
47963 "host" => "127.0.0.1",
47965 # "mode" => "authorizer",
47966 -# "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
47967 +# "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
47971 @@ -108,7 +108,7 @@
47972 ssl.pemfile = "server.pem"
47974 auth.backend = "plain"
47975 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
47976 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
47977 auth.backend.plain.groupfile = "lighttpd.group"
47979 auth.backend.ldap.hostname = "localhost"
47980 @@ -151,15 +151,15 @@
47981 status.config-url = "/server-config"
47983 simple-vhost.document-root = "pages"
47984 -simple-vhost.server-root = "@SRCDIR@/tmp/lighttpd/servers/"
47985 +simple-vhost.server-root = env.SRCDIR + "/tmp/lighttpd/servers/"
47986 simple-vhost.default-host = "www.example.org"
47988 $HTTP["host"] == "vvv.example.org" {
47989 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47990 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47993 $HTTP["host"] == "zzz.example.org" {
47994 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47995 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47996 server.name = "zzz.example.org"
47999 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/cachable.t lighttpd-1.4.12/tests/cachable.t
48000 --- lighttpd-1.4.11/tests/cachable.t 1970-01-01 03:00:00.000000000 +0300
48001 +++ lighttpd-1.4.12/tests/cachable.t 2006-07-11 21:23:41.000000000 +0300
48003 +#!/usr/bin/env perl
48005 + # add current source dir to the include-path
48006 + # we need this for make distcheck
48007 + (my $srcdir = $0) =~ s#/[^/]+$#/#;
48008 + unshift @INC, $srcdir;
48013 +use Test::More tests => 12;
48016 +my $tf = LightyTest->new();
48019 +$tf->{CONFIGFILE} = 'lighttpd.conf';
48021 +ok($tf->start_proc == 0, "Starting lighttpd") or die();
48023 +## check if If-Modified-Since, If-None-Match works
48025 +$t->{REQUEST} = ( <<EOF
48027 +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT
48030 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48031 +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since');
48033 +$t->{REQUEST} = ( <<EOF
48035 +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
48038 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48039 +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since, comment');
48041 +my $now = $t->{date};
48043 +$t->{REQUEST} = ( <<EOF
48045 +If-Modified-Since: $now
48048 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
48049 +ok($tf->handle_http($t) == 0, 'Conditional GET - new If-Modified-Since');
48051 +$t->{REQUEST} = ( <<EOF
48053 +If-Modified-Since: $now; foo
48056 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
48057 +ok($tf->handle_http($t) == 0, 'Conditional GET - new If-Modified-Since, comment');
48059 +$t->{REQUEST} = ( <<EOF
48061 +If-None-Match: foo
48064 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48065 +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match');
48067 +my $etag = $t->{etag};
48069 +$t->{REQUEST} = ( <<EOF
48071 +If-None-Match: $etag
48074 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
48075 +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match');
48077 +$t->{REQUEST} = ( <<EOF
48079 +If-None-Match: $etag
48080 +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
48083 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48084 +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag + old Last-Modified');
48086 +$t->{REQUEST} = ( <<EOF
48088 +If-None-Match: $etag
48089 +If-Modified-Since: $now; foo
48092 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
48093 +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag, Last-Modified + comment');
48095 +$t->{REQUEST} = ( <<EOF
48097 +If-None-Match: Foo
48098 +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
48101 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48102 +ok($tf->handle_http($t) == 0, 'Conditional GET - old ETAG + old Last-Modified');
48104 +$t->{REQUEST} = ( <<EOF
48106 +If-None-Match: $etag
48107 +If-Modified-Since: $now foo
48110 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 412 } ];
48111 +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag + Last-Modified + overlong timestamp');
48113 +ok($tf->stop_proc == 0, "Stopping lighttpd");
48115 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/condition.conf lighttpd-1.4.12/tests/condition.conf
48116 --- lighttpd-1.4.11/tests/condition.conf 2005-08-27 17:44:19.000000000 +0300
48117 +++ lighttpd-1.4.12/tests/condition.conf 2006-07-11 21:23:41.000000000 +0300
48119 debug.log-request-handling = "enable"
48120 debug.log-condition-handling = "enable"
48122 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48123 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48124 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48125 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48127 ## bind to port (default: 80)
48130 ## bind to localhost (default: all interfaces)
48131 server.bind = "localhost"
48132 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48133 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48134 server.name = "www.example.org"
48135 server.tag = "Apache 1.3.29"
48137 @@ -22,25 +22,25 @@
48138 ######################## MODULE CONFIG ############################
48141 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48142 +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48144 mimetype.assign = ( ".html" => "text/html" )
48146 url.redirect = ("^" => "/default")
48148 $HTTP["host"] == "www.example.org" {
48149 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48150 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48151 server.name = "www.example.org"
48152 url.redirect = ("^" => "/match_1")
48154 else $HTTP["host"] == "test1.example.org" {
48155 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48156 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48157 server.name = "test1.example.org"
48158 url.redirect = ("^" => "/match_2")
48161 else $HTTP["host"] == "test2.example.org" {
48162 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48163 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48164 server.name = "test2.example.org"
48165 url.redirect = ("^" => "/match_3")
48170 else $HTTP["host"] == "test3.example.org" {
48171 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48172 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48173 server.name = "test3.example.org"
48174 url.redirect = ("^" => "/match_4")
48176 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/core-keepalive.t lighttpd-1.4.12/tests/core-keepalive.t
48177 --- lighttpd-1.4.11/tests/core-keepalive.t 2005-11-17 15:54:19.000000000 +0200
48178 +++ lighttpd-1.4.12/tests/core-keepalive.t 2006-07-11 21:23:41.000000000 +0300
48181 GET /12345.txt HTTP/1.0
48182 Host: 123.example.org
48183 -Connection: keep-alive
48187 $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48188 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/123/Makefile.in lighttpd-1.4.12/tests/docroot/123/Makefile.in
48189 --- lighttpd-1.4.11/tests/docroot/123/Makefile.in 2006-03-07 14:21:03.000000000 +0200
48190 +++ lighttpd-1.4.12/tests/docroot/123/Makefile.in 2006-07-11 21:48:15.000000000 +0300
48192 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
48193 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
48194 # @configure_input@
48196 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
48198 am__aclocal_m4_deps = $(top_srcdir)/configure.in
48199 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
48201 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
48202 +mkinstalldirs = $(install_sh) -d
48203 CONFIG_HEADER = $(top_builddir)/config.h
48204 CONFIG_CLEAN_FILES =
48206 @@ -100,7 +100,6 @@
48207 LIBTOOL = @LIBTOOL@
48209 LTLIBOBJS = @LTLIBOBJS@
48210 -LUACONFIG = @LUACONFIG@
48211 LUA_CFLAGS = @LUA_CFLAGS@
48212 LUA_LIBS = @LUA_LIBS@
48214 @@ -143,6 +142,7 @@
48215 ac_ct_F77 = @ac_ct_F77@
48216 ac_ct_RANLIB = @ac_ct_RANLIB@
48217 ac_ct_STRIP = @ac_ct_STRIP@
48218 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
48219 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
48220 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
48221 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
48222 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/Makefile.in lighttpd-1.4.12/tests/docroot/Makefile.in
48223 --- lighttpd-1.4.11/tests/docroot/Makefile.in 2006-03-07 14:21:04.000000000 +0200
48224 +++ lighttpd-1.4.12/tests/docroot/Makefile.in 2006-07-11 21:48:15.000000000 +0300
48226 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
48227 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
48228 # @configure_input@
48230 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
48232 am__aclocal_m4_deps = $(top_srcdir)/configure.in
48233 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
48235 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
48236 +mkinstalldirs = $(install_sh) -d
48237 CONFIG_HEADER = $(top_builddir)/config.h
48238 CONFIG_CLEAN_FILES =
48240 @@ -109,7 +109,6 @@
48241 LIBTOOL = @LIBTOOL@
48243 LTLIBOBJS = @LTLIBOBJS@
48244 -LUACONFIG = @LUACONFIG@
48245 LUA_CFLAGS = @LUA_CFLAGS@
48246 LUA_LIBS = @LUA_LIBS@
48248 @@ -152,6 +151,7 @@
48249 ac_ct_F77 = @ac_ct_F77@
48250 ac_ct_RANLIB = @ac_ct_RANLIB@
48251 ac_ct_STRIP = @ac_ct_STRIP@
48252 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
48253 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
48254 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
48255 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
48256 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/Makefile.in lighttpd-1.4.12/tests/docroot/www/Makefile.in
48257 --- lighttpd-1.4.11/tests/docroot/www/Makefile.in 2006-03-07 14:21:05.000000000 +0200
48258 +++ lighttpd-1.4.12/tests/docroot/www/Makefile.in 2006-07-11 21:48:15.000000000 +0300
48260 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
48261 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
48262 # @configure_input@
48264 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
48266 am__aclocal_m4_deps = $(top_srcdir)/configure.in
48267 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
48269 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
48270 +mkinstalldirs = $(install_sh) -d
48271 CONFIG_HEADER = $(top_builddir)/config.h
48272 CONFIG_CLEAN_FILES =
48274 @@ -109,7 +109,6 @@
48275 LIBTOOL = @LIBTOOL@
48277 LTLIBOBJS = @LTLIBOBJS@
48278 -LUACONFIG = @LUACONFIG@
48279 LUA_CFLAGS = @LUA_CFLAGS@
48280 LUA_LIBS = @LUA_LIBS@
48282 @@ -152,6 +151,7 @@
48283 ac_ct_F77 = @ac_ct_F77@
48284 ac_ct_RANLIB = @ac_ct_RANLIB@
48285 ac_ct_STRIP = @ac_ct_STRIP@
48286 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
48287 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
48288 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
48289 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
48290 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries
48291 --- lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries 2006-03-09 19:21:49.000000000 +0200
48292 +++ lighttpd-1.4.12/tests/docroot/www/dummydir/.svn/entries 2006-07-11 21:23:41.000000000 +0300
48296 uuid="152afb58-edef-0310-8abb-c4023f1b3aa9"
48297 - revision="1040"/>
48298 + repos="svn://svn.lighttpd.net/lighttpd"
48299 + revision="1159"/>
48301 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/expire/Makefile.in lighttpd-1.4.12/tests/docroot/www/expire/Makefile.in
48302 --- lighttpd-1.4.11/tests/docroot/www/expire/Makefile.in 2006-03-07 14:21:05.000000000 +0200
48303 +++ lighttpd-1.4.12/tests/docroot/www/expire/Makefile.in 2006-07-11 21:48:15.000000000 +0300
48305 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
48306 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
48307 # @configure_input@
48309 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
48311 am__aclocal_m4_deps = $(top_srcdir)/configure.in
48312 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
48314 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
48315 +mkinstalldirs = $(install_sh) -d
48316 CONFIG_HEADER = $(top_builddir)/config.h
48317 CONFIG_CLEAN_FILES =
48319 @@ -100,7 +100,6 @@
48320 LIBTOOL = @LIBTOOL@
48322 LTLIBOBJS = @LTLIBOBJS@
48323 -LUACONFIG = @LUACONFIG@
48324 LUA_CFLAGS = @LUA_CFLAGS@
48325 LUA_LIBS = @LUA_LIBS@
48327 @@ -143,6 +142,7 @@
48328 ac_ct_F77 = @ac_ct_F77@
48329 ac_ct_RANLIB = @ac_ct_RANLIB@
48330 ac_ct_STRIP = @ac_ct_STRIP@
48331 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
48332 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
48333 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
48334 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
48335 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/go/Makefile.in lighttpd-1.4.12/tests/docroot/www/go/Makefile.in
48336 --- lighttpd-1.4.11/tests/docroot/www/go/Makefile.in 2006-03-07 14:21:06.000000000 +0200
48337 +++ lighttpd-1.4.12/tests/docroot/www/go/Makefile.in 2006-07-11 21:48:16.000000000 +0300
48339 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
48340 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
48341 # @configure_input@
48343 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
48345 am__aclocal_m4_deps = $(top_srcdir)/configure.in
48346 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
48348 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
48349 +mkinstalldirs = $(install_sh) -d
48350 CONFIG_HEADER = $(top_builddir)/config.h
48351 CONFIG_CLEAN_FILES =
48353 @@ -100,7 +100,6 @@
48354 LIBTOOL = @LIBTOOL@
48356 LTLIBOBJS = @LTLIBOBJS@
48357 -LUACONFIG = @LUACONFIG@
48358 LUA_CFLAGS = @LUA_CFLAGS@
48359 LUA_LIBS = @LUA_LIBS@
48361 @@ -143,6 +142,7 @@
48362 ac_ct_F77 = @ac_ct_F77@
48363 ac_ct_RANLIB = @ac_ct_RANLIB@
48364 ac_ct_STRIP = @ac_ct_STRIP@
48365 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
48366 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
48367 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
48368 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
48369 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/docroot/www/indexfile/Makefile.in lighttpd-1.4.12/tests/docroot/www/indexfile/Makefile.in
48370 --- lighttpd-1.4.11/tests/docroot/www/indexfile/Makefile.in 2006-03-07 14:21:07.000000000 +0200
48371 +++ lighttpd-1.4.12/tests/docroot/www/indexfile/Makefile.in 2006-07-11 21:48:16.000000000 +0300
48373 -# Makefile.in generated by automake 1.9.5 from Makefile.am.
48374 +# Makefile.in generated by automake 1.9.6 from Makefile.am.
48375 # @configure_input@
48377 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
48379 am__aclocal_m4_deps = $(top_srcdir)/configure.in
48380 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
48382 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
48383 +mkinstalldirs = $(install_sh) -d
48384 CONFIG_HEADER = $(top_builddir)/config.h
48385 CONFIG_CLEAN_FILES =
48387 @@ -100,7 +100,6 @@
48388 LIBTOOL = @LIBTOOL@
48390 LTLIBOBJS = @LTLIBOBJS@
48391 -LUACONFIG = @LUACONFIG@
48392 LUA_CFLAGS = @LUA_CFLAGS@
48393 LUA_LIBS = @LUA_LIBS@
48395 @@ -143,6 +142,7 @@
48396 ac_ct_F77 = @ac_ct_F77@
48397 ac_ct_RANLIB = @ac_ct_RANLIB@
48398 ac_ct_STRIP = @ac_ct_STRIP@
48399 +ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
48400 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
48401 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
48402 am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
48403 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fastcgi-10.conf lighttpd-1.4.12/tests/fastcgi-10.conf
48404 --- lighttpd-1.4.11/tests/fastcgi-10.conf 2005-08-31 23:36:34.000000000 +0300
48405 +++ lighttpd-1.4.12/tests/fastcgi-10.conf 2006-07-11 21:23:41.000000000 +0300
48407 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48408 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48409 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48410 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48412 ## bind to port (default: 80)
48415 ## bind to localhost (default: all interfaces)
48416 server.bind = "localhost"
48417 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48418 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48419 server.name = "www.example.org"
48420 server.tag = "Apache 1.3.29"
48423 ######################## MODULE CONFIG ############################
48426 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48427 +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48429 mimetype.assign = ( ".png" => "image/png",
48430 ".jpg" => "image/jpeg",
48432 ".c" => "text/plain",
48433 ".conf" => "text/plain" )
48435 -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48436 +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48437 compress.filetype = ("text/plain", "text/html")
48441 ssl.pemfile = "server.pem"
48443 auth.backend = "plain"
48444 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48445 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48446 auth.backend.plain.groupfile = "lighttpd.group"
48448 auth.backend.ldap.hostname = "localhost"
48449 @@ -128,11 +128,11 @@
48450 status.config-url = "/server-config"
48452 $HTTP["host"] == "vvv.example.org" {
48453 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48454 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48457 $HTTP["host"] == "zzz.example.org" {
48458 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48459 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48460 server.name = "zzz.example.org"
48463 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fastcgi-13.conf lighttpd-1.4.12/tests/fastcgi-13.conf
48464 --- lighttpd-1.4.11/tests/fastcgi-13.conf 2006-01-03 12:38:17.000000000 +0200
48465 +++ lighttpd-1.4.12/tests/fastcgi-13.conf 2006-07-11 21:23:41.000000000 +0300
48467 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48468 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48469 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48470 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48472 debug.log-request-header = "enable"
48473 debug.log-response-header = "enable"
48476 ## bind to localhost (default: all interfaces)
48477 server.bind = "localhost"
48478 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48479 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48480 server.name = "www.example.org"
48481 server.tag = "Apache 1.3.29"
48484 ######################## MODULE CONFIG ############################
48487 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48488 +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48490 mimetype.assign = ( ".png" => "image/png",
48491 ".jpg" => "image/jpeg",
48493 ".c" => "text/plain",
48494 ".conf" => "text/plain" )
48496 -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48497 +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48498 compress.filetype = ("text/plain", "text/html")
48501 @@ -102,7 +102,7 @@
48502 ssl.pemfile = "server.pem"
48504 auth.backend = "plain"
48505 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48506 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48507 auth.backend.plain.groupfile = "lighttpd.group"
48509 auth.backend.ldap.hostname = "localhost"
48510 @@ -145,11 +145,11 @@
48511 status.config-url = "/server-config"
48513 $HTTP["host"] == "vvv.example.org" {
48514 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48515 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48518 $HTTP["host"] == "zzz.example.org" {
48519 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48520 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48521 server.name = "zzz.example.org"
48524 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fastcgi-auth.conf lighttpd-1.4.12/tests/fastcgi-auth.conf
48525 --- lighttpd-1.4.11/tests/fastcgi-auth.conf 2005-08-27 17:44:19.000000000 +0300
48526 +++ lighttpd-1.4.12/tests/fastcgi-auth.conf 2006-07-11 21:23:42.000000000 +0300
48528 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48529 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48530 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48531 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48533 debug.log-request-header = "enable"
48534 debug.log-response-header = "enable"
48537 ## bind to localhost (default: all interfaces)
48538 server.bind = "localhost"
48539 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48540 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48541 server.name = "www.example.org"
48542 server.tag = "Apache 1.3.29"
48545 ######################## MODULE CONFIG ############################
48548 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48549 +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48551 mimetype.assign = ( ".png" => "image/png",
48552 ".jpg" => "image/jpeg",
48554 ".c" => "text/plain",
48555 ".conf" => "text/plain" )
48557 -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48558 +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48559 compress.filetype = ("text/plain", "text/html")
48564 "host" => "127.0.0.1",
48566 - "bin-path" => "@SRCDIR@/fcgi-auth",
48567 + "bin-path" => env.SRCDIR + "/fcgi-auth",
48568 "mode" => "authorizer",
48569 - "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
48570 + "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
48574 @@ -106,7 +106,7 @@
48575 ssl.pemfile = "server.pem"
48577 auth.backend = "plain"
48578 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48579 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48580 auth.backend.plain.groupfile = "lighttpd.group"
48582 auth.backend.ldap.hostname = "localhost"
48583 @@ -149,11 +149,11 @@
48584 status.config-url = "/server-config"
48586 $HTTP["host"] == "vvv.example.org" {
48587 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48588 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48591 $HTTP["host"] == "zzz.example.org" {
48592 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48593 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48594 server.name = "zzz.example.org"
48597 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fastcgi-responder.conf lighttpd-1.4.12/tests/fastcgi-responder.conf
48598 --- lighttpd-1.4.11/tests/fastcgi-responder.conf 2005-08-27 17:44:19.000000000 +0300
48599 +++ lighttpd-1.4.12/tests/fastcgi-responder.conf 2006-07-11 21:23:41.000000000 +0300
48601 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48602 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48603 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48604 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48606 #debug.log-request-header = "enable"
48607 #debug.log-response-header = "enable"
48610 ## bind to localhost (default: all interfaces)
48611 server.bind = "localhost"
48612 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48613 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48614 server.name = "www.example.org"
48615 server.tag = "Apache 1.3.29"
48618 ######################## MODULE CONFIG ############################
48621 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48622 +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48624 mimetype.assign = ( ".png" => "image/png",
48625 ".jpg" => "image/jpeg",
48627 ".c" => "text/plain",
48628 ".conf" => "text/plain" )
48630 -compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48631 +compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48632 compress.filetype = ("text/plain", "text/html")
48635 @@ -90,10 +90,11 @@
48637 "host" => "127.0.0.1",
48639 - "bin-path" => "@SRCDIR@/fcgi-responder",
48640 + "bin-path" => env.SRCDIR + "/fcgi-responder",
48641 "check-local" => "disable",
48644 + "min-procs" => 1,
48645 + "allow-x-send-file" => "enable",
48649 @@ -109,7 +110,7 @@
48650 ssl.pemfile = "server.pem"
48652 auth.backend = "plain"
48653 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48654 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48655 auth.backend.plain.groupfile = "lighttpd.group"
48657 auth.backend.ldap.hostname = "localhost"
48658 @@ -152,11 +153,11 @@
48659 status.config-url = "/server-config"
48661 $HTTP["host"] == "vvv.example.org" {
48662 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48663 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48666 $HTTP["host"] == "zzz.example.org" {
48667 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48668 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48669 server.name = "zzz.example.org"
48672 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/fcgi-responder.c lighttpd-1.4.12/tests/fcgi-responder.c
48673 --- lighttpd-1.4.11/tests/fcgi-responder.c 2005-08-11 01:26:55.000000000 +0300
48674 +++ lighttpd-1.4.12/tests/fcgi-responder.c 2006-07-11 21:23:41.000000000 +0300
48677 int num_requests = 2;
48679 - while (num_requests > 0 &&
48680 - FCGI_Accept() >= 0) {
48683 - if (NULL != (p = getenv("QUERY_STRING"))) {
48684 + while (num_requests > 0 && FCGI_Accept() >= 0) {
48686 + char* doc_root = NULL;
48687 + char fname[4096];
48688 + char* pfname = (char *)fname;
48690 + doc_root = getenv("DOCUMENT_ROOT");
48691 + p = getenv("QUERY_STRING");
48693 + if (NULL != p && NULL != doc_root) {
48694 + snprintf(pfname, sizeof(fname), "%s/phpinfo.php", doc_root);
48695 if (0 == strcmp(p, "lf")) {
48696 printf("Status: 200 OK\n\n");
48697 } else if (0 == strcmp(p, "crlf")) {
48699 printf("Status: 200 OK\r\n");
48702 + } else if (0 == strcmp(p,"x-lighttpd-send-file")) {
48703 + printf("Status: 200 OK\r\n");
48704 + printf("X-LIGHTTPD-send-file: %s\r\n", pfname);
48706 + } else if (0 == strcmp(p,"xsendfile")) {
48707 + printf("Status: 200 OK\r\n");
48708 + printf("X-Sendfile: %s\r\n", pfname);
48710 + } else if (0 == strcmp(p,"xsendfile-mixed-case")) {
48711 + printf("Status: 200 OK\r\n");
48712 + printf("X-SeNdFiLe: %s\r\n", pfname);
48714 } else if (0 == strcmp(p, "die-at-end")) {
48715 printf("Status: 200 OK\r\n\r\n");
48717 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/lighttpd.conf lighttpd-1.4.12/tests/lighttpd.conf
48718 --- lighttpd-1.4.11/tests/lighttpd.conf 2006-03-09 15:26:58.000000000 +0200
48719 +++ lighttpd-1.4.12/tests/lighttpd.conf 2006-07-11 21:23:41.000000000 +0300
48721 -debug.log-request-handling = "enable"
48722 -debug.log-condition-handling = "enable"
48723 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48724 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48725 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48726 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48727 +server.tag = "Apache 1.3.29"
48729 ## 64 Mbyte ... nice limit
48730 server.max-request-size = 65000
48732 -## bind to port (default: 80)
48733 -server.port = 2048
48734 +include "default.conf"
48736 -## bind to localhost (default: all interfaces)
48737 -server.bind = "localhost"
48738 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48739 -server.name = "www.example.org"
48740 -server.tag = "Apache 1.3.29"
48742 -server.dir-listing = "enable"
48744 -#server.event-handler = "linux-sysepoll"
48745 -#server.event-handler = "linux-rtsig"
48747 -#server.modules.path = ""
48748 -server.modules = (
48751 - "mod_secdownload",
48757 - "mod_simple_vhost",
48760 -# "mod_localizer",
48766 - "mod_accesslog" )
48768 -server.indexfiles = ( "index.php", "index.html",
48769 - "index.htm", "default.htm" )
48772 -######################## MODULE CONFIG ############################
48774 -ssi.extension = ( ".shtml" )
48776 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48778 -mimetype.assign = ( ".png" => "image/png",
48779 - ".jpg" => "image/jpeg",
48780 - ".jpeg" => "image/jpeg",
48781 - ".gif" => "image/gif",
48782 - ".html" => "text/html",
48783 - ".htm" => "text/html",
48784 - ".pdf" => "application/pdf",
48785 - ".swf" => "application/x-shockwave-flash",
48786 - ".spl" => "application/futuresplash",
48787 - ".txt" => "text/plain",
48788 - ".tar.gz" => "application/x-tgz",
48789 - ".tgz" => "application/x-tgz",
48790 - ".gz" => "application/x-gzip",
48791 - ".c" => "text/plain",
48792 - ".conf" => "text/plain" )
48793 +setenv.add-request-header = ( "FOO" => "foo")
48794 +setenv.add-response-header = ( "BAR" => "foo")
48796 $HTTP["host"] == "cache.example.org" {
48797 - compress.cache-dir = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48798 + compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48800 -compress.filetype = ("text/plain", "text/html")
48802 -setenv.add-environment = ( "TRAC_ENV" => "tracenv", "SETENV" => "setenv")
48803 -setenv.add-request-header = ( "FOO" => "foo")
48804 -setenv.add-response-header = ( "BAR" => "foo")
48806 $HTTP["url"] =~ "\.pdf$" {
48807 server.range-requests = "disable"
48808 @@ -85,76 +23,31 @@
48809 "/prefix.fcgi" => ( ( "host" => "127.0.0.1", "port" => 1026, "check-local" => "disable", "broken-scriptfilename" => "enable" ) )
48813 -cgi.assign = ( ".pl" => "/usr/bin/perl",
48814 - ".cgi" => "/usr/bin/perl",
48815 - ".py" => "/usr/bin/python" )
48817 -userdir.include-user = ( "jan" )
48818 -userdir.path = "/"
48820 -ssl.engine = "disable"
48821 -ssl.pemfile = "server.pem"
48823 $HTTP["host"] == "auth-htpasswd.example.org" {
48824 auth.backend = "htpasswd"
48827 -auth.backend = "plain"
48828 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48830 -auth.backend.htpasswd.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.htpasswd"
48833 -auth.require = ( "/server-status" =>
48835 - "method" => "digest",
48836 - "realm" => "download archiv",
48837 - "require" => "group=www|user=jan|host=192.168.2.10"
48839 - "/server-config" =>
48841 - "method" => "basic",
48842 - "realm" => "download archiv",
48843 - "require" => "valid-user"
48847 -url.access-deny = ( "~", ".inc")
48849 -url.rewrite = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1",
48850 - "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" )
48852 -expire.url = ( "/expire/access" => "access 2 hours",
48853 - "/expire/modification" => "access plus 1 seconds 2 minutes")
48855 -#cache.cache-dir = "/home/weigon/wwwroot/cache/"
48857 -#### status module
48858 -status.status-url = "/server-status"
48859 -status.config-url = "/server-config"
48861 $HTTP["host"] == "vvv.example.org" {
48862 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48863 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48864 secdownload.secret = "verysecret"
48865 - secdownload.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48866 + secdownload.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48867 secdownload.uri-prefix = "/sec/"
48868 secdownload.timeout = 120
48871 $HTTP["host"] == "zzz.example.org" {
48872 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48873 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48874 server.name = "zzz.example.org"
48877 $HTTP["host"] == "no-simple.example.org" {
48878 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/123.example.org/pages/"
48879 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/123.example.org/pages/"
48880 server.name = "zzz.example.org"
48883 $HTTP["host"] !~ "(no-simple\.example\.org)" {
48884 simple-vhost.document-root = "pages"
48885 - simple-vhost.server-root = "@SRCDIR@/tmp/lighttpd/servers/"
48886 + simple-vhost.server-root = env.SRCDIR + "/tmp/lighttpd/servers/"
48887 simple-vhost.default-host = "www.example.org"
48890 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/lowercase.conf lighttpd-1.4.12/tests/lowercase.conf
48891 --- lighttpd-1.4.11/tests/lowercase.conf 1970-01-01 03:00:00.000000000 +0300
48892 +++ lighttpd-1.4.12/tests/lowercase.conf 2006-07-11 21:23:41.000000000 +0300
48894 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48895 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48897 +## bind to port (default: 80)
48898 +server.port = 2048
48900 +## bind to localhost (default: all interfaces)
48901 +server.bind = "localhost"
48902 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48904 +server.force-lowercase-filenames = "enable"
48906 +server.dir-listing = "enable"
48908 +server.modules = (
48911 + "mod_secdownload",
48920 +server.indexfiles = ( "index.php", "index.html",
48921 + "index.htm", "default.htm" )
48924 +######################## MODULE CONFIG ############################
48926 +mimetype.assign = ( ".png" => "image/png",
48927 + ".jpg" => "image/jpeg",
48928 + ".jpeg" => "image/jpeg",
48929 + ".gif" => "image/gif",
48930 + ".html" => "text/html",
48931 + ".htm" => "text/html",
48932 + ".pdf" => "application/pdf",
48933 + ".swf" => "application/x-shockwave-flash",
48934 + ".spl" => "application/futuresplash",
48935 + ".txt" => "text/plain",
48936 + ".tar.gz" => "application/x-tgz",
48937 + ".tgz" => "application/x-tgz",
48938 + ".gz" => "application/x-gzip",
48939 + ".c" => "text/plain",
48940 + ".conf" => "text/plain" )
48943 +fastcgi.server = ( ".php" => ( ( "host" => "127.0.0.1", "port" => 1026, "broken-scriptfilename" => "enable" ) ),
48944 + "/prefix.fcgi" => ( ( "host" => "127.0.0.1", "port" => 1026, "check-local" => "disable", "broken-scriptfilename" => "enable" ) )
48948 +cgi.assign = ( ".pl" => "/usr/bin/perl",
48949 + ".cgi" => "/usr/bin/perl",
48950 + ".py" => "/usr/bin/python" )
48952 +auth.backend = "plain"
48953 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48955 +auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd"
48957 +$HTTP["host"] == "lowercase-auth" {
48958 + auth.require = ( "/image.jpg" =>
48960 + "method" => "digest",
48961 + "realm" => "download archiv",
48962 + "require" => "valid-user"
48967 +$HTTP["host"] == "lowercase-deny" {
48968 + url.access-deny = ( ".jpg")
48971 +$HTTP["host"] == "lowercase-exclude" {
48972 + static-file.exclude-extensions = ( ".jpg" )
48974 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/lowercase.t lighttpd-1.4.12/tests/lowercase.t
48975 --- lighttpd-1.4.11/tests/lowercase.t 1970-01-01 03:00:00.000000000 +0300
48976 +++ lighttpd-1.4.12/tests/lowercase.t 2006-07-11 21:23:41.000000000 +0300
48978 +#!/usr/bin/env perl
48980 + # add current source dir to the include-path
48981 + # we need this for make distcheck
48982 + (my $srcdir = $0) =~ s#/[^/]+$#/#;
48983 + unshift @INC, $srcdir;
48988 +use Test::More tests => 10;
48991 +my $tf = LightyTest->new();
48994 +$tf->{CONFIGFILE} = 'lowercase.conf';
48996 +ok($tf->start_proc == 0, "Starting lighttpd") or die();
48998 +## check if lower-casing works
49000 +$t->{REQUEST} = ( <<EOF
49001 +GET /image.JPG HTTP/1.0
49004 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
49005 +ok($tf->handle_http($t) == 0, 'uppercase access');
49007 +$t->{REQUEST} = ( <<EOF
49008 +GET /image.jpg HTTP/1.0
49011 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
49012 +ok($tf->handle_http($t) == 0, 'lowercase access');
49014 +## check that mod-auth works
49016 +$t->{REQUEST} = ( <<EOF
49017 +GET /image.JPG HTTP/1.0
49018 +Host: lowercase-auth
49021 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
49022 +ok($tf->handle_http($t) == 0, 'uppercase access');
49024 +$t->{REQUEST} = ( <<EOF
49025 +GET /image.jpg HTTP/1.0
49026 +Host: lowercase-auth
49029 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
49030 +ok($tf->handle_http($t) == 0, 'lowercase access');
49033 +## check that mod-staticfile exclude works
49034 +$t->{REQUEST} = ( <<EOF
49035 +GET /image.JPG HTTP/1.0
49036 +Host: lowercase-exclude
49039 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
49040 +ok($tf->handle_http($t) == 0, 'upper case access to staticfile.exclude-extension');
49042 +$t->{REQUEST} = ( <<EOF
49043 +GET /image.jpg HTTP/1.0
49044 +Host: lowercase-exclude
49047 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
49048 +ok($tf->handle_http($t) == 0, 'lowercase access');
49051 +## check that mod-access exclude works
49052 +$t->{REQUEST} = ( <<EOF
49053 +GET /image.JPG HTTP/1.0
49054 +Host: lowercase-deny
49057 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
49058 +ok($tf->handle_http($t) == 0, 'uppercase access to url.access-deny protected location');
49060 +$t->{REQUEST} = ( <<EOF
49061 +GET /image.jpg HTTP/1.0
49062 +Host: lowercase-deny
49065 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
49066 +ok($tf->handle_http($t) == 0, 'lowercase access');
49070 +ok($tf->stop_proc == 0, "Stopping lighttpd");
49072 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/mod-fastcgi.t lighttpd-1.4.12/tests/mod-fastcgi.t
49073 --- lighttpd-1.4.11/tests/mod-fastcgi.t 2006-03-09 15:30:45.000000000 +0200
49074 +++ lighttpd-1.4.12/tests/mod-fastcgi.t 2006-07-11 21:23:41.000000000 +0300
49079 -use Test::More tests => 47;
49080 +use Test::More tests => 49;
49083 my $tf = LightyTest->new();
49088 - skip "no PHP running on port 1026", 30 unless $tf->listening_on(1026);
49089 + skip "no PHP running on port 1026", 29 unless $tf->listening_on(1026);
49091 ok($tf->start_proc == 0, "Starting lighttpd") or die();
49093 @@ -223,7 +223,7 @@
49097 - skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php";
49098 + skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php";
49099 $tf->{CONFIGFILE} = 'fastcgi-13.conf';
49100 ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die();
49101 $t->{REQUEST} = ( <<EOF
49102 @@ -285,6 +285,34 @@
49103 $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'test123' } ];
49104 ok($tf->handle_http($t) == 0, 'line-ending \r\n + \r\n');
49106 + # X-LIGHTTPD-send-file
49107 + $t->{REQUEST} = ( <<EOF
49108 +GET /index.fcgi?x-lighttpd-send-file HTTP/1.0
49109 +Host: www.example.org
49112 + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
49114 + ok($tf->handle_http($t) == 0, 'X-LIGHTTPD-send-file');
49116 + $t->{REQUEST} = ( <<EOF
49117 +GET /index.fcgi?xsendfile HTTP/1.0
49118 +Host: www.example.org
49121 + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
49123 + ok($tf->handle_http($t) == 0, 'X-Sendfile');
49125 + $t->{REQUEST} = ( <<EOF
49126 +GET /index.fcgi?xsendfile-mixed-case HTTP/1.0
49127 +Host: www.example.org
49130 + $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
49132 + ok($tf->handle_http($t) == 0, 'X-SeNdFiLe in mixed case');
49134 $t->{REQUEST} = ( <<EOF
49135 GET /index.fcgi?die-at-end HTTP/1.0
49136 Host: www.example.org
49137 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/mod-proxy.t lighttpd-1.4.12/tests/mod-proxy.t
49138 --- lighttpd-1.4.11/tests/mod-proxy.t 1970-01-01 03:00:00.000000000 +0300
49139 +++ lighttpd-1.4.12/tests/mod-proxy.t 2006-07-11 21:23:41.000000000 +0300
49141 +#!/usr/bin/env perl
49143 + # add current source dir to the include-path
49144 + # we need this for make distcheck
49145 + (my $srcdir = $0) =~ s#/[^/]+$#/#;
49146 + unshift @INC, $srcdir;
49151 +use Test::More tests => 21;
49154 +my $tf_proxy = LightyTest->new();
49155 +my $tf_backend1 = LightyTest->new();
49156 +my $tf_backend2 = LightyTest->new();
49160 +## we need two procs
49161 +## 1. the real webserver
49162 +## 2. the proxy server
49164 +$tf_proxy->{PORT} = 2048;
49165 +$tf_proxy->{CONFIGFILE} = 'proxy.conf';
49166 +$tf_proxy->{LIGHTTPD_PIDFILE} = $tf_proxy->{SRCDIR}.'/tmp/lighttpd/lighttpd-proxy.pid';
49168 +$tf_backend1->{PORT} = 2050;
49169 +$tf_backend1->{CONFIGFILE} = 'proxy-backend-1.conf';
49170 +$tf_backend1->{LIGHTTPD_PIDFILE} = $tf_backend1->{SRCDIR}.'/tmp/lighttpd/lighttpd-backend-1.pid';
49172 +$tf_backend2->{PORT} = 2051;
49173 +$tf_backend2->{CONFIGFILE} = 'proxy-backend-2.conf';
49174 +$tf_backend2->{LIGHTTPD_PIDFILE} = $tf_backend2->{SRCDIR}.'/tmp/lighttpd/lighttpd-backend-2.pid';
49177 +ok($tf_backend1->start_proc == 0, "Starting lighttpd") or die();
49179 +ok($tf_proxy->start_proc == 0, "Starting lighttpd as proxy") or die();
49183 +$t->{REQUEST} = ( <<EOF
49184 +GET /index.html HTTP/1.0
49185 +Host: www.example.org
49188 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
49189 +ok($tf_proxy->handle_http($t) == 0, 'valid request');
49191 +$t->{REQUEST} = ( <<EOF
49192 +GET /index.html HTTP/1.0
49193 +Host: www.example.org
49196 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Server' => 'proxy-backend-1' } ];
49197 +ok($tf_proxy->handle_http($t) == 0, 'drop Server from real server');
49199 +$t->{REQUEST} = ( <<EOF
49200 +GET /balance-rr/foo HTTP/1.0
49201 +Host: www.example.org
49204 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
49205 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - one backend');
49207 +$t->{REQUEST} = ( <<EOF
49208 +GET /balance-rr/foo HTTP/1.0
49209 +Host: www.example.org
49212 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
49213 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - one host down, failover');
49215 +$t->{REQUEST} = ( <<EOF
49216 +GET /balance-fair/foo HTTP/1.0
49217 +Host: www.example.org
49220 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
49221 +ok($tf_proxy->handle_http($t) == 0, 'balance fair - one backend');
49223 +## backend 2 starting
49224 +ok($tf_backend2->start_proc == 0, "Starting second proxy backend") or die();
49226 +$t->{REQUEST} = ( <<EOF
49227 +GET /balance-rr/foo HTTP/1.0
49228 +Host: www.example.org
49231 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
49232 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - lb, backend 1');
49234 +$t->{REQUEST} = ( <<EOF
49235 +GET /balance-rr/foo HTTP/1.0
49236 +Host: www.example.org
49239 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
49240 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - lb, backend 2');
49242 +$t->{REQUEST} = ( <<EOF
49243 +GET /balance-hash/foo HTTP/1.0
49244 +Host: www.example.org
49247 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
49248 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 1');
49250 +$t->{REQUEST} = ( <<EOF
49251 +GET /balance-hash/foo HTTP/1.0
49252 +Host: www.example.org
49255 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
49256 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 1 - same URL');
49258 +$t->{REQUEST} = ( <<EOF
49259 +GET /balance-hash/bar HTTP/1.0
49260 +Host: www.example.org
49263 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
49264 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 2');
49266 +$t->{REQUEST} = ( <<EOF
49267 +GET /balance-hash/bar HTTP/1.0
49268 +Host: www.example.org
49271 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
49272 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 2 - same URL');
49274 +## backend 1 stopping, failover
49275 +ok($tf_backend1->stop_proc == 0, "Stopping backend 1");
49277 +$t->{REQUEST} = ( <<EOF
49278 +GET /balance-hash/foo HTTP/1.0
49279 +Host: www.example.org
49282 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
49283 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - failover to backend 2');
49285 +$t->{REQUEST} = ( <<EOF
49286 +GET /balance-hash/bar HTTP/1.0
49287 +Host: www.example.org
49290 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
49291 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - failover to backend 2 - same URL');
49293 +$t->{REQUEST} = ( <<EOF
49294 +GET /balance-rr/foo HTTP/1.0
49295 +Host: www.example.org
49298 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
49299 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - failover to backend 2');
49301 +$t->{REQUEST} = ( <<EOF
49302 +GET /balance-fair/foo HTTP/1.0
49303 +Host: www.example.org
49306 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
49307 +ok($tf_proxy->handle_http($t) == 0, 'balance fair - failover to backend 2');
49310 +ok($tf_backend2->stop_proc == 0, "Stopping lighttpd");
49312 +ok($tf_proxy->stop_proc == 0, "Stopping lighttpd proxy");
49314 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/proxy.conf lighttpd-1.4.12/tests/proxy.conf
49315 --- lighttpd-1.4.11/tests/proxy.conf 1970-01-01 03:00:00.000000000 +0300
49316 +++ lighttpd-1.4.12/tests/proxy.conf 2006-07-11 21:23:42.000000000 +0300
49318 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
49319 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd-proxy.pid"
49320 +server.tag = "proxy"
49322 +include "default.conf"
49324 +## 127.0.0.1 and 127.0.0.2 are the same host
49326 + "" => (( "host" => "127.0.0.1",
49327 + "port" => 2050 ),
49328 + ( "host" => "127.0.0.2",
49332 +$HTTP["url"] =~ "^/balance-rr/" {
49333 + proxy.balance = "round-robin"
49336 +$HTTP["url"] =~ "^/balance-hash/" {
49337 + proxy.balance = "hash"
49340 +$HTTP["url"] =~ "^/balance-fair/" {
49341 + proxy.balance = "fair"
49344 diff -ur -x '*.m4' -x compile -x 'config.*' -x configure -x depcomp -N -x missing -x 'ltmain*' -x install-sh -x mkinstalldirs lighttpd-1.4.11/tests/var-include.conf lighttpd-1.4.12/tests/var-include.conf
49345 --- lighttpd-1.4.11/tests/var-include.conf 2005-08-27 17:44:19.000000000 +0300
49346 +++ lighttpd-1.4.12/tests/var-include.conf 2006-07-11 21:23:41.000000000 +0300
49348 debug.log-request-handling = "enable"
49349 debug.log-condition-handling = "enable"
49351 -server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
49352 -server.pid-file = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
49353 +server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
49354 +server.pid-file = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
49356 ## bind to port (default: 80)
49359 ## bind to localhost (default: all interfaces)
49360 server.bind = "localhost"
49361 -server.errorlog = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
49362 +server.errorlog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
49363 server.name = "www.example.org"
49364 server.tag = "Apache 1.3.29"
49366 @@ -21,19 +21,19 @@
49367 ######################## MODULE CONFIG ############################
49370 -accesslog.filename = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
49371 +accesslog.filename = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
49373 mimetype.assign = ( ".html" => "text/html" )
49375 url.redirect = ("^" => "/default")
49377 $HTTP["host"] == "www.example.org" {
49378 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
49379 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
49380 server.name = "www.example.org"
49381 url.redirect = ("^" => "/redirect")
49383 $HTTP["host"] == "test.example.org" {
49384 - server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
49385 + server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
49386 server.name = "test.example.org"