]> git.pld-linux.org Git - packages/lighttpd.git/blob - lighttpd-branch.diff
- not all files in tarball, so branch diff has no use
[packages/lighttpd.git] / lighttpd-branch.diff
1 --- lighttpd-1.4.11/NEWS        2006-03-09 19:34:33.000000000 +0200
2 +++ lighttpd/NEWS       2006-07-11 21:23:42.928033114 +0300
3 @@ -3,6 +3,23 @@
4  NEWS
5  ====
6  
7 +- 1.4.12 - 2006-..-..
8 +
9 +  * added handling of Content-Range to PUT requests in mod_webdav
10 +  * added handling of ETag and If-Modified-Since to mod_compress if 
11 +    cache-dir is not set
12 +  * added experimental LOCK support for mod_webdav 
13 +  * added support for X-Sendfile as addition to X-LIGHTTPD-send-file.
14 +    This allows compatibility with mod_xsendfile for apache
15 +    (http://celebnamer.celebworld.ws/stuff/mod_xsendfile/)
16 +  * fixed handling of If-Modified-Since if Etag is not set
17 +  * fixed hanging fastcgi connections
18 +  * fixed stalling SSL POST requests 
19 +  * fixed round-robin load-balancing in mod_proxy
20 +  * TODO: add fail-over to mod-proxy
21 +  * TODO: fix CACHE_HIT/MISS in mod_cml
22 +  * TODO: finish LOCK/UNLOCK in mod_webdav
23 +
24  - 1.4.11 - 2006-03-09
25  
26    * added ability to specify which ip address spawn-fci listens on 
27 --- lighttpd-1.4.11/configure.in        2006-03-04 16:32:38.000000000 +0200
28 +++ lighttpd/configure.in       2006-07-11 21:23:42.880030107 +0300
29 @@ -1,7 +1,7 @@
30  #                                               -*- Autoconf -*-
31  # Process this file with autoconf to produce a configure script.
32  AC_PREREQ(2.57)
33 -AC_INIT(lighttpd, 1.4.11, jan@kneschke.de)
34 +AC_INIT(lighttpd, 1.4.12, jan@kneschke.de)
35  AC_CONFIG_SRCDIR([src/server.c])
36  
37  AC_CANONICAL_TARGET
38 @@ -66,7 +66,7 @@
39  AC_TYPE_PID_T
40  AC_TYPE_SIZE_T
41  
42 -AC_CHECK_MEMBER(struct tm.tm_gmtoff,AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm]),,[#include <time.h>])
43 +AC_CHECK_MEMBER(struct tm.tm_gmtoff,[AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm])],,[#include <time.h>])
44  AC_CHECK_TYPES(struct sockaddr_storage,,,[#include <sys/socket.h>])
45  AC_CHECK_TYPES(socklen_t,,,[#include <sys/types.h>
46  #include <sys/socket.h>])
47 @@ -339,6 +339,22 @@
48      AC_DEFINE([HAVE_SQLITE3], [1], [libsqlite3])
49      AC_DEFINE([HAVE_SQLITE3_H], [1], [sqlite3.h])
50   ])
51 +
52 + AC_MSG_CHECKING(for locks in mod_webdav)
53 + AC_ARG_WITH(webdav-locks, AC_HELP_STRING([--with-webdav-locks],[locks in mod_webdav]),
54 + [WITH_WEBDAV_LOCKS=$withval],[WITH_WEBDAV_LOCKS=no])
55 + AC_MSG_RESULT([$WITH_WEBDAV_LOCKS])
56 +
57 + if test "$WITH_WEBDAV_LOCKS" != "no"; then
58 +   AC_CHECK_LIB(uuid, uuid_unparse, [
59 +         AC_CHECK_HEADERS([uuid/uuid.h],[
60 +                 UUID_LIB=-luuid
61 +                 AC_DEFINE([HAVE_UUID], [1], [libuuid])
62 +                AC_DEFINE([HAVE_UUID_H], [1], [uuid/uuid.h is available])
63 +         ])
64 + ])
65 +
66 + fi
67  fi
68  
69  dnl Check for gdbm
70 @@ -381,30 +397,11 @@
71  
72  AC_MSG_RESULT($WITH_LUA)
73  if test "$WITH_LUA" != "no"; then
74 - AC_PATH_PROG(LUACONFIG, lua-config)
75 -
76 - if test x"$LUACONFIG" != x; then
77 -   LUA_CFLAGS=`$LUACONFIG --include`
78 -   LUA_LIBS=`$LUACONFIG --libs --extralibs`
79 -   AC_DEFINE([HAVE_LUA], [1], [liblua])
80 -   AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
81 - else
82 -   AC_CHECK_LIB(lua, lua_open, [
83 -     AC_CHECK_HEADERS([lua.h],[
84 -       LUA_LIBS="-llua -llualib"
85 -       AC_DEFINE([HAVE_LUA], [1], [liblua])
86 -       AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
87 -     ])
88 -   ])
89 - fi
90 -
91 - if test x"$LUA_LIBS" = x; then
92     # try pkgconfig
93 -   PKG_CHECK_MODULES(LUA, lua, [
94 + PKG_CHECK_MODULES(LUA, lua >= 5.1, [
95       AC_DEFINE([HAVE_LUA], [1], [liblua])
96       AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
97     ])
98 - fi
99  
100   AC_SUBST(LUA_CFLAGS)
101   AC_SUBST(LUA_LIBS)
102 @@ -440,7 +437,7 @@
103  esac
104  
105  AC_CHECK_FUNCS([dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \
106 -                 strdup strerror strstr strtol sendfile  getopt socket \
107 +                 strdup strerror strstr strtol sendfile  getopt socket lstat \
108                   gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot \
109                   getuid select signal pathconf madvise posix_fadvise posix_madvise \
110                   writev sigaction sendfile64 send_file kqueue port_create localtime_r])
111 @@ -538,7 +535,7 @@
112  AC_OUTPUT
113  
114  
115 -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" 
116 +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" 
117  
118  plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl"
119  features="regex-conditionals"
120 @@ -642,6 +639,14 @@
121         disable_feature="$disable_feature $features"
122  fi
123  
124 +features="webdav-locks"
125 +if test "x$UUID_LIB" \!= x; then
126 +       enable_feature="$enable_feature $features"
127 +else
128 +       disable_feature="$disable_feature $features"
129 +fi
130 +
131 +
132  ## output
133  
134  $ECHO
135 --- lighttpd-1.4.11/doc/authentication.txt      2006-01-12 20:34:26.000000000 +0200
136 +++ lighttpd/doc/authentication.txt     2006-07-11 21:23:42.708019334 +0300
137 @@ -7,8 +7,8 @@
138  ----------------
139  
140  :Author: Jan Kneschke
141 -:Date: $Date$
142 -:Revision: $Revision$
143 +:Date: $Date$
144 +:Revision: $Revision$
145  
146  :abstract:
147    The auth module provides ...
148 --- lighttpd-1.4.11/doc/compress.txt    2005-08-11 01:26:16.000000000 +0300
149 +++ lighttpd/doc/compress.txt   2006-07-11 21:23:42.680017580 +0300
150 @@ -22,12 +22,38 @@
151  ===========
152  
153  Output compression reduces the network load and can improve the overall
154 -throughput of the webserver. 
155 +throughput of the webserver. All major http-clients support compression by
156 +announcing it in the Accept-Encoding header. This is used to negotiate the 
157 +most suitable compression method. We support deflate, gzip and bzip2.
158  
159 -Only static content is supported up to now.
160 +deflate (RFC1950, RFC1951) and gzip (RFC1952) depend on zlib while bzip2 
161 +depends on libbzip2. bzip2 is only supported by lynx and some other console
162 +text-browsers.
163  
164 -The server negotiates automaticly which compression method is used.
165 -Supported are gzip, deflate, bzip.
166 +Currently we limit to compression support to static files.
167 +
168 +Caching
169 +-------
170 +
171 +mod_compress can stored compressed files on disk to optimized the compression
172 +on a second request away. As soon as compress.cache-dir is set the files are
173 +compressed. 
174 +
175 +The names of the cache files are made of the filename, the compression method
176 +and the etag associated to the file.
177 +
178 +Cleaning the cache is left to the user. A cron job deleting files older than
179 +10 days should do fine.
180 +
181 +Limitations
182 +-----------
183 +
184 +The module limits the compression of files to files larger than 128 Byte and
185 +smaller than 128 MByte.
186 +
187 +The lower limit is set as small files tend to become larger by compressing due
188 +to the compression headers, the upper limit is set to work sensable with
189 +memory and cpu-time.
190  
191  Options
192  =======
193 @@ -47,14 +73,27 @@
194    Default: not set, compress the file for every request
195  
196  compress.filetype
197 -  mimetypes where might get compressed
198 +  mimetypes which might get compressed
199    
200    e.g.: ::
201    
202      compress.filetype           = ("text/plain", "text/html")
203  
204 +  Keep in mind that compressed JavaScript and CSS files are broken in some
205 +  browsers.
206 +
207    Default: not set
208  
209 +compress.max-file-size 
210 +  maximum size of the original file to be compressed kBytes.
211 +
212 +  This is meant to protect the server against DoSing as compressing large
213 +  (let's say 1Gbyte) takes a lot of time and would delay the whole operation
214 +  of the server.
215 +
216 +  There is a hard upper limit of 128Mbyte.
217 +
218 +  Default: unlimited (== hard-limit of 128MByte)
219  
220  Compressing Dynamic Content
221  ===========================
222 --- lighttpd-1.4.11/doc/configuration.txt       2006-03-09 02:10:40.000000000 +0200
223 +++ lighttpd/doc/configuration.txt      2006-07-11 21:23:42.696018582 +0300
224 @@ -7,8 +7,8 @@
225  ------------
226  
227  :Author: Jan Kneschke
228 -:Date: $Date$
229 -:Revision: $Revision$
230 +:Date: $Date$
231 +:Revision: $Revision$
232  
233  :abstract:
234    the layout of the configuration file
235 @@ -511,3 +511,10 @@
236  
237  debug.log-request-handling
238    default: disabled 
239 +
240 +debug.log-condition-handling
241 +  default: disabled 
242 +
243 +debug.log-condition-cache-handling
244 +  for developers only
245 +  default: disabled 
246 --- lighttpd-1.4.11/doc/fastcgi.txt     2006-02-16 17:03:52.000000000 +0200
247 +++ lighttpd/doc/fastcgi.txt    2006-07-11 21:23:42.712019584 +0300
248 @@ -144,8 +144,8 @@
249                  PHP can extract PATH_INFO from it (default: disabled)
250    :"disable-time": time to wait before a disabled backend is checked
251                  again
252 -  :"allow-x-send-file": controls if X-LIGHTTPD-send-file headers
253 -                are allowed 
254 +  :"allow-x-send-file": controls if X-LIGHTTPD-send-file and X-Sendfile
255 +                headers are allowed 
256  
257    If bin-path is set:
258  
259 --- lighttpd-1.4.11/doc/lighttpd.conf   2006-03-04 14:41:12.000000000 +0200
260 +++ lighttpd/doc/lighttpd.conf  2006-07-11 21:23:42.736021088 +0300
261 @@ -176,6 +176,7 @@
262  #debug.log-response-header  = "enable"
263  #debug.log-request-handling = "enable"
264  #debug.log-file-not-found   = "enable"
265 +#debug.log-condition-handling = "enable"
266  
267  ### only root can use these options
268  #
269 --- lighttpd-1.4.11/doc/performance.txt 2006-02-02 13:01:08.000000000 +0200
270 +++ lighttpd/doc/performance.txt        2006-07-11 21:23:42.632014574 +0300
271 @@ -183,6 +183,8 @@
272  
273    server.stat-cache-engine = "fam"   # either fam, simple or disabled
274  
275 +See http://oss.sgi.com/projects/fam/faq.html for information about FAM.
276 +See http://www.gnome.org/~veillard/gamin/overview.html for information about gamin.
277  
278  Platform-Specific Notes
279  =======================
280 --- lighttpd-1.4.11/doc/secdownload.txt 2005-12-20 15:58:58.000000000 +0200
281 +++ lighttpd/doc/secdownload.txt        2006-07-11 21:23:42.640015075 +0300
282 @@ -118,7 +118,7 @@
283    $secret = "verysecret";
284    $uri_prefix = "/dl/";
285    
286 -  # filename
287 +  # filename, make sure it's started with a "/" or you'll get 404 in the browser
288    $f = "/secret-file.txt";
289    
290    # current timestamp
291 --- lighttpd-1.4.11/src/Makefile.am     2006-03-07 14:20:20.000000000 +0200
292 +++ lighttpd/src/Makefile.am    2006-07-11 21:23:40.099855979 +0300
293 @@ -16,14 +16,19 @@
294  else
295  configparser.y: lemon
296  mod_ssi_exprparser.y: lemon
297 +http_resp_parser.y: lemon
298  
299  configparser.c configparser.h: configparser.y
300         rm -f configparser.h
301 -       $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c
302 +       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
303 +
304 +http_resp_parser.c http_resp_parser.h: http_resp_parser.y
305 +       rm -f http_resp_parser.h
306 +       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
307  
308  mod_ssi_exprparser.c mod_ssi_exprparser.h: mod_ssi_exprparser.y 
309         rm -f mod_ssi_exprparser.h
310 -       $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
311 +       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
312  endif
313  
314  configfile.c: configparser.h
315 @@ -46,7 +51,7 @@
316        network_write.c network_linux_sendfile.c \
317        network_freebsd_sendfile.c network_writev.c \
318        network_solaris_sendfilev.c network_openssl.c \
319 -      splaytree.c 
320 +      splaytree.c http_resp.c http_resp_parser.c 
321        
322  src = server.c response.c connections.c network.c \
323        configfile.c configparser.c request.c proc_open.c
324 @@ -84,7 +89,7 @@
325  mod_webdav_la_SOURCES = mod_webdav.c
326  mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS)
327  mod_webdav_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
328 -mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS)
329 +mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) $(UUID_LIB)
330  
331  lib_LTLIBRARIES += mod_cml.la
332  mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c
333 @@ -103,6 +108,11 @@
334  mod_mysql_vhost_la_LIBADD = $(MYSQL_LIBS) $(common_libadd)
335  mod_mysql_vhost_la_CPPFLAGS = $(MYSQL_INCLUDE)
336  
337 +lib_LTLIBRARIES += mod_sql_vhost_core.la
338 +mod_sql_vhost_core_la_SOURCES = mod_sql_vhost_core.c
339 +mod_sql_vhost_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
340 +mod_sql_vhost_core_la_LIBADD = $(common_libadd)
341 +
342  lib_LTLIBRARIES += mod_cgi.la
343  mod_cgi_la_SOURCES = mod_cgi.c 
344  mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
345 @@ -240,7 +250,7 @@
346        mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
347        configparser.h mod_ssi_exprparser.h \
348        sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
349 -      splaytree.h proc_open.h
350 +      splaytree.h proc_open.h http_resp.h mod_sql_vhost_core.h
351  
352  DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\""
353  
354 --- lighttpd-1.4.11/src/array.c 2005-11-18 13:58:32.000000000 +0200
355 +++ lighttpd/src/array.c        2006-07-11 21:23:39.943846207 +0300
356 @@ -165,7 +165,7 @@
357         int pos = 0;
358         size_t j;
359         
360 -       /* generate unique index if neccesary */
361 +       /* generate unique index if necessary */
362         if (str->key->used == 0 || str->is_index_key) {
363                 buffer_copy_long(str->key, a->unique_ndx++);
364                 str->is_index_key = 1;
365 @@ -215,7 +215,7 @@
366                 pos++;
367         } 
368         
369 -       /* move everything on step to the right */
370 +       /* move everything one step to the right */
371         if (pos != ndx) {
372                 memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted));
373         }
374 --- lighttpd-1.4.11/src/array.h 2005-09-23 21:24:18.000000000 +0300
375 +++ lighttpd/src/array.h        2006-07-11 21:23:39.963847460 +0300
376 @@ -16,7 +16,7 @@
377  #define DATA_UNSET \
378         data_type_t type; \
379         buffer *key; \
380 -       int is_index_key; /* 1 if key is a array index (autogenerated keys) */ \
381 +       int is_index_key; /* 1 if key is an array index (auto-generated keys) */ \
382         struct data_unset *(*copy)(const struct data_unset *src); \
383         void (* free)(struct data_unset *p); \
384         void (* reset)(struct data_unset *p); \
385 --- lighttpd-1.4.11/src/base.h  2006-01-11 16:51:04.000000000 +0200
386 +++ lighttpd/src/base.h 2006-07-11 21:23:39.947846458 +0300
387 @@ -2,7 +2,6 @@
388  #define _BASE_H_
389  
390  #include <sys/types.h>
391 -#include <sys/time.h>
392  #include <sys/stat.h>
393  
394  #ifdef HAVE_CONFIG_H
395 @@ -26,7 +25,6 @@
396  #include "sys-socket.h"
397  #include "splaytree.h"
398  
399 -
400  #if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
401  # define USE_OPENSSL
402  # include <openssl/ssl.h> 
403 @@ -40,10 +38,6 @@
404  # define O_BINARY 0
405  #endif
406  
407 -#ifndef O_LARGEFILE
408 -# define O_LARGEFILE 0
409 -#endif
410 -
411  #ifndef SIZE_MAX
412  # ifdef SIZE_T_MAX
413  #  define SIZE_MAX SIZE_T_MAX
414 @@ -70,7 +64,8 @@
415  
416  /* solaris and NetBSD 1.3.x again */
417  #if (!defined(HAVE_STDINT_H)) && (!defined(HAVE_INTTYPES_H)) && (!defined(uint32_t))
418 -# define uint32_t u_int32_t
419 +/* # define uint32_t u_int32_t */
420 +typedef unsigned __int32 uint32_t;
421  #endif
422  
423  
424 @@ -171,7 +166,7 @@
425  
426  typedef struct {
427         off_t   content_length;
428 -       int     keep_alive;               /* used by  the subrequests in proxy, cgi and fcgi to say the subrequest was keep-alive or not */
429 +       int     keep_alive;               /* used by the subrequests in proxy, cgi and fcgi to say whether the subrequest was keep-alive or not */
430         
431         array  *headers;
432         
433 @@ -215,7 +210,7 @@
434  } stat_cache_entry;
435  
436  typedef struct {
437 -       splay_tree *files; /* the nodes of the tree are stat_cache_entry's */
438 +       splay_tree *files; /* the nodes of the tree are stat_cache_entries */
439         
440         buffer *dir_name; /* for building the dirname from the filename */
441  #ifdef HAVE_FAM_H
442 @@ -252,6 +247,7 @@
443         unsigned short log_request_handling;
444         unsigned short log_response_header;
445         unsigned short log_condition_handling;
446 +       unsigned short log_condition_cache_handling;
447         
448         
449         /* server wide */
450 @@ -272,13 +268,13 @@
451         /* server-wide traffic-shaper
452          * 
453          * each context has the counter which is inited once
454 -        * a second by the global_kbytes_per_second config-var
455 +        * per second by the global_kbytes_per_second config-var
456          *
457          * as soon as global_kbytes_per_second gets below 0
458          * the connected conns are "offline" a little bit
459          *
460          * the problem:
461 -        * we somehow have to loose our "we are writable" signal 
462 +        * we somehow have to lose our "we are writable" signal
463          * on the way.
464          * 
465          */
466 @@ -341,7 +337,7 @@
467         int is_readable;
468         int is_writable;
469         
470 -       int     keep_alive;           /* only request.c can enable it, all other just disable */
471 +       int     keep_alive;           /* only request.c can enable it, all others just disable */
472         
473         int file_started;
474         int file_finished;
475 @@ -439,6 +435,15 @@
476         size_t size;
477  } buffer_plugin;
478  
479 +typedef enum {
480 +    NETWORK_STATUS_UNSET,
481 +    NETWORK_STATUS_SUCCESS,
482 +    NETWORK_STATUS_FATAL_ERROR,
483 +    NETWORK_STATUS_CONNECTION_CLOSE,
484 +    NETWORK_STATUS_WAIT_FOR_EVENT,
485 +    NETWORK_STATUS_INTERRUPTED
486 +} network_status_t;
487 +
488  typedef struct {
489         unsigned short port;
490         buffer *bindhost;
491 @@ -591,15 +596,17 @@
492         
493         fdevent_handler_t event_handler;
494  
495 -       int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
496 -       int (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
497 +       network_status_t (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
498 +       network_status_t (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
499  #ifdef USE_OPENSSL
500 -       int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
501 -       int (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
502 +       network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
503 +       network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
504  #endif
505  
506 +#ifdef HAVE_PWD_H
507         uid_t uid;
508         gid_t gid;
509 +#endif
510  } server;
511  
512  
513 --- lighttpd-1.4.11/src/buffer.c        2006-01-13 00:00:45.000000000 +0200
514 +++ lighttpd/src/buffer.c       2006-07-11 21:23:40.087855227 +0300
515 @@ -63,7 +63,7 @@
516  
517  /**
518   * 
519 - * allocate (if neccessary) enough space for 'size' bytes and 
520 + * allocate (if necessary) enough space for 'size' bytes and
521   * set the 'used' counter to 0
522   * 
523   */
524 @@ -79,7 +79,7 @@
525                 
526                 b->size = size;
527                 
528 -               /* always allocate a multiply of BUFFER_PIECE_SIZE */
529 +               /* always allocate a multiple of BUFFER_PIECE_SIZE */
530                 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
531                 
532                 b->ptr = malloc(b->size);
533 @@ -91,7 +91,7 @@
534  
535  /**
536   * 
537 - * increase the internal buffer (if neccessary) to append another 'size' byte
538 + * increase the internal buffer (if necessary) to append another 'size' byte
539   * ->used isn't changed
540   * 
541   */
542 @@ -102,7 +102,7 @@
543         if (0 == b->size) {
544                 b->size = size;
545                 
546 -               /* always allocate a multiply of BUFFER_PIECE_SIZE */
547 +               /* always allocate a multiple of BUFFER_PIECE_SIZE */
548                 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
549                 
550                 b->ptr = malloc(b->size);
551 @@ -111,7 +111,7 @@
552         } else if (b->used + size > b->size) {
553                 b->size += size;
554                 
555 -               /* always allocate a multiply of BUFFER_PIECE_SIZE */
556 +               /* always allocate a multiple of BUFFER_PIECE_SIZE */
557                 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
558                 
559                 b->ptr = realloc(b->ptr, b->size);
560 @@ -203,7 +203,7 @@
561   * append a string to the end of the buffer
562   * 
563   * the resulting buffer is terminated with a '\0' 
564 - * s is treated as a un-terminated string (a \0 is handled a normal character)
565 + * s is treated as an un-terminated string (a \0 is handled as a normal character)
566   * 
567   * @param b a buffer
568   * @param s the string
569 @@ -402,6 +402,75 @@
570  
571  
572  /**
573 + * init the ptr buffer
574 + *
575 + */
576 +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer)
577 +{
578 +       buffer_ptr *l = calloc(1, sizeof(buffer_ptr));
579 +       l->free = freer;
580 +
581 +       return l;
582 +}
583 +
584 +/**
585 + * free the buffer_array
586 + *
587 + */
588 +void buffer_ptr_free(buffer_ptr *l)
589 +{
590 +       if (NULL != l) {
591 +               buffer_ptr_clear(l);
592 +               free(l);
593 +       }
594 +}
595 +
596 +void buffer_ptr_clear(buffer_ptr *l)
597 +{
598 +       assert(NULL != l);
599 +
600 +       if (l->free && l->used) {
601 +               size_t i;
602 +               for (i = 0; i < l->used; i ++) {
603 +                       l->free(l->ptr[i]);
604 +               }
605 +       }
606 +
607 +       if (l->ptr) {
608 +               free(l->ptr);
609 +               l->ptr = NULL;
610 +       }
611 +       l->used = 0;
612 +       l->size = 0;
613 +}
614 +
615 +void buffer_ptr_append(buffer_ptr* l, void *item)
616 +{
617 +       assert(NULL != l);
618 +       if (l->ptr == NULL) {
619 +               l->size = 16;
620 +               l->ptr = (void **)malloc(sizeof(void *) * l->size);
621 +       }
622 +       else if (l->used == l->size) {
623 +               l->size += 16;
624 +               l->ptr = realloc(l->ptr, sizeof(void *) * l->size);
625 +       }
626 +       l->ptr[l->used++] = item;
627 +}
628 +
629 +void *buffer_ptr_pop(buffer_ptr* l)
630 +{
631 +       assert(NULL != l && l->used > 0);
632 +       return l->ptr[--l->used];
633 +}
634 +
635 +void *buffer_ptr_top(buffer_ptr* l)
636 +{
637 +       assert(NULL != l && l->used > 0);
638 +       return l->ptr[l->used-1];
639 +}
640 +
641 +/**
642   * init the buffer 
643   * 
644   */
645 @@ -507,7 +576,7 @@
646  }
647  
648  /**
649 - * check if two buffer contain the same data
650 + * check if two buffers contain the same data
651   * 
652   * HISTORY: this function was pretty much optimized, but didn't handled
653   * alignment properly.
654 @@ -531,7 +600,7 @@
655  
656  /* simple-assumption:
657   * 
658 - * most parts are equal and doing a case conversion needs time
659 + * most parts are equal and doing a case conversion takes time
660   * 
661   */
662  int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {
663 @@ -592,7 +661,7 @@
664         if (b1->used == 0 || b2->used == 0) return 0;
665         
666         /* buffers too small -> not equal */
667 -       if (b1->used - 1 < len || b1->used - 1 < len) return 0;
668 +       if (b1->used - 1 < len || b2->used - 1 < len) return 0;
669         
670         if (0 == strncmp(b1->ptr + b1->used - 1 - len, 
671                          b2->ptr + b2->used - 1 - len, len)) {
672 @@ -760,12 +829,12 @@
673                 map = encoded_chars_hex;
674                 break;
675         case ENCODING_UNSET:
676 -               break;
677 +               return buffer_append_string_len(b, s, s_len);
678         }
679  
680         assert(map != NULL);
681         
682 -       /* count to-be-encoded-characters */
683 +       /* count to-be-encoded characters */
684         for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
685                 if (map[*ds]) {
686                         switch(encoding) {
687 @@ -829,7 +898,7 @@
688  }
689  
690  
691 -/* decodes url-special-chars inplace.
692 +/* decodes url-special chars in-place.
693   * replaces non-printable characters with '_'
694   */
695  
696 @@ -855,7 +924,7 @@
697                                 if (low != 0xFF) {
698                                         high = (high << 4) | low;
699                                         
700 -                                       /* map control-characters out */        
701 +                                       /* map out control characters */
702                                         if (high < 32 || high == 127) high = '_';
703                                         
704                                         *dst = high;
705 @@ -891,7 +960,7 @@
706   * /abc/./xyz       gets  /abc/xyz
707   * /abc//xyz        gets  /abc/xyz
708   *
709 - * NOTE: src and dest can point to the same buffer, in which case,
710 + * NOTE: src and dest can point to the same buffer, in which case
711   *       the operation is performed in-place.
712   */
713  
714 @@ -993,6 +1062,31 @@
715         return light_isdigit(c) || light_isalpha(c);
716  }
717  
718 +#undef BUFFER_CTYPE_FUNC
719 +#define BUFFER_CTYPE_FUNC(type) \
720 +       int buffer_is##type(buffer *b) { \
721 +               size_t i, len; \
722 +               if (b->used < 2) return 0; \
723 +               /* strlen */ \
724 +               len = b->used - 1; \
725 +               /* c-string only */ \
726 +               if (b->ptr[len] != '\0') { \
727 +                       return 0; \
728 +               } \
729 +               /* check on the whole string */ \
730 +               for (i = 0; i < len; i ++) { \
731 +                       if (!light_is##type(b->ptr[i])) { \
732 +                               return 0; \
733 +                       } \
734 +               } \
735 +               return 1; \
736 +       }
737 +
738 +BUFFER_CTYPE_FUNC(digit)
739 +BUFFER_CTYPE_FUNC(xdigit)
740 +BUFFER_CTYPE_FUNC(alpha)
741 +BUFFER_CTYPE_FUNC(alnum)
742 +
743  int buffer_to_lower(buffer *b) {
744         char *c;
745         
746 --- lighttpd-1.4.11/src/buffer.h        2006-01-13 00:00:45.000000000 +0200
747 +++ lighttpd/src/buffer.h       2006-07-11 21:23:40.095855728 +0300
748 @@ -17,6 +17,16 @@
749         size_t size;
750  } buffer;
751  
752 +
753 +typedef void (*buffer_ptr_free_t)(void *p);
754 +
755 +typedef struct {
756 +       void **ptr;
757 +       size_t size;
758 +       size_t used;
759 +       buffer_ptr_free_t free;
760 +} buffer_ptr;
761 +
762  typedef struct {
763         buffer **ptr;
764         
765 @@ -27,12 +37,19 @@
766  typedef struct {
767         char *ptr;
768         
769 -       size_t offset; /* input-pointer */
770 +       size_t offset; /* input pointer */
771         
772 -       size_t used;   /* output-pointer */
773 +       size_t used;   /* output pointer */
774         size_t size;
775  } read_buffer;
776  
777 +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer);
778 +void buffer_ptr_free(buffer_ptr *b);
779 +void buffer_ptr_clear(buffer_ptr *b);
780 +void buffer_ptr_append(buffer_ptr *b, void *item);
781 +void *buffer_ptr_pop(buffer_ptr *b);
782 +void *buffer_ptr_top(buffer_ptr *b);
783 +
784  buffer_array* buffer_array_init(void);
785  void buffer_array_free(buffer_array *b);
786  void buffer_array_reset(buffer_array *b);
787 @@ -85,9 +102,9 @@
788  
789  typedef enum {
790         ENCODING_UNSET,
791 -       ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
792 -       ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */
793 -       ENCODING_HTML,    /* & becomes &amp; and so on */
794 +       ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of an href */
795 +       ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus encoding "/" as "%2F" */
796 +       ENCODING_HTML,    /* "&" becomes "&amp;" and so on */
797         ENCODING_MINIMAL_XML, /* minimal encoding for xml */
798         ENCODING_HEX      /* encode string as hex */
799  } buffer_encoding_t;
800 @@ -111,19 +128,21 @@
801  int light_isalpha(int c);
802  int light_isalnum(int c);
803  
804 +#define BUFFER_CTYPE_FUNC(type) int buffer_is##type(buffer *b);
805 +BUFFER_CTYPE_FUNC(digit)
806 +BUFFER_CTYPE_FUNC(xdigit)
807 +BUFFER_CTYPE_FUNC(alpha)
808 +BUFFER_CTYPE_FUNC(alnum)
809 +
810  #define BUFFER_APPEND_STRING_CONST(x, y) \
811         buffer_append_string_len(x, y, sizeof(y) - 1)
812  
813  #define BUFFER_COPY_STRING_CONST(x, y) \
814         buffer_copy_string_len(x, y, sizeof(y) - 1)
815  
816 -#define BUFFER_APPEND_SLASH(x) \
817 -       if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); }
818 -
819  #define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
820  #define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
821  
822 -
823  #define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0)
824  #define UNUSED(x) ( (void)(x) )
825  
826 --- lighttpd-1.4.11/src/chunk.c 2005-11-18 15:18:19.000000000 +0200
827 +++ lighttpd/src/chunk.c        2006-07-11 21:23:39.995849464 +0300
828 @@ -6,11 +6,9 @@
829  
830  #include <sys/types.h>
831  #include <sys/stat.h>
832 -#include <sys/mman.h>
833  
834  #include <stdlib.h>
835  #include <fcntl.h>
836 -#include <unistd.h>
837  
838  #include <stdio.h>
839  #include <errno.h>
840 @@ -18,6 +16,9 @@
841  
842  #include "chunk.h"
843  
844 +#include "sys-mmap.h"
845 +#include "sys-files.h"
846 +
847  chunkqueue *chunkqueue_init(void) {
848         chunkqueue *cq;
849         
850 @@ -99,7 +100,7 @@
851  static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) {
852         chunk *c;
853         
854 -       /* check if we have a unused chunk */
855 +       /* check if we have an unused chunk */
856         if (!cq->unused) {
857                 c = chunk_init();
858         } else {
859 @@ -278,7 +279,7 @@
860                         data_string *ds = (data_string *)cq->tempdirs->data[i];
861  
862                         buffer_copy_string_buffer(template, ds->value);
863 -                       BUFFER_APPEND_SLASH(template);
864 +                       PATHNAME_APPEND_SLASH(template);
865                         BUFFER_APPEND_STRING_CONST(template, "lighttpd-upload-XXXXXX");
866  
867                         if (-1 != (c->file.fd = mkstemp(template->ptr))) {
868 --- lighttpd-1.4.11/src/chunk.h 2005-11-01 09:32:21.000000000 +0200
869 +++ lighttpd/src/chunk.h        2006-07-11 21:23:40.015850717 +0300
870 @@ -19,10 +19,10 @@
871                 struct { 
872                         char   *start; /* the start pointer of the mmap'ed area */
873                         size_t length; /* size of the mmap'ed area */
874 -                       off_t  offset; /* start is <n> octet away from the start of the file */
875 +                       off_t  offset; /* start is <n> octets away from the start of the file */
876                 } mmap;
877  
878 -               int is_temp; /* file is temporary and will be deleted if on cleanup */
879 +               int is_temp; /* file is temporary and will be deleted on cleanup */
880         } file;
881         
882         off_t  offset; /* octets sent from this chunk 
883 --- lighttpd-1.4.11/src/configfile-glue.c       2006-03-03 20:14:56.000000000 +0200
884 +++ lighttpd/src/configfile-glue.c      2006-07-11 21:23:39.879842199 +0300
885 @@ -1,4 +1,5 @@
886  #include <string.h>
887 +#include <ctype.h>
888  
889  #include "base.h"
890  #include "buffer.h"
891 @@ -71,6 +72,10 @@
892                                 data_string *ds = (data_string *)du;
893                                 
894                                 buffer_copy_string_buffer(cv[i].destination, ds->value);
895 +                       } else if (du->type == TYPE_INTEGER) {
896 +                               data_integer *di = (data_integer *)du;
897 +
898 +                               buffer_copy_long(cv[i].destination, di->value);
899                         } else {
900                                 log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\"");
901                                 
902 @@ -88,6 +93,11 @@
903                         case TYPE_STRING: {
904                                 data_string *ds = (data_string *)du;
905                                         
906 +                               if (buffer_isdigit(ds->value)) {
907 +                                       *((unsigned short *)(cv[i].destination)) = strtol(ds->value->ptr, NULL, 10);
908 +                                       break;
909 +                               }
910 +
911                                 log_error_write(srv, __FILE__, __LINE__, "ssb", "get a string but expected a short:", cv[i].key, ds->value);
912                                 
913                                 return -1;
914 @@ -230,7 +240,7 @@
915                                 break;
916                         }
917                 } else {
918 -                       l = NULL;
919 +                       l = srv->empty_string;
920                 }
921                 break;
922         }
923 @@ -254,6 +264,13 @@
924                         char *err;
925                         struct in_addr val_inp;
926                         
927 +                       if (con->conf.log_condition_handling) {
928 +                               l = srv->empty_string;
929 +
930 +                               log_error_write(srv, __FILE__, __LINE__,  "bsbsb", dc->comp_key,
931 +                                               "(", l, ") compare to", dc->string);
932 +                       }
933 +
934                         if (*(nm_slash+1) == '\0') {
935                                 log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string);
936                                         
937 @@ -270,7 +287,7 @@
938                         
939                         /* take IP convert to the native */
940                         buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr);
941 -#ifdef __WIN32                 
942 +#ifdef _WIN32
943                         if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) {
944                                 log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
945                                 
946 @@ -395,6 +412,9 @@
947         cond_cache_t *caches = con->cond_cache;
948  
949         if (COND_RESULT_UNSET == caches[dc->context_ndx].result) {
950 +               if (con->conf.log_condition_handling) {
951 +                       log_error_write(srv, __FILE__, __LINE__,  "sds",  "=== start of", dc->context_ndx, "condition block ===");
952 +               }
953                 if (COND_RESULT_TRUE == (caches[dc->context_ndx].result = config_check_cond_nocache(srv, con, dc))) {
954                         if (dc->next) {
955                                 data_config *c;
956 @@ -409,11 +429,11 @@
957                 }
958                 if (con->conf.log_condition_handling) {
959                         log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
960 -                                       "(uncached) result:",
961 +                                       "result:",
962                                         caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false");
963                 }
964         } else {
965 -               if (con->conf.log_condition_handling) {
966 +               if (con->conf.log_condition_cache_handling) {
967                         log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
968                                         "(cached) result:",
969                                         caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false");
970 @@ -423,9 +443,6 @@
971  }
972  
973  int config_check_cond(server *srv, connection *con, data_config *dc) {
974 -       if (con->conf.log_condition_handling) {
975 -               log_error_write(srv, __FILE__, __LINE__,  "s",  "=== start of condition block ===");
976 -       }
977         return (config_check_cond_cached(srv, con, dc) == COND_RESULT_TRUE);
978  }
979  
980 @@ -443,3 +460,85 @@
981         return 1;
982  }
983  
984 +/* return <0 on error
985 + * return 0-x if matched (and replaced)
986 + */
987 +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result)
988 +{
989 +#ifdef HAVE_PCRE_H
990 +       pcre *match;
991 +       pcre_extra *extra;
992 +       const char *pattern;
993 +       size_t pattern_len;
994 +       int n;
995 +       size_t i;
996 +       pcre_keyvalue *kv;
997 +# define N 10
998 +       int ovec[N * 3];
999 +
1000 +       for (i = 0; i < kvb->used; i++) {
1001 +               kv = kvb->kv[i];
1002 +
1003 +               match       = kv->key;
1004 +               extra       = kv->key_extra;
1005 +               pattern     = kv->value->ptr;
1006 +               pattern_len = kv->value->used - 1;
1007 +
1008 +               if ((n = pcre_exec(match, extra, match_buf->ptr, match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
1009 +                       if (n != PCRE_ERROR_NOMATCH) {
1010 +                               return n;
1011 +                       }
1012 +               } else {
1013 +                       const char **list;
1014 +                       size_t start, end;
1015 +                       size_t k;
1016 +
1017 +                       /* it matched */
1018 +                       pcre_get_substring_list(match_buf->ptr, ovec, n, &list);
1019 +
1020 +                       /* search for $[0-9] */
1021 +
1022 +                       buffer_reset(result);
1023 +
1024 +                       start = 0; end = pattern_len;
1025 +                       for (k = 0; k < pattern_len; k++) {
1026 +                               if ((pattern[k] == '$' || pattern[k] == '%') &&
1027 +                                   isdigit((unsigned char)pattern[k + 1])) {
1028 +                                       /* got one */
1029 +
1030 +                                       size_t num = pattern[k + 1] - '0';
1031 +
1032 +                                       end = k;
1033 +
1034 +                                       buffer_append_string_len(result, pattern + start, end - start);
1035 +
1036 +                                       if (pattern[k] == '$') {
1037 +                                               /* n is always > 0 */
1038 +                                               if (num < (size_t)n) {
1039 +                                                       buffer_append_string(result, list[num]);
1040 +                                               }
1041 +                                       } else {
1042 +                                               config_append_cond_match_buffer(con, context, result, num);
1043 +                                       }
1044 +
1045 +                                       k++;
1046 +                                       start = k + 1;
1047 +                               }
1048 +                       }
1049 +
1050 +                       buffer_append_string_len(result, pattern + start, pattern_len - start);
1051 +
1052 +                       pcre_free(list);
1053 +
1054 +                       return i;
1055 +               }
1056 +       }
1057 +
1058 +       return PCRE_ERROR_NOMATCH;
1059 +#undef N
1060 +#else
1061 +       UNUSED(kvb);
1062 +       return -2;
1063 +#endif
1064 +}
1065 +
1066 --- lighttpd-1.4.11/src/configfile.c    2006-02-15 14:26:42.000000000 +0200
1067 +++ lighttpd/src/configfile.c   2006-07-11 21:23:39.987848963 +0300
1068 @@ -2,7 +2,6 @@
1069  
1070  #include <stdlib.h>
1071  #include <fcntl.h>
1072 -#include <unistd.h>
1073  #include <errno.h>
1074  #include <string.h>
1075  #include <stdio.h>
1076 @@ -13,14 +12,17 @@
1077  #include "log.h"
1078  #include "stream.h"
1079  #include "plugin.h"
1080 -#ifdef USE_LICENSE
1081 -#include "license.h"
1082 -#endif
1083 -
1084  #include "configparser.h"
1085  #include "configfile.h"
1086  #include "proc_open.h"
1087  
1088 +#include "sys-files.h"
1089 +#include "sys-process.h"
1090 +
1091 +#ifndef PATH_MAX
1092 +/* win32 */
1093 +#define PATH_MAX 64
1094 +#endif
1095  
1096  static int config_insert(server *srv) {
1097         size_t i;
1098 @@ -80,6 +82,7 @@
1099                 { "server.network-backend",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 43 */
1100                 { "server.upload-dirs",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },   /* 44 */
1101                 { "server.core-files",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */
1102 +               { "debug.log-condition-cache-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },    /* 46 */
1103                 
1104                 { "server.host",                 "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
1105                 { "server.docroot",              "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
1106 @@ -165,6 +168,7 @@
1107                 cv[14].destination = s->document_root;
1108                 cv[15].destination = &(s->force_lowercase_filenames);
1109                 cv[16].destination = &(s->log_condition_handling);
1110 +               cv[46].destination = &(s->log_condition_cache_handling);
1111                 cv[17].destination = &(s->max_keep_alive_requests);
1112                 cv[18].destination = s->server_name;
1113                 cv[19].destination = &(s->max_keep_alive_idle);
1114 @@ -216,8 +220,8 @@
1115                                                                  
1116  }
1117  
1118 -
1119 -#define PATCH(x) con->conf.x = s->x
1120 +#define PATCH(x) \
1121 +       con->conf.x = s->x
1122  int config_setup_connection(server *srv, connection *con) {
1123         specific_config *s = srv->config_storage[0];
1124         
1125 @@ -244,6 +248,7 @@
1126         PATCH(log_response_header);
1127         PATCH(log_request_handling);
1128         PATCH(log_condition_handling);
1129 +       PATCH(log_condition_cache_handling);
1130         PATCH(log_file_not_found);
1131         
1132         PATCH(range_requests);
1133 @@ -315,6 +320,8 @@
1134                                 PATCH(log_response_header);
1135                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-handling"))) {
1136                                 PATCH(log_condition_handling);
1137 +                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-cache-handling"))) {
1138 +                               PATCH(log_condition_cache_handling);
1139                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-file-not-found"))) {
1140                                 PATCH(log_file_not_found);
1141                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) {
1142 @@ -699,21 +706,13 @@
1143                                 for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]);  i++);
1144                                 
1145                                 /* was there it least a digit ? */
1146 -                               if (i && t->input[t->offset + i]) {
1147 +                               if (i) {
1148                                         tid = TK_INTEGER;
1149                                         
1150                                         buffer_copy_string_len(token, t->input + t->offset, i);
1151                                         
1152                                         t->offset += i;
1153                                         t->line_pos += i;
1154 -                               } else {
1155 -                                       /* ERROR */
1156 -                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
1157 -                                                       "source:", t->source,
1158 -                                                       "line:", t->line, "pos:", t->line_pos, 
1159 -                                                       "unexpected EOF");
1160 -                                       
1161 -                                       return -1;
1162                                 }
1163                         } else {
1164                                 /* the key might consist of [-.0-9a-z] */
1165 @@ -781,6 +780,7 @@
1166         pParser = configparserAlloc( malloc );
1167         lasttoken = buffer_init();
1168         token = buffer_init();
1169 +
1170         while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) {
1171                 buffer_copy_string_buffer(lasttoken, token);
1172                 configparser(pParser, token_id, token, context);
1173 @@ -896,13 +896,12 @@
1174  static void context_init(server *srv, config_t *context) {
1175         context->srv = srv;
1176         context->ok = 1;
1177 -       context->configs_stack = array_init();
1178 -       context->configs_stack->is_weakref = 1;
1179 +       context->configs_stack = buffer_ptr_init(NULL);
1180         context->basedir = buffer_init();
1181  }
1182  
1183  static void context_free(config_t *context) {
1184 -       array_free(context->configs_stack);
1185 +       buffer_ptr_free(context->configs_stack);
1186         buffer_free(context->basedir);
1187  }
1188  
1189 @@ -918,13 +917,10 @@
1190         context_init(srv, &context);
1191         context.all_configs = srv->config_context;
1192  
1193 -       pos = strrchr(fn,
1194 -#ifdef __WIN32
1195 -                       '\\'
1196 -#else
1197 -                       '/'
1198 -#endif
1199 -                       );
1200 +    /* use the current dir as basedir for all other includes
1201 +    */
1202 +       pos = strrchr(fn, DIR_SEPERATOR);
1203 +
1204         if (pos) {
1205                 buffer_copy_string_len(context.basedir, fn, pos - fn + 1);
1206                 fn = pos + 1;
1207 @@ -1035,6 +1031,7 @@
1208         return 0;
1209  }
1210  
1211 +
1212  int config_set_defaults(server *srv) {
1213         size_t i;
1214         specific_config *s = srv->config_storage[0];
1215 @@ -1077,10 +1074,11 @@
1216         }  
1217         
1218         if (buffer_is_empty(srv->srvconf.changeroot)) {
1219 +        pathname_unix2local(s->document_root);
1220                 if (-1 == stat(s->document_root->ptr, &st1)) {  
1221 -                       log_error_write(srv, __FILE__, __LINE__, "sb",  
1222 +                       log_error_write(srv, __FILE__, __LINE__, "sbs",
1223                                         "base-docroot doesn't exist:",
1224 -                                       s->document_root);  
1225 +                                       s->document_root, strerror(errno));
1226                         return -1;
1227                 }
1228  
1229 --- lighttpd-1.4.11/src/configfile.h    2005-08-23 17:36:12.000000000 +0300
1230 +++ lighttpd/src/configfile.h   2006-07-11 21:23:39.995849464 +0300
1231 @@ -9,7 +9,7 @@
1232         server *srv;
1233         int     ok;
1234         array  *all_configs;
1235 -       array  *configs_stack; /* to parse nested block */
1236 +       buffer_ptr  *configs_stack; /* to parse nested block */
1237         data_config *current; /* current started with { */
1238         buffer *basedir;
1239  } config_t;
1240 --- lighttpd-1.4.11/src/configparser.y  2006-01-26 18:46:25.000000000 +0200
1241 +++ lighttpd/src/configparser.y 2006-07-11 21:23:40.127857732 +0300
1242 @@ -21,33 +21,18 @@
1243      dc->parent = ctx->current;
1244      array_insert_unique(dc->parent->childs, (data_unset *)dc);
1245    }
1246 -  array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current);
1247 +  buffer_ptr_append(ctx->configs_stack, (void *)ctx->current);
1248    ctx->current = dc;
1249  }
1250  
1251  static data_config *configparser_pop(config_t *ctx) {
1252    data_config *old = ctx->current;
1253 -  ctx->current = (data_config *) array_pop(ctx->configs_stack);
1254 +  ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack);
1255    return old;
1256  }
1257  
1258  /* return a copied variable */
1259  static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) {
1260 -  if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) {
1261 -    char *env;
1262 -
1263 -    if (NULL != (env = getenv(key->ptr + 4))) {
1264 -      data_string *ds;
1265 -      ds = data_string_init();
1266 -      buffer_append_string(ds->value, env);
1267 -      return (data_unset *)ds;
1268 -    }
1269 -
1270 -    fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4);
1271 -    ctx->ok = 0;
1272 -
1273 -    return NULL;
1274 -  } else {
1275      data_unset *du;
1276      data_config *dc;
1277  
1278 @@ -63,11 +48,8 @@
1279          return du->copy(du);
1280        }
1281      }
1282 -    fprintf(stderr, "Undefined config variable: %s\n", key->ptr);
1283 -    ctx->ok = 0;
1284      return NULL;
1285    }
1286 -}
1287  
1288  /* op1 is to be eat/return by this function, op1->key is not cared
1289     op2 is left untouch, unreferenced
1290 @@ -141,6 +123,7 @@
1291  %type       aelement               {data_unset *}
1292  %type       condline               {data_config *}
1293  %type       condlines              {data_config *}
1294 +%type       global                 {data_config *}
1295  %type       aelements              {array *}
1296  %type       array                  {array *}
1297  %type       key                    {buffer *}
1298 @@ -161,7 +144,12 @@
1299  
1300  varline ::= key(A) ASSIGN expression(B). {
1301    buffer_copy_string_buffer(B->key, A);
1302 -  if (NULL == array_get_element(ctx->current->value, B->key->ptr)) {
1303 +  if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
1304 +    fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
1305 +        ctx->current->context_ndx,
1306 +        ctx->current->key->ptr, A->ptr);
1307 +    ctx->ok = 0;
1308 +  } else if (NULL == array_get_element(ctx->current->value, B->key->ptr)) {
1309      array_insert_unique(ctx->current->value, B);
1310      B = NULL;
1311    } else {
1312 @@ -180,7 +168,12 @@
1313    array *vars = ctx->current->value;
1314    data_unset *du;
1315  
1316 -  if (NULL != (du = array_get_element(vars, A->ptr))) {
1317 +  if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
1318 +    fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n",
1319 +        ctx->current->context_ndx,
1320 +        ctx->current->key->ptr, A->ptr);
1321 +    ctx->ok = 0;
1322 +  } else if (NULL != (du = array_get_element(vars, A->ptr))) {
1323      /* exists in current block */
1324      du = configparser_merge_data(du, B);
1325      if (NULL == du) {
1326 @@ -190,6 +183,7 @@
1327        buffer_copy_string_buffer(du->key, A);
1328        array_replace(vars, du);
1329      }
1330 +    B->free(B);
1331    } else if (NULL != (du = configparser_get_variable(ctx, A))) {
1332      du = configparser_merge_data(du, B);
1333      if (NULL == du) {
1334 @@ -199,15 +193,13 @@
1335        buffer_copy_string_buffer(du->key, A);
1336        array_insert_unique(ctx->current->value, du);
1337      }
1338 +    B->free(B);
1339    } else {
1340 -    fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n", 
1341 -            ctx->current->context_ndx,
1342 -            ctx->current->key->ptr, A->ptr);
1343 -    ctx->ok = 0;
1344 +    buffer_copy_string_buffer(B->key, A);
1345 +    array_insert_unique(ctx->current->value, B);
1346    }
1347    buffer_free(A);
1348    A = NULL;
1349 -  B->free(B);
1350    B = NULL;
1351  }
1352  
1353 @@ -239,7 +231,24 @@
1354  }
1355  
1356  value(A) ::= key(B). {
1357 -  A = configparser_get_variable(ctx, B);
1358 +  if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) {
1359 +    char *env;
1360 +
1361 +    if (NULL != (env = getenv(B->ptr + 4))) {
1362 +      data_string *ds;
1363 +      ds = data_string_init();
1364 +      buffer_append_string(ds->value, env);
1365 +      A = (data_unset *)ds;
1366 +    }
1367 +    else {
1368 +      A = NULL;
1369 +      fprintf(stderr, "Undefined env variable: %s\n", B->ptr + 4);
1370 +      ctx->ok = 0;
1371 +    }
1372 +  } else if (NULL == (A = configparser_get_variable(ctx, B))) {
1373 +    fprintf(stderr, "Undefined config variable: %s\n", B->ptr);
1374 +    ctx->ok = 0;
1375 +  }
1376    if (!A) {
1377      /* make a dummy so it won't crash */
1378      A = (data_unset *)data_string_init();
1379 @@ -267,6 +276,9 @@
1380    ((data_array *)(A))->value = B;
1381    B = NULL;
1382  }
1383 +array(A) ::= LPARAN RPARAN. {
1384 +  A = array_init();
1385 +}
1386  array(A) ::= LPARAN aelements(B) RPARAN. {
1387    A = B;
1388    B = NULL;
1389 --- lighttpd-1.4.11/src/connections.c   2006-03-05 22:14:53.000000000 +0200
1390 +++ lighttpd/src/connections.c  2006-07-11 21:23:39.955846959 +0300
1391 @@ -2,7 +2,6 @@
1392  
1393  #include <stdlib.h>
1394  #include <stdio.h>
1395 -#include <unistd.h>
1396  #include <errno.h>
1397  #include <string.h>
1398  #include <fcntl.h>
1399 @@ -35,6 +34,7 @@
1400  #endif
1401  
1402  #include "sys-socket.h"
1403 +#include "sys-files.h"
1404  
1405  typedef struct {
1406                 PLUGIN_DATA;
1407 @@ -111,9 +111,7 @@
1408  int connection_close(server *srv, connection *con) {
1409  #ifdef USE_OPENSSL
1410         server_socket *srv_sock = con->srv_socket;
1411 -#endif
1412         
1413 -#ifdef USE_OPENSSL
1414         if (srv_sock->is_ssl) {
1415                 if (con->ssl) SSL_free(con->ssl);
1416                 con->ssl = NULL;
1417 @@ -122,7 +120,7 @@
1418         
1419         fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
1420         fdevent_unregister(srv->ev, con->fd);
1421 -#ifdef __WIN32
1422 +#ifdef _WIN32
1423         if (closesocket(con->fd)) {
1424                 log_error_write(srv, __FILE__, __LINE__, "sds",
1425                                 "(warning) close:", con->fd, strerror(errno));
1426 @@ -190,150 +188,39 @@
1427  }
1428  #endif 
1429  
1430 -static int connection_handle_read(server *srv, connection *con) {
1431 -       int len;
1432 -       buffer *b;
1433 -       int toread;
1434 -#ifdef USE_OPENSSL
1435 -       server_socket *srv_sock = con->srv_socket;
1436 -#endif
1437 -
1438 -       b = chunkqueue_get_append_buffer(con->read_queue);
1439 -       buffer_prepare_copy(b, 4096);
1440 -
1441 -#ifdef USE_OPENSSL
1442 -       if (srv_sock->is_ssl) {
1443 -               len = SSL_read(con->ssl, b->ptr, b->size - 1);
1444 -       } else {
1445 -               if (ioctl(con->fd, FIONREAD, &toread)) {
1446 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
1447 -                                       "unexpected end-of-file:",
1448 -                                       con->fd);
1449 -                       return -1;
1450 -               }
1451 -               buffer_prepare_copy(b, toread);
1452 -
1453 -               len = read(con->fd, b->ptr, b->size - 1);
1454 -       }
1455 -#elif defined(__WIN32)
1456 -       len = recv(con->fd, b->ptr, b->size - 1, 0);
1457 -#else
1458 -       if (ioctl(con->fd, FIONREAD, &toread)) {
1459 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
1460 -                               "unexpected end-of-file:",
1461 -                               con->fd);
1462 -               return -1;
1463 -       }
1464 -       buffer_prepare_copy(b, toread);
1465 -
1466 -       len = read(con->fd, b->ptr, b->size - 1);
1467 -#endif
1468 -       
1469 -       if (len < 0) {
1470 -               con->is_readable = 0;
1471 -               
1472 -#ifdef USE_OPENSSL
1473 -               if (srv_sock->is_ssl) {
1474 -                       int r, ssl_err;
1475 -                       
1476 -                       switch ((r = SSL_get_error(con->ssl, len))) {
1477 -                       case SSL_ERROR_WANT_READ:
1478 -                               return 0;
1479 -                       case SSL_ERROR_SYSCALL:
1480 -                               /**
1481 -                                * man SSL_get_error()
1482 -                                * 
1483 -                                * SSL_ERROR_SYSCALL
1484 -                                *   Some I/O error occurred.  The OpenSSL error queue may contain more 
1485 -                                *   information on the error.  If the error queue is empty (i.e.
1486 -                                *   ERR_get_error() returns 0), ret can be used to find out more about 
1487 -                                *   the error: If ret == 0, an EOF was observed that violates the
1488 -                                *   protocol.  If ret == -1, the underlying BIO reported an I/O error 
1489 -                                *   (for socket I/O on Unix systems, consult errno for details).
1490 -                                *
1491 -                                */
1492 -                               while((ssl_err = ERR_get_error())) {
1493 -                                       /* get all errors from the error-queue */
1494 -                                       log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
1495 -                                                       r, ERR_error_string(ssl_err, NULL));
1496 -                               }
1497 -
1498 -                               switch(errno) {
1499 -                               default:
1500 -                                       log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", 
1501 -                                                       len, r, errno,
1502 -                                                       strerror(errno));
1503 -                                       break;
1504 -                               }
1505 -                               
1506 -                               break;
1507 -                       case SSL_ERROR_ZERO_RETURN:
1508 -                               /* clean shutdown on the remote side */
1509 +static network_status_t connection_handle_read(server *srv, connection *con) {
1510 +       off_t oldlen, newlen;
1511                                 
1512 -                               if (r == 0) {
1513 -                                       /* FIXME: later */
1514 -                               }
1515 +    oldlen = chunkqueue_length(con->read_queue);
1516                                 
1517 -                               /* fall thourgh */
1518 -                       default:
1519 -                               while((ssl_err = ERR_get_error())) {
1520 -                                       /* get all errors from the error-queue */
1521 -                                       log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
1522 -                                                       r, ERR_error_string(ssl_err, NULL));
1523 -                               }
1524 +    switch(network_read_chunkqueue(srv, con, con->read_queue)) {
1525 +    case NETWORK_STATUS_SUCCESS:
1526                                 break;
1527 -                       }
1528 -               } else {
1529 -                       if (errno == EAGAIN) return 0;
1530 -                       if (errno == EINTR) {
1531 -                               /* we have been interrupted before we could read */
1532 -                               con->is_readable = 1;
1533 -                               return 0;
1534 -                       }
1535 -               
1536 -                       if (errno != ECONNRESET) {
1537 -                               /* expected for keep-alive */
1538 -                               log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
1539 -                       }
1540 -               }
1541 -#else
1542 -               if (errno == EAGAIN) return 0;
1543 -               if (errno == EINTR) {
1544 -                       /* we have been interrupted before we could read */
1545 -                       con->is_readable = 1;
1546 -                       return 0;
1547 -               }
1548 -               
1549 -               if (errno != ECONNRESET) {
1550 -                       /* expected for keep-alive */
1551 -                       log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
1552 -               }
1553 -#endif
1554 -               connection_set_state(srv, con, CON_STATE_ERROR);
1555 -               
1556 -               return -1;
1557 -       } else if (len == 0) {
1558 +    case NETWORK_STATUS_WAIT_FOR_EVENT:
1559                 con->is_readable = 0;
1560 -               /* the other end close the connection -> KEEP-ALIVE */
1561 -
1562 +        return NETWORK_STATUS_WAIT_FOR_EVENT;
1563 +    case NETWORK_STATUS_INTERRUPTED:
1564 +        con->is_readable = 1;
1565 +        return NETWORK_STATUS_WAIT_FOR_EVENT;
1566 +    case NETWORK_STATUS_CONNECTION_CLOSE:
1567                 /* pipelining */
1568 -
1569 -               return -2;
1570 -       } else if ((size_t)len < b->size - 1) {
1571 -               /* we got less then expected, wait for the next fd-event */
1572 -               
1573                 con->is_readable = 0;
1574 +        return NETWORK_STATUS_CONNECTION_CLOSE;
1575 +    case NETWORK_STATUS_FATAL_ERROR:
1576 +        con->is_readable = 0;
1577 +
1578 +        connection_set_state(srv, con, CON_STATE_ERROR);
1579 +        return NETWORK_STATUS_FATAL_ERROR;
1580 +    default:
1581 +        SEGFAULT();
1582 +        break;
1583         }
1584         
1585 -       b->used = len;
1586 -       b->ptr[b->used++] = '\0';
1587 +    newlen = chunkqueue_length(con->read_queue);
1588         
1589 -       con->bytes_read += len;
1590 -#if 0
1591 -       dump_packet(b->ptr, len);
1592 -#endif
1593 +       con->bytes_read += (newlen - oldlen);
1594         
1595 -       return 0;
1596 +       return NETWORK_STATUS_SUCCESS;
1597  }
1598  
1599  static int connection_handle_write_prepare(server *srv, connection *con) {
1600 @@ -343,6 +230,7 @@
1601                 case HTTP_METHOD_GET:
1602                 case HTTP_METHOD_POST:
1603                 case HTTP_METHOD_HEAD:
1604 +                       /* webdav */
1605                 case HTTP_METHOD_PUT:
1606                 case HTTP_METHOD_MKCOL:
1607                 case HTTP_METHOD_DELETE:
1608 @@ -350,6 +238,8 @@
1609                 case HTTP_METHOD_MOVE:
1610                 case HTTP_METHOD_PROPFIND:
1611                 case HTTP_METHOD_PROPPATCH:
1612 +               case HTTP_METHOD_LOCK:
1613 +               case HTTP_METHOD_UNLOCK:
1614                         break;
1615                 case HTTP_METHOD_OPTIONS:
1616                         /*
1617 @@ -392,6 +282,8 @@
1618         case 403:
1619         case 404:
1620         case 408:
1621 +       case 409:
1622 +       case 410:
1623         case 411:
1624         case 416:
1625         case 423:
1626 @@ -399,6 +291,7 @@
1627         case 501:
1628         case 503:
1629         case 505: 
1630 +       case 509:
1631                 if (con->mode != DIRECT) break;
1632                 
1633                 con->file_finished = 0;
1634 @@ -528,34 +421,37 @@
1635  
1636  static int connection_handle_write(server *srv, connection *con) {
1637         switch(network_write_chunkqueue(srv, con, con->write_queue)) {
1638 -       case 0:
1639 +       case NETWORK_STATUS_SUCCESS:
1640                 if (con->file_finished) {
1641                         connection_set_state(srv, con, CON_STATE_RESPONSE_END);
1642                         joblist_append(srv, con);
1643                 }
1644                 break;
1645 -       case -1: /* error on our side */
1646 +       case NETWORK_STATUS_FATAL_ERROR: /* error on our side */
1647                 log_error_write(srv, __FILE__, __LINE__, "sd",
1648                                 "connection closed: write failed on fd", con->fd);
1649                 connection_set_state(srv, con, CON_STATE_ERROR);
1650                 joblist_append(srv, con);
1651                 break;
1652 -       case -2: /* remote close */
1653 +       case NETWORK_STATUS_CONNECTION_CLOSE: /* remote close */
1654                 connection_set_state(srv, con, CON_STATE_ERROR);
1655                 joblist_append(srv, con);
1656                 break;
1657 -       case 1:
1658 +       case NETWORK_STATUS_WAIT_FOR_EVENT:
1659                 con->is_writable = 0;
1660                 
1661                 /* not finished yet -> WRITE */
1662                 break;
1663 +       case NETWORK_STATUS_INTERRUPTED:
1664 +               con->is_writable = 1;
1665 +               break;
1666 +       case NETWORK_STATUS_UNSET:
1667 +               break;
1668         }
1669         
1670         return 0;
1671  }
1672  
1673 -
1674 -
1675  connection *connection_init(server *srv) {
1676         connection *con;
1677         
1678 @@ -845,17 +741,20 @@
1679                 con->read_idle_ts = srv->cur_ts;
1680         
1681                 switch(connection_handle_read(srv, con)) {
1682 -               case -1:
1683 +               case NETWORK_STATUS_FATAL_ERROR:
1684                         return -1;
1685 -               case -2:
1686 +               case NETWORK_STATUS_CONNECTION_CLOSE:
1687                         /* remote side closed the connection
1688                          * if we still have content, handle it, if not leave here */
1689  
1690                         if (cq->first == cq->last &&
1691 -                           cq->first->mem->used == 0) {
1692 +                (NULL == cq->first ||
1693 +                           cq->first->mem->used == 0)) {
1694  
1695                                 /* conn-closed, leave here */
1696                                 connection_set_state(srv, con, CON_STATE_ERROR);
1697 +
1698 +                return 0;
1699                         }
1700                 default:
1701                         break;
1702 @@ -925,6 +824,7 @@
1703                                 
1704                                 /* the buffer has been read up to the terminator */
1705                                 c->offset += h_term - b.ptr + 4;
1706 +
1707                         } else {
1708                                 /* not found, copy everything */
1709                                 buffer_copy_string_len(con->request.request, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
1710 @@ -1177,6 +1077,13 @@
1711         if (con->state == CON_STATE_READ ||
1712             con->state == CON_STATE_READ_POST) {
1713                 connection_handle_read_state(srv, con);
1714 +               /**
1715 +                * if SSL_read() is not readin in the full packet we won't get
1716 +                * a fdevent as the low-level has already fetched everything.
1717 +                *
1718 +                * we have to call the state-engine to read the rest of the packet
1719 +                */
1720 +               if (con->is_readable) joblist_append(srv, con);
1721         }
1722         
1723         if (con->state == CON_STATE_WRITE &&
1724 @@ -1233,9 +1140,13 @@
1725         cnt_len = sizeof(cnt_addr);
1726  
1727         if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
1728 +#ifdef _WIN32
1729 +        errno = WSAGetLastError();
1730 +#endif
1731                 if ((errno != EAGAIN) &&
1732 +            (errno != EWOULDBLOCK) &&
1733                     (errno != EINTR)) {
1734 -                       log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
1735 +                       log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), srv_socket->fd);
1736                 }
1737                 return NULL;
1738         } else {
1739 @@ -1251,7 +1162,6 @@
1740                 srv->con_opened++;
1741                 
1742                 con = connections_get_new_connection(srv);
1743 -               
1744                 con->fd = cnt;
1745                 con->fde_ndx = -1;
1746  #if 0          
1747 @@ -1268,6 +1178,7 @@
1748                 
1749                 if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) {
1750                         log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
1751 +                       connection_close(srv, con);
1752                         return NULL;
1753                 }
1754  #ifdef USE_OPENSSL
1755 @@ -1276,7 +1187,7 @@
1756                         if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
1757                                 log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
1758                                                 ERR_error_string(ERR_get_error(), NULL));
1759 -                               
1760 +                               connection_close(srv, con);
1761                                 return NULL;
1762                         }
1763                         
1764 @@ -1286,6 +1197,7 @@
1765                         if (1 != (SSL_set_fd(con->ssl, cnt))) {
1766                                 log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
1767                                                 ERR_error_string(ERR_get_error(), NULL));
1768 +                               connection_close(srv, con);
1769                                 return NULL;
1770                         }
1771                 }
1772 --- lighttpd-1.4.11/src/crc32.h 2005-09-30 20:18:59.000000000 +0300
1773 +++ lighttpd/src/crc32.h        2006-07-11 21:23:40.131857983 +0300
1774 @@ -6,6 +6,7 @@
1775  #endif
1776  
1777  #include <sys/types.h>
1778 +#include <stdlib.h>
1779  
1780  #if defined HAVE_STDINT_H
1781  #include <stdint.h>
1782 @@ -13,6 +14,10 @@
1783  #include <inttypes.h>
1784  #endif
1785  
1786 +#ifdef _WIN32
1787 +#define uint32_t unsigned __int32
1788 +#endif
1789 +
1790  uint32_t generate_crc32c(char *string, size_t length);
1791  
1792  #endif
1793 --- lighttpd-1.4.11/src/etag.h  2005-08-11 01:26:40.000000000 +0300
1794 +++ lighttpd/src/etag.h 2006-07-11 21:23:40.027851469 +0300
1795 @@ -3,7 +3,6 @@
1796  
1797  #include <sys/types.h>
1798  #include <sys/stat.h>
1799 -#include <unistd.h>
1800  
1801  #include "buffer.h"
1802  
1803 --- lighttpd-1.4.11/src/fdevent.c       2005-11-15 10:51:05.000000000 +0200
1804 +++ lighttpd/src/fdevent.c      2006-07-11 21:23:40.287867754 +0300
1805 @@ -2,7 +2,6 @@
1806  
1807  #include "settings.h"
1808  
1809 -#include <unistd.h>
1810  #include <stdlib.h>
1811  #include <string.h>
1812  #include <errno.h>
1813 @@ -12,6 +11,8 @@
1814  #include "fdevent.h"
1815  #include "buffer.h"
1816  
1817 +#include "sys-socket.h"
1818 +
1819  fdevents *fdevent_init(size_t maxfds, fdevent_handler_t type) {
1820         fdevents *ev;
1821         
1822 @@ -181,6 +182,9 @@
1823  }
1824  
1825  int fdevent_fcntl_set(fdevents *ev, int fd) {
1826 +#ifdef _WIN32
1827 +    int i = 1;
1828 +#endif
1829  #ifdef FD_CLOEXEC
1830         /* close fd on exec (cgi) */
1831         fcntl(fd, F_SETFD, FD_CLOEXEC);
1832 @@ -188,6 +192,8 @@
1833         if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
1834  #ifdef O_NONBLOCK      
1835         return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
1836 +#elif defined _WIN32
1837 +    return ioctlsocket(fd, FIONBIO, &i);
1838  #else
1839         return 0;
1840  #endif
1841 --- lighttpd-1.4.11/src/fdevent.h       2005-09-27 11:26:33.000000000 +0300
1842 +++ lighttpd/src/fdevent.h      2006-07-11 21:23:39.883842449 +0300
1843 @@ -31,9 +31,11 @@
1844  #  include <signal.h>
1845  # endif
1846  #endif
1847 -
1848 +#ifdef _WIN32
1849 +# define HAVE_SELECT
1850 +#endif
1851  #if defined HAVE_SELECT
1852 -# ifdef __WIN32
1853 +# ifdef _WIN32
1854  #  include <winsock2.h>
1855  # endif
1856  # define USE_SELECT
1857 --- lighttpd-1.4.11/src/fdevent_freebsd_kqueue.c        2005-09-01 10:46:24.000000000 +0300
1858 +++ lighttpd/src/fdevent_freebsd_kqueue.c       2006-07-11 21:23:39.987848963 +0300
1859 @@ -1,6 +1,5 @@
1860  #include <sys/types.h>
1861  
1862 -#include <unistd.h>
1863  #include <stdlib.h>
1864  #include <stdio.h>
1865  #include <string.h>
1866 --- lighttpd-1.4.11/src/fdevent_linux_rtsig.c   2005-11-21 19:56:11.000000000 +0200
1867 +++ lighttpd/src/fdevent_linux_rtsig.c  2006-07-11 21:23:40.179860989 +0300
1868 @@ -1,6 +1,5 @@
1869  #include <sys/types.h>
1870  
1871 -#include <unistd.h>
1872  #include <stdlib.h>
1873  #include <stdio.h>
1874  #include <string.h>
1875 @@ -14,6 +13,7 @@
1876  #include "fdevent.h"
1877  #include "settings.h"
1878  #include "buffer.h"
1879 +#include "sys-process.h"
1880  
1881  #ifdef USE_LINUX_SIGIO
1882  static void fdevent_linux_rtsig_free(fdevents *ev) {
1883 --- lighttpd-1.4.11/src/fdevent_linux_sysepoll.c        2005-09-30 20:29:27.000000000 +0300
1884 +++ lighttpd/src/fdevent_linux_sysepoll.c       2006-07-11 21:23:40.223863745 +0300
1885 @@ -1,6 +1,5 @@
1886  #include <sys/types.h>
1887  
1888 -#include <unistd.h>
1889  #include <stdlib.h>
1890  #include <stdio.h>
1891  #include <string.h>
1892 @@ -12,6 +11,8 @@
1893  #include "settings.h"
1894  #include "buffer.h"
1895  
1896 +#include "sys-files.h"
1897 +
1898  #ifdef USE_LINUX_EPOLL
1899  static void fdevent_linux_sysepoll_free(fdevents *ev) {
1900         close(ev->epoll_fd);
1901 --- lighttpd-1.4.11/src/fdevent_poll.c  2005-11-18 13:59:16.000000000 +0200
1902 +++ lighttpd/src/fdevent_poll.c 2006-07-11 21:23:40.207862743 +0300
1903 @@ -1,6 +1,5 @@
1904  #include <sys/types.h>
1905  
1906 -#include <unistd.h>
1907  #include <stdlib.h>
1908  #include <stdio.h>
1909  #include <string.h>
1910 --- lighttpd-1.4.11/src/fdevent_select.c        2005-08-31 11:12:46.000000000 +0300
1911 +++ lighttpd/src/fdevent_select.c       2006-07-11 21:23:40.211862994 +0300
1912 @@ -1,18 +1,19 @@
1913 -#include <sys/time.h>
1914  #include <sys/types.h>
1915  
1916 -#include <unistd.h>
1917  #include <stdlib.h>
1918  #include <string.h>
1919  #include <errno.h>
1920  #include <signal.h>
1921  #include <fcntl.h>
1922  #include <assert.h>
1923 +#include <stdio.h>
1924  
1925  #include "fdevent.h"
1926  #include "settings.h"
1927  #include "buffer.h"
1928  
1929 +#include "sys-socket.h"
1930 +
1931  #ifdef USE_SELECT
1932  
1933  static int fdevent_select_reset(fdevents *ev) {
1934 @@ -38,7 +39,9 @@
1935         UNUSED(fde_ndx);
1936  
1937         /* we should be protected by max-fds, but you never know */
1938 +#ifndef _WIN32
1939         assert(fd < FD_SETSIZE);
1940 +#endif
1941  
1942         if (events & FDEVENT_IN) {
1943                 FD_SET(fd, &(ev->select_set_read));
1944 --- lighttpd-1.4.11/src/fdevent_solaris_devpoll.c       2005-09-01 10:45:26.000000000 +0300
1945 +++ lighttpd/src/fdevent_solaris_devpoll.c      2006-07-11 21:23:40.015850717 +0300
1946 @@ -1,6 +1,5 @@
1947  #include <sys/types.h>
1948  
1949 -#include <unistd.h>
1950  #include <stdlib.h>
1951  #include <stdio.h>
1952  #include <string.h>
1953 --- lighttpd-1.4.11/src/http-header-glue.c      2006-02-08 15:31:36.000000000 +0200
1954 +++ lighttpd/src/http-header-glue.c     2006-07-11 21:23:40.187861491 +0300
1955 @@ -261,13 +261,22 @@
1956                                                 con->http_status = 304;
1957                                                 return HANDLER_FINISHED;
1958                                         } else {
1959 +#ifdef HAVE_STRPTIME
1960                                                 char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
1961 -
1962 -                                               /* convert to timestamp */
1963 -                                               if (used_len < sizeof(buf)) {
1964                                                         time_t t_header, t_file;
1965                                                         struct tm tm;
1966                                                         
1967 +                                               /* check if we can safely copy the string */
1968 +                                               if (used_len >= sizeof(buf)) {
1969 +                                                       log_error_write(srv, __FILE__, __LINE__, "ssdd",
1970 +                                                                       "DEBUG: Last-Modified check failed as the received timestamp was too long:",
1971 +                                                                       con->request.http_if_modified_since, used_len, sizeof(buf) - 1);
1972 +
1973 +                                                       con->http_status = 412;
1974 +                                                       return HANDLER_FINISHED;
1975 +                                               }
1976 +
1977 +
1978                                                         strncpy(buf, con->request.http_if_modified_since, used_len);
1979                                                         buf[used_len] = '\0';
1980                                                         
1981 @@ -277,18 +286,13 @@
1982                                                         strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
1983                                                         t_file = mktime(&tm);
1984  
1985 -                                                       if (t_file > t_header) {
1986 -                                                               con->http_status = 304;
1987 -                                                               return HANDLER_FINISHED;
1988 -                                                       }
1989 -                                               } else {
1990 -                                                       log_error_write(srv, __FILE__, __LINE__, "ssdd", 
1991 -                                                                       "DEBUG: Last-Modified check failed as the received timestamp was too long:", 
1992 -                                                                       con->request.http_if_modified_since, used_len, sizeof(buf) - 1);
1993 +                                               if (t_file > t_header) return HANDLER_GO_ON;
1994                                                         
1995 -                                                       con->http_status = 412;
1996 +                                               con->http_status = 304;
1997                                                         return HANDLER_FINISHED;
1998 -                                               }
1999 +#else
2000 +                        return HANDLER_GO_ON;
2001 +#endif
2002                                         }
2003                                 } else {
2004                                         con->http_status = 304;
2005 @@ -312,6 +316,31 @@
2006                 if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
2007                         con->http_status = 304;
2008                         return HANDLER_FINISHED;
2009 +               } else {
2010 +#ifdef HAVE_STRPTIME
2011 +                       char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
2012 +                       time_t t_header, t_file;
2013 +                       struct tm tm;
2014 +
2015 +                       /* convert to timestamp */
2016 +                       if (used_len >= sizeof(buf)) return HANDLER_GO_ON;
2017 +
2018 +                       strncpy(buf, con->request.http_if_modified_since, used_len);
2019 +                       buf[used_len] = '\0';
2020 +
2021 +                       strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
2022 +                       t_header = mktime(&tm);
2023 +
2024 +                       strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
2025 +                       t_file = mktime(&tm);
2026 +
2027 +                       if (t_file > t_header) return HANDLER_GO_ON;
2028 +
2029 +                       con->http_status = 304;
2030 +                       return HANDLER_FINISHED;
2031 +#else
2032 +            return HANDLER_GO_ON;
2033 +#endif
2034                 }
2035         }
2036  
2037 --- lighttpd-1.4.11/src/http_auth.c     2006-02-01 13:02:52.000000000 +0200
2038 +++ lighttpd/src/http_auth.c    2006-07-11 21:23:40.115856981 +0300
2039 @@ -22,7 +22,6 @@
2040  #include <string.h>
2041  #include <time.h>
2042  #include <errno.h>
2043 -#include <unistd.h>
2044  #include <ctype.h>
2045  
2046  #include "server.h"
2047 @@ -31,23 +30,14 @@
2048  #include "http_auth_digest.h"
2049  #include "stream.h"
2050  
2051 +#include "sys-strings.h"
2052 +
2053  #ifdef USE_OPENSSL
2054  # include <openssl/md5.h>
2055  #else
2056  # include "md5.h"
2057  #endif
2058  
2059 -
2060 -#ifdef USE_PAM
2061 -#include <security/pam_appl.h>
2062 -#include <security/pam_misc.h>
2063 -
2064 -static struct pam_conv conv = {
2065 -       misc_conv,
2066 -               NULL
2067 -};
2068 -#endif
2069 -
2070  handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
2071  
2072  static const char base64_pad = '=';
2073 @@ -509,33 +499,6 @@
2074                 if (0 == strcmp(password->ptr, pw)) {
2075                         return 0;
2076                 }
2077 -       } else if (p->conf.auth_backend == AUTH_BACKEND_PAM) { 
2078 -#ifdef USE_PAM
2079 -               pam_handle_t *pamh=NULL;
2080 -               int retval;
2081 -               
2082 -               retval = pam_start("lighttpd", username->ptr, &conv, &pamh);
2083 -               
2084 -               if (retval == PAM_SUCCESS)
2085 -                       retval = pam_authenticate(pamh, 0);    /* is user really user? */
2086 -               
2087 -               if (retval == PAM_SUCCESS)
2088 -                       retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
2089 -               
2090 -               /* This is where we have been authorized or not. */
2091 -               
2092 -               if (pam_end(pamh,retval) != PAM_SUCCESS) {     /* close Linux-PAM */
2093 -                       pamh = NULL;
2094 -                       log_error_write(srv, __FILE__, __LINE__, "s", "failed to release authenticator");
2095 -               }
2096 -               
2097 -               if (retval == PAM_SUCCESS) {
2098 -                       log_error_write(srv, __FILE__, __LINE__, "s", "Authenticated");
2099 -                       return 0;
2100 -               } else {
2101 -                       log_error_write(srv, __FILE__, __LINE__, "s", "Not Authenticated");
2102 -               }
2103 -#endif
2104         } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { 
2105  #ifdef USE_LDAP
2106                 LDAP *ldap;
2107 --- lighttpd-1.4.11/src/http_auth.h     2005-08-14 17:12:31.000000000 +0300
2108 +++ lighttpd/src/http_auth.h    2006-07-11 21:23:40.119857231 +0300
2109 @@ -9,9 +9,13 @@
2110  # include <ldap.h>
2111  #endif
2112  
2113 -typedef enum { AUTH_BACKEND_UNSET, AUTH_BACKEND_PLAIN, 
2114 -               AUTH_BACKEND_LDAP, AUTH_BACKEND_HTPASSWD, 
2115 -               AUTH_BACKEND_HTDIGEST, AUTH_BACKEND_PAM } auth_backend_t;
2116 +typedef enum {
2117 +       AUTH_BACKEND_UNSET,
2118 +       AUTH_BACKEND_PLAIN,
2119 +       AUTH_BACKEND_LDAP,
2120 +       AUTH_BACKEND_HTPASSWD,
2121 +       AUTH_BACKEND_HTDIGEST
2122 +} auth_backend_t;
2123  
2124  typedef struct {
2125         /* auth */
2126 --- lighttpd-1.4.11/src/http_chunk.c    2005-08-11 01:26:50.000000000 +0300
2127 +++ lighttpd/src/http_chunk.c   2006-07-11 21:23:40.251865499 +0300
2128 @@ -9,7 +9,6 @@
2129  
2130  #include <stdlib.h>
2131  #include <fcntl.h>
2132 -#include <unistd.h>
2133  
2134  #include <stdio.h>
2135  #include <errno.h>
2136 --- lighttpd-1.4.11/src/keyvalue.c      2006-03-02 16:08:06.000000000 +0200
2137 +++ lighttpd/src/keyvalue.c     2006-07-11 21:23:40.027851469 +0300
2138 @@ -87,6 +87,7 @@
2139         { 504, "Gateway Timeout" },
2140         { 505, "HTTP Version Not Supported" },
2141         { 507, "Insufficient Storage" }, /* WebDAV */
2142 +       { 509, "Bandwidth Limit exceeded" },
2143         
2144         { -1, NULL }
2145  };
2146 --- lighttpd-1.4.11/src/log.c   2005-11-07 15:01:35.000000000 +0200
2147 +++ lighttpd/src/log.c  2006-07-11 21:23:40.275867002 +0300
2148 @@ -5,7 +5,6 @@
2149  #include <errno.h>
2150  #include <fcntl.h>
2151  #include <time.h>
2152 -#include <unistd.h>
2153  #include <string.h>
2154  #include <stdlib.h>
2155  
2156 @@ -16,6 +15,10 @@
2157  #include "config.h"
2158  #endif
2159  
2160 +#ifdef _WIN32
2161 +#undef HAVE_SYSLOG_H
2162 +#endif
2163 +
2164  #ifdef HAVE_SYSLOG_H
2165  #include <syslog.h>
2166  #endif
2167 @@ -23,6 +26,8 @@
2168  #include "log.h"
2169  #include "array.h"
2170  
2171 +#include "sys-files.h"
2172 +
2173  #ifdef HAVE_VALGRIND_VALGRIND_H
2174  #include <valgrind/valgrind.h>
2175  #endif
2176 @@ -246,9 +251,11 @@
2177                 BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
2178                 write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
2179                 break;
2180 +#ifdef HAVE_SYSLOG_H
2181         case ERRORLOG_SYSLOG:
2182                 syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
2183                 break;
2184 +#endif
2185         }
2186         
2187         return 0;
2188 --- lighttpd-1.4.11/src/md5.h   2005-11-17 16:20:40.000000000 +0200
2189 +++ lighttpd/src/md5.h  2006-07-11 21:23:40.155859486 +0300
2190 @@ -30,9 +30,15 @@
2191  # include <inttypes.h>
2192  #endif
2193  
2194 +#ifdef _WIN32
2195 +#define UINT4 unsigned __int32
2196 +#define UINT2 unsigned __int16
2197 +#define POINTER unsigned char *
2198 +#else
2199  #define UINT4 uint32_t
2200  #define UINT2 uint16_t
2201  #define POINTER unsigned char *
2202 +#endif
2203  
2204  /* MD5 context. */
2205  typedef struct {
2206 --- lighttpd-1.4.11/src/mod_access.c    2006-01-14 19:44:54.000000000 +0200
2207 +++ lighttpd/src/mod_access.c   2006-07-11 21:23:40.219863495 +0300
2208 @@ -8,6 +8,8 @@
2209  
2210  #include "plugin.h"
2211  
2212 +#include "sys-strings.h"
2213 +
2214  typedef struct {
2215         array *access_deny;
2216  } plugin_config;
2217 @@ -81,13 +83,11 @@
2218         return HANDLER_GO_ON;
2219  }
2220  
2221 -#define PATCH(x) \
2222 -       p->conf.x = s->x;
2223  static int mod_access_patch_connection(server *srv, connection *con, plugin_data *p) {
2224         size_t i, j;
2225         plugin_config *s = p->config_storage[0];
2226  
2227 -       PATCH(access_deny);
2228 +       PATCH_OPTION(access_deny);
2229         
2230         /* skip the first, the global context */
2231         for (i = 1; i < srv->config_context->used; i++) {
2232 @@ -102,14 +102,13 @@
2233                         data_unset *du = dc->value->data[j];
2234                         
2235                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-deny"))) {
2236 -                               PATCH(access_deny);
2237 +                               PATCH_OPTION(access_deny);
2238                         }
2239                 }
2240         }
2241         
2242         return 0;
2243  }
2244 -#undef PATCH
2245  
2246  URIHANDLER_FUNC(mod_access_uri_handler) {
2247         plugin_data *p = p_d;
2248 --- lighttpd-1.4.11/src/mod_accesslog.c 2006-01-31 14:01:43.000000000 +0200
2249 +++ lighttpd/src/mod_accesslog.c        2006-07-11 21:23:40.219863495 +0300
2250 @@ -6,8 +6,7 @@
2251  #include <ctype.h>
2252  #include <stdlib.h>
2253  #include <string.h>
2254 -#include <fcntl.h>
2255 -#include <unistd.h>
2256 +#include <fcntl.h> /* only the defines on windows */
2257  #include <errno.h>
2258  #include <time.h>
2259  
2260 @@ -22,6 +21,7 @@
2261  #include "inet_ntop_cache.h"
2262  
2263  #include "sys-socket.h"
2264 +#include "sys-files.h"
2265  
2266  #ifdef HAVE_SYSLOG_H
2267  # include <syslog.h>
2268 @@ -517,8 +517,9 @@
2269                         
2270                         return HANDLER_ERROR;
2271                 }
2272 +#ifndef _WIN32
2273                 fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC);
2274 -       
2275 +#endif
2276         }
2277         
2278         return HANDLER_GO_ON;
2279 @@ -567,20 +568,18 @@
2280         return HANDLER_GO_ON;
2281  }
2282  
2283 -#define PATCH(x) \
2284 -       p->conf.x = s->x;
2285  static int mod_accesslog_patch_connection(server *srv, connection *con, plugin_data *p) {
2286         size_t i, j;
2287         plugin_config *s = p->config_storage[0];
2288         
2289 -       PATCH(access_logfile);
2290 -       PATCH(format);
2291 -       PATCH(log_access_fd);
2292 -       PATCH(last_generated_accesslog_ts_ptr);
2293 -       PATCH(access_logbuffer);
2294 -       PATCH(ts_accesslog_str);
2295 -       PATCH(parsed_format);
2296 -       PATCH(use_syslog);
2297 +       PATCH_OPTION(access_logfile);
2298 +       PATCH_OPTION(format);
2299 +       PATCH_OPTION(log_access_fd);
2300 +       PATCH_OPTION(last_generated_accesslog_ts_ptr);
2301 +       PATCH_OPTION(access_logbuffer);
2302 +       PATCH_OPTION(ts_accesslog_str);
2303 +       PATCH_OPTION(parsed_format);
2304 +       PATCH_OPTION(use_syslog);
2305         
2306         /* skip the first, the global context */
2307         for (i = 1; i < srv->config_context->used; i++) {
2308 @@ -595,23 +594,22 @@
2309                         data_unset *du = dc->value->data[j];
2310                         
2311                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.filename"))) {
2312 -                               PATCH(access_logfile);
2313 -                               PATCH(log_access_fd);
2314 -                               PATCH(last_generated_accesslog_ts_ptr);
2315 -                               PATCH(access_logbuffer);
2316 -                               PATCH(ts_accesslog_str);
2317 +                               PATCH_OPTION(access_logfile);
2318 +                               PATCH_OPTION(log_access_fd);
2319 +                               PATCH_OPTION(last_generated_accesslog_ts_ptr);
2320 +                               PATCH_OPTION(access_logbuffer);
2321 +                               PATCH_OPTION(ts_accesslog_str);
2322                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.format"))) {
2323 -                               PATCH(format);
2324 -                               PATCH(parsed_format);
2325 +                               PATCH_OPTION(format);
2326 +                               PATCH_OPTION(parsed_format);
2327                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.use-syslog"))) {
2328 -                               PATCH(use_syslog);
2329 +                               PATCH_OPTION(use_syslog);
2330                         }
2331                 }
2332         }
2333         
2334         return 0;
2335  }
2336 -#undef PATCH
2337  
2338  REQUESTDONE_FUNC(log_access_write) {
2339         plugin_data *p = p_d;
2340 --- lighttpd-1.4.11/src/mod_alias.c     2006-03-01 23:18:51.000000000 +0200
2341 +++ lighttpd/src/mod_alias.c    2006-07-11 21:23:39.979848462 +0300
2342 @@ -8,6 +8,7 @@
2343  #include "buffer.h"
2344  
2345  #include "plugin.h"
2346 +#include "sys-strings.h"
2347  
2348  /* plugin config for all request/connections */
2349  typedef struct {
2350 @@ -114,13 +115,11 @@
2351         return HANDLER_GO_ON;
2352  }
2353  
2354 -#define PATCH(x) \
2355 -       p->conf.x = s->x;
2356  static int mod_alias_patch_connection(server *srv, connection *con, plugin_data *p) {
2357         size_t i, j;
2358         plugin_config *s = p->config_storage[0];
2359         
2360 -       PATCH(alias);
2361 +       PATCH_OPTION(alias);
2362         
2363         /* skip the first, the global context */
2364         for (i = 1; i < srv->config_context->used; i++) {
2365 @@ -135,14 +134,13 @@
2366                         data_unset *du = dc->value->data[j];
2367                         
2368                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("alias.url"))) {
2369 -                               PATCH(alias);
2370 +                               PATCH_OPTION(alias);
2371                         }
2372                 }
2373         }
2374         
2375         return 0;
2376  }
2377 -#undef PATCH
2378  
2379  PHYSICALPATH_FUNC(mod_alias_physical_handler) {
2380         plugin_data *p = p_d;
2381 --- lighttpd-1.4.11/src/mod_auth.c      2006-02-15 20:01:31.000000000 +0200
2382 +++ lighttpd/src/mod_auth.c     2006-07-11 21:23:40.171860488 +0300
2383 @@ -5,13 +5,15 @@
2384  #include <string.h>
2385  #include <errno.h>
2386  #include <fcntl.h>
2387 -#include <unistd.h>
2388  
2389  #include "plugin.h"
2390  #include "http_auth.h"
2391  #include "log.h"
2392  #include "response.h"
2393  
2394 +#include "sys-strings.h"
2395 +#include "sys-files.h"
2396 +
2397  handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
2398  
2399  
2400 @@ -93,30 +95,28 @@
2401         return HANDLER_GO_ON;
2402  }
2403  
2404 -#define PATCH(x) \
2405 -       p->conf.x = s->x;
2406  static int mod_auth_patch_connection(server *srv, connection *con, mod_auth_plugin_data *p) {
2407         size_t i, j;
2408         mod_auth_plugin_config *s = p->config_storage[0];
2409  
2410 -       PATCH(auth_backend);
2411 -       PATCH(auth_plain_groupfile);
2412 -       PATCH(auth_plain_userfile);
2413 -       PATCH(auth_htdigest_userfile);
2414 -       PATCH(auth_htpasswd_userfile);
2415 -       PATCH(auth_require);
2416 -       PATCH(auth_debug);
2417 -       PATCH(auth_ldap_hostname);
2418 -       PATCH(auth_ldap_basedn);
2419 -       PATCH(auth_ldap_binddn);
2420 -       PATCH(auth_ldap_bindpw);
2421 -       PATCH(auth_ldap_filter);
2422 -       PATCH(auth_ldap_cafile);
2423 -       PATCH(auth_ldap_starttls);
2424 +       PATCH_OPTION(auth_backend);
2425 +       PATCH_OPTION(auth_plain_groupfile);
2426 +       PATCH_OPTION(auth_plain_userfile);
2427 +       PATCH_OPTION(auth_htdigest_userfile);
2428 +       PATCH_OPTION(auth_htpasswd_userfile);
2429 +       PATCH_OPTION(auth_require);
2430 +       PATCH_OPTION(auth_debug);
2431 +       PATCH_OPTION(auth_ldap_hostname);
2432 +       PATCH_OPTION(auth_ldap_basedn);
2433 +       PATCH_OPTION(auth_ldap_binddn);
2434 +       PATCH_OPTION(auth_ldap_bindpw);
2435 +       PATCH_OPTION(auth_ldap_filter);
2436 +       PATCH_OPTION(auth_ldap_cafile);
2437 +       PATCH_OPTION(auth_ldap_starttls);
2438  #ifdef USE_LDAP
2439 -       PATCH(ldap);
2440 -       PATCH(ldap_filter_pre);
2441 -       PATCH(ldap_filter_post);
2442 +       PATCH_OPTION(ldap);
2443 +       PATCH_OPTION(ldap_filter_pre);
2444 +       PATCH_OPTION(ldap_filter_post);
2445  #endif
2446         
2447         /* skip the first, the global context */
2448 @@ -132,41 +132,40 @@
2449                         data_unset *du = dc->value->data[j];
2450                         
2451                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend"))) {
2452 -                               PATCH(auth_backend);
2453 +                               PATCH_OPTION(auth_backend);
2454                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.groupfile"))) {
2455 -                               PATCH(auth_plain_groupfile);
2456 +                               PATCH_OPTION(auth_plain_groupfile);
2457                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.userfile"))) {
2458 -                               PATCH(auth_plain_userfile);
2459 +                               PATCH_OPTION(auth_plain_userfile);
2460                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htdigest.userfile"))) {
2461 -                               PATCH(auth_htdigest_userfile);
2462 +                               PATCH_OPTION(auth_htdigest_userfile);
2463                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htpasswd.userfile"))) {
2464 -                               PATCH(auth_htpasswd_userfile);
2465 +                               PATCH_OPTION(auth_htpasswd_userfile);
2466                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.require"))) {
2467 -                               PATCH(auth_require);
2468 +                               PATCH_OPTION(auth_require);
2469                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.debug"))) {
2470 -                               PATCH(auth_debug);
2471 +                               PATCH_OPTION(auth_debug);
2472                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.hostname"))) {
2473 -                               PATCH(auth_ldap_hostname);
2474 +                               PATCH_OPTION(auth_ldap_hostname);
2475  #ifdef USE_LDAP
2476 -                               PATCH(ldap);
2477 -                               PATCH(ldap_filter_pre);
2478 -                               PATCH(ldap_filter_post);
2479 +                               PATCH_OPTION(ldap);
2480 +                               PATCH_OPTION(ldap_filter_pre);
2481 +                               PATCH_OPTION(ldap_filter_post);
2482  #endif
2483                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) {
2484 -                               PATCH(auth_ldap_basedn);
2485 +                               PATCH_OPTION(auth_ldap_basedn);
2486                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) {
2487 -                               PATCH(auth_ldap_filter);
2488 +                               PATCH_OPTION(auth_ldap_filter);
2489                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.ca-file"))) {
2490 -                               PATCH(auth_ldap_cafile);
2491 +                               PATCH_OPTION(auth_ldap_cafile);
2492                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) {
2493 -                               PATCH(auth_ldap_starttls);
2494 +                               PATCH_OPTION(auth_ldap_starttls);
2495                         }
2496                 }
2497         }
2498         
2499         return 0;
2500  }
2501 -#undef PATCH
2502  
2503  static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
2504         size_t k;
2505 --- lighttpd-1.4.11/src/mod_cgi.c       2006-02-22 15:15:10.000000000 +0200
2506 +++ lighttpd/src/mod_cgi.c      2006-07-11 21:23:39.887842700 +0300
2507 @@ -1,21 +1,8 @@
2508  #include <sys/types.h>
2509 -#ifdef __WIN32
2510 -#include <winsock2.h>
2511 -#else
2512 -#include <sys/socket.h>
2513 -#include <sys/wait.h>
2514 -#include <sys/mman.h>
2515 -
2516 -#include <netinet/in.h>
2517 -
2518 -#include <arpa/inet.h>
2519 -#endif
2520  
2521 -#include <unistd.h>
2522  #include <errno.h>
2523  #include <stdlib.h>
2524  #include <string.h>
2525 -#include <fdevent.h>
2526  #include <signal.h>
2527  #include <ctype.h>
2528  #include <assert.h>
2529 @@ -29,9 +16,16 @@
2530  #include "connections.h"
2531  #include "joblist.h"
2532  #include "http_chunk.h"
2533 +#include "fdevent.h"
2534  
2535  #include "plugin.h"
2536  
2537 +#include "sys-files.h"
2538 +#include "sys-mmap.h"
2539 +#include "sys-socket.h"
2540 +#include "sys-strings.h"
2541 +#include "sys-process.h"
2542 +
2543  #ifdef HAVE_SYS_FILIO_H
2544  # include <sys/filio.h>
2545  #endif
2546 @@ -45,6 +39,7 @@
2547         size_t used;
2548  } char_array;
2549  
2550 +#define pid_t int
2551  typedef struct {
2552         pid_t *ptr;
2553         size_t used;
2554 @@ -478,7 +473,7 @@
2555         
2556         if (con->mode != p->id) return HANDLER_GO_ON;
2557  
2558 -#ifndef __WIN32
2559 +#ifndef _WIN32
2560         
2561         /* the connection to the browser went away, but we still have a connection
2562          * to the CGI script 
2563 @@ -509,6 +504,7 @@
2564         /* if waitpid hasn't been called by response.c yet, do it here */
2565         if (pid) {
2566                 /* check if the CGI-script is already gone */
2567 +#ifndef _WIN32
2568                 switch(waitpid(pid, &status, WNOHANG)) {
2569                 case 0:
2570                         /* not finished yet */
2571 @@ -558,7 +554,7 @@
2572                 
2573         
2574                 kill(pid, SIGTERM);
2575 -               
2576 +#endif
2577                 /* cgi-script is still alive, queue the PID for removal */
2578                 cgi_pid_add(srv, p, pid);
2579         }
2580 @@ -695,7 +691,7 @@
2581         int from_cgi_fds[2];
2582         struct stat st;
2583         
2584 -#ifndef __WIN32        
2585 +#ifndef _WIN32
2586         
2587         if (cgi_handler->used > 1) {
2588                 /* stat the exec file */
2589 @@ -811,6 +807,9 @@
2590                 cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200"));
2591                 if (!buffer_is_empty(con->uri.query)) {
2592                         cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
2593 +               } else {
2594 +                       /* set a empty QUERY_STRING */
2595 +                       cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
2596                 }
2597                 if (!buffer_is_empty(con->request.orig_uri)) {
2598                         cgi_env_add(&env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
2599 @@ -1101,13 +1100,11 @@
2600  #endif
2601  }
2602  
2603 -#define PATCH(x) \
2604 -       p->conf.x = s->x;
2605  static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p) {
2606         size_t i, j;
2607         plugin_config *s = p->config_storage[0];
2608         
2609 -       PATCH(cgi);
2610 +       PATCH_OPTION(cgi);
2611         
2612         /* skip the first, the global context */
2613         for (i = 1; i < srv->config_context->used; i++) {
2614 @@ -1122,14 +1119,13 @@
2615                         data_unset *du = dc->value->data[j];
2616                         
2617                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.assign"))) {
2618 -                               PATCH(cgi);
2619 +                               PATCH_OPTION(cgi);
2620                         }
2621                 }
2622         }
2623         
2624         return 0;
2625  }
2626 -#undef PATCH
2627  
2628  URIHANDLER_FUNC(cgi_is_handled) {
2629         size_t k, s_len;
2630 @@ -1168,7 +1164,7 @@
2631         plugin_data *p = p_d;
2632         size_t ndx;
2633         /* the trigger handle only cares about lonely PID which we have to wait for */
2634 -#ifndef __WIN32
2635 +#ifndef _WIN32
2636  
2637         for (ndx = 0; ndx < p->cgi_pid.used; ndx++) {
2638                 int status;
2639 @@ -1218,7 +1214,7 @@
2640         log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid);
2641  #endif 
2642         if (hctx->pid == 0) return HANDLER_FINISHED;
2643 -#ifndef __WIN32        
2644 +#ifndef _WIN32
2645         switch(waitpid(hctx->pid, &status, WNOHANG)) {
2646         case 0:
2647                 /* we only have for events here if we don't have the header yet,
2648 --- lighttpd-1.4.11/src/mod_cml.c       2006-01-30 13:51:48.000000000 +0200
2649 +++ lighttpd/src/mod_cml.c      2006-07-11 21:23:39.931845456 +0300
2650 @@ -4,7 +4,6 @@
2651  #include <stdlib.h>
2652  #include <string.h>
2653  #include <errno.h>
2654 -#include <unistd.h>
2655  #include <stdio.h>
2656  
2657  #include "buffer.h"
2658 @@ -135,18 +134,16 @@
2659         return HANDLER_GO_ON;
2660  }
2661  
2662 -#define PATCH(x) \
2663 -       p->conf.x = s->x;
2664  static int mod_cml_patch_connection(server *srv, connection *con, plugin_data *p) {
2665         size_t i, j;
2666         plugin_config *s = p->config_storage[0];
2667         
2668 -       PATCH(ext);
2669 +       PATCH_OPTION(ext);
2670  #if defined(HAVE_MEMCACHE_H)
2671 -       PATCH(mc);
2672 +       PATCH_OPTION(mc);
2673  #endif
2674 -       PATCH(mc_namespace);
2675 -       PATCH(power_magnet);
2676 +       PATCH_OPTION(mc_namespace);
2677 +       PATCH_OPTION(power_magnet);
2678         
2679         /* skip the first, the global context */
2680         for (i = 1; i < srv->config_context->used; i++) {
2681 @@ -161,22 +158,21 @@
2682                         data_unset *du = dc->value->data[j];
2683                         
2684                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.extension"))) {
2685 -                               PATCH(ext);
2686 +                               PATCH_OPTION(ext);
2687                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-hosts"))) {
2688  #if defined(HAVE_MEMCACHE_H)
2689 -                               PATCH(mc);
2690 +                               PATCH_OPTION(mc);
2691  #endif
2692                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-namespace"))) {
2693 -                               PATCH(mc_namespace);
2694 +                               PATCH_OPTION(mc_namespace);
2695                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.power-magnet"))) {
2696 -                               PATCH(power_magnet);
2697 +                               PATCH_OPTION(power_magnet);
2698                         }
2699                 }
2700         }
2701         
2702         return 0;
2703  }
2704 -#undef PATCH
2705  
2706  int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
2707         buffer *b;
2708 --- lighttpd-1.4.11/src/mod_cml_funcs.c 2005-11-17 16:15:08.000000000 +0200
2709 +++ lighttpd/src/mod_cml_funcs.c        2006-07-11 21:23:40.083854976 +0300
2710 @@ -4,8 +4,7 @@
2711  #include <stdlib.h>
2712  #include <string.h>
2713  #include <errno.h>
2714 -#include <unistd.h>
2715 -#include <dirent.h>
2716 +
2717  #include <stdio.h>
2718  
2719  #include "buffer.h"
2720 @@ -13,6 +12,7 @@
2721  #include "log.h"
2722  #include "plugin.h"
2723  #include "response.h"
2724 +#include "sys-files.h"
2725  
2726  #include "mod_cml.h"
2727  #include "mod_cml_funcs.h"
2728 @@ -92,7 +92,7 @@
2729         
2730         return 1;
2731  }
2732 -
2733 +#ifndef _WIN32
2734  int f_dir_files_iter(lua_State *L) {
2735         DIR *d;
2736         struct dirent *de;
2737 @@ -136,7 +136,7 @@
2738         
2739         return 1;
2740  }
2741 -
2742 +#endif
2743  int f_file_isreg(lua_State *L) {
2744         struct stat st;
2745         int n = lua_gettop(L);
2746 --- lighttpd-1.4.11/src/mod_cml_lua.c   2006-01-30 13:56:40.000000000 +0200
2747 +++ lighttpd/src/mod_cml_lua.c  2006-07-11 21:23:40.179860989 +0300
2748 @@ -31,6 +31,7 @@
2749  
2750  #include <lua.h>
2751  #include <lualib.h>
2752 +#include <lauxlib.h>
2753  
2754  typedef struct {
2755         stream st;
2756 @@ -220,13 +221,8 @@
2757         stream_open(&rm.st, fn);
2758         
2759         /* push the lua file to the interpreter and see what happends */
2760 -       L = lua_open();
2761 -       
2762 -       luaopen_base(L);
2763 -       luaopen_table(L);
2764 -       luaopen_string(L);
2765 -       luaopen_math(L);
2766 -       luaopen_io(L);
2767 +       L = luaL_newstate();
2768 +       luaL_openlibs(L);
2769         
2770         /* register functions */
2771         lua_register(L, "md5", f_crypto_md5);
2772 --- lighttpd-1.4.11/src/mod_compress.c  2005-11-18 13:49:14.000000000 +0200
2773 +++ lighttpd/src/mod_compress.c 2006-07-11 21:23:40.139858484 +0300
2774 @@ -2,7 +2,6 @@
2775  #include <sys/stat.h>
2776  
2777  #include <fcntl.h>
2778 -#include <unistd.h>
2779  #include <ctype.h>
2780  #include <stdlib.h>
2781  #include <string.h>
2782 @@ -14,6 +13,7 @@
2783  #include "buffer.h"
2784  #include "response.h"
2785  #include "stat_cache.h"
2786 +#include "http_chunk.h"
2787  
2788  #include "plugin.h"
2789  
2790 @@ -33,6 +33,7 @@
2791  #endif
2792  
2793  #include "sys-mmap.h"
2794 +#include "sys-files.h"
2795  
2796  /* request: accept-encoding */
2797  #define HTTP_ACCEPT_ENCODING_IDENTITY BV(0)
2798 @@ -102,6 +103,28 @@
2799         return HANDLER_GO_ON;
2800  }
2801  
2802 +void mkdir_recursive(const char *dir) {
2803 +
2804 +       char dir_copy[256];
2805 +       char *p = dir_copy;
2806 +
2807 +       if (!dir || !dir[0])
2808 +               return;
2809 +
2810 +       strncpy(dir_copy, dir, sizeof(dir_copy) / sizeof(dir_copy[0]));
2811 +
2812 +       while ((p = strchr(p + 1, '/')) != NULL) {
2813 +
2814 +               *p = '\0';
2815 +               if ((mkdir(dir_copy, 0700) != 0) && (errno != EEXIST))
2816 +                       return;
2817 +
2818 +               *p++ = '/';
2819 +       }
2820 +
2821 +       mkdir(dir, 0700);
2822 +}
2823 +
2824  SETDEFAULTS_FUNC(mod_compress_setdefaults) {
2825         plugin_data *p = p_d;
2826         size_t i = 0;
2827 @@ -136,13 +159,21 @@
2828                 if (!buffer_is_empty(s->compress_cache_dir)) {
2829                         struct stat st;
2830                         if (0 != stat(s->compress_cache_dir->ptr, &st)) {
2831 -                               log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir", 
2832 +
2833 +                               log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, attempting to create",
2834 +                                               s->compress_cache_dir, strerror(errno));
2835 +                               mkdir_recursive(s->compress_cache_dir->ptr);
2836 +
2837 +                               if (0 != stat(s->compress_cache_dir->ptr, &st)) {
2838 +
2839 +                                       log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, create failed",
2840                                                 s->compress_cache_dir, strerror(errno));
2841                                 
2842                                 return HANDLER_ERROR;
2843                         }
2844                 }
2845         }
2846 +       }
2847         
2848         return HANDLER_GO_ON;
2849         
2850 @@ -326,6 +357,9 @@
2851         void *start;
2852         const char *filename = fn->ptr;
2853         ssize_t r;
2854 +       stat_cache_entry *compressed_sce = NULL;
2855 +
2856 +       if (buffer_is_empty(p->conf.compress_cache_dir)) return -1;
2857         
2858         /* overflow */
2859         if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1;
2860 @@ -339,7 +373,7 @@
2861         
2862         buffer_reset(p->ofn);
2863         buffer_copy_string_buffer(p->ofn, p->conf.compress_cache_dir);
2864 -       BUFFER_APPEND_SLASH(p->ofn);
2865 +       PATHNAME_APPEND_SLASH(p->ofn);
2866         
2867         if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) {
2868                 size_t offset = p->ofn->used - 1;
2869 @@ -384,26 +418,33 @@
2870         
2871         buffer_append_string_buffer(p->ofn, sce->etag);
2872         
2873 +
2874 +       if (HANDLER_ERROR != stat_cache_get_entry(srv, con, p->ofn, &compressed_sce)) {
2875 +               /* file exists */
2876 +
2877 +               http_chunk_append_file(srv, con, p->ofn, 0, compressed_sce->st.st_size);
2878 +               con->file_finished = 1;
2879 +
2880 +               return 0;
2881 +       }
2882 +
2883         if (-1 == (ofd = open(p->ofn->ptr, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600))) {
2884                 if (errno == EEXIST) {
2885                         /* cache-entry exists */
2886 -#if 0
2887 -                       log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit");
2888 -#endif
2889 -                       buffer_copy_string_buffer(con->physical.path, p->ofn);
2890                         
2891 -                       return 0;
2892                 }
2893                 
2894 -               log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cachefile", p->ofn, "failed", strerror(errno));
2895 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
2896 +                               "creating cachefile", p->ofn,
2897 +                               "failed", strerror(errno));
2898                 
2899                 return -1;
2900         }
2901 -#if 0
2902 -       log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache miss");
2903 -#endif 
2904 +
2905         if (-1 == (ifd = open(filename, O_RDONLY | O_BINARY))) {
2906 -               log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
2907 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
2908 +                               "opening plain-file", fn,
2909 +                               "failed", strerror(errno));
2910                 
2911                 close(ofd);
2912                 
2913 @@ -412,7 +453,9 @@
2914         
2915         
2916         if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
2917 -               log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno));
2918 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
2919 +                               "mmaping", fn,
2920 +                               "failed", strerror(errno));
2921                 
2922                 close(ofd);
2923                 close(ifd);
2924 @@ -455,7 +498,8 @@
2925         
2926         if (ret != 0) return -1;
2927         
2928 -       buffer_copy_string_buffer(con->physical.path, p->ofn);
2929 +       http_chunk_append_file(srv, con, p->ofn, 0, r);
2930 +       con->file_finished = 1;
2931         
2932         return 0;
2933  }
2934 @@ -476,18 +520,19 @@
2935         
2936         if (sce->st.st_size > 128 * 1024 * 1024) return -1;
2937         
2938 -       
2939         if (-1 == (ifd = open(fn->ptr, O_RDONLY | O_BINARY))) {
2940                 log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
2941                 
2942                 return -1;
2943         }
2944         
2945 +       start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0);
2946         
2947 -       if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
2948 +       close(ifd);
2949 +
2950 +       if (MAP_FAILED == start) {
2951                 log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno));
2952                 
2953 -               close(ifd);
2954                 return -1;
2955         }
2956         
2957 @@ -511,7 +556,6 @@
2958         }
2959                 
2960         munmap(start, sce->st.st_size);
2961 -       close(ifd);
2962         
2963         if (ret != 0) return -1;
2964         
2965 @@ -527,16 +571,13 @@
2966         return 0;
2967  }
2968  
2969 -
2970 -#define PATCH(x) \
2971 -       p->conf.x = s->x;
2972  static int mod_compress_patch_connection(server *srv, connection *con, plugin_data *p) {
2973         size_t i, j;
2974         plugin_config *s = p->config_storage[0];
2975  
2976 -       PATCH(compress_cache_dir);
2977 -       PATCH(compress);
2978 -       PATCH(compress_max_filesize);
2979 +       PATCH_OPTION(compress_cache_dir);
2980 +       PATCH_OPTION(compress);
2981 +       PATCH_OPTION(compress_max_filesize);
2982         
2983         /* skip the first, the global context */
2984         for (i = 1; i < srv->config_context->used; i++) {
2985 @@ -551,18 +592,17 @@
2986                         data_unset *du = dc->value->data[j];
2987                         
2988                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.cache-dir"))) {
2989 -                               PATCH(compress_cache_dir);
2990 +                               PATCH_OPTION(compress_cache_dir);
2991                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.filetype"))) {
2992 -                               PATCH(compress);
2993 +                               PATCH_OPTION(compress);
2994                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.max-filesize"))) {
2995 -                               PATCH(compress_max_filesize);
2996 +                               PATCH_OPTION(compress_max_filesize);
2997                         }
2998                 }
2999         }
3000         
3001         return 0;
3002  }
3003 -#undef PATCH
3004  
3005  PHYSICALPATH_FUNC(mod_compress_physical) {
3006         plugin_data *p = p_d;
3007 @@ -589,6 +629,9 @@
3008         /* don't compress files that are too large as we need to much time to handle them */
3009         if (max_fsize && (sce->st.st_size >> 10) > max_fsize) return HANDLER_GO_ON;
3010                 
3011 +       /* compressing the file might lead to larger files instead */
3012 +       if (sce->st.st_size < 128) return HANDLER_GO_ON;
3013 +
3014         /* check if mimetype is in compress-config */
3015         for (m = 0; m < p->conf.compress->used; m++) {
3016                 data_string *compress_ds = (data_string *)p->conf.compress->data[m];
3017 @@ -638,6 +681,19 @@
3018                                         
3019                                         const char *compression_name = NULL;
3020                                         int compression_type = 0;
3021 +                                       buffer *mtime;
3022 +
3023 +                                       mtime = strftime_cache_get(srv, sce->st.st_mtime);
3024 +                                       etag_mutate(con->physical.etag, sce->etag);
3025 +
3026 +                                       response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
3027 +                                       response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
3028 +
3029 +                                       /* perhaps we don't even have to compress the file as the browser still has the
3030 +                                        * current version */
3031 +                                       if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) {
3032 +                                               return HANDLER_FINISHED;
3033 +                                       }
3034                                         
3035                                         /* select best matching encoding */
3036                                         if (matched_encodings & HTTP_ACCEPT_ENCODING_BZIP2) {
3037 @@ -651,29 +707,19 @@
3038                                                 compression_name = dflt_deflate;
3039                                         }
3040                                         
3041 -                                       /* deflate it */
3042 -                                       if (p->conf.compress_cache_dir->used) {
3043 +                                       /* deflate it to file (cached) or to memory */
3044                                                 if (0 == deflate_file_to_file(srv, con, p,
3045 -                                                                             con->physical.path, sce, compression_type)) {
3046 -                                                       buffer *mtime;
3047 -                                                       
3048 -                                                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
3049 -                                                       
3050 -                                                       mtime = strftime_cache_get(srv, sce->st.st_mtime);
3051 -                                                       response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
3052 -
3053 -                                                       etag_mutate(con->physical.etag, sce->etag);
3054 -                                                       response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
3055 -
3056 -                                                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
3057 -
3058 -                                                       return HANDLER_GO_ON;
3059 -                                               }
3060 -                                       } else if (0 == deflate_file_to_buffer(srv, con, p,
3061 +                                                       con->physical.path, sce, compression_type) ||
3062 +                                           0 == deflate_file_to_buffer(srv, con, p,
3063                                                                                con->physical.path, sce, compression_type)) {
3064                                                         
3065 -                                               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
3066 -                                               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
3067 +                                               response_header_overwrite(srv, con,
3068 +                                                               CONST_STR_LEN("Content-Encoding"),
3069 +                                                               compression_name, strlen(compression_name));
3070 +
3071 +                                               response_header_overwrite(srv, con,
3072 +                                                               CONST_STR_LEN("Content-Type"),
3073 +                                                               CONST_BUF_LEN(sce->content_type));
3074                                                 
3075                                                 return HANDLER_FINISHED;
3076                                         }
3077 --- lighttpd-1.4.11/src/mod_dirlisting.c        2006-01-13 00:00:45.000000000 +0200
3078 +++ lighttpd/src/mod_dirlisting.c       2006-07-11 21:23:40.247865249 +0300
3079 @@ -1,11 +1,9 @@
3080  #include <ctype.h>
3081  #include <stdlib.h>
3082  #include <string.h>
3083 -#include <dirent.h>
3084  #include <assert.h>
3085  #include <errno.h>
3086  #include <stdio.h>
3087 -#include <unistd.h>
3088  #include <time.h>
3089  
3090  #include "base.h"
3091 @@ -31,6 +29,9 @@
3092  #include <attr/attributes.h>
3093  #endif
3094  
3095 +#include "sys-files.h"
3096 +#include "sys-strings.h"
3097 +
3098  /* plugin config for all request/connections */
3099  
3100  typedef struct {
3101 @@ -292,21 +293,19 @@
3102         return HANDLER_GO_ON;
3103  }
3104  
3105 -#define PATCH(x) \
3106 -       p->conf.x = s->x;
3107  static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_data *p) {
3108         size_t i, j;
3109         plugin_config *s = p->config_storage[0];
3110  
3111 -       PATCH(dir_listing);
3112 -       PATCH(external_css);
3113 -       PATCH(hide_dot_files);
3114 -       PATCH(encoding);
3115 -       PATCH(show_readme);
3116 -       PATCH(hide_readme_file);
3117 -       PATCH(show_header);
3118 -       PATCH(hide_header_file);
3119 -       PATCH(excludes);
3120 +       PATCH_OPTION(dir_listing);
3121 +       PATCH_OPTION(external_css);
3122 +       PATCH_OPTION(hide_dot_files);
3123 +       PATCH_OPTION(encoding);
3124 +       PATCH_OPTION(show_readme);
3125 +       PATCH_OPTION(hide_readme_file);
3126 +       PATCH_OPTION(show_header);
3127 +       PATCH_OPTION(hide_header_file);
3128 +       PATCH_OPTION(excludes);
3129         
3130         /* skip the first, the global context */
3131         for (i = 1; i < srv->config_context->used; i++) {
3132 @@ -322,30 +321,29 @@
3133                         
3134                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.activate")) ||
3135                             buffer_is_equal_string(du->key, CONST_STR_LEN("server.dir-listing"))) {
3136 -                               PATCH(dir_listing);
3137 +                               PATCH_OPTION(dir_listing);
3138                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-dotfiles"))) {
3139 -                               PATCH(hide_dot_files);
3140 +                               PATCH_OPTION(hide_dot_files);
3141                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.external-css"))) {
3142 -                               PATCH(external_css);
3143 +                               PATCH_OPTION(external_css);
3144                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.encoding"))) {
3145 -                               PATCH(encoding);
3146 +                               PATCH_OPTION(encoding);
3147                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-readme"))) {
3148 -                               PATCH(show_readme);
3149 +                               PATCH_OPTION(show_readme);
3150                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-readme-file"))) {
3151 -                               PATCH(hide_readme_file);
3152 +                               PATCH_OPTION(hide_readme_file);
3153                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-header"))) {
3154 -                               PATCH(show_header);
3155 +                               PATCH_OPTION(show_header);
3156                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-header-file"))) {
3157 -                               PATCH(hide_header_file);
3158 +                               PATCH_OPTION(hide_header_file);
3159                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.excludes"))) {
3160 -                               PATCH(excludes);
3161 +                               PATCH_OPTION(excludes);
3162                         }
3163                 }
3164         }
3165         
3166         return 0;
3167  }
3168 -#undef PATCH
3169  
3170  typedef struct {
3171         size_t  namelen;
3172 @@ -494,7 +492,7 @@
3173                 /* if we have a HEADER file, display it in <pre class="header"></pre> */
3174                 
3175                 buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
3176 -               BUFFER_APPEND_SLASH(p->tmp_buf);
3177 +               PATHNAME_APPEND_SLASH(p->tmp_buf);
3178                 BUFFER_APPEND_STRING_CONST(p->tmp_buf, "HEADER.txt");
3179                 
3180                 if (-1 != stream_open(&s, p->tmp_buf)) {
3181 @@ -543,7 +541,7 @@
3182                 /* if we have a README file, display it in <pre class="readme"></pre> */
3183                 
3184                 buffer_copy_string_buffer(p->tmp_buf,  con->physical.path);
3185 -               BUFFER_APPEND_SLASH(p->tmp_buf);
3186 +               PATHNAME_APPEND_SLASH(p->tmp_buf);
3187                 BUFFER_APPEND_STRING_CONST(p->tmp_buf, "README.txt");
3188                 
3189                 if (-1 != stream_open(&s, p->tmp_buf)) {
3190 @@ -606,7 +604,7 @@
3191                 name_max = 256; /* stupid default */
3192  #endif
3193         }
3194 -#elif defined __WIN32
3195 +#elif defined _WIN32
3196         name_max = FILENAME_MAX;
3197  #else
3198         name_max = NAME_MAX;
3199 @@ -615,6 +613,11 @@
3200         path = malloc(dir->used + name_max);
3201         assert(path);
3202         strcpy(path, dir->ptr);
3203 +#ifdef _WIN32
3204 +    /* append \*.* to the path and keep the \ as part of the pathname */
3205 +    strcat(path, "\\*.*");
3206 +    i++;
3207 +#endif
3208         path_file = path + i;
3209  
3210         if (NULL == (dp = opendir(path))) {
3211 @@ -693,8 +696,10 @@
3212                 if (i > (size_t)name_max) continue;
3213                 
3214                 memcpy(path_file, dent->d_name, i + 1);
3215 -               if (stat(path, &st) != 0)
3216 +               if (stat(path, &st) != 0) {
3217 +            fprintf(stderr, "%s.%d: %s, %s\r\n", __FILE__, __LINE__, path, strerror(errno));
3218                         continue;
3219 +        }
3220  
3221                 list = &files;
3222                 if (S_ISDIR(st.st_mode))
3223 --- lighttpd-1.4.11/src/mod_evasive.c   2006-01-04 15:24:51.000000000 +0200
3224 +++ lighttpd/src/mod_evasive.c  2006-07-11 21:23:40.187861491 +0300
3225 @@ -96,13 +96,11 @@
3226         return HANDLER_GO_ON;
3227  }
3228  
3229 -#define PATCH(x) \
3230 -       p->conf.x = s->x;
3231  static int mod_evasive_patch_connection(server *srv, connection *con, plugin_data *p) {
3232         size_t i, j;
3233         plugin_config *s = p->config_storage[0];
3234  
3235 -       PATCH(max_conns);
3236 +       PATCH_OPTION(max_conns);
3237         
3238         /* skip the first, the global context */
3239         for (i = 1; i < srv->config_context->used; i++) {
3240 @@ -117,14 +115,13 @@
3241                         data_unset *du = dc->value->data[j];
3242                         
3243                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.max-conns-per-ip"))) {
3244 -                               PATCH(max_conns);
3245 +                               PATCH_OPTION(max_conns);
3246                         }
3247                 }
3248         }
3249         
3250         return 0;
3251  }
3252 -#undef PATCH
3253  
3254  URIHANDLER_FUNC(mod_evasive_uri_handler) {
3255         plugin_data *p = p_d;
3256 --- lighttpd-1.4.11/src/mod_evhost.c    2005-08-17 10:42:03.000000000 +0300
3257 +++ lighttpd/src/mod_evhost.c   2006-07-11 21:23:39.991849214 +0300
3258 @@ -7,6 +7,8 @@
3259  #include "response.h"
3260  #include "stat_cache.h"
3261  
3262 +#include "sys-files.h"
3263 +
3264  typedef struct {
3265         /* unparsed pieces */
3266         buffer *path_pieces_raw;
3267 @@ -221,14 +223,12 @@
3268         return 0;
3269  }
3270  
3271 -#define PATCH(x) \
3272 -       p->conf.x = s->x;
3273  static int mod_evhost_patch_connection(server *srv, connection *con, plugin_data *p) {
3274         size_t i, j;
3275         plugin_config *s = p->config_storage[0];
3276         
3277 -       PATCH(path_pieces);
3278 -       PATCH(len);
3279 +       PATCH_OPTION(path_pieces);
3280 +       PATCH_OPTION(len);
3281         
3282         /* skip the first, the global context */
3283         for (i = 1; i < srv->config_context->used; i++) {
3284 @@ -243,16 +243,14 @@
3285                         data_unset *du = dc->value->data[j];
3286                         
3287                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("evhost.path-pattern"))) {
3288 -                               PATCH(path_pieces);
3289 -                               PATCH(len);
3290 +                               PATCH_OPTION(path_pieces);
3291 +                               PATCH_OPTION(len);
3292                         }
3293                 }
3294         }
3295         
3296         return 0;
3297  }
3298 -#undef PATCH
3299 -
3300  
3301  static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d) {
3302         plugin_data *p = p_d;
3303 @@ -299,7 +297,7 @@
3304                 }
3305         }
3306         
3307 -       BUFFER_APPEND_SLASH(p->tmp_buf);
3308 +       PATHNAME_APPEND_SLASH(p->tmp_buf);
3309         
3310         array_free(parsed_host);
3311         
3312 --- lighttpd-1.4.11/src/mod_expire.c    2005-11-03 09:52:13.000000000 +0200
3313 +++ lighttpd/src/mod_expire.c   2006-07-11 21:23:40.103856229 +0300
3314 @@ -245,13 +245,11 @@
3315         return HANDLER_GO_ON;
3316  }
3317  
3318 -#define PATCH(x) \
3319 -       p->conf.x = s->x;
3320  static int mod_expire_patch_connection(server *srv, connection *con, plugin_data *p) {
3321         size_t i, j;
3322         plugin_config *s = p->config_storage[0];
3323         
3324 -       PATCH(expire_url);
3325 +       PATCH_OPTION(expire_url);
3326         
3327         /* skip the first, the global context */
3328         for (i = 1; i < srv->config_context->used; i++) {
3329 @@ -266,14 +264,13 @@
3330                         data_unset *du = dc->value->data[j];
3331                         
3332                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("expire.url"))) {
3333 -                               PATCH(expire_url);
3334 +                               PATCH_OPTION(expire_url);
3335                         }
3336                 }
3337         }
3338         
3339         return 0;
3340  }
3341 -#undef PATCH
3342  
3343  URIHANDLER_FUNC(mod_expire_path_handler) {
3344         plugin_data *p = p_d;
3345 --- lighttpd-1.4.11/src/mod_fastcgi.c   2006-03-09 13:18:39.000000000 +0200
3346 +++ lighttpd/src/mod_fastcgi.c  2006-07-11 21:23:40.207862743 +0300
3347 @@ -1,5 +1,4 @@
3348  #include <sys/types.h>
3349 -#include <unistd.h>
3350  #include <errno.h>
3351  #include <fcntl.h>
3352  #include <string.h>
3353 @@ -24,7 +23,7 @@
3354  #include "inet_ntop_cache.h"
3355  #include "stat_cache.h"
3356  
3357 -#include <fastcgi.h>
3358 +#include "fastcgi.h"
3359  #include <stdio.h>
3360  
3361  #ifdef HAVE_SYS_FILIO_H
3362 @@ -32,7 +31,11 @@
3363  #endif
3364  
3365  #include "sys-socket.h"
3366 +#include "sys-files.h"
3367 +#include "sys-strings.h"
3368 +#include "sys-process.h"
3369  
3370 +#include "http_resp.h"
3371  
3372  #ifndef UNIX_PATH_MAX
3373  # define UNIX_PATH_MAX 108
3374 @@ -45,7 +48,6 @@
3375  #include <sys/wait.h>
3376  #endif
3377  
3378 -
3379  /*
3380   * 
3381   * TODO:
3382 @@ -310,10 +312,11 @@
3383         buffer *fcgi_env;
3384         
3385         buffer *path;
3386 -       buffer *parse_response;
3387  
3388         buffer *statuskey;
3389         
3390 +       http_resp *resp;
3391 +
3392         plugin_config **config_storage;
3393         
3394         plugin_config conf; /* this is only used as long as no handler_ctx is setup */
3395 @@ -339,11 +342,10 @@
3396         
3397         int      reconnects; /* number of reconnect attempts */
3398         
3399 -       chunkqueue *rb; /* read queue */
3400 +       chunkqueue *rb; /* the raw fcgi read-queue */
3401 +       chunkqueue *http_rb; /* the decoded read-queue for http-parsing */
3402         chunkqueue *wb; /* write queue */
3403         
3404 -       buffer   *response_header;
3405 -       
3406         size_t    request_id;
3407         int       fd;        /* fd to the fastcgi process */
3408         int       fde_ndx;   /* index into the fd-event buffer */
3409 @@ -451,8 +453,6 @@
3410         
3411         hctx->fde_ndx = -1;
3412         
3413 -       hctx->response_header = buffer_init();
3414 -       
3415         hctx->request_id = 0;
3416         hctx->state = FCGI_STATE_INIT;
3417         hctx->proc = NULL;
3418 @@ -463,6 +463,7 @@
3419         hctx->send_content_body = 1;
3420  
3421         hctx->rb = chunkqueue_init();
3422 +       hctx->http_rb = chunkqueue_init();
3423         hctx->wb = chunkqueue_init();
3424         
3425         return hctx;
3426 @@ -474,9 +475,8 @@
3427                 hctx->host = NULL;
3428         }
3429         
3430 -       buffer_free(hctx->response_header);
3431 -
3432         chunkqueue_free(hctx->rb);
3433 +       chunkqueue_free(hctx->http_rb);
3434         chunkqueue_free(hctx->wb);
3435  
3436         free(hctx);
3437 @@ -639,7 +639,8 @@
3438         p->fcgi_env = buffer_init();
3439         
3440         p->path = buffer_init();
3441 -       p->parse_response = buffer_init();
3442 +
3443 +       p->resp = http_response_init();
3444  
3445         p->statuskey = buffer_init();
3446         
3447 @@ -657,9 +658,10 @@
3448         
3449         buffer_free(p->fcgi_env);
3450         buffer_free(p->path);
3451 -       buffer_free(p->parse_response);
3452         buffer_free(p->statuskey);
3453         
3454 +       http_response_free(p->resp);
3455 +
3456         if (p->config_storage) {
3457                 size_t i, j, n;
3458                 for (i = 0; i < srv->config_context->used; i++) {
3459 @@ -825,12 +827,8 @@
3460                 fcgi_addr_un.sun_family = AF_UNIX;
3461                 strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
3462                 
3463 -#ifdef SUN_LEN
3464                 servlen = SUN_LEN(&fcgi_addr_un);
3465 -#else
3466 -               /* stevens says: */
3467 -               servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
3468 -#endif
3469 +
3470                 socket_type = AF_UNIX;
3471                 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
3472  
3473 @@ -933,7 +931,7 @@
3474                         return -1;
3475                 }
3476                 
3477 -#ifdef HAVE_FORK       
3478 +#ifndef _WIN32
3479                 switch ((child = fork())) {
3480                 case 0: {
3481                         size_t i = 0;
3482 @@ -1677,12 +1675,9 @@
3483                 /* use the unix domain socket */
3484                 fcgi_addr_un.sun_family = AF_UNIX;
3485                 strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
3486 -#ifdef SUN_LEN
3487 +
3488                 servlen = SUN_LEN(&fcgi_addr_un);
3489 -#else
3490 -               /* stevens says: */
3491 -               servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
3492 -#endif
3493 +
3494                 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
3495         
3496                 if (buffer_is_empty(proc->connection_name)) {
3497 @@ -1695,6 +1690,7 @@
3498  #endif
3499         } else {
3500                 fcgi_addr_in.sin_family = AF_INET;
3501 +
3502                 if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
3503                         log_error_write(srv, __FILE__, __LINE__, "sbs", 
3504                                         "converting IP-adress failed for", host->host, 
3505 @@ -1702,6 +1698,7 @@
3506                         
3507                         return -1;
3508                 }
3509 +
3510                 fcgi_addr_in.sin_port = htons(proc->port);
3511                 servlen = sizeof(fcgi_addr_in);
3512                 
3513 @@ -2186,105 +2183,6 @@
3514         return 0;
3515  }
3516  
3517 -static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
3518 -       char *s, *ns;
3519 -       
3520 -       handler_ctx *hctx = con->plugin_ctx[p->id];
3521 -       fcgi_extension_host *host= hctx->host;
3522 -       
3523 -       UNUSED(srv);
3524 -
3525 -       buffer_copy_string_buffer(p->parse_response, in);
3526 -       
3527 -       /* search for \n */
3528 -       for (s = p->parse_response->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) {
3529 -               char *key, *value;
3530 -               int key_len;
3531 -               data_string *ds;
3532 -               
3533 -               /* a good day. Someone has read the specs and is sending a \r\n to us */
3534 -               
3535 -               if (ns > p->parse_response->ptr &&
3536 -                   *(ns-1) == '\r') {
3537 -                       *(ns-1) = '\0';
3538 -               }
3539 -               
3540 -               ns[0] = '\0';
3541 -               
3542 -               key = s;
3543 -               if (NULL == (value = strchr(s, ':'))) {
3544 -                       /* we expect: "<key>: <value>\n" */
3545 -                       continue;
3546 -               }
3547 -               
3548 -               key_len = value - key;
3549 -               
3550 -               value++;
3551 -               /* strip WS */
3552 -               while (*value == ' ' || *value == '\t') value++;
3553 -               
3554 -               if (host->mode != FCGI_AUTHORIZER ||
3555 -                   !(con->http_status == 0 ||
3556 -                     con->http_status == 200)) {
3557 -                       /* authorizers shouldn't affect the response headers sent back to the client */
3558 -                       
3559 -                       /* don't forward Status: */
3560 -                       if (0 != strncasecmp(key, "Status", key_len)) {
3561 -                               if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
3562 -                                       ds = data_response_init();
3563 -                               }
3564 -                               buffer_copy_string_len(ds->key, key, key_len);
3565 -                               buffer_copy_string(ds->value, value);
3566 -                               
3567 -                               array_insert_unique(con->response.headers, (data_unset *)ds);
3568 -                       }
3569 -               }
3570 -               
3571 -               switch(key_len) {
3572 -               case 4:
3573 -                       if (0 == strncasecmp(key, "Date", key_len)) {
3574 -                               con->parsed_response |= HTTP_DATE;
3575 -                       }
3576 -                       break;
3577 -               case 6:
3578 -                       if (0 == strncasecmp(key, "Status", key_len)) {
3579 -                               con->http_status = strtol(value, NULL, 10);
3580 -                               con->parsed_response |= HTTP_STATUS;
3581 -                       }
3582 -                       break;
3583 -               case 8:
3584 -                       if (0 == strncasecmp(key, "Location", key_len)) {
3585 -                               con->parsed_response |= HTTP_LOCATION;
3586 -                       }
3587 -                       break;
3588 -               case 10:
3589 -                       if (0 == strncasecmp(key, "Connection", key_len)) {
3590 -                               con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
3591 -                               con->parsed_response |= HTTP_CONNECTION;
3592 -                       }
3593 -                       break;
3594 -               case 14:
3595 -                       if (0 == strncasecmp(key, "Content-Length", key_len)) {
3596 -                               con->response.content_length = strtol(value, NULL, 10);
3597 -                               con->parsed_response |= HTTP_CONTENT_LENGTH;
3598 -                               
3599 -                               if (con->response.content_length < 0) con->response.content_length = 0;
3600 -                       }
3601 -                       break;
3602 -               default:
3603 -                       break;
3604 -               }
3605 -       }
3606 -       
3607 -       /* CGI/1.1 rev 03 - 7.2.1.2 */
3608 -       if ((con->parsed_response & HTTP_LOCATION) &&
3609 -           !(con->parsed_response & HTTP_STATUS)) {
3610 -               con->http_status = 302;
3611 -       }
3612 -       
3613 -       return 0;
3614 -}
3615 -
3616  typedef struct {
3617         buffer  *b; 
3618         size_t   len;
3619 @@ -2386,52 +2284,24 @@
3620  
3621  static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
3622         int fin = 0;
3623 -       int toread;
3624 -       ssize_t r;
3625         
3626         plugin_data *p    = hctx->plugin_data;
3627         connection *con   = hctx->remote_conn;
3628 -       int fcgi_fd       = hctx->fd;
3629         fcgi_extension_host *host= hctx->host;
3630         fcgi_proc *proc   = hctx->proc;
3631         
3632 -       /* 
3633 -        * check how much we have to read 
3634 -        */
3635 -       if (ioctl(hctx->fd, FIONREAD, &toread)) {
3636 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
3637 -                               "unexpected end-of-file (perhaps the fastcgi process died):",
3638 -                               fcgi_fd);
3639 -               return -1;
3640 -       }
3641 -       
3642 -       /* init read-buffer */
3643 -       
3644 -       if (toread > 0) {
3645 -               buffer *b;
3646 -
3647 -               b = chunkqueue_get_append_buffer(hctx->rb);
3648 -               buffer_prepare_copy(b, toread + 1);
3649 -
3650 -               /* append to read-buffer */
3651 -               if (-1 == (r = read(hctx->fd, b->ptr, toread))) {
3652 -                       log_error_write(srv, __FILE__, __LINE__, "sds", 
3653 -                                       "unexpected end-of-file (perhaps the fastcgi process died):",
3654 -                                       fcgi_fd, strerror(errno));
3655 -                       return -1;
3656 -               }
3657 -               
3658 -               /* this should be catched by the b > 0 above */
3659 -               assert(r);
3660 -
3661 -               b->used = r + 1; /* one extra for the fake \0 */
3662 -               b->ptr[b->used - 1] = '\0';
3663 -       } else {
3664 +       switch(srv->network_backend_read(srv, con, hctx->fd, hctx->rb)) {
3665 +       case NETWORK_STATUS_WAIT_FOR_EVENT:
3666 +               /* we are only triggered when there is a event */
3667                 log_error_write(srv, __FILE__, __LINE__, "ssdsb", 
3668                                 "unexpected end-of-file (perhaps the fastcgi process died):",
3669                                 "pid:", proc->pid,
3670                                 "socket:", proc->connection_name);
3671 -               
3672 +               return -1;
3673 +       case NETWORK_STATUS_SUCCESS:
3674 +               break;
3675 +       default:
3676 +               log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi-read failed");
3677                 return -1;
3678         }
3679  
3680 @@ -2454,80 +2324,123 @@
3681  
3682                         /* is the header already finished */
3683                         if (0 == con->file_started) {
3684 -                               char *c;
3685 -                               size_t blen;
3686 -                               data_string *ds;
3687 -                                       
3688 -                               /* search for header terminator 
3689 -                                * 
3690 -                                * if we start with \r\n check if last packet terminated with \r\n
3691 -                                * if we start with \n check if last packet terminated with \n
3692 -                                * search for \r\n\r\n
3693 -                                * search for \n\n
3694 -                                */
3695 -
3696 -                               if (hctx->response_header->used == 0) {
3697 -                                       buffer_copy_string_buffer(hctx->response_header, packet.b);
3698 -                               } else {
3699 -                                       buffer_append_string_buffer(hctx->response_header, packet.b);
3700 -                               }
3701 +                               int have_content_length = 0;
3702 +                               int need_more = 0;
3703 +                               size_t i;
3704  
3705 -                               if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\r\n\r\n")))) {
3706 -                                       blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4;
3707 -                                       hctx->response_header->used = (c - hctx->response_header->ptr) + 3;
3708 -                                       c += 4; /* point the the start of the response */
3709 -                               } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) {
3710 -                                       blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2;
3711 -                                       hctx->response_header->used = c - hctx->response_header->ptr + 2;
3712 -                                       c += 2; /* point the the start of the response */
3713 -                               } else {
3714 -                                       /* no luck, no header found */
3715 +                               /* append the current packet to the chunk queue */
3716 +                               chunkqueue_append_buffer(hctx->http_rb, packet.b);
3717 +                               http_response_reset(p->resp);
3718 +
3719 +                               switch(http_response_parse_cq(hctx->http_rb, p->resp)) {
3720 +                               case PARSE_ERROR:
3721 +                                       /* parsing the response header failed */
3722 +
3723 +                                       con->http_status = 502; /* Bad Gateway */
3724 +
3725 +                                       return 1;
3726 +                               case PARSE_NEED_MORE:
3727 +                                       need_more = 1;
3728 +                                       break; /* leave the loop */
3729 +                               case PARSE_SUCCESS:
3730                                         break;
3731 +                               default:
3732 +                                       /* should not happen */
3733 +                                       SEGFAULT();
3734                                 }
3735  
3736 -                               /* parse the response header */
3737 -                               fcgi_response_parse(srv, con, p, hctx->response_header);
3738 +                               if (need_more) break;
3739  
3740 -                               con->file_started = 1;
3741 +                               chunkqueue_remove_finished_chunks(hctx->http_rb);
3742  
3743 -                               if (host->mode == FCGI_AUTHORIZER &&
3744 -                                   (con->http_status == 0 ||
3745 -                                    con->http_status == 200)) {
3746 +                               con->http_status = p->resp->status;
3747 +
3748 +                               /* handle the header fields */
3749 +                               if (host->mode == FCGI_AUTHORIZER) {
3750 +                                       /* auth mode is a bit different */
3751 +
3752 +                                       if (con->http_status == 0 ||
3753 +                                           con->http_status == 200) {
3754                                         /* a authorizer with approved the static request, ignore the content here */
3755                                         hctx->send_content_body = 0;
3756                                 }
3757 +                               }
3758  
3759 -                               if (host->allow_xsendfile &&
3760 -                                   NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-LIGHTTPD-send-file"))) {
3761 -                                       stat_cache_entry *sce;
3762 +                               /* copy the http-headers */
3763 +                               for (i = 0; i < p->resp->headers->used; i++) {
3764 +                                       const char *ign[] = { "Status", NULL };
3765 +                                       size_t j;
3766 +                                       data_string *ds;
3767  
3768 -                                       if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) {
3769 -                                               /* found */
3770 +                                       data_string *header = (data_string *)p->resp->headers->data[i];
3771 +
3772 +                                       /* ignore all headers in AUTHORIZER mode */
3773 +                                       if (host->mode == FCGI_AUTHORIZER) continue;
3774 +
3775 +                                       /* some headers are ignored by default */
3776 +                                       for (j = 0; ign[j]; j++) {
3777 +                                               if (0 == strcasecmp(ign[j], header->key->ptr)) break;
3778 +                                       }
3779 +                                       if (ign[j]) continue;
3780 +
3781 +                                       if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
3782 +                                               /* CGI/1.1 rev 03 - 7.2.1.2 */
3783 +                                               con->http_status = 302;
3784 +                                       } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
3785 +                                               have_content_length = 1;
3786 +                                       } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Sendfile")) || 
3787 +                                                  0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-LIGHTTPD-send-file"))) {
3788  
3789 -                                               http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
3790 +                                               stat_cache_entry *sce;
3791 +                                               
3792 +                                               if (host->allow_xsendfile &&
3793 +                                                   HANDLER_ERROR != stat_cache_get_entry(srv, con, header->value, &sce)) {
3794 +                                                       http_chunk_append_file(srv, con, header->value, 0, sce->st.st_size);
3795                                                 hctx->send_content_body = 0; /* ignore the content */
3796 +                                       
3797                                                 joblist_append(srv, con);
3798                                         }
3799 +
3800 +                                               continue; /* ignore header */
3801                                 }
3802  
3803 +                                       if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
3804 +                                               ds = data_response_init();
3805 +                                       }
3806 +                                       buffer_copy_string_buffer(ds->key, header->key);
3807 +                                       buffer_copy_string_buffer(ds->value, header->value);
3808                                                 
3809 -                               if (hctx->send_content_body && blen > 1) {                                              
3810 -                                       /* enable chunked-transfer-encoding */
3811 +                                       array_insert_unique(con->response.headers, (data_unset *)ds);
3812 +                               }
3813 +
3814 +                               /* header is complete ... go on with the body */
3815 +
3816 +                               con->file_started = 1;
3817 +
3818 +                               if (hctx->send_content_body) {
3819 +                                       chunk *c = hctx->http_rb->first;
3820 +
3821 +                                       /* if we don't have a content-length enable chunked encoding 
3822 +                                        * if possible
3823 +                                        * 
3824 +                                        * TODO: move this to a later stage in the filter-queue
3825 +                                        *  */
3826                                         if (con->request.http_version == HTTP_VERSION_1_1 &&
3827 -                                           !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
3828 +                                           !have_content_length) {
3829                                                 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
3830                                         }
3831  
3832 -                                       http_chunk_append_mem(srv, con, c, blen);
3833 +                                       /* copy the rest of the data */
3834 +                                       for (c = hctx->http_rb->first; c; c = c->next) {
3835 +                                               if (c->mem->used > 1) {
3836 +                                                       http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
3837 +                                                       c->offset = c->mem->used - 1;
3838 +                                               }
3839 +                                       }
3840 +                                       chunkqueue_remove_finished_chunks(hctx->http_rb);
3841                                         joblist_append(srv, con);
3842                                 }
3843                         } else if (hctx->send_content_body && packet.b->used > 1) {
3844 -                               if (con->request.http_version == HTTP_VERSION_1_1 &&
3845 -                                   !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
3846 -                                       /* enable chunked-transfer-encoding */
3847 -                                       con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
3848 -                               }
3849 -
3850                                 http_chunk_append_mem(srv, con, packet.b->ptr, packet.b->used);
3851                                 joblist_append(srv, con);
3852                         }
3853 @@ -2606,7 +2519,7 @@
3854                         if (!proc->is_local) break;
3855  
3856                         /* the child should not terminate at all */
3857 -                       
3858 +#ifndef _WIN32
3859                         switch(waitpid(proc->pid, &status, WNOHANG)) {
3860                         case 0:
3861                                 /* child is still alive */
3862 @@ -2633,7 +2546,7 @@
3863                                 proc->state = PROC_STATE_DIED;
3864                                 break;
3865                         }
3866 -
3867 +#endif
3868                         /* fall through if we have a dead proc now */
3869                         if (proc->state != PROC_STATE_DIED) break;
3870  
3871 @@ -2934,10 +2847,11 @@
3872                                  */ 
3873                                 if (hctx->wb->bytes_out == 0 &&
3874                                     hctx->reconnects < 5) {
3875 +#ifndef _WIN32
3876                                         usleep(10000); /* take away the load of the webserver 
3877                                                         * to let the php a chance to restart 
3878                                                         */
3879 -                                       
3880 +#endif
3881                                         fcgi_reconnect(srv, hctx);
3882                                 
3883                                         return HANDLER_WAIT_FOR_FD;
3884 @@ -2949,7 +2863,7 @@
3885                                  * 
3886                                  */
3887                                 
3888 -                               log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
3889 +                               log_error_write(srv, __FILE__, __LINE__, "ssosd",
3890                                                 "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
3891                                                 "write-offset:", hctx->wb->bytes_out,
3892                                                 "reconnect attempts:", hctx->reconnects);
3893 @@ -3155,7 +3069,7 @@
3894                                 int status;
3895                                 
3896                                 /* only fetch the zombie if it is not already done */
3897 -                               
3898 +#ifndef _WIN32
3899                                 switch(waitpid(proc->pid, &status, WNOHANG)) {
3900                                 case 0:
3901                                         /* child is still alive */
3902 @@ -3195,6 +3109,7 @@
3903                                         
3904                                         break;
3905                                 }
3906 +#endif
3907                         }
3908  
3909                         if (con->file_started == 0) {
3910 @@ -3307,15 +3222,14 @@
3911         
3912         return HANDLER_FINISHED;
3913  }
3914 -#define PATCH(x) \
3915 -       p->conf.x = s->x;
3916 +
3917  static int fcgi_patch_connection(server *srv, connection *con, plugin_data *p) {
3918         size_t i, j;
3919         plugin_config *s = p->config_storage[0];
3920         
3921 -       PATCH(exts);
3922 -       PATCH(debug);
3923 -       PATCH(ext_mapping);
3924 +       PATCH_OPTION(exts);
3925 +       PATCH_OPTION(debug);
3926 +       PATCH_OPTION(ext_mapping);
3927         
3928         /* skip the first, the global context */
3929         for (i = 1; i < srv->config_context->used; i++) {
3930 @@ -3330,19 +3244,17 @@
3931                         data_unset *du = dc->value->data[j];
3932                         
3933                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.server"))) {
3934 -                               PATCH(exts);
3935 +                               PATCH_OPTION(exts);
3936                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.debug"))) {
3937 -                               PATCH(debug);
3938 +                               PATCH_OPTION(debug);
3939                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.map-extensions"))) {
3940 -                               PATCH(ext_mapping);
3941 +                               PATCH_OPTION(ext_mapping);
3942                         }
3943                 }
3944         }
3945         
3946         return 0;
3947  }
3948 -#undef PATCH
3949 -
3950  
3951  static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
3952         plugin_data *p = p_d;
3953 @@ -3610,10 +3522,33 @@
3954          * 
3955          * currently we wait for the TCP timeout which is on Linux 180 seconds
3956          * 
3957 -        * 
3958 -        * 
3959          */
3960  
3961 +       for (i = 0; i < srv->conns->used; i++) {
3962 +               connection *con = srv->conns->ptr[i];
3963 +               handler_ctx *hctx = con->plugin_ctx[p->id];
3964 +
3965 +               /* if a connection is ours and is in handle-req for more than max-request-time
3966 +                * kill the connection */
3967 +
3968 +               if (con->mode != p->id) continue;
3969 +               if (con->state != CON_STATE_HANDLE_REQUEST) continue;
3970 +               if (srv->cur_ts < con->request_start + 60) continue;
3971 +
3972 +               /* the request is waiting for a FCGI_STDOUT since 60 seconds */
3973 +
3974 +               /* kill the connection */
3975 +
3976 +               log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi backend didn't responded after 60 seconds");
3977 +
3978 +               fcgi_connection_close(srv, hctx);
3979 +
3980 +               con->mode = DIRECT;
3981 +               con->http_status = 500;
3982 +
3983 +               joblist_append(srv, con);
3984 +       }
3985 +
3986         /* check all childs if they are still up */
3987  
3988         for (i = 0; i < srv->config_context->used; i++) {
3989 @@ -3737,7 +3672,7 @@
3990                                         int status;
3991                                         
3992                                         if (proc->pid == 0) continue;
3993 -                                       
3994 +#ifndef _WIN32
3995                                         switch (waitpid(proc->pid, &status, WNOHANG)) {
3996                                         case 0:
3997                                                 /* child still running after timeout, good */
3998 @@ -3781,6 +3716,7 @@
3999                                                 proc->state = PROC_STATE_UNSET;
4000                                                 host->max_id--;
4001                                         }
4002 +#endif
4003                                 }
4004                         }
4005                 }
4006 --- lighttpd-1.4.11/src/mod_flv_streaming.c     2006-03-07 14:06:26.000000000 +0200
4007 +++ lighttpd/src/mod_flv_streaming.c    2006-07-11 21:23:40.043852471 +0300
4008 @@ -108,13 +108,11 @@
4009         return HANDLER_GO_ON;
4010  }
4011  
4012 -#define PATCH(x) \
4013 -       p->conf.x = s->x;
4014  static int mod_flv_streaming_patch_connection(server *srv, connection *con, plugin_data *p) {
4015         size_t i, j;
4016         plugin_config *s = p->config_storage[0];
4017         
4018 -       PATCH(extensions);
4019 +       PATCH_OPTION(extensions);
4020         
4021         /* skip the first, the global context */
4022         for (i = 1; i < srv->config_context->used; i++) {
4023 @@ -129,16 +127,15 @@
4024                         data_unset *du = dc->value->data[j];
4025                         
4026                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("flv-streaming.extensions"))) {
4027 -                               PATCH(extensions);
4028 +                               PATCH_OPTION(extensions);
4029                         }
4030                 }
4031         }
4032         
4033         return 0;
4034  }
4035 -#undef PATCH
4036  
4037 -static int split_get_params(server *srv, connection *con, array *get_params, buffer *qrystr) {
4038 +static int split_get_params(array *get_params, buffer *qrystr) {
4039         size_t is_key = 1;
4040         size_t i;
4041         char *key = NULL, *val = NULL;
4042 @@ -167,7 +164,7 @@
4043                                 /* terminate the value */
4044                                 qrystr->ptr[i] = '\0';
4045  
4046 -                               if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
4047 +                               if (NULL == (ds = (data_string *)array_get_unused_element(get_params, TYPE_STRING))) {
4048                                         ds = data_string_init();
4049                                 }
4050                                 buffer_copy_string_len(ds->key, key, strlen(key));
4051 @@ -217,7 +214,7 @@
4052  
4053                         array_reset(p->get_params);
4054                         buffer_copy_string_buffer(p->query_str, con->uri.query);
4055 -                       split_get_params(srv, con, p->get_params, p->query_str);
4056 +                       split_get_params(p->get_params, p->query_str);
4057  
4058                         if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {
4059                                 return HANDLER_GO_ON;
4060 --- lighttpd-1.4.11/src/mod_indexfile.c 2005-09-30 01:08:53.000000000 +0300
4061 +++ lighttpd/src/mod_indexfile.c        2006-07-11 21:23:40.191861741 +0300
4062 @@ -103,13 +103,11 @@
4063         return HANDLER_GO_ON;
4064  }
4065  
4066 -#define PATCH(x) \
4067 -       p->conf.x = s->x;
4068  static int mod_indexfile_patch_connection(server *srv, connection *con, plugin_data *p) {
4069         size_t i, j;
4070         plugin_config *s = p->config_storage[0];
4071         
4072 -       PATCH(indexfiles);
4073 +       PATCH_OPTION(indexfiles);
4074         
4075         /* skip the first, the global context */
4076         for (i = 1; i < srv->config_context->used; i++) {
4077 @@ -124,16 +122,15 @@
4078                         data_unset *du = dc->value->data[j];
4079                         
4080                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.indexfiles"))) {
4081 -                               PATCH(indexfiles);
4082 +                               PATCH_OPTION(indexfiles);
4083                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("index-file.names"))) {
4084 -                               PATCH(indexfiles);
4085 +                               PATCH_OPTION(indexfiles);
4086                         }
4087                 }
4088         }
4089         
4090         return 0;
4091  }
4092 -#undef PATCH
4093  
4094  URIHANDLER_FUNC(mod_indexfile_subrequest) {
4095         plugin_data *p = p_d;
4096 --- lighttpd-1.4.11/src/mod_mysql_vhost.c       2006-01-14 20:35:10.000000000 +0200
4097 +++ lighttpd/src/mod_mysql_vhost.c      2006-07-11 21:23:40.031851719 +0300
4098 @@ -1,13 +1,18 @@
4099 -#include <unistd.h>
4100  #include <stdio.h>
4101  #include <errno.h>
4102  #include <fcntl.h>
4103 -#include <strings.h>
4104 +#include <string.h>
4105  
4106  #ifdef HAVE_CONFIG_H
4107  #include "config.h"
4108  #endif
4109  
4110 +#ifdef HAVE_MYSQL_H 
4111 +# ifdef HAVE_LIBMYSQL
4112 +#  define HAVE_MYSQL
4113 +# endif
4114 +#endif
4115 +
4116  #ifdef HAVE_MYSQL
4117  #include <mysql.h>
4118  #endif
4119 @@ -16,36 +21,21 @@
4120  #include "log.h"
4121  
4122  #include "stat_cache.h"
4123 -#ifdef DEBUG_MOD_MYSQL_VHOST
4124 -#define DEBUG
4125 -#endif
4126 +#include "sys-files.h"
4127  
4128 -/*
4129 - * Plugin for lighttpd to use MySQL 
4130 - *   for domain to directory lookups,
4131 - *   i.e virtual hosts (vhosts).
4132 - *   
4133 - * Optionally sets fcgi_offset and fcgi_arg 
4134 - *   in preparation for fcgi.c to handle 
4135 - *   per-user fcgi chroot jails.
4136 - *
4137 - * /ada@riksnet.se 2004-12-06
4138 - */
4139 +#include "mod_sql_vhost_core.h"
4140  
4141  #ifdef HAVE_MYSQL
4142 -typedef struct {
4143 -       MYSQL   *mysql;
4144         
4145 -       buffer  *mydb;
4146 -       buffer  *myuser;
4147 -       buffer  *mypass;
4148 -       buffer  *mysock;
4149 +#define CORE_PLUGIN "mod_sql_vhost_core"
4150         
4151 -       buffer  *hostname;
4152 -       unsigned short port;
4153 +typedef struct {
4154 +       MYSQL   *mysql;
4155         
4156         buffer  *mysql_pre;
4157         buffer  *mysql_post;
4158 +
4159 +       mod_sql_vhost_core_plugin_config *core;
4160  } plugin_config;
4161  
4162  /* global plugin data */
4163 @@ -59,13 +49,7 @@
4164         plugin_config conf; 
4165  } plugin_data;
4166  
4167 -/* per connection plugin data */
4168 -typedef struct {
4169 -       buffer  *server_name;
4170 -       buffer  *document_root;
4171 -       buffer  *fcgi_arg;
4172 -       unsigned fcgi_offset;
4173 -} plugin_connection_data;
4174 +SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost); 
4175  
4176  /* init the plugin data */
4177  INIT_FUNC(mod_mysql_vhost_init) {
4178 @@ -84,10 +68,6 @@
4179  
4180         UNUSED(srv);
4181         
4182 -#ifdef DEBUG
4183 -       log_error_write(srv, __FILE__, __LINE__, "ss", 
4184 -               "mod_mysql_vhost_cleanup", p ? "yes" : "NO");
4185 -#endif
4186         if (!p) return HANDLER_GO_ON;
4187         
4188         if (p->config_storage) {
4189 @@ -99,10 +79,6 @@
4190                         
4191                         mysql_close(s->mysql);
4192                         
4193 -                       buffer_free(s->mydb);
4194 -                       buffer_free(s->myuser);
4195 -                       buffer_free(s->mypass);
4196 -                       buffer_free(s->mysock);
4197                         buffer_free(s->mysql_pre);
4198                         buffer_free(s->mysql_post);
4199                         
4200 @@ -117,109 +93,50 @@
4201         return HANDLER_GO_ON;
4202  }
4203  
4204 -/* handle the plugin per connection data */
4205 -static void* mod_mysql_vhost_connection_data(server *srv, connection *con, void *p_d)
4206 -{
4207 -       plugin_data *p = p_d;
4208 -       plugin_connection_data *c = con->plugin_ctx[p->id];
4209 -
4210 -       UNUSED(srv);
4211 -
4212 -#ifdef DEBUG
4213 -        log_error_write(srv, __FILE__, __LINE__, "ss", 
4214 -               "mod_mysql_connection_data", c ? "old" : "NEW");
4215 -#endif
4216 -
4217 -       if (c) return c;
4218 -       c = calloc(1, sizeof(*c));
4219 -
4220 -       c->server_name = buffer_init();
4221 -       c->document_root = buffer_init();
4222 -       c->fcgi_arg = buffer_init();
4223 -       c->fcgi_offset = 0;
4224 -
4225 -       return con->plugin_ctx[p->id] = c;
4226 -}
4227 -
4228 -/* destroy the plugin per connection data */
4229 -CONNECTION_FUNC(mod_mysql_vhost_handle_connection_close) {
4230 -       plugin_data *p = p_d;
4231 -       plugin_connection_data *c = con->plugin_ctx[p->id];
4232 -
4233 -       UNUSED(srv);
4234 -
4235 -#ifdef DEBUG
4236 -       log_error_write(srv, __FILE__, __LINE__, "ss", 
4237 -               "mod_mysql_vhost_handle_connection_close", c ? "yes" : "NO");
4238 -#endif
4239 -       
4240 -       if (!c) return HANDLER_GO_ON;
4241 -
4242 -       buffer_free(c->server_name);
4243 -       buffer_free(c->document_root);
4244 -       buffer_free(c->fcgi_arg);
4245 -       c->fcgi_offset = 0;
4246 -
4247 -       free(c);
4248 -
4249 -       con->plugin_ctx[p->id] = NULL;
4250 -       return HANDLER_GO_ON;
4251 -}
4252 -
4253  /* set configuration values */
4254  SERVER_FUNC(mod_mysql_vhost_set_defaults) {
4255         plugin_data *p = p_d;
4256 +       mod_sql_vhost_core_plugin_data *core_config;
4257  
4258 -       char *qmark;
4259         size_t i = 0;
4260  
4261 -       config_values_t cv[] = {
4262 -               { "mysql-vhost.db",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
4263 -               { "mysql-vhost.user",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
4264 -               { "mysql-vhost.pass",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
4265 -               { "mysql-vhost.sock",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
4266 -               { "mysql-vhost.sql",    NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
4267 -               { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER },
4268 -               { "mysql-vhost.port",   NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER },
4269 -                { NULL,                        NULL, T_CONFIG_UNSET,   T_CONFIG_SCOPE_UNSET }
4270 -        };
4271 -       
4272 +       /* our very own plugin storage, one entry for each conditional
4273 +        * 
4274 +        * srv->config_context->used is the number of conditionals
4275 +        * */
4276         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
4277         
4278 +       /* get the config of the core-plugin */
4279 +       core_config = plugin_get_config(srv, CORE_PLUGIN);
4280 +
4281 +
4282 +       /* walk through all conditionals and check for assignments */
4283         for (i = 0; i < srv->config_context->used; i++) {
4284                 plugin_config *s;
4285                 buffer *sel;
4286 +               char *qmark;
4287                 
4288 -               
4289 +               /* get the config from the core plugin for this conditional-context */
4290                 s = calloc(1, sizeof(plugin_config));
4291 -               s->mydb = buffer_init();
4292 -               s->myuser = buffer_init();
4293 -               s->mypass = buffer_init();
4294 -               s->mysock = buffer_init();
4295 -               s->hostname = buffer_init();
4296 -               s->port   = 0;               /* default port for mysql */
4297 -               sel = buffer_init();
4298 +
4299 +               s->core = core_config->config_storage[i];
4300 +               
4301                 s->mysql = NULL;
4302                 
4303                 s->mysql_pre = buffer_init();
4304                 s->mysql_post = buffer_init();
4305                 
4306 -               cv[0].destination = s->mydb;
4307 -               cv[1].destination = s->myuser;
4308 -               cv[2].destination = s->mypass;
4309 -               cv[3].destination = s->mysock;
4310 -               cv[4].destination = sel;
4311 -               cv[5].destination = s->hostname;
4312 -               cv[6].destination = &(s->port);
4313 -               
4314                 p->config_storage[i] = s;
4315                 
4316 -               if (config_insert_values_global(srv, 
4317 -                       ((data_config *)srv->config_context->data[i])->value,
4318 -                       cv)) return HANDLER_ERROR;
4319 +               /* check if we are the plugin for this backend */
4320 +               if (!buffer_is_equal_string(s->core->backend, CONST_STR_LEN("mysql"))) continue;
4321                 
4322 -               s->mysql_pre = buffer_init();
4323 -               s->mysql_post = buffer_init();
4324 +               /* attach us to the core-plugin */
4325 +               s->core->backend_data = p;
4326 +               s->core->get_vhost = mod_mysql_vhost_get_vhost;
4327 +
4328 +               sel = buffer_init();
4329 +               buffer_copy_string_buffer(sel, s->core->select_vhost);
4330                 
4331                 if (sel->used && (qmark = index(sel->ptr, '?'))) {
4332                         *qmark = '\0';
4333 @@ -241,8 +158,8 @@
4334                  */
4335                 
4336                 /* all have to be set */
4337 -               if (!(buffer_is_empty(s->myuser) ||
4338 -                     buffer_is_empty(s->mydb))) {
4339 +               if (!(buffer_is_empty(s->core->user) ||
4340 +                     buffer_is_empty(s->core->db))) {
4341  
4342                         int fd;
4343                 
4344 @@ -251,10 +168,10 @@
4345                                 
4346                                 return HANDLER_ERROR;
4347                         }
4348 -#define FOO(x) (s->x->used ? s->x->ptr : NULL)
4349 +#define FOO(x) (s->core->x->used ? s->core->x->ptr : NULL)
4350                         
4351 -                       if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(myuser), FOO(mypass), 
4352 -                                               FOO(mydb), s->port, FOO(mysock), 0)) {
4353 +                       if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(user), FOO(pass),
4354 +                                               FOO(db), s->core->port, FOO(sock), 0)) {
4355                                 log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(s->mysql));
4356                                 
4357                                 return HANDLER_ERROR;
4358 @@ -275,17 +192,13 @@
4359          return HANDLER_GO_ON;
4360  }
4361  
4362 -#define PATCH(x) \
4363 -       p->conf.x = s->x;
4364  static int mod_mysql_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
4365 -       size_t i, j;
4366 +       size_t i;
4367         plugin_config *s = p->config_storage[0];
4368         
4369 -       PATCH(mysql_pre);
4370 -       PATCH(mysql_post);
4371 -#ifdef HAVE_MYSQL
4372 -       PATCH(mysql);
4373 -#endif
4374 +       PATCH_OPTION(mysql_pre);
4375 +       PATCH_OPTION(mysql_post);
4376 +       PATCH_OPTION(mysql);
4377         
4378         /* skip the first, the global context */
4379         for (i = 1; i < srv->config_context->used; i++) {
4380 @@ -295,31 +208,21 @@
4381                 /* condition didn't match */
4382                 if (!config_check_cond(srv, con, dc)) continue;
4383                 
4384 -               /* merge config */
4385 -               for (j = 0; j < dc->value->used; j++) {
4386 -                       data_unset *du = dc->value->data[j];
4387 -                       
4388 -                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("mysql-vhost.sql"))) {
4389 -                               PATCH(mysql_pre);
4390 -                               PATCH(mysql_post);
4391 -                       }
4392 -               }
4393 -               
4394                 if (s->mysql) {
4395 -                       PATCH(mysql);
4396 +                       PATCH_OPTION(mysql);
4397 +                       PATCH_OPTION(mysql_pre);
4398 +                       PATCH_OPTION(mysql_post);
4399                 }
4400         }
4401         
4402         return 0;
4403  }
4404 -#undef PATCH
4405  
4406 -
4407 -/* handle document root request */
4408 -CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
4409 +/**
4410 + * get the vhost info from the database 
4411 + */
4412 +SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost) {
4413         plugin_data *p = p_d;
4414 -       plugin_connection_data *c;
4415 -       stat_cache_entry *sce;
4416  
4417         unsigned  cols;
4418         MYSQL_ROW row;
4419 @@ -332,13 +235,6 @@
4420  
4421         if (!p->conf.mysql) return HANDLER_GO_ON;
4422  
4423 -       /* sets up connection data if not done yet */
4424 -       c = mod_mysql_vhost_connection_data(srv, con, p_d);
4425 -
4426 -       /* check if cached this connection */
4427 -       if (c->server_name->used && /* con->uri.authority->used && */
4428 -            buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON;
4429 -
4430         /* build and run SQL query */
4431         buffer_copy_string_buffer(p->tmp_buf, p->conf.mysql_pre);
4432         if (p->conf.mysql_post->used) {
4433 @@ -347,76 +243,42 @@
4434         }
4435         if (mysql_query(p->conf.mysql, p->tmp_buf->ptr)) {
4436                 log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(p->conf.mysql));
4437 -               goto ERR500;
4438 +
4439 +               mysql_free_result(result);
4440 +               return HANDLER_GO_ON;
4441         }
4442         result = mysql_store_result(p->conf.mysql);
4443         cols = mysql_num_fields(result);
4444         row = mysql_fetch_row(result);
4445 +
4446         if (!row || cols < 1) {
4447                 /* no such virtual host */
4448                 mysql_free_result(result);
4449                 return HANDLER_GO_ON;
4450         }
4451  
4452 -       /* sanity check that really is a directory */
4453 -       buffer_copy_string(p->tmp_buf, row[0]);
4454 -       BUFFER_APPEND_SLASH(p->tmp_buf);
4455 -
4456 -       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
4457 -               log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
4458 -               goto ERR500;
4459 -       }
4460 -        if (!S_ISDIR(sce->st.st_mode)) {
4461 -               log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->tmp_buf);
4462 -               goto ERR500;
4463 -       }
4464 -
4465 -       /* cache the data */
4466 -       buffer_copy_string_buffer(c->server_name, con->uri.authority);
4467 -       buffer_copy_string_buffer(c->document_root, p->tmp_buf);
4468 +       buffer_copy_string(docroot, row[0]);
4469  
4470 -       /* fcgi_offset and fcgi_arg are optional */
4471 -       if (cols > 1 && row[1]) {
4472 -               c->fcgi_offset = atoi(row[1]);
4473 -               
4474 -               if (cols > 2 && row[2]) {
4475 -                       buffer_copy_string(c->fcgi_arg, row[2]);
4476 -               } else {
4477 -                       c->fcgi_arg->used = 0;
4478 -               }
4479 -       } else {
4480 -               c->fcgi_offset = c->fcgi_arg->used = 0;
4481 -       }
4482         mysql_free_result(result);
4483  
4484 -       /* fix virtual server and docroot */
4485 -GO_ON: buffer_copy_string_buffer(con->server_name, c->server_name);
4486 -       buffer_copy_string_buffer(con->physical.doc_root, c->document_root);
4487 -
4488 -#ifdef DEBUG
4489 -       log_error_write(srv, __FILE__, __LINE__, "sbbdb", 
4490 -               result ? "NOT CACHED" : "cached", 
4491 -               con->server_name, con->physical.doc_root,
4492 -               c->fcgi_offset, c->fcgi_arg);
4493 -#endif
4494         return HANDLER_GO_ON;   
4495 -
4496 -ERR500:        if (result) mysql_free_result(result);
4497 -       con->http_status = 500; /* Internal Error */
4498 -       return HANDLER_FINISHED;
4499  }
4500  
4501  /* this function is called at dlopen() time and inits the callbacks */
4502  int mod_mysql_vhost_plugin_init(plugin *p) {
4503 +       data_string *ds;
4504 +       
4505         p->version     = LIGHTTPD_VERSION_ID;
4506         p->name                         = buffer_init_string("mysql_vhost");
4507  
4508         p->init                         = mod_mysql_vhost_init;
4509         p->cleanup                      = mod_mysql_vhost_cleanup;
4510 -       p->handle_request_done          = mod_mysql_vhost_handle_connection_close;
4511  
4512         p->set_defaults                 = mod_mysql_vhost_set_defaults;
4513 -       p->handle_docroot               = mod_mysql_vhost_handle_docroot;
4514 +       
4515 +       ds = data_string_init();
4516 +       buffer_copy_string(ds->value, CORE_PLUGIN);
4517 +       array_insert_unique(p->required_plugins, (data_unset *)ds);
4518         
4519         return 0;
4520  }
4521 --- lighttpd-1.4.11/src/mod_proxy.c     2006-01-31 13:01:22.000000000 +0200
4522 +++ lighttpd/src/mod_proxy.c    2006-07-11 21:23:40.099855979 +0300
4523 @@ -1,6 +1,5 @@
4524  #include <sys/types.h>
4525  
4526 -#include <unistd.h>
4527  #include <errno.h>
4528  #include <fcntl.h>
4529  #include <string.h>
4530 @@ -23,6 +22,9 @@
4531  
4532  #include "inet_ntop_cache.h"
4533  #include "crc32.h"
4534 +#include "network.h"
4535 +
4536 +#include "http_resp.h"
4537  
4538  #include <stdio.h>
4539  
4540 @@ -31,6 +33,8 @@
4541  #endif
4542  
4543  #include "sys-socket.h"
4544 +#include "sys-files.h"
4545 +#include "sys-strings.h"
4546  
4547  #define data_proxy data_fastcgi
4548  #define data_proxy_init data_fastcgi_init
4549 @@ -66,6 +70,8 @@
4550         int debug;
4551  
4552         proxy_balance_t balance;
4553 +
4554 +       array *last_used_backends; /* "extension" : last_used_backend */
4555  } plugin_config;
4556  
4557  typedef struct {
4558 @@ -74,6 +80,8 @@
4559         buffer *parse_response;
4560         buffer *balance_buf;
4561         
4562 +       array *ignore_headers;
4563 +
4564         plugin_config **config_storage;
4565         
4566         plugin_config conf;
4567 @@ -84,7 +92,8 @@
4568         PROXY_STATE_CONNECT, 
4569         PROXY_STATE_PREPARE_WRITE, 
4570         PROXY_STATE_WRITE, 
4571 -       PROXY_STATE_READ, 
4572 +    PROXY_STATE_RESPONSE_HEADER,
4573 +    PROXY_STATE_RESPONSE_CONTENT,
4574         PROXY_STATE_ERROR 
4575  } proxy_connection_state_t;
4576  
4577 @@ -100,6 +109,7 @@
4578         buffer *response_header;
4579  
4580         chunkqueue *wb;
4581 +    chunkqueue *rb;
4582         
4583         int fd; /* fd to the proxy process */
4584         int fde_ndx; /* index into the fd-event buffer */
4585 @@ -127,6 +137,7 @@
4586         hctx->response_header = buffer_init();
4587  
4588         hctx->wb = chunkqueue_init();
4589 +    hctx->rb = chunkqueue_init();
4590  
4591         hctx->fd = -1;
4592         hctx->fde_ndx = -1;
4593 @@ -138,17 +149,38 @@
4594         buffer_free(hctx->response);
4595         buffer_free(hctx->response_header);
4596         chunkqueue_free(hctx->wb);
4597 +    chunkqueue_free(hctx->rb);
4598         
4599         free(hctx);
4600  }
4601  
4602  INIT_FUNC(mod_proxy_init) {
4603         plugin_data *p;
4604 +       size_t i;
4605 +
4606 +       char *hop2hop_headers[] = {
4607 +               "Connection",
4608 +               "Keep-Alive",
4609 +               "Host",
4610 +               NULL
4611 +       };
4612         
4613         p = calloc(1, sizeof(*p));
4614         
4615         p->parse_response = buffer_init();
4616         p->balance_buf = buffer_init();
4617 +       p->ignore_headers = array_init();
4618 +
4619 +       for (i = 0; hop2hop_headers[i]; i++) {
4620 +               data_string *ds;
4621 +
4622 +               if (NULL == (ds = (data_string *)array_get_unused_element(p->ignore_headers, TYPE_STRING))) {
4623 +                       ds = data_string_init();
4624 +               }
4625 +
4626 +               buffer_copy_string(ds->value, hop2hop_headers[i]);
4627 +               array_insert_unique(p->ignore_headers, (data_unset *)ds);
4628 +       }
4629         
4630         return p;
4631  }
4632 @@ -168,8 +200,8 @@
4633                         plugin_config *s = p->config_storage[i];
4634                         
4635                         if (s) {
4636 -                       
4637                                 array_free(s->extensions);
4638 +                               array_free(s->last_used_backends);
4639                         
4640                                 free(s);
4641                         }
4642 @@ -177,6 +209,8 @@
4643                 free(p->config_storage);
4644         }
4645         
4646 +       free(p->ignore_headers);
4647 +
4648         free(p);
4649         
4650         return HANDLER_GO_ON;
4651 @@ -202,6 +236,7 @@
4652                 
4653                 s = malloc(sizeof(plugin_config));
4654                 s->extensions    = array_init();
4655 +               s->last_used_backends = array_init();
4656                 s->debug         = 0;
4657                 
4658                 cv[0].destination = s->extensions;
4659 @@ -372,14 +407,22 @@
4660         proxy_addr = (struct sockaddr *) &proxy_addr_in;
4661         
4662         if (-1 == connect(proxy_fd, proxy_addr, servlen)) {
4663 -               if (errno == EINPROGRESS || errno == EALREADY) {
4664 +#ifdef _WIN32
4665 +        errno = WSAGetLastError();
4666 +#endif
4667 +        switch(errno) {
4668 +#ifdef _WIN32
4669 +        case WSAEWOULDBLOCK:
4670 +#endif
4671 +        case EINPROGRESS:
4672 +        case EALREADY:
4673                         if (p->conf.debug) {
4674                                 log_error_write(srv, __FILE__, __LINE__, "sd", 
4675                                                 "connect delayed:", proxy_fd);
4676                         }
4677                         
4678                         return 1;
4679 -               } else {
4680 +               default:
4681                         
4682                         log_error_write(srv, __FILE__, __LINE__, "sdsd", 
4683                                         "connect failed:", proxy_fd, strerror(errno), errno);
4684 @@ -387,6 +430,7 @@
4685                         return -1;
4686                 }
4687         }
4688 +    fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, proxy_fd);
4689         if (p->conf.debug) {
4690                 log_error_write(srv, __FILE__, __LINE__, "sd", 
4691                                 "connect succeeded: ", proxy_fd);
4692 @@ -424,6 +468,7 @@
4693         size_t i;
4694         
4695         connection *con   = hctx->remote_conn;
4696 +       plugin_data *p    = hctx->plugin_data;
4697         buffer *b;
4698         
4699         /* build header */
4700 @@ -453,7 +498,9 @@
4701                 ds = (data_string *)con->request.headers->data[i];
4702                 
4703                 if (ds->value->used && ds->key->used) {
4704 -                       if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
4705 +
4706 +                       /* don't copy hop-to-hop headers */
4707 +                       if (array_get_element(p->ignore_headers, ds->key->ptr)) continue;
4708                         
4709                         buffer_append_string_buffer(b, ds->key);
4710                         BUFFER_APPEND_STRING_CONST(b, ": ");
4711 @@ -531,199 +578,101 @@
4712  }
4713  
4714  
4715 -static int proxy_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
4716 -       char *s, *ns;
4717 -       int http_response_status = -1;
4718 -       
4719 -       UNUSED(srv);
4720 -
4721 -       /* \r\n -> \0\0 */
4722 -       
4723 -       buffer_copy_string_buffer(p->parse_response, in);
4724 -       
4725 -       for (s = p->parse_response->ptr; NULL != (ns = strstr(s, "\r\n")); s = ns + 2) {
4726 -               char *key, *value;
4727 -               int key_len;
4728 -               data_string *ds;
4729 -               int copy_header;
4730 -               
4731 -               ns[0] = '\0';
4732 -               ns[1] = '\0';
4733 -
4734 -               if (-1 == http_response_status) {
4735 -                       /* The first line of a Response message is the Status-Line */
4736 -
4737 -                       for (key=s; *key && *key != ' '; key++);
4738 +static void chunkqueue_print(chunkqueue *cq) {
4739 +    chunk *c;
4740  
4741 -                       if (*key) {
4742 -                               http_response_status = (int) strtol(key, NULL, 10);
4743 -                               if (http_response_status <= 0) http_response_status = 502;
4744 -                       } else {
4745 -                               http_response_status = 502;
4746 +    for (c = cq->first; c; c = c->next) {
4747 +        fprintf(stderr, "%s", c->mem->ptr + c->offset);
4748                         }
4749 -
4750 -                       con->http_status = http_response_status;
4751 -                       con->parsed_response |= HTTP_STATUS;
4752 -                       continue;
4753 +    fprintf(stderr, "\r\n");
4754                 }
4755                 
4756 -               if (NULL == (value = strchr(s, ':'))) {
4757 -                       /* now we expect: "<key>: <value>\n" */
4758 -
4759 -                       continue;
4760 -               }
4761 -
4762 -               key = s;
4763 -               key_len = value - key;
4764 -               
4765 -               value++;
4766 -               /* strip WS */
4767 -               while (*value == ' ' || *value == '\t') value++;
4768 -               
4769 -               copy_header = 1;
4770 +static int proxy_demux_response(server *srv, handler_ctx *hctx) {
4771 +       plugin_data *p    = hctx->plugin_data;
4772 +       connection *con   = hctx->remote_conn;
4773 +       int proxy_fd       = hctx->fd;
4774 +    chunkqueue *next_queue = NULL;
4775 +    chunk *c = NULL;
4776                 
4777 -               switch(key_len) {
4778 -               case 4:
4779 -                       if (0 == strncasecmp(key, "Date", key_len)) {
4780 -                               con->parsed_response |= HTTP_DATE;
4781 -                       }
4782 -                       break;
4783 -               case 8:
4784 -                       if (0 == strncasecmp(key, "Location", key_len)) {
4785 -                               con->parsed_response |= HTTP_LOCATION;
4786 -                       }
4787 -                       break;
4788 -               case 10:
4789 -                       if (0 == strncasecmp(key, "Connection", key_len)) {
4790 -                               copy_header = 0;
4791 -                       }
4792 +    switch(srv->network_backend_read(srv, con, proxy_fd, hctx->rb)) {
4793 +    case NETWORK_STATUS_SUCCESS:
4794 +        /* we got content */
4795                         break;
4796 -               case 14:
4797 -                       if (0 == strncasecmp(key, "Content-Length", key_len)) {
4798 -                               con->response.content_length = strtol(value, NULL, 10);
4799 -                               con->parsed_response |= HTTP_CONTENT_LENGTH;
4800 -                       }
4801 -                       break;
4802 -               default:
4803 -                       break;
4804 -               }
4805 +    case NETWORK_STATUS_CONNECTION_CLOSE:
4806 +        /* we are done, get out of here */
4807 +               con->file_finished = 1;
4808  
4809 -               if (copy_header) {
4810 -                       if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
4811 -                               ds = data_response_init();
4812 -                       }
4813 -                       buffer_copy_string_len(ds->key, key, key_len);
4814 -                       buffer_copy_string(ds->value, value);
4815 +        /* close the chunk-queue with a empty chunk */
4816 +               http_chunk_append_mem(srv, con, NULL, 0);
4817 +               joblist_append(srv, con);
4818                         
4819 -                       array_insert_unique(con->response.headers, (data_unset *)ds);
4820 -               }
4821 +        return 1;
4822 +    default:
4823 +        /* oops */
4824 +        return -1;
4825         }
4826         
4827 -       return 0;
4828 -}
4829 +    /* looks like we got some content
4830 +    *
4831 +    * split off the header from the incoming stream
4832 +    */
4833  
4834 +    if (hctx->state == PROXY_STATE_RESPONSE_HEADER) {
4835 +        http_resp *resp = http_response_init();
4836  
4837 -static int proxy_demux_response(server *srv, handler_ctx *hctx) {
4838 -       int fin = 0;
4839 -       int b;
4840 -       ssize_t r;
4841 +        /* the response header is not fully received yet,
4842 +        *
4843 +        * extract the http-response header from the rb-cq
4844 +        */
4845 +        fprintf(stderr, "%s.%d: network-read\r\n", __FILE__, __LINE__);
4846 +        chunkqueue_print(hctx->rb);
4847         
4848 -       plugin_data *p    = hctx->plugin_data;
4849 -       connection *con   = hctx->remote_conn;
4850 -       int proxy_fd       = hctx->fd;
4851 +        switch (http_response_parse_cq(hctx->rb, resp)) {
4852 +        case PARSE_ERROR:
4853 +            /* parsing failed */
4854         
4855 -       /* check how much we have to read */
4856 -       if (ioctl(hctx->fd, FIONREAD, &b)) {
4857 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
4858 -                               "ioctl failed: ",
4859 -                               proxy_fd);
4860 -               return -1;
4861 -       }
4862 +            con->http_status = 502; /* Bad Gateway */
4863 +            return 1;
4864 +        case PARSE_NEED_MORE:
4865 +            return 0;
4866 +        case PARSE_SUCCESS:
4867 +            con->http_status = resp->status;
4868  
4869 +            fprintf(stderr, "%s.%d: parsing done\r\n", __FILE__, __LINE__);
4870 +            chunkqueue_print(hctx->rb);
4871  
4872 -       if (p->conf.debug) {
4873 -               log_error_write(srv, __FILE__, __LINE__, "sd",
4874 -                              "proxy - have to read:", b);
4875 -       }
4876 +            con->file_started = 1;
4877  
4878 -       if (b > 0) {
4879 -               if (hctx->response->used == 0) {
4880 -                       /* avoid too small buffer */
4881 -                       buffer_prepare_append(hctx->response, b + 1);
4882 -                       hctx->response->used = 1;
4883 -               } else {
4884 -                       buffer_prepare_append(hctx->response, hctx->response->used + b);
4885 +            hctx->state = PROXY_STATE_RESPONSE_CONTENT;
4886 +            break;
4887                 }
4888 -               
4889 -               if (-1 == (r = read(hctx->fd, hctx->response->ptr + hctx->response->used - 1, b))) {
4890 -                       log_error_write(srv, __FILE__, __LINE__, "sds", 
4891 -                                       "unexpected end-of-file (perhaps the proxy process died):",
4892 -                                       proxy_fd, strerror(errno));
4893 -                       return -1;
4894                 }
4895                 
4896 -               /* this should be catched by the b > 0 above */
4897 -               assert(r);
4898 +    /* FIXME: pass the response-header to the other plugins to
4899 +    * setup the filter-queue
4900 +    *
4901 +    * - use next-queue instead of con->write_queue
4902 +    */
4903                 
4904 -               hctx->response->used += r;
4905 -               hctx->response->ptr[hctx->response->used - 1] = '\0';
4906 +    next_queue = con->write_queue;
4907  
4908 -#if 0
4909 -               log_error_write(srv, __FILE__, __LINE__, "sdsbs", 
4910 -                               "demux: Response buffer len", hctx->response->used, ":", hctx->response, ":");
4911 -#endif
4912 +    assert(hctx->state == PROXY_STATE_RESPONSE_CONTENT);
4913  
4914 -               if (0 == con->got_response) {
4915 -                       con->got_response = 1;
4916 -                       buffer_prepare_copy(hctx->response_header, 128);
4917 -               }
4918 -                               
4919 -               if (0 == con->file_started) {
4920 -                       char *c;
4921 -                               
4922 -                       /* search for the \r\n\r\n in the string */
4923 -                       if (NULL != (c = buffer_search_string_len(hctx->response, "\r\n\r\n", 4))) {
4924 -                               size_t hlen = c - hctx->response->ptr + 4;
4925 -                               size_t blen = hctx->response->used - hlen - 1;
4926 -                               /* found */
4927 -                               
4928 -                               buffer_append_string_len(hctx->response_header, hctx->response->ptr, c - hctx->response->ptr + 4);
4929 -#if 0
4930 -                               log_error_write(srv, __FILE__, __LINE__, "sb", "Header:", hctx->response_header);
4931 -#endif
4932 -                               /* parse the response header */
4933 -                               proxy_response_parse(srv, con, p, hctx->response_header);
4934 +    /* FIXME: if we have a content-length or chunked-encoding
4935 +    * handle it.
4936 +    *
4937 +    * for now we wait for EOF on the socket */
4938                                         
4939 -                               /* enable chunked-transfer-encoding */
4940 -                               if (con->request.http_version == HTTP_VERSION_1_1 &&
4941 -                                   !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
4942 -                                       con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
4943 -                               }
4944 +    /* copy the content to the next cq */
4945 +    for (c = hctx->rb->first; c; c = c->next) {
4946 +        http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
4947                                         
4948 -                               con->file_started = 1;
4949 -                               if (blen) {
4950 -                                       http_chunk_append_mem(srv, con, c + 4, blen + 1);
4951 -                                       joblist_append(srv, con);
4952 +        c->offset = c->mem->used - 1;
4953                                 }
4954 -                               hctx->response->used = 0;
4955 -                       }
4956 -               } else {
4957 -                       http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
4958 -                       joblist_append(srv, con);
4959 -                       hctx->response->used = 0;
4960 -               }
4961 -               
4962 -       } else {
4963 -               /* reading from upstream done */
4964 -               con->file_finished = 1;
4965 -               
4966 -               http_chunk_append_mem(srv, con, NULL, 0);
4967 -               joblist_append(srv, con);
4968                 
4969 -               fin = 1;
4970 -       }
4971 +    chunkqueue_remove_finished_chunks(hctx->rb);
4972         
4973 -       return fin;
4974 +       return 0;
4975  }
4976  
4977  
4978 @@ -803,6 +752,7 @@
4979                         if (p->conf.debug) {
4980                                 log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - connect - delayed success"); 
4981                         }
4982 +            fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, hctx->fd);
4983                 }
4984                 
4985                 proxy_set_state(srv, hctx, PROXY_STATE_PREPARE_WRITE);
4986 @@ -818,21 +768,20 @@
4987  
4988                 chunkqueue_remove_finished_chunks(hctx->wb);
4989  
4990 -               if (-1 == ret) {
4991 -                       if (errno != EAGAIN &&
4992 -                           errno != EINTR) {
4993 +               switch(ret) {
4994 +        case NETWORK_STATUS_FATAL_ERROR:
4995                                 log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno);
4996                                 
4997                                 return HANDLER_ERROR;
4998 -                       } else {
4999 +        case NETWORK_STATUS_WAIT_FOR_EVENT:
5000 +
5001                                 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
5002  
5003                                 return HANDLER_WAIT_FOR_EVENT;
5004                         }
5005 -               }
5006  
5007                 if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
5008 -                       proxy_set_state(srv, hctx, PROXY_STATE_READ);
5009 +                       proxy_set_state(srv, hctx, PROXY_STATE_RESPONSE_HEADER);
5010  
5011                         fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
5012                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
5013 @@ -843,8 +792,9 @@
5014                 }
5015                 
5016                 return HANDLER_WAIT_FOR_EVENT;
5017 -       case PROXY_STATE_READ:
5018 +       case PROXY_STATE_RESPONSE_HEADER:
5019                 /* waiting for a response */
5020 +
5021                 return HANDLER_WAIT_FOR_EVENT;
5022         default:
5023                 log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
5024 @@ -854,15 +804,14 @@
5025         return HANDLER_GO_ON;
5026  }
5027  
5028 -#define PATCH(x) \
5029 -       p->conf.x = s->x;
5030  static int mod_proxy_patch_connection(server *srv, connection *con, plugin_data *p) {
5031         size_t i, j;
5032         plugin_config *s = p->config_storage[0];
5033         
5034 -       PATCH(extensions);
5035 -       PATCH(debug);
5036 -       PATCH(balance);
5037 +       PATCH_OPTION(extensions);
5038 +       PATCH_OPTION(debug);
5039 +       PATCH_OPTION(balance);
5040 +       PATCH_OPTION(last_used_backends);
5041         
5042         /* skip the first, the global context */
5043         for (i = 1; i < srv->config_context->used; i++) {
5044 @@ -877,18 +826,18 @@
5045                         data_unset *du = dc->value->data[j];
5046                         
5047                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.server"))) {
5048 -                               PATCH(extensions);
5049 +                               PATCH_OPTION(extensions);
5050                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.debug"))) {
5051 -                               PATCH(debug);
5052 +                               PATCH_OPTION(debug);
5053                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balance"))) {
5054 -                               PATCH(balance);
5055 +                               PATCH_OPTION(balance);
5056 +                               PATCH_OPTION(last_used_backends);
5057                         }
5058                 }
5059         }
5060         
5061         return 0;
5062  }
5063 -#undef PATCH
5064  
5065  SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
5066         plugin_data *p = p_d;
5067 @@ -954,7 +903,8 @@
5068         
5069         
5070         if ((revents & FDEVENT_IN) &&
5071 -           hctx->state == PROXY_STATE_READ) {
5072 +        (hctx->state == PROXY_STATE_RESPONSE_HEADER ||
5073 +         hctx->state == PROXY_STATE_RESPONSE_CONTENT)) {
5074  
5075                 if (p->conf.debug) {
5076                         log_error_write(srv, __FILE__, __LINE__, "sd", 
5077 @@ -1058,6 +1008,11 @@
5078         buffer *fn;
5079         data_array *extension = NULL;
5080         size_t path_info_offset;
5081 +       data_integer *last_used_backend;
5082 +       data_proxy *host = NULL;
5083 +       handler_ctx *hctx = NULL;
5084 +
5085 +       array *backends = NULL;
5086         
5087         /* Possibly, we processed already this request */
5088         if (con->file_started == 1) return HANDLER_GO_ON;
5089 @@ -1111,6 +1066,8 @@
5090                 return HANDLER_GO_ON;
5091         }
5092  
5093 +       backends = extension->value;
5094 +
5095         if (p->conf.debug) {    
5096                 log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - ext found");
5097         }
5098 @@ -1121,33 +1078,33 @@
5099  
5100                 if (p->conf.debug) {
5101                         log_error_write(srv, __FILE__, __LINE__,  "sd", 
5102 -                                       "proxy - used hash balancing, hosts:", extension->value->used);
5103 +                                       "proxy - used hash balancing, hosts:", backends->used);
5104                 }
5105  
5106 -               for (k = 0, ndx = -1, last_max = ULONG_MAX; k < extension->value->used; k++) {
5107 -                       data_proxy *host = (data_proxy *)extension->value->data[k];
5108 +               for (k = 0, ndx = -1, last_max = ULONG_MAX; k < backends->used; k++) {
5109                         unsigned long cur_max;
5110  
5111 -                       if (host->is_disabled) continue;
5112 +                       data_proxy *cur = (data_proxy *)backends->data[k];
5113 +
5114 +                       if (cur->is_disabled) continue;
5115                         
5116                         cur_max = generate_crc32c(CONST_BUF_LEN(con->uri.path)) +
5117 -                               generate_crc32c(CONST_BUF_LEN(host->host)) + /* we can cache this */
5118 +                               generate_crc32c(CONST_BUF_LEN(cur->host)) + /* we can cache this */
5119                                 generate_crc32c(CONST_BUF_LEN(con->uri.authority));
5120                         
5121                         if (p->conf.debug) {
5122                                 log_error_write(srv, __FILE__, __LINE__,  "sbbbd", 
5123                                                 "proxy - election:",
5124                                                 con->uri.path,
5125 -                                               host->host,
5126 +                                               cur->host,
5127                                                 con->uri.authority,
5128                                                 cur_max);
5129                         }
5130  
5131 -                       if ((last_max == ULONG_MAX) || /* first round */
5132 -                           (cur_max > last_max)) {
5133 +                       if (host == NULL || (cur_max > last_max)) {
5134                                 last_max = cur_max;
5135  
5136 -                               ndx = k;
5137 +                               host = cur;
5138                         }
5139                 }
5140  
5141 @@ -1159,15 +1116,16 @@
5142                                         "proxy - used fair balancing");
5143                 }
5144  
5145 -               for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
5146 -                       data_proxy *host = (data_proxy *)extension->value->data[k];
5147 +               /* try to find the host with the lowest load */
5148 +               for (k = 0, max_usage = 0; k < backends->used; k++) {
5149 +                       data_proxy *cur = (data_proxy *)backends->data[k];
5150                 
5151 -                       if (host->is_disabled) continue;
5152 +                       if (cur->is_disabled) continue;
5153  
5154 -                       if (host->usage < max_usage) {
5155 -                               max_usage = host->usage;
5156 +                       if (NULL == host || cur->usage < max_usage) {
5157 +                               max_usage = cur->usage;
5158                         
5159 -                               ndx = k;
5160 +                               host = cur;
5161                         }
5162                 }
5163  
5164 @@ -1180,30 +1138,50 @@
5165                 }
5166  
5167                 /* just to be sure */
5168 -               assert(extension->value->used < INT_MAX);
5169 +               assert(backends->used < INT_MAX);
5170 +
5171 +               /* send each request to another host:
5172 +                *
5173 +                * e.g.:
5174 +                *
5175 +                * if we have three hosts it is
5176 +                *
5177 +                * 1 .. 2 .. 3 .. 1 .. 2 .. 3
5178 +                *
5179 +                **/
5180 +
5181 +               /* walk through the list */
5182 +               last_used_backend = (data_integer *)array_get_element(p->conf.last_used_backends, extension->key->ptr);
5183                 
5184 -               for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
5185 -                       data_proxy *host = (data_proxy *)extension->value->data[k];
5186 +               if (NULL == last_used_backend) {
5187 +                       last_used_backend = data_integer_init();
5188                 
5189 -                       if (host->is_disabled) continue;
5190 +                       buffer_copy_string_buffer(last_used_backend->key, extension->key);
5191 +                       last_used_backend->value = 0;
5192  
5193 -                       /* first usable ndx */
5194 -                       if (max_usage == INT_MAX) {
5195 -                               max_usage = k;
5196 +                       array_insert_unique(p->conf.last_used_backends, (data_unset *)last_used_backend);
5197                         }
5198  
5199 -                       /* get next ndx */
5200 -                       if ((int)k > host->last_used_ndx) {
5201 -                               ndx = k;
5202 -                               host->last_used_ndx = k;
5203 +               /* scan all but the last host to see if they are up
5204 +                * take the first running host */
5205 +               for (k = last_used_backend->value + 1; (int)(k % backends->used) != last_used_backend->value; k++) {
5206 +                       data_proxy *cur = (data_proxy *)backends->data[k % backends->used];
5207 +
5208 +                       if (cur->is_disabled) continue;
5209 +
5210 +                       host = cur;
5211 +
5212 +                       last_used_backend->value = k;
5213  
5214                                 break;
5215                         }
5216 -               }
5217                 
5218 -               /* didn't found a higher id, wrap to the start */
5219 -               if (ndx != -1 && max_usage != INT_MAX) {
5220 -                       ndx = max_usage;
5221 +               if (NULL == host) {
5222 +                       /* we found nothing better, fallback to the last used backend
5223 +                        * and check if it is still up */
5224 +                       host = (data_proxy *)backends->data[last_used_backend->value];
5225 +
5226 +                       if (host->is_disabled) host = NULL;
5227                 }
5228  
5229                 break;
5230 @@ -1211,17 +1189,18 @@
5231                 break;
5232         }
5233         
5234 -       /* found a server */
5235 -       if (ndx != -1) {
5236 -               data_proxy *host = (data_proxy *)extension->value->data[ndx];
5237 +       /* we havn't found a host */
5238 +       if (NULL == host) {
5239 +               con->http_status = 500;
5240                 
5241 -               /* 
5242 -                * if check-local is disabled, use the uri.path handler 
5243 -                * 
5244 -                */
5245 +               log_error_write(srv, __FILE__, __LINE__,  "sb",
5246 +                               "no proxy-handler found for:",
5247 +                               fn);
5248 +
5249 +               return HANDLER_FINISHED;
5250 +       }
5251                 
5252                 /* init handler-context */
5253 -               handler_ctx *hctx;
5254                 hctx = handler_ctx_init();
5255                                 
5256                 hctx->path_info_offset = path_info_offset;
5257 @@ -1233,6 +1212,7 @@
5258                 
5259                 host->usage++;
5260                 
5261 +       /* we handle this request */
5262                 con->mode = p->id;
5263                 
5264                 if (p->conf.debug) {
5265 @@ -1242,17 +1222,6 @@
5266                 }
5267  
5268                 return HANDLER_GO_ON;
5269 -       } else {
5270 -               /* no handler found */
5271 -               con->http_status = 500;
5272 -               
5273 -               log_error_write(srv, __FILE__, __LINE__,  "sb", 
5274 -                               "no proxy-handler found for:", 
5275 -                               fn);
5276 -               
5277 -               return HANDLER_FINISHED;
5278 -       }
5279 -       return HANDLER_GO_ON;
5280  }
5281  
5282  static handler_t mod_proxy_connection_close_callback(server *srv, connection *con, void *p_d) {
5283 --- lighttpd-1.4.11/src/mod_redirect.c  2006-02-08 15:38:06.000000000 +0200
5284 +++ lighttpd/src/mod_redirect.c 2006-07-11 21:23:40.111856730 +0300
5285 @@ -166,7 +166,7 @@
5286  static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_data) {
5287  #ifdef HAVE_PCRE_H
5288         plugin_data *p = p_data;
5289 -       size_t i;
5290 +       int i;
5291  
5292         /* 
5293          * REWRITE URL
5294 @@ -178,70 +178,9 @@
5295         mod_redirect_patch_connection(srv, con, p);
5296         
5297         buffer_copy_string_buffer(p->match_buf, con->request.uri);
5298 +       i = config_exec_pcre_keyvalue_buffer(con, p->conf.redirect, p->conf.context, p->match_buf, p->location);
5299         
5300 -       for (i = 0; i < p->conf.redirect->used; i++) {
5301 -               pcre *match;
5302 -               pcre_extra *extra;
5303 -               const char *pattern;
5304 -               size_t pattern_len;
5305 -               int n;
5306 -               pcre_keyvalue *kv = p->conf.redirect->kv[i];
5307 -# define N 10
5308 -               int ovec[N * 3];
5309 -               
5310 -               match       = kv->key;
5311 -               extra       = kv->key_extra;
5312 -               pattern     = kv->value->ptr;
5313 -               pattern_len = kv->value->used - 1;
5314 -               
5315 -               if ((n = pcre_exec(match, extra, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
5316 -                       if (n != PCRE_ERROR_NOMATCH) {
5317 -                               log_error_write(srv, __FILE__, __LINE__, "sd",
5318 -                                               "execution error while matching: ", n);
5319 -                               return HANDLER_ERROR;
5320 -                       }
5321 -               } else {
5322 -                       const char **list;
5323 -                       size_t start, end;
5324 -                       size_t k;
5325 -                       
5326 -                       /* it matched */
5327 -                       pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list);
5328 -                       
5329 -                       /* search for $[0-9] */
5330 -                       
5331 -                       buffer_reset(p->location);
5332 -                       
5333 -                       start = 0; end = pattern_len;
5334 -                       for (k = 0; k < pattern_len; k++) {
5335 -                               if ((pattern[k] == '$' || pattern[k] == '%') &&
5336 -                                   isdigit((unsigned char)pattern[k + 1])) {
5337 -                                       /* got one */
5338 -                                       
5339 -                                       size_t num = pattern[k + 1] - '0';
5340 -                                       
5341 -                                       end = k;
5342 -                                       
5343 -                                       buffer_append_string_len(p->location, pattern + start, end - start);
5344 -                                       
5345 -                                       if (pattern[k] == '$') {
5346 -                                               /* n is always > 0 */
5347 -                                               if (num < (size_t)n) {
5348 -                                                       buffer_append_string(p->location, list[num]);
5349 -                                               }
5350 -                                       } else {
5351 -                                               config_append_cond_match_buffer(con, p->conf.context, p->location, num);
5352 -                                       }
5353 -                                       
5354 -                                       k++;
5355 -                                       start = k + 1;
5356 -                               } 
5357 -                       }
5358 -                       
5359 -                       buffer_append_string_len(p->location, pattern + start, pattern_len - start);
5360 -                       
5361 -                       pcre_free(list);
5362 -                       
5363 +       if (i >= 0) {
5364                         response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
5365                         
5366                         con->http_status = 301;
5367 @@ -249,6 +188,9 @@
5368                         
5369                         return HANDLER_FINISHED;
5370                 }
5371 +       else if (i != PCRE_ERROR_NOMATCH) {
5372 +               log_error_write(srv, __FILE__, __LINE__, "s",
5373 +                               "execution error while matching", i);
5374         }
5375  #undef N
5376                 
5377 --- lighttpd-1.4.11/src/mod_rewrite.c   2005-09-29 20:59:10.000000000 +0300
5378 +++ lighttpd/src/mod_rewrite.c  2006-07-11 21:23:39.947846458 +0300
5379 @@ -13,24 +13,8 @@
5380  #endif
5381  
5382  typedef struct {
5383 -#ifdef HAVE_PCRE_H
5384 -       pcre *key;
5385 -#endif
5386 -       
5387 -       buffer *value;
5388 -       
5389 -       int once;
5390 -} rewrite_rule;
5391 -
5392 -typedef struct {
5393 -       rewrite_rule **ptr;
5394 -       
5395 -       size_t used;
5396 -       size_t size;
5397 -} rewrite_rule_buffer;
5398 -
5399 -typedef struct {
5400 -       rewrite_rule_buffer *rewrite;
5401 +       pcre_keyvalue_buffer *rewrite;
5402 +       buffer *once;
5403         data_config *context; /* to which apply me */
5404  } plugin_config;
5405  
5406 @@ -63,80 +47,6 @@
5407         free(hctx);
5408  }
5409  
5410 -rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
5411 -       rewrite_rule_buffer *kvb;
5412 -       
5413 -       kvb = calloc(1, sizeof(*kvb));
5414 -       
5415 -       return kvb;
5416 -}
5417 -
5418 -int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
5419 -#ifdef HAVE_PCRE_H
5420 -       size_t i;
5421 -       const char *errptr;
5422 -       int erroff;
5423 -       
5424 -       if (!key) return -1;
5425 -
5426 -       if (kvb->size == 0) {
5427 -               kvb->size = 4;
5428 -               kvb->used = 0;
5429 -               
5430 -               kvb->ptr = malloc(kvb->size * sizeof(*kvb->ptr));
5431 -               
5432 -               for(i = 0; i < kvb->size; i++) {
5433 -                       kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
5434 -               }
5435 -       } else if (kvb->used == kvb->size) {
5436 -               kvb->size += 4;
5437 -               
5438 -               kvb->ptr = realloc(kvb->ptr, kvb->size * sizeof(*kvb->ptr));
5439 -               
5440 -               for(i = kvb->used; i < kvb->size; i++) {
5441 -                       kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
5442 -               }
5443 -       }
5444 -       
5445 -       if (NULL == (kvb->ptr[kvb->used]->key = pcre_compile(key->ptr,
5446 -                                                           0, &errptr, &erroff, NULL))) {
5447 -               
5448 -               return -1;
5449 -       }
5450 -       
5451 -       kvb->ptr[kvb->used]->value = buffer_init();
5452 -       buffer_copy_string_buffer(kvb->ptr[kvb->used]->value, value);
5453 -       kvb->ptr[kvb->used]->once = once;
5454 -       
5455 -       kvb->used++;
5456 -       
5457 -       return 0;
5458 -#else
5459 -       UNUSED(kvb);
5460 -       UNUSED(value);
5461 -       UNUSED(once);
5462 -       UNUSED(key);
5463 -
5464 -       return -1;
5465 -#endif
5466 -}
5467 -
5468 -void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
5469 -#ifdef HAVE_PCRE_H
5470 -       size_t i;
5471 -
5472 -       for (i = 0; i < kvb->size; i++) {
5473 -               if (kvb->ptr[i]->key) pcre_free(kvb->ptr[i]->key);
5474 -               if (kvb->ptr[i]->value) buffer_free(kvb->ptr[i]->value);
5475 -               free(kvb->ptr[i]);
5476 -       }
5477 -       
5478 -       if (kvb->ptr) free(kvb->ptr);
5479 -#endif
5480 -       
5481 -       free(kvb);
5482 -}
5483 -
5484  
5485  INIT_FUNC(mod_rewrite_init) {
5486         plugin_data *p;
5487 @@ -160,7 +70,8 @@
5488                 size_t i;
5489                 for (i = 0; i < srv->config_context->used; i++) {
5490                         plugin_config *s = p->config_storage[i];
5491 -                       rewrite_rule_buffer_free(s->rewrite);
5492 +                       pcre_keyvalue_buffer_free(s->rewrite);
5493 +                       buffer_free(s->once);
5494                         
5495                         free(s);
5496                 }
5497 @@ -198,10 +109,9 @@
5498                                 return HANDLER_ERROR;
5499                         }
5500                         
5501 -                       if (0 != rewrite_rule_buffer_append(s->rewrite, 
5502 -                                                           ((data_string *)(da->value->data[j]))->key,
5503 -                                                           ((data_string *)(da->value->data[j]))->value,
5504 -                                                           once)) {
5505 +                       if (0 != pcre_keyvalue_buffer_append(s->rewrite,
5506 +                                                           ((data_string *)(da->value->data[j]))->key->ptr,
5507 +                                                           ((data_string *)(da->value->data[j]))->value->ptr)) {
5508  #ifdef HAVE_PCRE_H
5509                                 log_error_write(srv, __FILE__, __LINE__, "sb", 
5510                                                 "pcre-compile failed for", da->value->data[j]->key);
5511 @@ -210,6 +120,12 @@
5512                                                 "pcre support is missing, please install libpcre and the headers");
5513  #endif
5514                         }
5515 +
5516 +                       if (once) {
5517 +                               buffer_append_string_len(s->once, CONST_STR_LEN("1"));
5518 +                       } else {
5519 +                               buffer_append_string_len(s->once, CONST_STR_LEN("0"));
5520 +                       }
5521                 }
5522         }
5523         
5524 @@ -245,11 +161,8 @@
5525                 array *ca;
5526                 
5527                 s = calloc(1, sizeof(plugin_config));
5528 -               s->rewrite   = rewrite_rule_buffer_init();
5529 -               
5530 -               cv[0].destination = s->rewrite;
5531 -               cv[1].destination = s->rewrite;
5532 -               cv[2].destination = s->rewrite;
5533 +               s->rewrite   = pcre_keyvalue_buffer_init();
5534 +               s->once      = buffer_init();
5535                 
5536                 p->config_storage[i] = s;
5537                 ca = ((data_config *)srv->config_context->data[i])->value;
5538 @@ -271,6 +184,7 @@
5539         size_t i, j;
5540         plugin_config *s = p->config_storage[0];
5541         p->conf.rewrite = s->rewrite;
5542 +       p->conf.once    = s->once;
5543         
5544         /* skip the first, the global context */
5545         for (i = 1; i < srv->config_context->used; i++) {
5546 @@ -288,15 +202,19 @@
5547                         
5548                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite"))) {
5549                                 p->conf.rewrite = s->rewrite;
5550 +                               p->conf.once    = s->once;
5551                                 p->conf.context = dc;
5552                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-once"))) {
5553                                 p->conf.rewrite = s->rewrite;
5554 +                               p->conf.once    = s->once;
5555                                 p->conf.context = dc;
5556                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-repeat"))) {
5557                                 p->conf.rewrite = s->rewrite;
5558 +                               p->conf.once    = s->once;
5559                                 p->conf.context = dc;
5560                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-final"))) {
5561                                 p->conf.rewrite = s->rewrite;
5562 +                               p->conf.once    = s->once;
5563                                 p->conf.context = dc;
5564                         }
5565                 }
5566 @@ -321,7 +239,7 @@
5567  URIHANDLER_FUNC(mod_rewrite_uri_handler) {
5568  #ifdef HAVE_PCRE_H
5569         plugin_data *p = p_d;
5570 -       size_t i;
5571 +       int i;
5572         handler_ctx *hctx;
5573  
5574         /* 
5575 @@ -349,76 +267,21 @@
5576         if (!p->conf.rewrite) return HANDLER_GO_ON;
5577         
5578         buffer_copy_string_buffer(p->match_buf, con->request.uri);
5579 +       i = config_exec_pcre_keyvalue_buffer(con, p->conf.rewrite, p->conf.context, p->match_buf, con->request.uri);
5580         
5581 -       for (i = 0; i < p->conf.rewrite->used; i++) {
5582 -               pcre *match;
5583 -               const char *pattern;
5584 -               size_t pattern_len;
5585 -               int n;
5586 -               rewrite_rule *rule = p->conf.rewrite->ptr[i];
5587 -# define N 10
5588 -               int ovec[N * 3];
5589 -               
5590 -               match       = rule->key;
5591 -               pattern     = rule->value->ptr;
5592 -               pattern_len = rule->value->used - 1;
5593 -               
5594 -               if ((n = pcre_exec(match, NULL, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
5595 -                       if (n != PCRE_ERROR_NOMATCH) {
5596 -                               log_error_write(srv, __FILE__, __LINE__, "sd",
5597 -                                               "execution error while matching: ", n);
5598 -                               return HANDLER_ERROR;
5599 -                       }
5600 -               } else {
5601 -                       const char **list;
5602 -                       size_t start, end;
5603 -                       size_t k;
5604 -                       
5605 -                       /* it matched */
5606 -                       pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list);
5607 -                       
5608 -                       /* search for $[0-9] */
5609 -                       
5610 -                       buffer_reset(con->request.uri);
5611 -                       
5612 -                       start = 0; end = pattern_len;
5613 -                       for (k = 0; k < pattern_len; k++) {
5614 -                               if ((pattern[k] == '$' || pattern[k] == '%') &&
5615 -                                   isdigit((unsigned char)pattern[k + 1])) {
5616 -                                       /* got one */
5617 -                                       
5618 -                                       size_t num = pattern[k + 1] - '0';
5619 -                                       
5620 -                                       end = k;
5621 -                                       
5622 -                                       buffer_append_string_len(con->request.uri, pattern + start, end - start);
5623 -                                       
5624 -                                       if (pattern[k] == '$') {
5625 -                                               /* n is always > 0 */
5626 -                                               if (num < (size_t)n) {
5627 -                                                       buffer_append_string(con->request.uri, list[num]);
5628 -                                               }
5629 -                                       } else {
5630 -                                               config_append_cond_match_buffer(con, p->conf.context, con->request.uri, num);
5631 -                                       }
5632 -                                       
5633 -                                       k++;
5634 -                                       start = k + 1;
5635 -                               } 
5636 -                       }
5637 -                       
5638 -                       buffer_append_string_len(con->request.uri, pattern + start, pattern_len - start);
5639 -                       
5640 -                       pcre_free(list);
5641 -                       
5642 +       if (i >= 0) {
5643                         hctx = handler_ctx_init();
5644                                 
5645                         con->plugin_ctx[p->id] = hctx;
5646                         
5647 -                       if (rule->once) hctx->state = REWRITE_STATE_FINISHED;
5648 +               if (p->conf.once->ptr[i] == '1')
5649 +                       hctx->state = REWRITE_STATE_FINISHED;
5650                         
5651                         return HANDLER_COMEBACK;
5652                 }
5653 +       else if (i != PCRE_ERROR_NOMATCH) {
5654 +               log_error_write(srv, __FILE__, __LINE__, "s",
5655 +                               "execution error while matching", i);
5656         }
5657  #undef N
5658                 
5659 --- lighttpd-1.4.11/src/mod_rrdtool.c   2005-08-22 01:52:24.000000000 +0300
5660 +++ lighttpd/src/mod_rrdtool.c  2006-07-11 21:23:40.059853473 +0300
5661 @@ -5,7 +5,6 @@
5662  #include <stdlib.h>
5663  #include <stdio.h>
5664  #include <string.h>
5665 -#include <unistd.h>
5666  #include <errno.h>
5667  #include <time.h>
5668  
5669 @@ -20,6 +19,10 @@
5670  /* no need for waitpid if we don't have fork */
5671  #include <sys/wait.h>
5672  #endif
5673 +
5674 +#include "sys-files.h"
5675 +#include "sys-process.h"
5676 +
5677  typedef struct {
5678         buffer *path_rrdtool_bin;
5679         buffer *path_rrd;
5680 @@ -250,14 +253,12 @@
5681         return HANDLER_GO_ON;
5682  }
5683  
5684 -#define PATCH(x) \
5685 -       p->conf.x = s->x;
5686  static int mod_rrd_patch_connection(server *srv, connection *con, plugin_data *p) {
5687         size_t i, j;
5688         plugin_config *s = p->config_storage[0];
5689         
5690 -       PATCH(path_rrdtool_bin);
5691 -       PATCH(path_rrd);
5692 +       PATCH_OPTION(path_rrdtool_bin);
5693 +       PATCH_OPTION(path_rrd);
5694         
5695         p->conf.bytes_written_ptr = &(s->bytes_written);
5696         p->conf.bytes_read_ptr = &(s->bytes_read);
5697 @@ -276,7 +277,7 @@
5698                         data_unset *du = dc->value->data[j];
5699                         
5700                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("rrdtool.db-name"))) {
5701 -                               PATCH(path_rrd);
5702 +                               PATCH_OPTION(path_rrd);
5703                                 /* get pointers to double values */
5704                                 
5705                                 p->conf.bytes_written_ptr = &(s->bytes_written);
5706 @@ -288,7 +289,6 @@
5707         
5708         return 0;
5709  }
5710 -#undef PATCH
5711  
5712  SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
5713         plugin_data *p = p_d;
5714 --- lighttpd-1.4.11/src/mod_scgi.c      2006-03-04 17:15:26.000000000 +0200
5715 +++ lighttpd/src/mod_scgi.c     2006-07-11 21:23:40.023851218 +0300
5716 @@ -1,5 +1,4 @@
5717  #include <sys/types.h>
5718 -#include <unistd.h>
5719  #include <errno.h>
5720  #include <fcntl.h>
5721  #include <string.h>
5722 @@ -30,7 +29,9 @@
5723  #endif
5724  
5725  #include "sys-socket.h"
5726 -
5727 +#include "sys-files.h"
5728 +#include "sys-strings.h"
5729 +#include "sys-process.h"
5730  
5731  #ifndef UNIX_PATH_MAX
5732  # define UNIX_PATH_MAX 108
5733 @@ -61,7 +62,6 @@
5734         
5735         pid_t pid;   /* PID of the spawned process (0 if not spawned locally) */
5736  
5737 -
5738         size_t load; /* number of requests waiting on this process */
5739  
5740         time_t last_used; /* see idle_timeout */
5741 @@ -308,7 +308,6 @@
5742         size_t    request_id;
5743         int       fd;        /* fd to the scgi process */
5744         int       fde_ndx;   /* index into the fd-event buffer */
5745 -
5746         pid_t     pid;
5747         int       got_proc;
5748         
5749 @@ -555,7 +554,9 @@
5750                                         host = ex->hosts[n];
5751                                         
5752                                         for (proc = host->first; proc; proc = proc->next) {
5753 +#ifndef _WIN32
5754                                                 if (proc->pid != 0) kill(proc->pid, SIGTERM);
5755 +#endif
5756                                                 
5757                                                 if (proc->is_local && 
5758                                                     !buffer_is_empty(proc->socket)) {
5759 @@ -564,7 +565,9 @@
5760                                         }
5761                                         
5762                                         for (proc = host->unused_procs; proc; proc = proc->next) {
5763 +#ifndef _WIN32
5764                                                 if (proc->pid != 0) kill(proc->pid, SIGTERM);
5765 +#endif
5766                                                 
5767                                                 if (proc->is_local && 
5768                                                     !buffer_is_empty(proc->socket)) {
5769 @@ -641,12 +644,8 @@
5770                 scgi_addr_un.sun_family = AF_UNIX;
5771                 strcpy(scgi_addr_un.sun_path, proc->socket->ptr);
5772                 
5773 -#ifdef SUN_LEN
5774                 servlen = SUN_LEN(&scgi_addr_un);
5775 -#else
5776 -               /* stevens says: */
5777 -               servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
5778 -#endif
5779 +
5780                 socket_type = AF_UNIX;
5781                 scgi_addr = (struct sockaddr *) &scgi_addr_un;
5782  #else
5783 @@ -1292,12 +1291,9 @@
5784                 /* use the unix domain socket */
5785                 scgi_addr_un.sun_family = AF_UNIX;
5786                 strcpy(scgi_addr_un.sun_path, proc->socket->ptr);
5787 -#ifdef SUN_LEN
5788 +               
5789                 servlen = SUN_LEN(&scgi_addr_un);
5790 -#else
5791 -               /* stevens says: */
5792 -               servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
5793 -#endif
5794 +
5795                 scgi_addr = (struct sockaddr *) &scgi_addr_un;
5796  #else
5797                 return -1;
5798 @@ -2058,6 +2054,7 @@
5799                         int status;
5800                         
5801                         if (proc->state == PROC_STATE_DIED_WAIT_FOR_PID) {
5802 +#ifndef _WIN32
5803                                 switch(waitpid(proc->pid, &status, WNOHANG)) {
5804                                 case 0:
5805                                         /* child is still alive */
5806 @@ -2084,6 +2081,7 @@
5807                                         proc->state = PROC_STATE_DIED;
5808                                         break;
5809                                 }
5810 +#endif
5811                         }
5812                         
5813                         /* 
5814 @@ -2271,10 +2269,11 @@
5815                                  */ 
5816                                 if (hctx->wb->bytes_out == 0 &&
5817                                     hctx->reconnects < 5) {
5818 +#ifndef _WIN32
5819                                         usleep(10000); /* take away the load of the webserver 
5820                                                         * to let the php a chance to restart 
5821                                                         */
5822 -                                       
5823 +#endif
5824                                         scgi_reconnect(srv, hctx);
5825                                 
5826                                         return HANDLER_WAIT_FOR_FD;
5827 @@ -2286,7 +2285,7 @@
5828                                  * 
5829                                  */
5830                                 
5831 -                               log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
5832 +                               log_error_write(srv, __FILE__, __LINE__, "ssosd",
5833                                                 "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
5834                                                 "write-offset:", hctx->wb->bytes_out,
5835                                                 "reconnect attempts:", hctx->reconnects);
5836 @@ -2479,7 +2478,7 @@
5837                                 int status;
5838                                 
5839                                 /* only fetch the zombie if it is not already done */
5840 -                               
5841 +#ifndef _WIN32
5842                                 switch(waitpid(proc->pid, &status, WNOHANG)) {
5843                                 case 0:
5844                                         /* child is still alive */
5845 @@ -2519,6 +2518,7 @@
5846                                         
5847                                         break;
5848                                 }
5849 +#endif
5850                         }
5851  
5852                         if (con->file_started == 0) {
5853 @@ -2536,7 +2536,7 @@
5854                                         return HANDLER_WAIT_FOR_FD;
5855                                 }
5856                                 
5857 -                               log_error_write(srv, __FILE__, __LINE__, "sdsdsd", 
5858 +                               log_error_write(srv, __FILE__, __LINE__, "sosdsd",
5859                                                 "response not sent, request sent:", hctx->wb->bytes_out,
5860                                                 "connection-fd:", con->fd,
5861                                                 "fcgi-fd:", hctx->fd);
5862 @@ -2631,14 +2631,13 @@
5863         
5864         return HANDLER_FINISHED;
5865  }
5866 -#define PATCH(x) \
5867 -       p->conf.x = s->x;
5868 +
5869  static int scgi_patch_connection(server *srv, connection *con, plugin_data *p) {
5870         size_t i, j;
5871         plugin_config *s = p->config_storage[0];
5872         
5873 -       PATCH(exts);
5874 -       PATCH(debug);
5875 +       PATCH_OPTION(exts);
5876 +       PATCH_OPTION(debug);
5877         
5878         /* skip the first, the global context */
5879         for (i = 1; i < srv->config_context->used; i++) {
5880 @@ -2653,17 +2652,15 @@
5881                         data_unset *du = dc->value->data[j];
5882                         
5883                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.server"))) {
5884 -                               PATCH(exts);
5885 +                               PATCH_OPTION(exts);
5886                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.debug"))) {
5887 -                               PATCH(debug);
5888 +                               PATCH_OPTION(debug);
5889                         }
5890                 }
5891         }
5892         
5893         return 0;
5894  }
5895 -#undef PATCH
5896 -
5897  
5898  static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
5899         plugin_data *p = p_d;
5900 @@ -2971,7 +2968,7 @@
5901                                         if (proc->load != 0) break;
5902                                         if (host->num_procs <= host->min_procs) break;
5903                                         if (proc->pid == 0) continue;
5904 -                                       
5905 +#ifndef _WIN32
5906                                         if (srv->cur_ts - proc->last_used > host->idle_timeout) {
5907                                                 /* a proc is idling for a long time now,
5908                                                  * terminated it */
5909 @@ -3009,13 +3006,14 @@
5910                                                 /* proc is now in unused, let the next second handle the next process */
5911                                                 break;
5912                                         }       
5913 +#endif
5914                                 }
5915                                 
5916                                 for (proc = host->unused_procs; proc; proc = proc->next) {
5917                                         int status;
5918                                         
5919                                         if (proc->pid == 0) continue;
5920 -                                       
5921 +#ifndef _WIN32
5922                                         switch (waitpid(proc->pid, &status, WNOHANG)) {
5923                                         case 0:
5924                                                 /* child still running after timeout, good */
5925 @@ -3059,6 +3057,7 @@
5926                                                 proc->state = PROC_STATE_UNSET;
5927                                                 host->max_id--;
5928                                         }
5929 +#endif
5930                                 }
5931                         }
5932                 }
5933 --- lighttpd-1.4.11/src/mod_secure_download.c   2005-12-14 14:37:29.000000000 +0200
5934 +++ lighttpd/src/mod_secure_download.c  2006-07-11 21:23:39.935845706 +0300
5935 @@ -156,16 +156,14 @@
5936         return i == len;
5937  }
5938  
5939 -#define PATCH(x) \
5940 -       p->conf.x = s->x;
5941  static int mod_secdownload_patch_connection(server *srv, connection *con, plugin_data *p) {
5942         size_t i, j;
5943         plugin_config *s = p->config_storage[0];
5944         
5945 -       PATCH(secret);
5946 -       PATCH(doc_root);
5947 -       PATCH(uri_prefix);
5948 -       PATCH(timeout);
5949 +       PATCH_OPTION(secret);
5950 +       PATCH_OPTION(doc_root);
5951 +       PATCH_OPTION(uri_prefix);
5952 +       PATCH_OPTION(timeout);
5953         
5954         /* skip the first, the global context */
5955         for (i = 1; i < srv->config_context->used; i++) {
5956 @@ -180,21 +178,19 @@
5957                         data_unset *du = dc->value->data[j];
5958                         
5959                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.secret"))) {
5960 -                               PATCH(secret);
5961 +                               PATCH_OPTION(secret);
5962                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.document-root"))) {
5963 -                               PATCH(doc_root);
5964 +                               PATCH_OPTION(doc_root);
5965                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.uri-prefix"))) {
5966 -                               PATCH(uri_prefix);
5967 +                               PATCH_OPTION(uri_prefix);
5968                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.timeout"))) {
5969 -                               PATCH(timeout);
5970 +                               PATCH_OPTION(timeout);
5971                         }
5972                 }
5973         }
5974         
5975         return 0;
5976  }
5977 -#undef PATCH
5978 -
5979  
5980  URIHANDLER_FUNC(mod_secdownload_uri_handler) {
5981         plugin_data *p = p_d;
5982 --- lighttpd-1.4.11/src/mod_setenv.c    2006-01-14 20:33:12.000000000 +0200
5983 +++ lighttpd/src/mod_setenv.c   2006-07-11 21:23:40.191861741 +0300
5984 @@ -120,15 +120,13 @@
5985         return HANDLER_GO_ON;
5986  }
5987  
5988 -#define PATCH(x) \
5989 -       p->conf.x = s->x;
5990  static int mod_setenv_patch_connection(server *srv, connection *con, plugin_data *p) {
5991         size_t i, j;
5992         plugin_config *s = p->config_storage[0];
5993         
5994 -       PATCH(request_header);
5995 -       PATCH(response_header);
5996 -       PATCH(environment);
5997 +       PATCH_OPTION(request_header);
5998 +       PATCH_OPTION(response_header);
5999 +       PATCH_OPTION(environment);
6000         
6001         /* skip the first, the global context */
6002         for (i = 1; i < srv->config_context->used; i++) {
6003 @@ -143,18 +141,17 @@
6004                         data_unset *du = dc->value->data[j];
6005                         
6006                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-request-header"))) {
6007 -                               PATCH(request_header);
6008 +                               PATCH_OPTION(request_header);
6009                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-response-header"))) {
6010 -                               PATCH(response_header);
6011 +                               PATCH_OPTION(response_header);
6012                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-environment"))) {
6013 -                               PATCH(environment);
6014 +                               PATCH_OPTION(environment);
6015                         }
6016                 }
6017         }
6018         
6019         return 0;
6020  }
6021 -#undef PATCH
6022  
6023  URIHANDLER_FUNC(mod_setenv_uri_handler) {
6024         plugin_data *p = p_d;
6025 --- lighttpd-1.4.11/src/mod_simple_vhost.c      2005-11-18 15:16:13.000000000 +0200
6026 +++ lighttpd/src/mod_simple_vhost.c     2006-07-11 21:23:40.087855227 +0300
6027 @@ -10,6 +10,8 @@
6028  
6029  #include "plugin.h"
6030  
6031 +#include "sys-files.h"
6032 +
6033  #ifdef HAVE_CONFIG_H
6034  #include "config.h"
6035  #endif
6036 @@ -139,7 +141,7 @@
6037                          */
6038                         char *dp;
6039                         
6040 -                       BUFFER_APPEND_SLASH(out);
6041 +                       PATHNAME_APPEND_SLASH(out);
6042                         
6043                         if (NULL == (dp = strchr(host->ptr, ':'))) {
6044                                 buffer_append_string_buffer(out, host);
6045 @@ -147,17 +149,17 @@
6046                                 buffer_append_string_len(out, host->ptr, dp - host->ptr);
6047                         }
6048                 }
6049 -               BUFFER_APPEND_SLASH(out);
6050 +               PATHNAME_APPEND_SLASH(out);
6051                 
6052                 if (p->conf.document_root->used > 2 && p->conf.document_root->ptr[0] == '/') {
6053                         buffer_append_string_len(out, p->conf.document_root->ptr + 1, p->conf.document_root->used - 2);
6054                 } else {
6055                         buffer_append_string_buffer(out, p->conf.document_root);
6056 -                       BUFFER_APPEND_SLASH(out);
6057 +                       PATHNAME_APPEND_SLASH(out);
6058                 }
6059         } else {
6060                 buffer_copy_string_buffer(out, con->conf.document_root);
6061 -               BUFFER_APPEND_SLASH(out);
6062 +               PATHNAME_APPEND_SLASH(out);
6063         }
6064         
6065         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, out, &sce)) {
6066 @@ -173,22 +175,19 @@
6067         return 0;
6068  }
6069  
6070 -
6071 -#define PATCH(x) \
6072 -       p->conf.x = s->x;
6073  static int mod_simple_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
6074         size_t i, j;
6075         plugin_config *s = p->config_storage[0];
6076         
6077 -       PATCH(server_root);
6078 -       PATCH(default_host);
6079 -       PATCH(document_root);
6080 -       
6081 -       PATCH(docroot_cache_key);
6082 -       PATCH(docroot_cache_value);
6083 -       PATCH(docroot_cache_servername);
6084 +       PATCH_OPTION(server_root);
6085 +       PATCH_OPTION(default_host);
6086 +       PATCH_OPTION(document_root);
6087 +
6088 +       PATCH_OPTION(docroot_cache_key);
6089 +       PATCH_OPTION(docroot_cache_value);
6090 +       PATCH_OPTION(docroot_cache_servername);
6091  
6092 -       PATCH(debug);
6093 +       PATCH_OPTION(debug);
6094         
6095         /* skip the first, the global context */
6096         for (i = 1; i < srv->config_context->used; i++) {
6097 @@ -203,23 +202,22 @@
6098                         data_unset *du = dc->value->data[j];
6099                         
6100                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.server-root"))) {
6101 -                               PATCH(server_root);
6102 -                               PATCH(docroot_cache_key);
6103 -                               PATCH(docroot_cache_value);
6104 -                               PATCH(docroot_cache_servername);
6105 +                               PATCH_OPTION(server_root);
6106 +                               PATCH_OPTION(docroot_cache_key);
6107 +                               PATCH_OPTION(docroot_cache_value);
6108 +                               PATCH_OPTION(docroot_cache_servername);
6109                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.default-host"))) {
6110 -                               PATCH(default_host);
6111 +                               PATCH_OPTION(default_host);
6112                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.document-root"))) {
6113 -                               PATCH(document_root);
6114 +                               PATCH_OPTION(document_root);
6115                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.debug"))) {
6116 -                               PATCH(debug);
6117 +                               PATCH_OPTION(debug);
6118                         }
6119                 }
6120         }
6121         
6122         return 0;
6123  }
6124 -#undef PATCH
6125  
6126  static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_data) {
6127         plugin_data *p = p_data;
6128 --- lighttpd-1.4.11/src/mod_skeleton.c  2005-10-02 18:30:51.000000000 +0300
6129 +++ lighttpd/src/mod_skeleton.c 2006-07-11 21:23:40.019850968 +0300
6130 @@ -132,13 +132,11 @@
6131         return HANDLER_GO_ON;
6132  }
6133  
6134 -#define PATCH(x) \
6135 -       p->conf.x = s->x;
6136  static int mod_skeleton_patch_connection(server *srv, connection *con, plugin_data *p) {
6137         size_t i, j;
6138         plugin_config *s = p->config_storage[0];
6139         
6140 -       PATCH(match);
6141 +       PATCH_OPTION(match);
6142         
6143         /* skip the first, the global context */
6144         for (i = 1; i < srv->config_context->used; i++) {
6145 @@ -153,14 +151,13 @@
6146                         data_unset *du = dc->value->data[j];
6147                         
6148                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("skeleton.array"))) {
6149 -                               PATCH(match);
6150 +                               PATCH_OPTION(match);
6151                         }
6152                 }
6153         }
6154         
6155         return 0;
6156  }
6157 -#undef PATCH
6158  
6159  URIHANDLER_FUNC(mod_skeleton_uri_handler) {
6160         plugin_data *p = p_d;
6161 --- lighttpd-1.4.11/src/mod_ssi.c       2006-03-04 17:09:48.000000000 +0200
6162 +++ lighttpd/src/mod_ssi.c      2006-07-11 21:23:40.159859737 +0300
6163 @@ -6,7 +6,6 @@
6164  #include <string.h>
6165  #include <errno.h>
6166  #include <time.h>
6167 -#include <unistd.h>
6168  
6169  #include "base.h"
6170  #include "log.h"
6171 @@ -23,6 +22,8 @@
6172  #include "inet_ntop_cache.h"
6173  
6174  #include "sys-socket.h"
6175 +#include "sys-strings.h"
6176 +#include "sys-files.h"
6177  
6178  #ifdef HAVE_PWD_H
6179  #include <pwd.h>
6180 @@ -660,6 +661,8 @@
6181                 
6182                 break;
6183         case SSI_EXEC: {
6184 +#ifndef _WIN32
6185 +
6186                 const char *cmd = NULL;
6187                 pid_t pid;
6188                 int from_exec_fds[2];
6189 @@ -682,7 +685,7 @@
6190                  */
6191                 
6192                 if (!cmd) break;
6193 -#ifdef HAVE_FORK       
6194 +
6195                 if (pipe(from_exec_fds)) {
6196                         log_error_write(srv, __FILE__, __LINE__, "ss", 
6197                                         "pipe failed: ", strerror(errno));
6198 @@ -760,7 +763,6 @@
6199                 }
6200                 }
6201  #else
6202 -
6203                 return -1;
6204  #endif
6205                 
6206 @@ -1008,13 +1010,11 @@
6207         return 0;
6208  }
6209  
6210 -#define PATCH(x) \
6211 -       p->conf.x = s->x;
6212  static int mod_ssi_patch_connection(server *srv, connection *con, plugin_data *p) {
6213         size_t i, j;
6214         plugin_config *s = p->config_storage[0];
6215         
6216 -       PATCH(ssi_extension);
6217 +       PATCH_OPTION(ssi_extension);
6218         
6219         /* skip the first, the global context */
6220         for (i = 1; i < srv->config_context->used; i++) {
6221 @@ -1029,14 +1029,13 @@
6222                         data_unset *du = dc->value->data[j];
6223                         
6224                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) {
6225 -                               PATCH(ssi_extension);
6226 +                               PATCH_OPTION(ssi_extension);
6227                         }
6228                 }
6229         }
6230         
6231         return 0;
6232  }
6233 -#undef PATCH
6234  
6235  URIHANDLER_FUNC(mod_ssi_physical_path) {
6236         plugin_data *p = p_d;
6237 --- lighttpd-1.4.11/src/mod_staticfile.c        2006-02-15 14:31:14.000000000 +0200
6238 +++ lighttpd/src/mod_staticfile.c       2006-07-11 21:23:39.979848462 +0300
6239 @@ -14,6 +14,8 @@
6240  #include "http_chunk.h"
6241  #include "response.h"
6242  
6243 +#include "sys-files.h"
6244 +#include "sys-strings.h"
6245  /**
6246   * this is a staticfile for a lighttpd plugin
6247   * 
6248 @@ -48,7 +50,7 @@
6249         return p;
6250  }
6251  
6252 -/* detroy the plugin data */
6253 +/* destroy the plugin data */
6254  FREE_FUNC(mod_staticfile_free) {
6255         plugin_data *p = p_d;
6256         
6257 @@ -107,13 +109,11 @@
6258         return HANDLER_GO_ON;
6259  }
6260  
6261 -#define PATCH(x) \
6262 -       p->conf.x = s->x;
6263  static int mod_staticfile_patch_connection(server *srv, connection *con, plugin_data *p) {
6264         size_t i, j;
6265         plugin_config *s = p->config_storage[0];
6266         
6267 -       PATCH(exclude_ext);
6268 +       PATCH_OPTION(exclude_ext);
6269         
6270         /* skip the first, the global context */
6271         for (i = 1; i < srv->config_context->used; i++) {
6272 @@ -128,14 +128,13 @@
6273                         data_unset *du = dc->value->data[j];
6274                         
6275                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.exclude-extensions"))) {
6276 -                               PATCH(exclude_ext);
6277 +                               PATCH_OPTION(exclude_ext);
6278                         }
6279                 }
6280         }
6281         
6282         return 0;
6283  }
6284 -#undef PATCH
6285  
6286  static int http_response_parse_range(server *srv, connection *con, plugin_data *p) {
6287         int multipart = 0;
6288 @@ -396,7 +395,7 @@
6289                 return HANDLER_FINISHED;
6290         }
6291         
6292 -       /* we only handline regular files */
6293 +       /* we only handle regular files */
6294         if (!S_ISREG(sce->st.st_mode)) {
6295                 con->http_status = 404;
6296                 
6297 @@ -409,7 +408,7 @@
6298                 return HANDLER_FINISHED;
6299         }
6300  
6301 -       /* mod_compress might set several data directly, don't overwrite them */
6302 +       /* mod_compress might set several parameters directly; don't overwrite them */
6303         
6304         /* set response content-type, if not set already */
6305  
6306 --- lighttpd-1.4.11/src/mod_status.c    2006-01-10 21:45:32.000000000 +0200
6307 +++ lighttpd/src/mod_status.c   2006-07-11 21:23:40.131857983 +0300
6308 @@ -4,7 +4,6 @@
6309  #include <fcntl.h>
6310  #include <stdlib.h>
6311  #include <string.h>
6312 -#include <unistd.h>
6313  #include <errno.h>
6314  #include <time.h>
6315  #include <stdio.h>
6316 @@ -202,7 +201,7 @@
6317         size_t j;
6318         double avg;
6319         char multiplier = '\0';
6320 -       char buf[32];
6321 +       char buf[128];
6322         time_t ts;
6323         
6324         int days, hours, mins, seconds;
6325 @@ -304,13 +303,13 @@
6326         /* connection listing */
6327         BUFFER_APPEND_STRING_CONST(b, "<h1>Server-Status</h1>");
6328         
6329 -       BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">");
6330 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\">");
6331 +       BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" id=\"status\" summary=\"Server Status\">");
6332 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\"><span id=\"host_addr\">");
6333         buffer_append_string_buffer(b, con->uri.authority);
6334 -       BUFFER_APPEND_STRING_CONST(b, " (");
6335 +       BUFFER_APPEND_STRING_CONST(b, "</span> (<span id=\"host_name\">");
6336         buffer_append_string_buffer(b, con->server_name);
6337 -       BUFFER_APPEND_STRING_CONST(b, ")</td></tr>\n");
6338 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\">");
6339 +       BUFFER_APPEND_STRING_CONST(b, "</span>)</td></tr>\n");
6340 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\" id=\"uptime\">");
6341         
6342         ts = srv->cur_ts - srv->startup_ts;
6343         
6344 @@ -348,58 +347,58 @@
6345         
6346         ts = srv->startup_ts;
6347         
6348 -       strftime(buf, sizeof(buf) - 1, "%Y-%m-%d %H:%M:%S", localtime(&ts));
6349 +       strftime(buf, sizeof(buf) - 1, "<span id=\"start_date\">%Y-%m-%d</span> <span id=\"start_time\">%H:%M:%S</span>", localtime(&ts));
6350         buffer_append_string(b, buf);
6351         BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
6352         
6353         
6354         BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">absolute (since start)</th></tr>\n");
6355         
6356 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
6357 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\" ><span id=\"requests\">");
6358         avg = p->abs_requests;
6359  
6360         mod_status_get_multiplier(&avg, &multiplier, 1000);
6361         
6362         buffer_append_long(b, avg);
6363 -       BUFFER_APPEND_STRING_CONST(b, " ");
6364 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_mult\">");
6365         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
6366 -       BUFFER_APPEND_STRING_CONST(b, "req</td></tr>\n");
6367 +       BUFFER_APPEND_STRING_CONST(b, "</span>req</td></tr>\n");
6368         
6369 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
6370 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic\">");
6371         avg = p->abs_traffic_out;
6372  
6373         mod_status_get_multiplier(&avg, &multiplier, 1024);
6374  
6375         sprintf(buf, "%.2f", avg);
6376         buffer_append_string(b, buf);
6377 -       BUFFER_APPEND_STRING_CONST(b, " ");
6378 +       BUFFER_APPEND_STRING_CONST(b, "</span>  <span id=\"traffic_mult\">");
6379         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
6380 -       BUFFER_APPEND_STRING_CONST(b, "byte</td></tr>\n");
6381 +       BUFFER_APPEND_STRING_CONST(b, "</span>byte</td></tr>\n");
6382  
6383  
6384  
6385         BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (since start)</th></tr>\n");
6386         
6387 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
6388 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_avg\">");
6389         avg = p->abs_requests / (srv->cur_ts - srv->startup_ts);
6390  
6391         mod_status_get_multiplier(&avg, &multiplier, 1000);
6392  
6393         buffer_append_long(b, avg);
6394 -       BUFFER_APPEND_STRING_CONST(b, " ");
6395 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_avg_mult\">");
6396         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
6397 -       BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
6398 +       BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n");
6399         
6400 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
6401 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic_avg\">");
6402         avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts);
6403  
6404         mod_status_get_multiplier(&avg, &multiplier, 1024);
6405  
6406         sprintf(buf, "%.2f", avg);
6407         buffer_append_string(b, buf);
6408 -       BUFFER_APPEND_STRING_CONST(b, " ");
6409 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"traffic_avg_mult\">");
6410         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
6411 -       BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
6412 +       BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n");
6413  
6414         
6415         
6416 @@ -410,15 +409,15 @@
6417         
6418         avg /= 5;
6419         
6420 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
6421 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_sliding_avg\">");
6422  
6423         mod_status_get_multiplier(&avg, &multiplier, 1000);
6424  
6425         buffer_append_long(b, avg);
6426 -       BUFFER_APPEND_STRING_CONST(b, " ");
6427 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_avg_mult\">");
6428         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
6429         
6430 -       BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
6431 +       BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n");
6432         
6433         for (j = 0, avg = 0; j < 5; j++) {
6434                 avg += p->mod_5s_traffic_out[j];
6435 @@ -426,15 +425,15 @@
6436         
6437         avg /= 5;
6438         
6439 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
6440 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"requests_sliding_traffic\">");
6441  
6442         mod_status_get_multiplier(&avg, &multiplier, 1024);
6443  
6444         sprintf(buf, "%.2f", avg);
6445         buffer_append_string(b, buf);
6446 -       BUFFER_APPEND_STRING_CONST(b, " ");
6447 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_traffic_mult\">");
6448         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
6449 -       BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
6450 +       BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n");
6451         
6452         BUFFER_APPEND_STRING_CONST(b, "</table>\n");
6453         
6454 @@ -445,9 +444,9 @@
6455         BUFFER_APPEND_STRING_CONST(b, "q = request-start,  Q = request-end\n");
6456         BUFFER_APPEND_STRING_CONST(b, "s = response-start, S = response-end\n");
6457         
6458 -       BUFFER_APPEND_STRING_CONST(b, "<b>");
6459 +       BUFFER_APPEND_STRING_CONST(b, "<strong><span id=\"connections\">");
6460         buffer_append_long(b, srv->conns->used);
6461 -       BUFFER_APPEND_STRING_CONST(b, " connections</b>\n");
6462 +       BUFFER_APPEND_STRING_CONST(b, "</span> connections</strong>\n");
6463         
6464         for (j = 0; j < srv->conns->used; j++) {
6465                 connection *c = srv->conns->ptr[j];
6466 @@ -462,7 +461,7 @@
6467         
6468         BUFFER_APPEND_STRING_CONST(b, "\n</pre><hr />\n<h2>Connections</h2>\n");
6469         
6470 -       BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">\n");
6471 +       BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" summary=\"Current connections\" id=\"clients\">\n");
6472         BUFFER_APPEND_STRING_CONST(b, "<tr>");
6473         mod_status_header_append_sort(b, p_d, "Client IP");
6474         mod_status_header_append_sort(b, p_d, "Read");
6475 @@ -477,11 +476,11 @@
6476         for (j = 0; j < srv->conns->used; j++) {
6477                 connection *c = srv->conns->ptr[j];
6478                 
6479 -               BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string\">");
6480 +               BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string ip\">");
6481                 
6482                 buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(c->dst_addr)));
6483                 
6484 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
6485 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_read\">");
6486                 
6487                 if (con->request.content_length) {
6488                         buffer_append_long(b, c->request_content_queue->bytes_in);
6489 @@ -491,21 +490,21 @@
6490                         BUFFER_APPEND_STRING_CONST(b, "0/0");
6491                 }
6492         
6493 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
6494 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_written\">");
6495                 
6496                 buffer_append_off_t(b, chunkqueue_written(c->write_queue));
6497                 BUFFER_APPEND_STRING_CONST(b, "/");
6498                 buffer_append_off_t(b, chunkqueue_length(c->write_queue));
6499                 
6500 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
6501 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string state\">");
6502                 
6503                 buffer_append_string(b, connection_get_state(c->state));
6504                 
6505 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
6506 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int time\">");
6507                 
6508                 buffer_append_long(b, srv->cur_ts - c->request_start);
6509                 
6510 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
6511 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string host\">");
6512                 
6513                 if (buffer_is_empty(c->server_name)) {
6514                         buffer_append_string_buffer(b, c->uri.authority);
6515 @@ -514,13 +513,13 @@
6516                         buffer_append_string_buffer(b, c->server_name);
6517                 }
6518                 
6519 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
6520 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string uri\">");
6521                 
6522                 if (!buffer_is_empty(c->uri.path)) {
6523                         buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
6524                 }
6525                 
6526 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
6527 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string file\">");
6528                 
6529                 buffer_append_string_buffer(b, c->physical.path);
6530                 
6531 @@ -723,16 +722,14 @@
6532         return HANDLER_FINISHED;
6533  }
6534  
6535 -#define PATCH(x) \
6536 -       p->conf.x = s->x;
6537  static int mod_status_patch_connection(server *srv, connection *con, plugin_data *p) {
6538         size_t i, j;
6539         plugin_config *s = p->config_storage[0];
6540         
6541 -       PATCH(status_url);
6542 -       PATCH(config_url);
6543 -       PATCH(sort);
6544 -       PATCH(statistics_url);
6545 +       PATCH_OPTION(status_url);
6546 +       PATCH_OPTION(config_url);
6547 +       PATCH_OPTION(sort);
6548 +       PATCH_OPTION(statistics_url);
6549         
6550         /* skip the first, the global context */
6551         for (i = 1; i < srv->config_context->used; i++) {
6552 @@ -747,13 +744,13 @@
6553                         data_unset *du = dc->value->data[j];
6554                         
6555                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.status-url"))) {
6556 -                               PATCH(status_url);
6557 +                               PATCH_OPTION(status_url);
6558                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.config-url"))) {
6559 -                               PATCH(config_url);
6560 +                               PATCH_OPTION(config_url);
6561                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.enable-sort"))) {
6562 -                               PATCH(sort);
6563 +                               PATCH_OPTION(sort);
6564                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.statistics-url"))) {
6565 -                               PATCH(statistics_url);
6566 +                               PATCH_OPTION(statistics_url);
6567                         } 
6568                 }
6569         }
6570 --- lighttpd-1.4.11/src/mod_trigger_b4_dl.c     2005-09-23 22:53:55.000000000 +0300
6571 +++ lighttpd/src/mod_trigger_b4_dl.c    2006-07-11 21:23:39.991849214 +0300
6572 @@ -241,25 +241,23 @@
6573         return HANDLER_GO_ON;
6574  }
6575  
6576 -#define PATCH(x) \
6577 -       p->conf.x = s->x;
6578  static int mod_trigger_b4_dl_patch_connection(server *srv, connection *con, plugin_data *p) {
6579         size_t i, j;
6580         plugin_config *s = p->config_storage[0];
6581         
6582  #if defined(HAVE_GDBM)
6583 -       PATCH(db);
6584 +       PATCH_OPTION(db);
6585  #endif 
6586  #if defined(HAVE_PCRE_H)
6587 -       PATCH(download_regex);
6588 -       PATCH(trigger_regex);
6589 +       PATCH_OPTION(download_regex);
6590 +       PATCH_OPTION(trigger_regex);
6591  #endif 
6592 -       PATCH(trigger_timeout);
6593 -       PATCH(deny_url);
6594 -       PATCH(mc_namespace);
6595 -       PATCH(debug);
6596 +       PATCH_OPTION(trigger_timeout);
6597 +       PATCH_OPTION(deny_url);
6598 +       PATCH_OPTION(mc_namespace);
6599 +       PATCH_OPTION(debug);
6600  #if defined(HAVE_MEMCACHE_H)
6601 -       PATCH(mc);
6602 +       PATCH_OPTION(mc);
6603  #endif
6604         
6605         /* skip the first, the global context */
6606 @@ -276,27 +274,27 @@
6607  
6608                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.download-url"))) {
6609  #if defined(HAVE_PCRE_H)
6610 -                               PATCH(download_regex);
6611 +                               PATCH_OPTION(download_regex);
6612  #endif
6613                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-url"))) {
6614  # if defined(HAVE_PCRE_H)
6615 -                               PATCH(trigger_regex);
6616 +                               PATCH_OPTION(trigger_regex);
6617  # endif
6618                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.gdbm-filename"))) {
6619  #if defined(HAVE_GDBM_H)
6620 -                               PATCH(db);
6621 +                               PATCH_OPTION(db);
6622  #endif
6623                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-timeout"))) {
6624 -                               PATCH(trigger_timeout);
6625 +                               PATCH_OPTION(trigger_timeout);
6626                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.debug"))) {
6627 -                               PATCH(debug);
6628 +                               PATCH_OPTION(debug);
6629                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.deny-url"))) {
6630 -                               PATCH(deny_url);
6631 +                               PATCH_OPTION(deny_url);
6632                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-namespace"))) {
6633 -                               PATCH(mc_namespace);
6634 +                               PATCH_OPTION(mc_namespace);
6635                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-hosts"))) {
6636  #if defined(HAVE_MEMCACHE_H)
6637 -                               PATCH(mc);
6638 +                               PATCH_OPTION(mc);
6639  #endif
6640                         }
6641                 }
6642 @@ -304,7 +302,6 @@
6643         
6644         return 0;
6645  }
6646 -#undef PATCH
6647  
6648  URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
6649         plugin_data *p = p_d;
6650 --- lighttpd-1.4.11/src/mod_userdir.c   2005-10-28 16:48:28.000000000 +0300
6651 +++ lighttpd/src/mod_userdir.c  2006-07-11 21:23:40.091855478 +0300
6652 @@ -10,6 +10,7 @@
6653  #include "response.h"
6654  
6655  #include "plugin.h"
6656 +#include "sys-files.h"
6657  
6658  #ifdef HAVE_PWD_H
6659  #include <pwd.h>
6660 @@ -118,16 +119,14 @@
6661         return HANDLER_GO_ON;
6662  }
6663  
6664 -#define PATCH(x) \
6665 -       p->conf.x = s->x;
6666  static int mod_userdir_patch_connection(server *srv, connection *con, plugin_data *p) {
6667         size_t i, j;
6668         plugin_config *s = p->config_storage[0];
6669         
6670 -       PATCH(path);
6671 -       PATCH(exclude_user);
6672 -       PATCH(include_user);
6673 -       PATCH(basepath);
6674 +       PATCH_OPTION(path);
6675 +       PATCH_OPTION(exclude_user);
6676 +       PATCH_OPTION(include_user);
6677 +       PATCH_OPTION(basepath);
6678         
6679         /* skip the first, the global context */
6680         for (i = 1; i < srv->config_context->used; i++) {
6681 @@ -142,20 +141,19 @@
6682                         data_unset *du = dc->value->data[j];
6683                         
6684                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.path"))) {
6685 -                               PATCH(path);
6686 +                               PATCH_OPTION(path);
6687                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.exclude-user"))) {
6688 -                               PATCH(exclude_user);
6689 +                               PATCH_OPTION(exclude_user);
6690                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.include-user"))) {
6691 -                               PATCH(include_user);
6692 +                               PATCH_OPTION(include_user);
6693                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.basepath"))) {
6694 -                               PATCH(basepath);
6695 +                               PATCH_OPTION(basepath);
6696                         }
6697                 }
6698         }
6699         
6700         return 0;
6701  }
6702 -#undef PATCH
6703  
6704  URIHANDLER_FUNC(mod_userdir_docroot_handler) {
6705         plugin_data *p = p_d;
6706 @@ -252,10 +250,10 @@
6707                 }
6708  
6709                 buffer_copy_string_buffer(p->temp_path, p->conf.basepath);
6710 -               BUFFER_APPEND_SLASH(p->temp_path);
6711 +               PATHNAME_APPEND_SLASH(p->temp_path);
6712                 buffer_append_string_buffer(p->temp_path, p->username);
6713         }
6714 -       BUFFER_APPEND_SLASH(p->temp_path);
6715 +       PATHNAME_APPEND_SLASH(p->temp_path);
6716         buffer_append_string_buffer(p->temp_path, p->conf.path); 
6717  
6718         if (buffer_is_empty(p->conf.basepath)) {
6719 @@ -268,7 +266,7 @@
6720                 } 
6721         }
6722  
6723 -       BUFFER_APPEND_SLASH(p->temp_path);
6724 +       PATHNAME_APPEND_SLASH(p->temp_path);
6725         buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */
6726         buffer_copy_string_buffer(con->physical.path, p->temp_path);
6727  
6728 --- lighttpd-1.4.11/src/mod_usertrack.c 2006-01-31 15:01:20.000000000 +0200
6729 +++ lighttpd/src/mod_usertrack.c        2006-07-11 21:23:40.115856981 +0300
6730 @@ -136,15 +136,13 @@
6731         return HANDLER_GO_ON;
6732  }
6733  
6734 -#define PATCH(x) \
6735 -       p->conf.x = s->x;
6736  static int mod_usertrack_patch_connection(server *srv, connection *con, plugin_data *p) {
6737         size_t i, j;
6738         plugin_config *s = p->config_storage[0];
6739         
6740 -       PATCH(cookie_name);
6741 -       PATCH(cookie_domain);
6742 -       PATCH(cookie_max_age);
6743 +       PATCH_OPTION(cookie_name);
6744 +       PATCH_OPTION(cookie_domain);
6745 +       PATCH_OPTION(cookie_max_age);
6746         
6747         /* skip the first, the global context */
6748         for (i = 1; i < srv->config_context->used; i++) {
6749 @@ -159,18 +157,17 @@
6750                         data_unset *du = dc->value->data[j];
6751                         
6752                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-name"))) {
6753 -                               PATCH(cookie_name);
6754 +                               PATCH_OPTION(cookie_name);
6755                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-max-age"))) {
6756 -                               PATCH(cookie_max_age);
6757 +                               PATCH_OPTION(cookie_max_age);
6758                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-domain"))) {
6759 -                               PATCH(cookie_domain);
6760 +                               PATCH_OPTION(cookie_domain);
6761                         }
6762                 }
6763         }
6764         
6765         return 0;
6766  }
6767 -#undef PATCH
6768  
6769  URIHANDLER_FUNC(mod_usertrack_uri_handler) {
6770         plugin_data *p = p_d;
6771 --- lighttpd-1.4.11/src/mod_webdav.c    2006-03-03 01:28:58.000000000 +0200
6772 +++ lighttpd/src/mod_webdav.c   2006-07-11 21:23:40.123857482 +0300
6773 @@ -3,13 +3,10 @@
6774  #include <ctype.h>
6775  #include <stdlib.h>
6776  #include <string.h>
6777 -#include <dirent.h>
6778  #include <errno.h>
6779 -#include <unistd.h>
6780  #include <fcntl.h>
6781  #include <stdio.h>
6782  #include <assert.h>
6783 -#include <sys/mman.h>
6784  
6785  #ifdef HAVE_CONFIG_H
6786  #include "config.h"
6787 @@ -23,6 +20,11 @@
6788  #include <sqlite3.h>
6789  #endif
6790  
6791 +#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H) && defined(HAVE_UUID_H)
6792 +#define USE_LOCKS
6793 +#include <uuid/uuid.h>
6794 +#endif
6795 +
6796  #include "base.h"
6797  #include "log.h"
6798  #include "buffer.h"
6799 @@ -33,6 +35,9 @@
6800  #include "stream.h"
6801  #include "stat_cache.h"
6802  
6803 +#include "sys-files.h"
6804 +#include "sys-mmap.h"
6805 +#include "sys-strings.h"
6806  
6807  /**
6808   * this is a webdav for a lighttpd plugin
6809 @@ -62,6 +67,12 @@
6810         sqlite3_stmt *stmt_delete_uri;
6811         sqlite3_stmt *stmt_move_uri;
6812         sqlite3_stmt *stmt_copy_uri;
6813 +
6814 +       sqlite3_stmt *stmt_remove_lock;
6815 +       sqlite3_stmt *stmt_create_lock;
6816 +       sqlite3_stmt *stmt_read_lock;
6817 +       sqlite3_stmt *stmt_read_lock_by_uri;
6818 +       sqlite3_stmt *stmt_refresh_lock;
6819  #endif
6820  } plugin_config;
6821  
6822 @@ -123,6 +134,12 @@
6823                                 sqlite3_finalize(s->stmt_update_prop);
6824                                 sqlite3_finalize(s->stmt_select_prop);
6825                                 sqlite3_finalize(s->stmt_select_propnames);
6826 +
6827 +                               sqlite3_finalize(s->stmt_read_lock);
6828 +                               sqlite3_finalize(s->stmt_read_lock_by_uri);
6829 +                               sqlite3_finalize(s->stmt_create_lock);
6830 +                               sqlite3_finalize(s->stmt_remove_lock);
6831 +                               sqlite3_finalize(s->stmt_refresh_lock);
6832                                 sqlite3_close(s->sql);
6833                         }
6834  #endif 
6835 @@ -193,6 +210,24 @@
6836                                 return HANDLER_ERROR;
6837                         }
6838  
6839 +                       if (SQLITE_OK != sqlite3_exec(s->sql,
6840 +                                       "CREATE TABLE properties ("
6841 +                                       "  resource TEXT NOT NULL,"
6842 +                                       "  prop TEXT NOT NULL,"
6843 +                                       "  ns TEXT NOT NULL,"
6844 +                                       "  value TEXT NOT NULL,"
6845 +                                       "  PRIMARY KEY(resource, prop, ns))",
6846 +                                       NULL, NULL, &err)) {
6847 +
6848 +                               if (0 != strcmp(err, "table properties already exists")) {
6849 +                                       log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
6850 +                                       sqlite3_free(err);
6851 +
6852 +                                       return HANDLER_ERROR;
6853 +                               }
6854 +                               sqlite3_free(err);
6855 +                       }
6856 +
6857                         if (SQLITE_OK != sqlite3_prepare(s->sql, 
6858                                 CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), 
6859                                 &(s->stmt_select_prop), &next_stmt)) {
6860 @@ -211,23 +246,6 @@
6861                                 return HANDLER_ERROR;
6862                         }
6863  
6864 -                       if (SQLITE_OK != sqlite3_exec(s->sql, 
6865 -                                       "CREATE TABLE properties ("
6866 -                                       "  resource TEXT NOT NULL,"
6867 -                                       "  prop TEXT NOT NULL,"
6868 -                                       "  ns TEXT NOT NULL,"
6869 -                                       "  value TEXT NOT NULL,"
6870 -                                       "  PRIMARY KEY(resource, prop, ns))",
6871 -                                       NULL, NULL, &err)) {
6872 -
6873 -                               if (0 != strcmp(err, "table properties already exists")) {
6874 -                                       log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
6875 -                                       sqlite3_free(err);
6876 -
6877 -                                       return HANDLER_ERROR;
6878 -                               }
6879 -                               sqlite3_free(err);
6880 -                       }
6881         
6882                         if (SQLITE_OK != sqlite3_prepare(s->sql, 
6883                                 CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"), 
6884 @@ -273,6 +291,76 @@
6885  
6886                                 return HANDLER_ERROR;
6887                         }
6888 +
6889 +                       /* LOCKS */
6890 +
6891 +                       if (SQLITE_OK != sqlite3_exec(s->sql,
6892 +                                       "CREATE TABLE locks ("
6893 +                                       "  locktoken TEXT NOT NULL,"
6894 +                                       "  resource TEXT NOT NULL,"
6895 +                                       "  lockscope TEXT NOT NULL,"
6896 +                                       "  locktype TEXT NOT NULL,"
6897 +                                       "  owner TEXT NOT NULL,"
6898 +                                       "  depth INT NOT NULL,"
6899 +                                       "  timeout TIMESTAMP NOT NULL,"
6900 +                                       "  PRIMARY KEY(locktoken))",
6901 +                                       NULL, NULL, &err)) {
6902 +
6903 +                               if (0 != strcmp(err, "table locks already exists")) {
6904 +                                       log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
6905 +                                       sqlite3_free(err);
6906 +
6907 +                                       return HANDLER_ERROR;
6908 +                               }
6909 +                               sqlite3_free(err);
6910 +                       }
6911 +
6912 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
6913 +                               CONST_STR_LEN("INSERT INTO locks (locktoken, resource, lockscope, locktype, owner, depth, timeout) VALUES (?,?,?,?,?,?, CURRENT_TIME + 600)"),
6914 +                               &(s->stmt_create_lock), &next_stmt)) {
6915 +                               /* prepare failed */
6916 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
6917 +
6918 +                               return HANDLER_ERROR;
6919 +                       }
6920 +
6921 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
6922 +                               CONST_STR_LEN("DELETE FROM locks WHERE locktoken = ?"),
6923 +                               &(s->stmt_remove_lock), &next_stmt)) {
6924 +                               /* prepare failed */
6925 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
6926 +
6927 +                               return HANDLER_ERROR;
6928 +                       }
6929 +
6930 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
6931 +                               CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE locktoken = ?"),
6932 +                               &(s->stmt_read_lock), &next_stmt)) {
6933 +                               /* prepare failed */
6934 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
6935 +
6936 +                               return HANDLER_ERROR;
6937 +                       }
6938 +
6939 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
6940 +                               CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE resource = ?"),
6941 +                               &(s->stmt_read_lock_by_uri), &next_stmt)) {
6942 +                               /* prepare failed */
6943 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
6944 +
6945 +                               return HANDLER_ERROR;
6946 +                       }
6947 +
6948 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
6949 +                               CONST_STR_LEN("UPDATE locks SET timeout = CURRENT_TIME + 600 WHERE locktoken = ?"),
6950 +                               &(s->stmt_refresh_lock), &next_stmt)) {
6951 +                               /* prepare failed */
6952 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
6953 +
6954 +                               return HANDLER_ERROR;
6955 +                       }
6956 +
6957 +
6958  #else
6959                         log_error_write(srv, __FILE__, __LINE__, "s", "Sorry, no sqlite3 and libxml2 support include, compile with --with-webdav-props");
6960                         return HANDLER_ERROR;
6961 @@ -283,26 +371,30 @@
6962         return HANDLER_GO_ON;
6963  }
6964  
6965 -#define PATCH(x) \
6966 -       p->conf.x = s->x;
6967  static int mod_webdav_patch_connection(server *srv, connection *con, plugin_data *p) {
6968         size_t i, j;
6969         plugin_config *s = p->config_storage[0];
6970         
6971 -       PATCH(enabled);
6972 -       PATCH(is_readonly);
6973 -       PATCH(log_xml);
6974 +       PATCH_OPTION(enabled);
6975 +       PATCH_OPTION(is_readonly);
6976 +       PATCH_OPTION(log_xml);
6977         
6978  #ifdef USE_PROPPATCH
6979 -       PATCH(sql);
6980 -       PATCH(stmt_update_prop);
6981 -       PATCH(stmt_delete_prop);
6982 -       PATCH(stmt_select_prop);
6983 -       PATCH(stmt_select_propnames);
6984 -
6985 -       PATCH(stmt_delete_uri);
6986 -       PATCH(stmt_move_uri);
6987 -       PATCH(stmt_copy_uri);
6988 +       PATCH_OPTION(sql);
6989 +       PATCH_OPTION(stmt_update_prop);
6990 +       PATCH_OPTION(stmt_delete_prop);
6991 +       PATCH_OPTION(stmt_select_prop);
6992 +       PATCH_OPTION(stmt_select_propnames);
6993 +
6994 +       PATCH_OPTION(stmt_delete_uri);
6995 +       PATCH_OPTION(stmt_move_uri);
6996 +       PATCH_OPTION(stmt_copy_uri);
6997 +
6998 +       PATCH_OPTION(stmt_remove_lock);
6999 +       PATCH_OPTION(stmt_refresh_lock);
7000 +       PATCH_OPTION(stmt_create_lock);
7001 +       PATCH_OPTION(stmt_read_lock);
7002 +       PATCH_OPTION(stmt_read_lock_by_uri);
7003  #endif
7004         /* skip the first, the global context */
7005         for (i = 1; i < srv->config_context->used; i++) {
7006 @@ -317,22 +409,28 @@
7007                         data_unset *du = dc->value->data[j];
7008                         
7009                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.activate"))) {
7010 -                               PATCH(enabled);
7011 +                               PATCH_OPTION(enabled);
7012                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.is-readonly"))) {
7013 -                               PATCH(is_readonly);
7014 +                               PATCH_OPTION(is_readonly);
7015                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.log-xml"))) {
7016 -                               PATCH(log_xml);
7017 +                               PATCH_OPTION(log_xml);
7018                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.sqlite-db-name"))) {
7019  #ifdef USE_PROPPATCH
7020 -                               PATCH(sql);
7021 -                               PATCH(stmt_update_prop);
7022 -                               PATCH(stmt_delete_prop);
7023 -                               PATCH(stmt_select_prop);
7024 -                               PATCH(stmt_select_propnames);
7025 -                               
7026 -                               PATCH(stmt_delete_uri);
7027 -                               PATCH(stmt_move_uri);
7028 -                               PATCH(stmt_copy_uri);
7029 +                               PATCH_OPTION(sql);
7030 +                               PATCH_OPTION(stmt_update_prop);
7031 +                               PATCH_OPTION(stmt_delete_prop);
7032 +                               PATCH_OPTION(stmt_select_prop);
7033 +                               PATCH_OPTION(stmt_select_propnames);
7034 +
7035 +                               PATCH_OPTION(stmt_delete_uri);
7036 +                               PATCH_OPTION(stmt_move_uri);
7037 +                               PATCH_OPTION(stmt_copy_uri);
7038 +
7039 +                               PATCH_OPTION(stmt_remove_lock);
7040 +                               PATCH_OPTION(stmt_refresh_lock);
7041 +                               PATCH_OPTION(stmt_create_lock);
7042 +                               PATCH_OPTION(stmt_read_lock);
7043 +                               PATCH_OPTION(stmt_read_lock_by_uri);
7044  #endif
7045                         }
7046                 }
7047 @@ -340,7 +438,6 @@
7048         
7049         return 0;
7050  }
7051 -#undef PATCH
7052  
7053  URIHANDLER_FUNC(mod_webdav_uri_handler) {
7054         plugin_data *p = p_d;
7055 @@ -362,7 +459,7 @@
7056                 if (p->conf.is_readonly) {
7057                         response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND"));
7058                 } else {
7059 -                       response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH"));
7060 +                       response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK"));
7061                 }
7062                 break;
7063         default:
7064 @@ -496,11 +593,11 @@
7065                         } 
7066  
7067                         buffer_copy_string_buffer(d.path, dst->path);
7068 -                       BUFFER_APPEND_SLASH(d.path);
7069 +                       PATHNAME_APPEND_SLASH(d.path);
7070                         buffer_append_string(d.path, de->d_name);
7071                         
7072                         buffer_copy_string_buffer(d.rel_path, dst->rel_path);
7073 -                       BUFFER_APPEND_SLASH(d.rel_path);
7074 +                       PATHNAME_APPEND_SLASH(d.rel_path);
7075                         buffer_append_string(d.rel_path, de->d_name);
7076  
7077                         /* stat and unlink afterwards */
7078 @@ -657,19 +754,19 @@
7079                         }
7080                         
7081                         buffer_copy_string_buffer(s.path, src->path);
7082 -                       BUFFER_APPEND_SLASH(s.path);
7083 +                       PATHNAME_APPEND_SLASH(s.path);
7084                         buffer_append_string(s.path, de->d_name);
7085  
7086                         buffer_copy_string_buffer(d.path, dst->path);
7087 -                       BUFFER_APPEND_SLASH(d.path);
7088 +                       PATHNAME_APPEND_SLASH(d.path);
7089                         buffer_append_string(d.path, de->d_name);
7090  
7091                         buffer_copy_string_buffer(s.rel_path, src->rel_path);
7092 -                       BUFFER_APPEND_SLASH(s.rel_path);
7093 +                       PATHNAME_APPEND_SLASH(s.rel_path);
7094                         buffer_append_string(s.rel_path, de->d_name);
7095  
7096                         buffer_copy_string_buffer(d.rel_path, dst->rel_path);
7097 -                       BUFFER_APPEND_SLASH(d.rel_path);
7098 +                       PATHNAME_APPEND_SLASH(d.rel_path);
7099                         buffer_append_string(d.rel_path, de->d_name);
7100  
7101                         if (-1 == stat(s.path->ptr, &st)) {
7102 @@ -821,9 +918,9 @@
7103                                           SQLITE_TRANSIENT);
7104  
7105                         /* it is the PK */
7106 -                       while (SQLITE_ROW == sqlite3_step(p->conf.stmt_select_prop)) {
7107 +                       while (SQLITE_ROW == sqlite3_step(stmt)) {
7108                                 /* there is a row for us, we only expect a single col 'value' */
7109 -                               webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(p->conf.stmt_select_prop, 0), b);
7110 +                               webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(stmt, 0), b);
7111                                 found = 1;
7112                         }
7113                 }
7114 @@ -991,6 +1088,113 @@
7115  }
7116  #endif
7117  
7118 +int webdav_lockdiscovery(server *srv, connection *con,
7119 +               buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
7120 +
7121 +       buffer *b;
7122 +
7123 +       response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken));
7124 +
7125 +       response_header_overwrite(srv, con,
7126 +               CONST_STR_LEN("Content-Type"),
7127 +               CONST_STR_LEN("text/xml; charset=\"utf-8\""));
7128 +
7129 +       b = chunkqueue_get_append_buffer(con->write_queue);
7130 +
7131 +       buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
7132 +
7133 +       buffer_append_string(b,"<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n");
7134 +       buffer_append_string(b,"<D:lockdiscovery>\n");
7135 +       buffer_append_string(b,"<D:activelock>\n");
7136 +
7137 +       buffer_append_string(b,"<D:lockscope>");
7138 +       buffer_append_string(b,"<D:");
7139 +       buffer_append_string(b, lockscope);
7140 +       buffer_append_string(b, "/>");
7141 +       buffer_append_string(b,"</D:lockscope>\n");
7142 +
7143 +       buffer_append_string(b,"<D:locktype>");
7144 +       buffer_append_string(b,"<D:");
7145 +       buffer_append_string(b, locktype);
7146 +       buffer_append_string(b, "/>");
7147 +       buffer_append_string(b,"</D:locktype>\n");
7148 +
7149 +       buffer_append_string(b,"<D:depth>");
7150 +       buffer_append_string(b, depth == 0 ? "0" : "infinity");
7151 +       buffer_append_string(b,"</D:depth>\n");
7152 +
7153 +       buffer_append_string(b,"<D:timeout>");
7154 +       buffer_append_string(b, "Second-600");
7155 +       buffer_append_string(b,"</D:timeout>\n");
7156 +
7157 +       buffer_append_string(b,"<D:owner>");
7158 +       buffer_append_string(b,"</D:owner>\n");
7159 +
7160 +       buffer_append_string(b,"<D:locktoken>");
7161 +       buffer_append_string(b, "<D:href>");
7162 +       buffer_append_string_buffer(b, locktoken);
7163 +       buffer_append_string(b, "</D:href>");
7164 +       buffer_append_string(b,"</D:locktoken>\n");
7165 +
7166 +       buffer_append_string(b,"</D:activelock>\n");
7167 +       buffer_append_string(b,"</D:lockdiscovery>\n");
7168 +       buffer_append_string(b,"</D:prop>\n");
7169 +
7170 +       return 0;
7171 +}
7172 +/**
7173 + * check if resource is having the right locks to access to resource
7174 + *
7175 + *
7176 + *
7177 + */
7178 +int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
7179 +       int has_lock = 1;
7180 +
7181 +#ifdef USE_LOCKS
7182 +       data_string *ds;
7183 +
7184 +       /**
7185 +        * If can have
7186 +        * - <lock-token>
7187 +        * - [etag]
7188 +        *
7189 +        * there is NOT, AND and OR
7190 +        * and a list can be tagged
7191 +        *
7192 +        * (<lock-token>) is untagged
7193 +        * <tag> (<lock-token>) is tagged
7194 +        *
7195 +        * as long as we don't handle collections it is simple. :)
7196 +        *
7197 +        * X-Litmus: locks: 11 (owner_modify)
7198 +        * If: <http://127.0.0.1:1025/dav/litmus/lockme> (<opaquelocktoken:2165478d-0611-49c4-be92-e790d68a38f1>)
7199 +        *
7200 +        * X-Litmus: locks: 16 (fail_cond_put)
7201 +        * If: (<DAV:no-lock> ["-1622396671"])
7202 +        */
7203 +       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
7204 +       } else {
7205 +               /* we didn't provided a lock-token -> */
7206 +               /* if the resource is locked -> 423 */
7207 +
7208 +               sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
7209 +
7210 +               sqlite3_reset(stmt);
7211 +
7212 +               sqlite3_bind_text(stmt, 1,
7213 +                         CONST_BUF_LEN(uri),
7214 +                         SQLITE_TRANSIENT);
7215 +
7216 +               while (SQLITE_ROW == sqlite3_step(stmt)) {
7217 +                       has_lock = 0;
7218 +               }
7219 +       }
7220 +#endif
7221 +
7222 +       return has_lock;
7223 +}
7224 +
7225  URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
7226         plugin_data *p = p_d;
7227         buffer *b;
7228 @@ -1001,6 +1205,7 @@
7229         buffer *prop_200;
7230         buffer *prop_404;
7231         webdav_properties *req_props;
7232 +       stat_cache_entry *sce = NULL;
7233         
7234         UNUSED(srv);
7235  
7236 @@ -1020,6 +1225,18 @@
7237  
7238                 /* is there a content-body ? */
7239         
7240 +               switch (stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
7241 +               case HANDLER_ERROR:
7242 +                       if (errno == ENOENT) {
7243 +                               con->http_status = 404;
7244 +                               return HANDLER_FINISHED;
7245 +                       }
7246 +                       break;
7247 +               default:
7248 +                       break;
7249 +               }
7250 +
7251 +
7252  #ifdef USE_PROPPATCH
7253                 /* any special requests or just allprop ? */
7254                 if (con->request.content_length) {
7255 @@ -1182,10 +1399,10 @@
7256                                         } 
7257  
7258                                         buffer_copy_string_buffer(d.path, dst->path);
7259 -                                       BUFFER_APPEND_SLASH(d.path);
7260 +                                       PATHNAME_APPEND_SLASH(d.path);
7261  
7262                                         buffer_copy_string_buffer(d.rel_path, dst->rel_path);
7263 -                                       BUFFER_APPEND_SLASH(d.rel_path);
7264 +                                       PATHNAME_APPEND_SLASH(d.rel_path);
7265  
7266                                         if (de->d_name[0] == '.' && de->d_name[1] == '\0') {
7267                                                 /* don't append the . */ 
7268 @@ -1304,6 +1521,12 @@
7269                         return HANDLER_FINISHED;
7270                 }
7271                 
7272 +               /* does the client have a lock for this connection ? */
7273 +               if (!webdav_has_lock(srv, con, p, con->uri.path)) {
7274 +                       con->http_status = 423;
7275 +                       return HANDLER_FINISHED;
7276 +               }
7277 +
7278                 /* stat and unlink afterwards */
7279                 if (-1 == stat(con->physical.path->ptr, &st)) {
7280                         /* don't about it yet, unlink will fail too */
7281 @@ -1375,22 +1598,100 @@
7282         case HTTP_METHOD_PUT: {
7283                 int fd;
7284                 chunkqueue *cq = con->request_content_queue;
7285 +               chunk *c;
7286 +               data_string *ds_range;
7287  
7288                 if (p->conf.is_readonly) {
7289                         con->http_status = 403;
7290                         return HANDLER_FINISHED;
7291                 }
7292  
7293 +               /* is a exclusive lock set on the source */
7294 +               if (!webdav_has_lock(srv, con, p, con->uri.path)) {
7295 +                       con->http_status = 423;
7296 +                       return HANDLER_FINISHED;
7297 +               }
7298 +
7299 +
7300                 assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
7301  
7302 -               /* taken what we have in the request-body and write it to a file */
7303 -               if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC, 0600))) {
7304 +               /* RFC2616 Section 9.6 PUT requires us to send 501 on all Content-* we don't support
7305 +                * - most important Content-Range
7306 +                *
7307 +                *
7308 +                * Example: Content-Range: bytes 100-1037/1038 */
7309 +
7310 +               if (NULL != (ds_range = (data_string *)array_get_element(con->request.headers, "Content-Range"))) {
7311 +                       const char *num = ds_range->value->ptr;
7312 +                       off_t offset;
7313 +                       char *err = NULL;
7314 +
7315 +                       if (0 != strncmp(num, "bytes ", 6)) {
7316 +                               con->http_status = 501; /* not implemented */
7317 +
7318 +                               return HANDLER_FINISHED;
7319 +                       }
7320 +
7321 +                       /* we only support <num>- ... */
7322 +
7323 +                       num += 6;
7324 +
7325 +                       /* skip WS */
7326 +                       while (*num == ' ' || *num == '\t') num++;
7327 +
7328 +                       if (*num == '\0') {
7329 +                               con->http_status = 501; /* not implemented */
7330 +
7331 +                               return HANDLER_FINISHED;
7332 +                       }
7333 +
7334 +                       offset = strtoll(num, &err, 10);
7335 +
7336 +                       if (*err != '-' || offset < 0) {
7337 +                               con->http_status = 501; /* not implemented */
7338 +
7339 +                               return HANDLER_FINISHED;
7340 +                       }
7341 +
7342 +                       if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY, 0600))) {
7343 +                               switch (errno) {
7344 +                               case ENOENT:
7345 +                                       con->http_status = 404; /* not found */
7346 +                                       break;
7347 +                               default:
7348 +                                       con->http_status = 403; /* not found */
7349 +                                       break;
7350 +                               }
7351 +                               return HANDLER_FINISHED;
7352 +                       }
7353 +
7354 +                       if (-1 == lseek(fd, offset, SEEK_SET)) {
7355 +                               con->http_status = 501; /* not implemented */
7356 +
7357 +                               close(fd);
7358 +
7359 +                               return HANDLER_FINISHED;
7360 +                       }
7361 +                       con->http_status = 200; /* modified */
7362 +               } else {
7363 +                       /* take what we have in the request-body and write it to a file */
7364 +
7365 +                       /* if the file doesn't exist, create it */
7366 +                       if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_TRUNC, 0600))) {
7367 +                               if (errno == ENOENT &&
7368 +                                   -1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0600))) {
7369                         /* we can't open the file */
7370                         con->http_status = 403;
7371 -               } else {
7372 -                       chunk *c;
7373  
7374 +                                       return HANDLER_FINISHED;
7375 +                               } else {
7376                         con->http_status = 201; /* created */
7377 +                               }
7378 +                       } else {
7379 +                               con->http_status = 200; /* modified */
7380 +                       }
7381 +               }
7382 +
7383                         con->file_finished = 1;
7384  
7385                         for (c = cq->first; c; c = cq->first) {
7386 @@ -1462,7 +1763,6 @@
7387                         }
7388                         close(fd);
7389  
7390 -               }
7391                 return HANDLER_FINISHED;
7392         }
7393         case HTTP_METHOD_MOVE: 
7394 @@ -1476,6 +1776,14 @@
7395                         return HANDLER_FINISHED;
7396                 }
7397                 
7398 +               /* is a exclusive lock set on the source */
7399 +               if (con->request.http_method == HTTP_METHOD_MOVE) {
7400 +                       if (!webdav_has_lock(srv, con, p, con->uri.path)) {
7401 +                               con->http_status = 423;
7402 +                               return HANDLER_FINISHED;
7403 +                       }
7404 +               }
7405 +
7406                 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Destination"))) {
7407                         destination = ds->value;
7408                 } else {
7409 @@ -1549,7 +1857,7 @@
7410                 }
7411  
7412                 buffer_copy_string_buffer(p->physical.path, p->physical.doc_root);
7413 -               BUFFER_APPEND_SLASH(p->physical.path);
7414 +               PATHNAME_APPEND_SLASH(p->physical.path);
7415                 buffer_copy_string_buffer(p->physical.basedir, p->physical.path);
7416  
7417                 /* don't add a second / */ 
7418 @@ -1613,6 +1921,12 @@
7419                         /* it is just a file, good */
7420                         int r;
7421  
7422 +                       /* does the client have a lock for this connection ? */
7423 +                       if (!webdav_has_lock(srv, con, p, p->uri.path)) {
7424 +                               con->http_status = 423;
7425 +                               return HANDLER_FINISHED;
7426 +                       }
7427 +
7428                         /* destination exists */
7429                         if (0 == (r = stat(p->physical.path->ptr, &st))) {
7430                                 if (S_ISDIR(st.st_mode)) {
7431 @@ -1691,12 +2005,17 @@
7432  
7433                 return HANDLER_FINISHED;
7434         }
7435 -       case HTTP_METHOD_PROPPATCH: {
7436 +       case HTTP_METHOD_PROPPATCH:
7437                 if (p->conf.is_readonly) {
7438                         con->http_status = 403;
7439                         return HANDLER_FINISHED;
7440                 }
7441  
7442 +               if (!webdav_has_lock(srv, con, p, con->uri.path)) {
7443 +                       con->http_status = 423;
7444 +                       return HANDLER_FINISHED;
7445 +               }
7446 +
7447                 /* check if destination exists */
7448                 if (-1 == stat(con->physical.path->ptr, &st)) {
7449                         switch(errno) {
7450 @@ -1789,7 +2108,8 @@
7451                                                                         }
7452                                                                 
7453                                                                         if (SQLITE_DONE != (r = sqlite3_step(stmt))) {
7454 -                                                                               log_error_write(srv, __FILE__, __LINE__, "ss", "sql-set failed:", sqlite3_errmsg(p->conf.sql));
7455 +                                                                               log_error_write(srv, __FILE__, __LINE__, "ss",
7456 +                                                                                               "sql-set failed:", sqlite3_errmsg(p->conf.sql));
7457                                                                         }
7458                                                                 }
7459                                                         }
7460 @@ -1821,6 +2141,7 @@
7461                                 }
7462  
7463  propmatch_cleanup:
7464 +
7465                                 xmlFreeDoc(xml);
7466                         } else {
7467                                 con->http_status = 400;
7468 @@ -1830,7 +2151,303 @@
7469  #endif
7470                 con->http_status = 501;
7471                 return HANDLER_FINISHED;
7472 +       case HTTP_METHOD_LOCK:
7473 +               /**
7474 +                * a mac wants to write
7475 +                *
7476 +                * LOCK /dav/expire.txt HTTP/1.1\r\n
7477 +                * User-Agent: WebDAVFS/1.3 (01308000) Darwin/8.1.0 (Power Macintosh)\r\n
7478 +                * Accept: * / *\r\n
7479 +                * Depth: 0\r\n
7480 +                * Timeout: Second-600\r\n
7481 +                * Content-Type: text/xml; charset=\"utf-8\"\r\n
7482 +                * Content-Length: 229\r\n
7483 +                * Connection: keep-alive\r\n
7484 +                * Host: 192.168.178.23:1025\r\n
7485 +                * \r\n
7486 +                * <?xml version=\"1.0\" encoding=\"utf-8\"?>\n
7487 +                * <D:lockinfo xmlns:D=\"DAV:\">\n
7488 +                *  <D:lockscope><D:exclusive/></D:lockscope>\n
7489 +                *  <D:locktype><D:write/></D:locktype>\n
7490 +                *  <D:owner>\n
7491 +                *   <D:href>http://www.apple.com/webdav_fs/</D:href>\n
7492 +                *  </D:owner>\n
7493 +                * </D:lockinfo>\n
7494 +                */
7495 +
7496 +               if (depth != 0 && depth != -1) {
7497 +                       con->http_status = 400;
7498 +
7499 +                       return HANDLER_FINISHED;
7500 +               }
7501 +
7502 +#ifdef USE_LOCKS
7503 +               if (con->request.content_length) {
7504 +                       xmlDocPtr xml;
7505 +                       buffer *hdr_if = NULL;
7506 +
7507 +                       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
7508 +                               hdr_if = ds->value;
7509 +                       }
7510 +
7511 +                       /* we don't support Depth: Infinity on locks */
7512 +                       if (hdr_if == NULL && depth == -1) {
7513 +                               con->http_status = 409; /* Conflict */
7514 +
7515 +                               return HANDLER_FINISHED;
7516 +                       }
7517 +
7518 +                       if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
7519 +                               xmlNode *rootnode = xmlDocGetRootElement(xml);
7520 +
7521 +                               assert(rootnode);
7522 +
7523 +                               if (0 == xmlStrcmp(rootnode->name, BAD_CAST "lockinfo")) {
7524 +                                       xmlNode *lockinfo;
7525 +                                       const xmlChar *lockscope = NULL, *locktype = NULL, *owner = NULL;
7526 +
7527 +                                       for (lockinfo = rootnode->children; lockinfo; lockinfo = lockinfo->next) {
7528 +                                               if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "lockscope")) {
7529 +                                                       xmlNode *value;
7530 +                                                       for (value = lockinfo->children; value; value = value->next) {
7531 +                                                               if ((0 == xmlStrcmp(value->name, BAD_CAST "exclusive")) ||
7532 +                                                                   (0 == xmlStrcmp(value->name, BAD_CAST "shared"))) {
7533 +                                                                       lockscope = value->name;
7534 +                                                               } else {
7535 +                                                                       con->http_status = 400;
7536 +
7537 +                                                                       xmlFreeDoc(xml);
7538 +                                                                       return HANDLER_FINISHED;
7539 +                                                               }
7540 +                                                       }
7541 +                                               } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "locktype")) {
7542 +                                                       xmlNode *value;
7543 +                                                       for (value = lockinfo->children; value; value = value->next) {
7544 +                                                               if ((0 == xmlStrcmp(value->name, BAD_CAST "write"))) {
7545 +                                                                       locktype = value->name;
7546 +                                                               } else {
7547 +                                                                       con->http_status = 400;
7548 +
7549 +                                                                       xmlFreeDoc(xml);
7550 +                                                                       return HANDLER_FINISHED;
7551 +                                                               }
7552 +                                                       }
7553 +
7554 +                                               } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "owner")) {
7555 +                                               }
7556 +                                       }
7557 +
7558 +                                       if (lockscope && locktype) {
7559 +                                               sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
7560 +
7561 +                                               /* is this resourse already locked ? */
7562 +
7563 +                                               /* SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout
7564 +                                                *   FROM locks
7565 +                                                *  WHERE resource = ? */
7566 +
7567 +                                               if (stmt) {
7568 +
7569 +                                                       sqlite3_reset(stmt);
7570 +
7571 +                                                       sqlite3_bind_text(stmt, 1,
7572 +                                                                         p->uri.path->ptr,
7573 +                                                                         p->uri.path->used - 1,
7574 +                                                                         SQLITE_TRANSIENT);
7575 +
7576 +                                                       /* it is the PK */
7577 +                                                       while (SQLITE_ROW == sqlite3_step(stmt)) {
7578 +                                                               /* we found a lock
7579 +                                                                * 1. is it compatible ?
7580 +                                                                * 2. is it ours */
7581 +                                                               char *sql_lockscope = (char *)sqlite3_column_text(stmt, 2);
7582 +
7583 +                                                               if (strcmp(sql_lockscope, "exclusive")) {
7584 +                                                                       con->http_status = 423;
7585 +                                                               } else if (0 == xmlStrcmp(lockscope, BAD_CAST "exclusive")) {
7586 +                                                                       /* resourse is locked with a shared lock
7587 +                                                                        * client wants exclusive */
7588 +                                                                       con->http_status = 423;
7589 +                                                               }
7590 +                                                       }
7591 +                                                       if (con->http_status == 423) {
7592 +                                                               xmlFreeDoc(xml);
7593 +                                                               return HANDLER_FINISHED;
7594 +                                                       }
7595         }
7596 +
7597 +                                               stmt = p->conf.stmt_create_lock;
7598 +                                               if (stmt) {
7599 +                                                       /* create a lock-token */
7600 +                                                       uuid_t id;
7601 +                                                       char uuid[37] /* 36 + \0 */;
7602 +
7603 +                                                       uuid_generate(id);
7604 +                                                       uuid_unparse(id, uuid);
7605 +
7606 +                                                       buffer_copy_string(p->tmp_buf, "opaquelocktoken:");
7607 +                                                       buffer_append_string(p->tmp_buf, uuid);
7608 +
7609 +                                                       /* "CREATE TABLE locks ("
7610 +                                                        * "  locktoken TEXT NOT NULL,"
7611 +                                                        * "  resource TEXT NOT NULL,"
7612 +                                                        * "  lockscope TEXT NOT NULL,"
7613 +                                                        * "  locktype TEXT NOT NULL,"
7614 +                                                        * "  owner TEXT NOT NULL,"
7615 +                                                        * "  depth INT NOT NULL,"
7616 +                                                        */
7617 +
7618 +                                                       sqlite3_reset(stmt);
7619 +
7620 +                                                       sqlite3_bind_text(stmt, 1,
7621 +                                                                         CONST_BUF_LEN(p->tmp_buf),
7622 +                                                                         SQLITE_TRANSIENT);
7623 +
7624 +                                                       sqlite3_bind_text(stmt, 2,
7625 +                                                                         CONST_BUF_LEN(con->uri.path),
7626 +                                                                         SQLITE_TRANSIENT);
7627 +
7628 +                                                       sqlite3_bind_text(stmt, 3,
7629 +                                                                         lockscope,
7630 +                                                                         xmlStrlen(lockscope),
7631 +                                                                         SQLITE_TRANSIENT);
7632 +
7633 +                                                       sqlite3_bind_text(stmt, 4,
7634 +                                                                         locktype,
7635 +                                                                         xmlStrlen(locktype),
7636 +                                                                         SQLITE_TRANSIENT);
7637 +
7638 +                                                       /* owner */
7639 +                                                       sqlite3_bind_text(stmt, 5,
7640 +                                                                         "",
7641 +                                                                         0,
7642 +                                                                         SQLITE_TRANSIENT);
7643 +
7644 +                                                       /* depth */
7645 +                                                       sqlite3_bind_int(stmt, 6,
7646 +                                                                        depth);
7647 +
7648 +
7649 +                                                       if (SQLITE_DONE != sqlite3_step(stmt)) {
7650 +                                                               log_error_write(srv, __FILE__, __LINE__, "ss",
7651 +                                                                               "create lock:", sqlite3_errmsg(p->conf.sql));
7652 +                                                       }
7653 +
7654 +                                                       /* looks like we survived */
7655 +                                                       webdav_lockdiscovery(srv, con, p->tmp_buf, lockscope, locktype, depth);
7656 +
7657 +                                                       con->http_status = 201;
7658 +                                                       con->file_finished = 1;
7659 +                                               }
7660 +                                       }
7661 +                               }
7662 +
7663 +                               xmlFreeDoc(xml);
7664 +                               return HANDLER_FINISHED;
7665 +                       } else {
7666 +                               con->http_status = 400;
7667 +                               return HANDLER_FINISHED;
7668 +                       }
7669 +               } else {
7670 +
7671 +                       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
7672 +                               buffer *locktoken = ds->value;
7673 +                               sqlite3_stmt *stmt = p->conf.stmt_refresh_lock;
7674 +
7675 +                               /* remove the < > around the token */
7676 +                               if (locktoken->used < 6) {
7677 +                                       con->http_status = 400;
7678 +
7679 +                                       return HANDLER_FINISHED;
7680 +                               }
7681 +
7682 +                               buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, locktoken->used - 5);
7683 +
7684 +                               sqlite3_reset(stmt);
7685 +
7686 +                               sqlite3_bind_text(stmt, 1,
7687 +                                         CONST_BUF_LEN(p->tmp_buf),
7688 +                                         SQLITE_TRANSIENT);
7689 +
7690 +                               if (SQLITE_DONE != sqlite3_step(stmt)) {
7691 +                                       log_error_write(srv, __FILE__, __LINE__, "ss",
7692 +                                               "refresh lock:", sqlite3_errmsg(p->conf.sql));
7693 +                               }
7694 +
7695 +                               webdav_lockdiscovery(srv, con, p->tmp_buf, "exclusive", "write", 0);
7696 +
7697 +                               con->http_status = 200;
7698 +                               con->file_finished = 1;
7699 +                               return HANDLER_FINISHED;
7700 +                       } else {
7701 +                               /* we need a lock-token to refresh */
7702 +                               con->http_status = 400;
7703 +
7704 +                               return HANDLER_FINISHED;
7705 +                       }
7706 +               }
7707 +               break;
7708 +#else
7709 +               con->http_status = 501;
7710 +               return HANDLER_FINISHED;
7711 +#endif
7712 +       case HTTP_METHOD_UNLOCK:
7713 +#ifdef USE_LOCKS
7714 +               if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Lock-Token"))) {
7715 +                       buffer *locktoken = ds->value;
7716 +                       sqlite3_stmt *stmt = p->conf.stmt_remove_lock;
7717 +
7718 +                       /* remove the < > around the token */
7719 +                       if (locktoken->used < 4) {
7720 +                               con->http_status = 400;
7721 +
7722 +                               return HANDLER_FINISHED;
7723 +                       }
7724 +
7725 +                       /**
7726 +                        * FIXME:
7727 +                        *
7728 +                        * if the resourse is locked:
7729 +                        * - by us: unlock
7730 +                        * - by someone else: 401
7731 +                        * if the resource is not locked:
7732 +                        * - 412
7733 +                        *  */
7734 +
7735 +                       buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, locktoken->used - 3);
7736 +
7737 +                       sqlite3_reset(stmt);
7738 +
7739 +                       sqlite3_bind_text(stmt, 1,
7740 +                                 CONST_BUF_LEN(p->tmp_buf),
7741 +                                 SQLITE_TRANSIENT);
7742 +
7743 +                       sqlite3_bind_text(stmt, 2,
7744 +                                 CONST_BUF_LEN(con->uri.path),
7745 +                                 SQLITE_TRANSIENT);
7746 +
7747 +                       if (SQLITE_DONE != sqlite3_step(stmt)) {
7748 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
7749 +                                       "remove lock:", sqlite3_errmsg(p->conf.sql));
7750 +                       }
7751 +
7752 +                       if (0 == sqlite3_changes(p->conf.sql)) {
7753 +                               con->http_status = 401;
7754 +                       } else {
7755 +                               con->http_status = 204;
7756 +                       }
7757 +                       return HANDLER_FINISHED;
7758 +               } else {
7759 +                       /* we need a lock-token to unlock */
7760 +                       con->http_status = 400;
7761 +
7762 +                       return HANDLER_FINISHED;
7763 +               }
7764 +               break;
7765 +#else
7766 +               con->http_status = 501;
7767 +               return HANDLER_FINISHED;
7768 +#endif
7769         default:
7770                 break;
7771         }
7772 --- lighttpd-1.4.11/src/network.c       2006-03-04 16:45:46.000000000 +0200
7773 +++ lighttpd/src/network.c      2006-07-11 21:23:39.983848713 +0300
7774 @@ -1,14 +1,14 @@
7775  #include <sys/types.h>
7776  #include <sys/stat.h>
7777 -#include <sys/time.h>
7778  
7779  #include <errno.h>
7780  #include <fcntl.h>
7781 -#include <unistd.h>
7782  #include <string.h>
7783  #include <stdlib.h>
7784  #include <assert.h>
7785  
7786 +#include <stdio.h>
7787 +
7788  #include "network.h"
7789  #include "fdevent.h"
7790  #include "log.h"
7791 @@ -19,6 +19,7 @@
7792  #include "network_backends.h"
7793  #include "sys-mmap.h"
7794  #include "sys-socket.h"
7795 +#include "sys-files.h"
7796  
7797  #ifdef USE_OPENSSL
7798  # include <openssl/ssl.h> 
7799 @@ -77,7 +78,7 @@
7800         struct accept_filter_arg afa;
7801  #endif
7802  
7803 -#ifdef __WIN32
7804 +#ifdef _WIN32
7805         WORD wVersionRequested;
7806         WSADATA wsaData;
7807         int err;
7808 @@ -244,6 +245,7 @@
7809                 addr_len = sizeof(struct sockaddr_in);
7810                 
7811                 break;
7812 +#ifndef _WIN32
7813         case AF_UNIX:
7814                 srv_socket->addr.un.sun_family = AF_UNIX;
7815                 strcpy(srv_socket->addr.un.sun_path, host);
7816 @@ -283,6 +285,7 @@
7817                 }
7818  
7819                 break;
7820 +#endif
7821         default:
7822                 addr_len = 0;
7823                 
7824 @@ -404,7 +407,6 @@
7825         }
7826         
7827         srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket;
7828 -       
7829         buffer_free(b);
7830         
7831         return 0;
7832 @@ -425,11 +427,20 @@
7833                         close(srv_socket->fd);
7834                 }
7835                 
7836 +               if (srv_socket->is_ssl) {
7837 +#ifdef USE_OPENSSL
7838 +                       SSL_CTX_free(srv_socket->ssl_ctx);
7839 +#endif
7840 +               }
7841 +
7842                 buffer_free(srv_socket->srv_token);
7843                 
7844                 free(srv_socket);
7845         }
7846         
7847 +#ifdef USE_OPENSSL
7848 +       ERR_free_strings();
7849 +#endif
7850         free(srv->srv_sockets.ptr);
7851         
7852         return 0;
7853 @@ -437,11 +448,15 @@
7854  
7855  typedef enum {
7856         NETWORK_BACKEND_UNSET,
7857 +
7858         NETWORK_BACKEND_WRITE,
7859         NETWORK_BACKEND_WRITEV,
7860         NETWORK_BACKEND_LINUX_SENDFILE,
7861         NETWORK_BACKEND_FREEBSD_SENDFILE,
7862 -       NETWORK_BACKEND_SOLARIS_SENDFILEV
7863 +       NETWORK_BACKEND_SOLARIS_SENDFILEV,
7864 +
7865 +    NETWORK_BACKEND_WIN32_SEND,
7866 +    NETWORK_BACKEND_WIN32_TRANSMITFILE,
7867  } network_backend_t;
7868  
7869  int network_init(server *srv) {
7870 @@ -466,7 +481,16 @@
7871  #if defined USE_WRITEV
7872                 { NETWORK_BACKEND_WRITEV,               "writev" },
7873  #endif
7874 +#if defined USE_WRITE
7875                 { NETWORK_BACKEND_WRITE,                "write" },
7876 +#endif
7877 +#if defined USE_WIN32_TRANSMITFILE
7878 +               { NETWORK_BACKEND_WIN32_TRANSMITFILE,   "win32-transmitfile" },
7879 +#endif
7880 +#if defined USE_WIN32_SEND
7881 +               { NETWORK_BACKEND_WIN32_SEND,           "win32-send" },
7882 +#endif
7883 +
7884                 { NETWORK_BACKEND_UNSET,                NULL }
7885         };
7886         
7887 @@ -508,33 +532,59 @@
7888                 }
7889         }
7890  
7891 +#define SET_NETWORK_BACKEND(read, write) \
7892 +    srv->network_backend_write = network_write_chunkqueue_##write;\
7893 +    srv->network_backend_read = network_read_chunkqueue_##read
7894 +
7895 +#define SET_NETWORK_BACKEND_SSL(read, write) \
7896 +    srv->network_ssl_backend_write = network_write_chunkqueue_##write;\
7897 +    srv->network_ssl_backend_read = network_read_chunkqueue_##read
7898 +
7899         switch(backend) {
7900 +
7901 +#ifdef USE_WIN32_SEND
7902 +       case NETWORK_BACKEND_WIN32_SEND:
7903 +        SET_NETWORK_BACKEND(win32recv, win32send);
7904 +               break;
7905 +#ifdef USE_WIN32_TRANSMITFILE
7906 +       case NETWORK_BACKEND_WIN32_TRANSMITFILE:
7907 +        SET_NETWORK_BACKEND(win32recv, win32transmitfile);
7908 +               break;
7909 +#endif
7910 +#endif
7911 +
7912 +#ifdef USE_WRITE
7913         case NETWORK_BACKEND_WRITE:
7914 -               srv->network_backend_write = network_write_chunkqueue_write;
7915 +        SET_NETWORK_BACKEND(read, write);
7916                 break;
7917 +
7918  #ifdef USE_WRITEV
7919         case NETWORK_BACKEND_WRITEV:
7920 -               srv->network_backend_write = network_write_chunkqueue_writev;
7921 +        SET_NETWORK_BACKEND(read, writev);
7922                 break;
7923  #endif
7924  #ifdef USE_LINUX_SENDFILE
7925         case NETWORK_BACKEND_LINUX_SENDFILE:
7926 -               srv->network_backend_write = network_write_chunkqueue_linuxsendfile; 
7927 +        SET_NETWORK_BACKEND(read, linuxsendfile);
7928                 break;
7929  #endif
7930  #ifdef USE_FREEBSD_SENDFILE
7931         case NETWORK_BACKEND_FREEBSD_SENDFILE:
7932 -               srv->network_backend_write = network_write_chunkqueue_freebsdsendfile; 
7933 +        SET_NETWORK_BACKEND(read, freebsdsendfile);
7934                 break;
7935  #endif
7936  #ifdef USE_SOLARIS_SENDFILEV
7937         case NETWORK_BACKEND_SOLARIS_SENDFILEV:
7938 -               srv->network_backend_write = network_write_chunkqueue_solarissendfilev; 
7939 +        SET_NETWORK_BACKEND(read, solarissendfilev);
7940                 break;
7941  #endif
7942 +#endif
7943         default:
7944                 return -1;
7945         }
7946 +#ifdef USE_OPENSSL
7947 +        SET_NETWORK_BACKEND_SSL(openssl, openssl);
7948 +#endif
7949  
7950         /* check for $SERVER["socket"] */
7951         for (i = 1; i < srv->config_context->used; i++) {
7952 @@ -569,23 +619,34 @@
7953  
7954  int network_register_fdevents(server *srv) {
7955         size_t i;
7956 -       
7957         if (-1 == fdevent_reset(srv->ev)) {
7958                 return -1;
7959         }
7960 -       
7961         /* register fdevents after reset */
7962         for (i = 0; i < srv->srv_sockets.used; i++) {
7963                 server_socket *srv_socket = srv->srv_sockets.ptr[i];
7964 -               
7965                 fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
7966                 fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
7967         }
7968         return 0;
7969  }
7970  
7971 -int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
7972 -       int ret = -1;
7973 +network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
7974 +    server_socket *srv_socket = con->srv_socket;
7975 +
7976 +       if (srv_socket->is_ssl) {
7977 +#ifdef USE_OPENSSL
7978 +               return srv->network_ssl_backend_read(srv, con, con->ssl, cq);
7979 +#else
7980 +               return NETWORK_STATUS_FATAL_ERROR;
7981 +#endif
7982 +       } else {
7983 +               return srv->network_backend_read(srv, con, con->fd, cq);
7984 +       }
7985 +}
7986 +
7987 +network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
7988 +       network_status_t ret = NETWORK_STATUS_UNSET;
7989         off_t written = 0;
7990  #ifdef TCP_CORK        
7991         int corked = 0;
7992 @@ -622,9 +683,14 @@
7993                 ret = srv->network_backend_write(srv, con, con->fd, cq);
7994         }
7995         
7996 -       if (ret >= 0) {
7997 +    switch (ret) {
7998 +    case NETWORK_STATUS_WAIT_FOR_EVENT:
7999 +    case NETWORK_STATUS_SUCCESS:
8000                 chunkqueue_remove_finished_chunks(cq);
8001 -               ret = chunkqueue_is_empty(cq) ? 0 : 1;
8002 +
8003 +        break;
8004 +    default:
8005 +        break;
8006         }
8007         
8008  #ifdef TCP_CORK
8009 --- lighttpd-1.4.11/src/network.h       2005-08-11 01:26:42.000000000 +0300
8010 +++ lighttpd/src/network.h      2006-07-11 21:23:39.983848713 +0300
8011 @@ -3,7 +3,8 @@
8012  
8013  #include "server.h"
8014  
8015 -int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c);
8016 +network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *c);
8017 +network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *c);
8018  
8019  int network_init(server *srv);
8020  int network_close(server *srv);
8021 --- lighttpd-1.4.11/src/network_backends.h      2005-10-24 15:13:51.000000000 +0300
8022 +++ lighttpd/src/network_backends.h     2006-07-11 21:23:40.035851970 +0300
8023 @@ -43,16 +43,52 @@
8024  # define USE_AIX_SENDFILE
8025  #endif
8026  
8027 +/**
8028 +* unix can use read/write or recv/send on sockets
8029 +* win32 only recv/send
8030 +*/
8031 +#ifdef _WIN32
8032 +# define USE_WIN32_SEND
8033 +/* wait for async-io support
8034 +# define USE_WIN32_TRANSMITFILE
8035 +*/
8036 +#else
8037 +# define USE_WRITE
8038 +#endif
8039 +
8040  #include "base.h"
8041 +#include "network.h"
8042 +
8043 +#define NETWORK_BACKEND_WRITE_CHUNK(x) \
8044 +    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq, chunk *c)
8045 +
8046 +#define NETWORK_BACKEND_WRITE(x) \
8047 +    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
8048 +#define NETWORK_BACKEND_READ(x) \
8049 +    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
8050  
8051 +NETWORK_BACKEND_WRITE_CHUNK(writev_mem);
8052 +
8053 +NETWORK_BACKEND_WRITE(write);
8054 +NETWORK_BACKEND_WRITE(writev);
8055 +NETWORK_BACKEND_WRITE(linuxsendfile);
8056 +NETWORK_BACKEND_WRITE(freebsdsendfile);
8057 +NETWORK_BACKEND_WRITE(solarissendfilev);
8058 +
8059 +NETWORK_BACKEND_WRITE(win32transmitfile);
8060 +NETWORK_BACKEND_WRITE(win32send);
8061 +
8062 +NETWORK_BACKEND_READ(read);
8063 +NETWORK_BACKEND_READ(win32recv);
8064  
8065 -int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq);
8066 -int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq);
8067 -int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq);
8068 -int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq);
8069 -int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq);
8070  #ifdef USE_OPENSSL
8071 -int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq);
8072 +#define NETWORK_BACKEND_WRITE_SSL(x) \
8073 +    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
8074 +#define NETWORK_BACKEND_READ_SSL(x) \
8075 +    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
8076 +
8077 +NETWORK_BACKEND_WRITE_SSL(openssl);
8078 +NETWORK_BACKEND_READ_SSL(openssl);
8079  #endif
8080  
8081  #endif
8082 --- lighttpd-1.4.11/src/network_freebsd_sendfile.c      2005-10-22 12:28:18.000000000 +0300
8083 +++ lighttpd/src/network_freebsd_sendfile.c     2006-07-11 21:23:40.107856480 +0300
8084 @@ -31,106 +31,25 @@
8085  # endif
8086  #endif
8087  
8088 -int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq) {
8089 +NETWORK_BACKEND_WRITE(freebsdsendfile) {
8090         chunk *c;
8091         size_t chunks_written = 0;
8092         
8093         for(c = cq->first; c; c = c->next, chunks_written++) {
8094                 int chunk_finished = 0;
8095 +               network_status_t ret;
8096                 
8097                 switch(c->type) {
8098 -               case MEM_CHUNK: {
8099 -                       char * offset;
8100 -                       size_t toSend;
8101 -                       ssize_t r;
8102 -                       
8103 -                       size_t num_chunks, i;
8104 -                       struct iovec chunks[UIO_MAXIOV];
8105 -                       chunk *tc;
8106 -                       size_t num_bytes = 0;
8107 -                       
8108 -                       /* we can't send more then SSIZE_MAX bytes in one chunk */
8109 -                       
8110 -                       /* build writev list 
8111 -                        * 
8112 -                        * 1. limit: num_chunks < UIO_MAXIOV
8113 -                        * 2. limit: num_bytes < SSIZE_MAX
8114 -                        */
8115 -                       for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
8116 -                       
8117 -                       for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
8118 -                               if (tc->mem->used == 0) {
8119 -                                       chunks[i].iov_base = tc->mem->ptr;
8120 -                                       chunks[i].iov_len  = 0;
8121 -                               } else {
8122 -                                       offset = tc->mem->ptr + tc->offset;
8123 -                                       toSend = tc->mem->used - 1 - tc->offset;
8124 -                                       
8125 -                                       chunks[i].iov_base = offset;
8126 -                                       
8127 -                                       /* protect the return value of writev() */
8128 -                                       if (toSend > SSIZE_MAX ||
8129 -                                           num_bytes + toSend > SSIZE_MAX) {
8130 -                                               chunks[i].iov_len = SSIZE_MAX - num_bytes;
8131 -                                               
8132 -                                               num_chunks = i + 1;
8133 -                                               break;
8134 -                                       } else {
8135 -                                               chunks[i].iov_len = toSend;
8136 -                                       }
8137 -                                
8138 -                                       num_bytes += toSend;
8139 -                               }
8140 -                       }
8141 -                       
8142 -                       if ((r = writev(fd, chunks, num_chunks)) < 0) {
8143 -                               switch (errno) {
8144 -                               case EAGAIN:
8145 -                               case EINTR:
8146 -                                       r = 0;
8147 -                                       break;
8148 -                               case EPIPE:
8149 -                               case ECONNRESET:
8150 -                                       return -2;
8151 -                               default:
8152 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
8153 -                                                       "writev failed:", strerror(errno), fd);
8154 -                                       
8155 -                                       return -1;
8156 -                               }
8157 -
8158 -                               r = 0;
8159 -                       }
8160 +               case MEM_CHUNK:
8161 +                       ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
8162                         
8163 -                       /* check which chunks have been written */
8164 -                       cq->bytes_out += r;
8165 -                       
8166 -                       for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
8167 -                               if (r >= (ssize_t)chunks[i].iov_len) {
8168 -                                       /* written */
8169 -                                       r -= chunks[i].iov_len;
8170 -                                       tc->offset += chunks[i].iov_len;
8171 -                                       
8172 -                                       if (chunk_finished) {
8173 -                                               /* skip the chunks from further touches */
8174 -                                               chunks_written++;
8175 -                                               c = c->next;
8176 -                                       } else {
8177 -                                               /* chunks_written + c = c->next is done in the for()*/
8178 -                                               chunk_finished++;
8179 +                       if (ret != NETWORK_STATUS_SUCCESS) {
8180 +                               return ret;
8181                                         }
8182 -                               } else {
8183 -                                       /* partially written */
8184                                         
8185 -                                       tc->offset += r;
8186 -                                       chunk_finished = 0;
8187 -                                       
8188 -                                       break;
8189 -                               }
8190 -                       }
8191 +                       chunk_finished = 1;
8192                         
8193                         break;
8194 -               }
8195                 case FILE_CHUNK: {
8196                         off_t offset, r;
8197                         size_t toSend;
8198 @@ -140,7 +59,7 @@
8199                         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
8200                                 log_error_write(srv, __FILE__, __LINE__, "sb",
8201                                                 strerror(errno), c->file.name);
8202 -                               return -1;
8203 +                               return NETWORK_STATUS_FATAL_ERROR;
8204                         }
8205                         
8206                         offset = c->file.start + c->offset;
8207 @@ -151,13 +70,13 @@
8208                         if (offset > sce->st.st_size) {
8209                                 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
8210                                 
8211 -                               return -1;
8212 +                               return NETWORK_STATUS_FATAL_ERROR;
8213                         }
8214                         
8215                         if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
8216                                 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
8217                                 
8218 -                               return -1;
8219 +                               return NETWORK_STATUS_FATAL_ERROR;
8220                         }
8221                         
8222                         r = 0;
8223 @@ -169,11 +88,11 @@
8224                                         break;
8225                                 case ENOTCONN:
8226                                         close(ifd);
8227 -                                       return -2;
8228 +                                       return NETWORK_STATUS_CONNECTION_CLOSE;
8229                                 default:
8230                                         log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
8231                                         close(ifd);
8232 -                                       return -1;
8233 +                                       return NETWORK_STATUS_FATAL_ERROR;
8234                                 }
8235                         }
8236                         close(ifd);
8237 @@ -201,7 +120,7 @@
8238                 }
8239         }
8240  
8241 -       return chunks_written;
8242 +       return NETWORK_STATUS_SUCCESS;
8243  }
8244  
8245  #endif
8246 --- lighttpd-1.4.11/src/network_linux_sendfile.c        2006-02-15 20:02:36.000000000 +0200
8247 +++ lighttpd/src/network_linux_sendfile.c       2006-07-11 21:23:40.271866752 +0300
8248 @@ -26,106 +26,38 @@
8249  /* on linux 2.4.29 + debian/ubuntu we have crashes if this is enabled */
8250  #undef HAVE_POSIX_FADVISE
8251  
8252 -int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq) {
8253 -       chunk *c;
8254 +NETWORK_BACKEND_WRITE(linuxsendfile) {
8255 +       chunk *c, *tc;
8256         size_t chunks_written = 0;
8257         
8258         for(c = cq->first; c; c = c->next, chunks_written++) {
8259                 int chunk_finished = 0;
8260 +               network_status_t ret;
8261                 
8262                 switch(c->type) {
8263 -               case MEM_CHUNK: {
8264 -                       char * offset;
8265 -                       size_t toSend;
8266 -                       ssize_t r;
8267 -                       
8268 -                       size_t num_chunks, i;
8269 -                       struct iovec chunks[UIO_MAXIOV];
8270 -                       chunk *tc;
8271 -                       size_t num_bytes = 0;
8272 -                       
8273 -                       /* we can't send more then SSIZE_MAX bytes in one chunk */
8274 -                       
8275 -                       /* build writev list 
8276 -                        * 
8277 -                        * 1. limit: num_chunks < UIO_MAXIOV
8278 -                        * 2. limit: num_bytes < SSIZE_MAX
8279 -                        */
8280 -                       for (num_chunks = 0, tc = c; 
8281 -                            tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; 
8282 -                            tc = tc->next, num_chunks++);
8283 -                       
8284 -                       for (tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
8285 -                               if (tc->mem->used == 0) {
8286 -                                       chunks[i].iov_base = tc->mem->ptr;
8287 -                                       chunks[i].iov_len  = 0;
8288 -                               } else {
8289 -                                       offset = tc->mem->ptr + tc->offset;
8290 -                                       toSend = tc->mem->used - 1 - tc->offset;
8291 -                               
8292 -                                       chunks[i].iov_base = offset;
8293 -                                       
8294 -                                       /* protect the return value of writev() */
8295 -                                       if (toSend > SSIZE_MAX ||
8296 -                                           num_bytes + toSend > SSIZE_MAX) {
8297 -                                               chunks[i].iov_len = SSIZE_MAX - num_bytes;
8298 -                                               
8299 -                                               num_chunks = i + 1;
8300 -                                               break;
8301 -                                       } else {
8302 -                                               chunks[i].iov_len = toSend;
8303 -                                       }
8304 -                                
8305 -                                       num_bytes += toSend;
8306 -                               }
8307 -                       }
8308 -                       
8309 -                       if ((r = writev(fd, chunks, num_chunks)) < 0) {
8310 -                               switch (errno) {
8311 -                               case EAGAIN:
8312 -                               case EINTR:
8313 -                                       r = 0;
8314 -                                       break;
8315 -                               case EPIPE:
8316 -                               case ECONNRESET:
8317 -                                       return -2;
8318 -                               default:
8319 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
8320 -                                                       "writev failed:", strerror(errno), fd);
8321 -                               
8322 -                                       return -1;
8323 -                               }
8324 -                       }
8325 -                       
8326 -                       /* check which chunks have been written */
8327 -                       cq->bytes_out += r;
8328 -
8329 -                       for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
8330 -                               if (r >= (ssize_t)chunks[i].iov_len) {
8331 -                                       /* written */
8332 -                                       r -= chunks[i].iov_len;
8333 -                                       tc->offset += chunks[i].iov_len;
8334 +               case MEM_CHUNK:
8335 +                       ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
8336                                         
8337 +                       /* check which chunks are finished now */
8338 +                       for (tc = c; tc; tc = tc->next) {
8339 +                               /* finished the chunk */
8340 +                               if (tc->offset == tc->mem->used - 1) {
8341 +                                       /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
8342                                         if (chunk_finished) {
8343 -                                               /* skip the chunks from further touches */
8344 -                                               chunks_written++;
8345                                                 c = c->next;
8346                                         } else {
8347 -                                               /* chunks_written + c = c->next is done in the for()*/
8348 -                                               chunk_finished++;
8349 +                                               chunk_finished = 1;
8350                                         }
8351                                 } else {
8352 -                                       /* partially written */
8353 -                                       
8354 -                                       tc->offset += r;
8355 -                                       chunk_finished = 0;
8356 -                                       
8357                                         break;
8358                                 }
8359                         }
8360                         
8361 -                       break;
8362 +                       if (ret != NETWORK_STATUS_SUCCESS) {
8363 +                               return ret;
8364                 }
8365 +
8366 +                       break;
8367                 case FILE_CHUNK: {
8368                         ssize_t r;
8369                         off_t offset;
8370 --- lighttpd-1.4.11/src/network_openssl.c       2005-11-17 14:53:29.000000000 +0200
8371 +++ lighttpd/src/network_openssl.c      2006-07-11 21:23:40.107856480 +0300
8372 @@ -26,7 +26,77 @@
8373  # include <openssl/ssl.h> 
8374  # include <openssl/err.h> 
8375  
8376 -int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) {
8377 +NETWORK_BACKEND_READ_SSL(openssl) {
8378 +       buffer *b;
8379 +       off_t len;
8380 +
8381 +       b = chunkqueue_get_append_buffer(cq);
8382 +       buffer_prepare_copy(b, 8192);
8383 +       len = SSL_read(ssl, b->ptr, b->size - 1);
8384 +
8385 +       log_error_write(srv, __FILE__, __LINE__, "so", "SSL:", len);
8386 +
8387 +       if (len < 0) {
8388 +               int r, ssl_err;
8389 +
8390 +               switch ((r = SSL_get_error(con->ssl, len))) {
8391 +               case SSL_ERROR_WANT_READ:
8392 +                       return NETWORK_STATUS_WAIT_FOR_EVENT;
8393 +               case SSL_ERROR_SYSCALL:
8394 +                       /**
8395 +                        * man SSL_get_error()
8396 +                        *
8397 +                        * SSL_ERROR_SYSCALL
8398 +                        *   Some I/O error occurred.  The OpenSSL error queue may contain more
8399 +                        *   information on the error.  If the error queue is empty (i.e.
8400 +                        *   ERR_get_error() returns 0), ret can be used to find out more about
8401 +                        *   the error: If ret == 0, an EOF was observed that violates the
8402 +                        *   protocol.  If ret == -1, the underlying BIO reported an I/O error
8403 +                        *   (for socket I/O on Unix systems, consult errno for details).
8404 +                        *
8405 +                        */
8406 +                       while((ssl_err = ERR_get_error())) {
8407 +                               /* get all errors from the error-queue */
8408 +                               log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
8409 +                                               r, ERR_error_string(ssl_err, NULL));
8410 +                       }
8411 +
8412 +                       switch(errno) {
8413 +                       default:
8414 +                               log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
8415 +                                               len, r, errno,
8416 +                                               strerror(errno));
8417 +                               break;
8418 +                       }
8419 +
8420 +                       break;
8421 +               case SSL_ERROR_ZERO_RETURN:
8422 +                       /* clean shutdown on the remote side */
8423 +
8424 +                       if (r == 0) {
8425 +                               /* FIXME: later */
8426 +                       }
8427 +
8428 +                       /* fall thourgh */
8429 +               default:
8430 +                       while((ssl_err = ERR_get_error())) {
8431 +                               /* get all errors from the error-queue */
8432 +                               log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
8433 +                                               r, ERR_error_string(ssl_err, NULL));
8434 +                       }
8435 +                       break;
8436 +               }
8437 +       }
8438 +
8439 +       assert(len > 0);
8440 +       b->used += len;
8441 +       b->ptr[b->used - 1] = '\0';
8442 +
8443 +       return NETWORK_STATUS_SUCCESS;
8444 +}
8445 +
8446 +
8447 +NETWORK_BACKEND_WRITE_SSL(openssl) {
8448         int ssl_r;
8449         chunk *c;
8450         size_t chunks_written = 0;
8451 @@ -65,7 +135,7 @@
8452                 case MEM_CHUNK: {
8453                         char * offset;
8454                         size_t toSend;
8455 -                       ssize_t r;
8456 +                       ssize_t r = 0;
8457                         
8458                         if (c->mem->used == 0) {
8459                                 chunk_finished = 1;
8460 @@ -83,9 +153,11 @@
8461                          *        SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be
8462                          *        repeated with the same arguments.
8463                          * 
8464 +                        * SSL_write(..., 0) return 0 which is handle as an error (Success)
8465 +                        * checking toSend and not calling SSL_write() is simpler
8466                          */
8467                         
8468 -                       if ((r = SSL_write(ssl, offset, toSend)) <= 0) {
8469 +                       if (toSend != 0 && (r = SSL_write(ssl, offset, toSend)) <= 0) {
8470                                 unsigned long err;
8471  
8472                                 switch ((ssl_r = SSL_get_error(ssl, r))) {
8473 --- lighttpd-1.4.11/src/network_solaris_sendfilev.c     2005-10-22 12:28:27.000000000 +0300
8474 +++ lighttpd/src/network_solaris_sendfilev.c    2006-07-11 21:23:40.211862994 +0300
8475 @@ -38,105 +38,25 @@
8476   */
8477  
8478  
8479 -int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq) {
8480 +NETWORK_BACKEND_WRITE(solarissendfilev) {
8481         chunk *c;
8482         size_t chunks_written = 0;
8483         
8484         for(c = cq->first; c; c = c->next, chunks_written++) {
8485                 int chunk_finished = 0;
8486 +               network_status_t ret;
8487                 
8488                 switch(c->type) {
8489 -               case MEM_CHUNK: {
8490 -                       char * offset;
8491 -                       size_t toSend;
8492 -                       ssize_t r;
8493 -                       
8494 -                       size_t num_chunks, i;
8495 -                       struct iovec chunks[UIO_MAXIOV];
8496 -                       chunk *tc;
8497 -                       
8498 -                       size_t num_bytes = 0;
8499 -                       
8500 -                       /* we can't send more then SSIZE_MAX bytes in one chunk */
8501 -                       
8502 -                       /* build writev list 
8503 -                        * 
8504 -                        * 1. limit: num_chunks < UIO_MAXIOV
8505 -                        * 2. limit: num_bytes < SSIZE_MAX
8506 -                        */
8507 -                       for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
8508 -                       
8509 -                       for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
8510 -                               if (tc->mem->used == 0) {
8511 -                                       chunks[i].iov_base = tc->mem->ptr;
8512 -                                       chunks[i].iov_len  = 0;
8513 -                               } else {
8514 -                                       offset = tc->mem->ptr + tc->offset;
8515 -                                       toSend = tc->mem->used - 1 - tc->offset;
8516 -                               
8517 -                                       chunks[i].iov_base = offset;
8518 -                                       
8519 -                                       /* protect the return value of writev() */
8520 -                                       if (toSend > SSIZE_MAX ||
8521 -                                           num_bytes + toSend > SSIZE_MAX) {
8522 -                                               chunks[i].iov_len = SSIZE_MAX - num_bytes;
8523 -                                               
8524 -                                               num_chunks = i + 1;
8525 -                                               break;
8526 -                                       } else {
8527 -                                               chunks[i].iov_len = toSend;
8528 -                                       }
8529 -                                       
8530 -                                       num_bytes += toSend;
8531 -                               }
8532 -                       }
8533 -                       
8534 -                       if ((r = writev(fd, chunks, num_chunks)) < 0) {
8535 -                               switch (errno) {
8536 -                               case EAGAIN:
8537 -                               case EINTR:
8538 -                                       r = 0;
8539 -                                       break;
8540 -                               case EPIPE:
8541 -                               case ECONNRESET:
8542 -                                       return -2;
8543 -                               default:
8544 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
8545 -                                                       "writev failed:", strerror(errno), fd);
8546 -                               
8547 -                                       return -1;
8548 -                               }
8549 -                       }
8550 +               case MEM_CHUNK:
8551 +                       ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
8552                         
8553 -                       /* check which chunks have been written */
8554 -                       cq->bytes_out += r;
8555 -                       
8556 -                       for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
8557 -                               if (r >= (ssize_t)chunks[i].iov_len) {
8558 -                                       /* written */
8559 -                                       r -= chunks[i].iov_len;
8560 -                                       tc->offset += chunks[i].iov_len;
8561 -                                       
8562 -                                       if (chunk_finished) {
8563 -                                               /* skip the chunks from further touches */
8564 -                                               chunks_written++;
8565 -                                               c = c->next;
8566 -                                       } else {
8567 -                                               /* chunks_written + c = c->next is done in the for()*/
8568 -                                               chunk_finished++;
8569 +                       if (ret != NETWORK_STATUS_SUCCESS) {
8570 +                               return ret;
8571                                         }
8572 -                               } else {
8573 -                                       /* partially written */
8574 -                                       
8575 -                                       tc->offset += r;
8576 -                                       chunk_finished = 0;
8577                                         
8578 -                                       break;
8579 -                               }
8580 -                       }
8581 +                       chunk_finished = 1;
8582                         
8583                         break;
8584 -               }
8585                 case FILE_CHUNK: {
8586                         ssize_t r;
8587                         off_t offset;
8588 @@ -177,7 +97,7 @@
8589                                         log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
8590                                         
8591                                         close(ifd);
8592 -                                       return -1;
8593 +                                       return NETWORK_STATUS_FATAL_ERROR;
8594                                 }
8595                                 
8596                                 r = 0;
8597 @@ -194,10 +114,9 @@
8598                         break;
8599                 }
8600                 default:
8601 -                       
8602                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
8603                         
8604 -                       return -1;
8605 +                       return NETWORK_STATUS_FATAL_ERROR;
8606                 }
8607                 
8608                 if (!chunk_finished) {
8609 @@ -207,7 +126,7 @@
8610                 }
8611         }
8612  
8613 -       return chunks_written;
8614 +       return NETWORK_STATUS_SUCCESS;
8615  }
8616  
8617  #endif
8618 --- lighttpd-1.4.11/src/network_write.c 2005-10-22 12:27:56.000000000 +0300
8619 +++ lighttpd/src/network_write.c        2006-07-11 21:23:39.887842700 +0300
8620 @@ -1,11 +1,11 @@
8621  #include <sys/types.h>
8622  #include <sys/stat.h>
8623 -#include <sys/time.h>
8624 +
8625  #include <errno.h>
8626  #include <fcntl.h>
8627 -#include <unistd.h>
8628  #include <string.h>
8629  #include <stdlib.h>
8630 +#include <assert.h>
8631  
8632  #include "network.h"
8633  #include "fdevent.h"
8634 @@ -13,9 +13,12 @@
8635  #include "stat_cache.h"
8636  
8637  #include "sys-socket.h"
8638 +#include "sys-files.h"
8639  
8640  #include "network_backends.h"
8641  
8642 +#ifdef USE_WRITE
8643 +
8644  #ifdef HAVE_SYS_FILIO_H
8645  # include <sys/filio.h>
8646  #endif
8647 @@ -24,7 +27,53 @@
8648  #include <sys/resource.h>
8649  #endif
8650  
8651 -int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq) {
8652 +/**
8653 +* fill the chunkqueue will all the data that we can get
8654 +*
8655 +* this might be optimized into a readv() which uses the chunks
8656 +* as vectors
8657 +*/
8658 +NETWORK_BACKEND_READ(read) {
8659 +    int toread;
8660 +    buffer *b;
8661 +    off_t r;
8662 +
8663 +       /* check how much we have to read */
8664 +       if (ioctl(fd, FIONREAD, &toread)) {
8665 +               log_error_write(srv, __FILE__, __LINE__, "sd",
8666 +                               "ioctl failed: ",
8667 +                               fd);
8668 +               return NETWORK_STATUS_FATAL_ERROR;
8669 +       }
8670 +
8671 +       if (toread == 0) return NETWORK_STATUS_WAIT_FOR_EVENT;
8672 +
8673 +    /*
8674 +    * our chunk queue is quiet large already
8675 +    *
8676 +    * let's buffer it to disk
8677 +    */
8678 +
8679 +    b = chunkqueue_get_append_buffer(cq);
8680 +
8681 +    buffer_prepare_copy(b, toread);
8682 +
8683 +    if (-1 == (r = read(fd, b->ptr, toread))) {
8684 +               log_error_write(srv, __FILE__, __LINE__, "sds",
8685 +                               "unexpected end-of-file (perhaps the proxy process died):",
8686 +                               fd, strerror(errno));
8687 +               return NETWORK_STATUS_FATAL_ERROR;
8688 +       }
8689 +
8690 +       /* this should be catched by the b > 0 above */
8691 +       assert(r);
8692 +       b->used += r + 1;
8693 +       b->ptr[b->used - 1] = '\0';
8694 +
8695 +    return NETWORK_STATUS_SUCCESS;
8696 +}
8697 +
8698 +NETWORK_BACKEND_WRITE(write) {
8699         chunk *c;
8700         size_t chunks_written = 0;
8701         
8702 @@ -44,19 +93,12 @@
8703                         
8704                         offset = c->mem->ptr + c->offset;
8705                         toSend = c->mem->used - 1 - c->offset;
8706 -#ifdef __WIN32 
8707 -                       if ((r = send(fd, offset, toSend, 0)) < 0) {
8708 -                               log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
8709                                 
8710 -                               return -1;
8711 -                       }
8712 -#else
8713                         if ((r = write(fd, offset, toSend)) < 0) {
8714                                 log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
8715                                 
8716 -                               return -1;
8717 +                               return NETWORK_STATUS_FATAL_ERROR;
8718                         }
8719 -#endif
8720                         
8721                         c->offset += r;
8722                         cq->bytes_out += r;
8723 @@ -80,7 +122,7 @@
8724                         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
8725                                 log_error_write(srv, __FILE__, __LINE__, "sb",
8726                                                 strerror(errno), c->file.name);
8727 -                               return -1;
8728 +                               return NETWORK_STATUS_FATAL_ERROR;
8729                         }
8730                         
8731                         offset = c->file.start + c->offset;
8732 @@ -89,13 +131,13 @@
8733                         if (offset > sce->st.st_size) {
8734                                 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
8735                                 
8736 -                               return -1;
8737 +                               return NETWORK_STATUS_FATAL_ERROR;
8738                         }
8739  
8740                         if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
8741                                 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
8742                                 
8743 -                               return -1;
8744 +                               return NETWORK_STATUS_FATAL_ERROR;
8745                         }
8746                         
8747  #if defined USE_MMAP
8748 @@ -104,14 +146,14 @@
8749  
8750                                 close(ifd);
8751                                 
8752 -                               return -1;
8753 +                               return NETWORK_STATUS_FATAL_ERROR;
8754                         }
8755                         close(ifd);
8756  
8757                         if ((r = write(fd, p + offset, toSend)) <= 0) {
8758                                 log_error_write(srv, __FILE__, __LINE__, "ss", "write failed: ", strerror(errno));
8759                                 munmap(p, sce->st.st_size);
8760 -                               return -1;
8761 +                               return NETWORK_STATUS_FATAL_ERROR;
8762                         }
8763                         
8764                         munmap(p, sce->st.st_size);
8765 @@ -123,14 +165,14 @@
8766                                 log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno));
8767                                 close(ifd);
8768                                 
8769 -                               return -1;
8770 +                               return NETWORK_STATUS_FATAL_ERROR;
8771                         }
8772                         close(ifd);
8773  
8774                         if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) {
8775                                 log_error_write(srv, __FILE__, __LINE__, "ss", "write: ", strerror(errno));
8776                                 
8777 -                               return -1;
8778 +                               return NETWORK_STATUS_FATAL_ERROR;
8779                         }
8780  #endif
8781                         c->offset += r;
8782 @@ -146,7 +188,7 @@
8783                         
8784                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
8785                         
8786 -                       return -1;
8787 +                       return NETWORK_STATUS_FATAL_ERROR;
8788                 }
8789                 
8790                 if (!chunk_finished) {
8791 @@ -158,11 +200,7 @@
8792                 chunks_written++;
8793         }
8794  
8795 -       return chunks_written;
8796 +       return NETWORK_STATUS_SUCCESS;
8797  }
8798  
8799 -#if 0
8800 -network_write_init(void) {
8801 -       p->write = network_write_write_chunkset;
8802 -}
8803  #endif
8804 --- lighttpd-1.4.11/src/network_writev.c        2006-02-15 01:02:36.000000000 +0200
8805 +++ lighttpd/src/network_writev.c       2006-07-11 21:23:40.103856229 +0300
8806 @@ -51,22 +51,14 @@
8807  #define LOCAL_BUFFERING 1
8808  #endif
8809  
8810 -int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq) {
8811 -       chunk *c;
8812 -       size_t chunks_written = 0;
8813 -       
8814 -       for(c = cq->first; c; c = c->next) {
8815 -               int chunk_finished = 0;
8816 -               
8817 -               switch(c->type) {
8818 -               case MEM_CHUNK: {
8819 +NETWORK_BACKEND_WRITE_CHUNK(writev_mem) {
8820                         char * offset;
8821                         size_t toSend;
8822                         ssize_t r;
8823                         
8824                         size_t num_chunks, i;
8825                         struct iovec chunks[UIO_MAXIOV];
8826 -                       chunk *tc;
8827 +       chunk *tc; /* transfer chunks */
8828                         size_t num_bytes = 0;
8829                         
8830                         /* we can't send more then SSIZE_MAX bytes in one chunk */
8831 @@ -111,12 +103,12 @@
8832                                         break;
8833                                 case EPIPE:
8834                                 case ECONNRESET:
8835 -                                       return -2;
8836 +                       return NETWORK_STATUS_CONNECTION_CLOSE;
8837                                 default:
8838                                         log_error_write(srv, __FILE__, __LINE__, "ssd", 
8839                                                         "writev failed:", strerror(errno), fd);
8840                                 
8841 -                                       return -1;
8842 +                       return NETWORK_STATUS_FATAL_ERROR;
8843                                 }
8844                         }
8845                         
8846 @@ -129,27 +121,49 @@
8847                                         /* written */
8848                                         r -= chunks[i].iov_len;
8849                                         tc->offset += chunks[i].iov_len;
8850 +               } else {
8851 +                       /* partially written */
8852                                         
8853 +                       tc->offset += r;
8854 +                       break;
8855 +               }
8856 +       }
8857 +
8858 +       return NETWORK_STATUS_SUCCESS;
8859 +}
8860 +
8861 +NETWORK_BACKEND_WRITE(writev) {
8862 +       chunk *c, *tc;
8863 +       size_t chunks_written = 0;
8864 +
8865 +       for(c = cq->first; c; c = c->next) {
8866 +               int chunk_finished = 0;
8867 +               network_status_t ret;
8868 +
8869 +               switch(c->type) {
8870 +               case MEM_CHUNK:
8871 +                       ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
8872 +
8873 +                       /* check which chunks are finished now */
8874 +                       for (tc = c; tc; tc = tc->next) {
8875 +                               /* finished the chunk */
8876 +                               if (tc->offset == tc->mem->used - 1) {
8877 +                                       /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
8878                                         if (chunk_finished) {
8879 -                                               /* skip the chunks from further touches */
8880 -                                               chunks_written++;
8881                                                 c = c->next;
8882                                         } else {
8883 -                                               /* chunks_written + c = c->next is done in the for()*/
8884 -                                               chunk_finished++;
8885 +                                               chunk_finished = 1;
8886                                         }
8887                                 } else {
8888 -                                       /* partially written */
8889 -                                       
8890 -                                       tc->offset += r;
8891 -                                       chunk_finished = 0;
8892 -
8893                                         break;
8894                                 }
8895                         }
8896                         
8897 -                       break;
8898 +                       if (ret != NETWORK_STATUS_SUCCESS) {
8899 +                               return ret;
8900                 }
8901 +
8902 +                       break;
8903                 case FILE_CHUNK: {
8904                         ssize_t r;
8905                         off_t abs_offset;
8906 @@ -165,7 +179,7 @@
8907                         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
8908                                 log_error_write(srv, __FILE__, __LINE__, "sb",
8909                                                 strerror(errno), c->file.name);
8910 -                               return -1;
8911 +                               return NETWORK_STATUS_FATAL_ERROR;
8912                         }
8913  
8914                         abs_offset = c->file.start + c->offset;
8915 @@ -174,7 +188,7 @@
8916                                 log_error_write(srv, __FILE__, __LINE__, "sb", 
8917                                                 "file was shrinked:", c->file.name);
8918                                 
8919 -                               return -1;
8920 +                               return NETWORK_STATUS_FATAL_ERROR;
8921                         }
8922  
8923                         /* mmap the buffer 
8924 @@ -235,7 +249,7 @@
8925                                         if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
8926                                                 log_error_write(srv, __FILE__, __LINE__, "sbs", "open failed for:", c->file.name, strerror(errno));
8927                                 
8928 -                                               return -1;
8929 +                                               return NETWORK_STATUS_FATAL_ERROR;
8930                                         }
8931  #ifdef FD_CLOEXEC
8932                                         fcntl(c->file.fd, F_SETFD, FD_CLOEXEC);
8933 @@ -248,7 +262,7 @@
8934                                         log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:", 
8935                                                         strerror(errno), c->file.name, c->file.fd);
8936  
8937 -                                       return -1;
8938 +                                       return NETWORK_STATUS_FATAL_ERROR;
8939                                 }
8940  
8941                                 c->file.mmap.length = to_mmap;
8942 @@ -297,12 +311,12 @@
8943                                         break;
8944                                 case EPIPE:
8945                                 case ECONNRESET:
8946 -                                       return -2;
8947 +                                       return NETWORK_STATUS_CONNECTION_CLOSE;
8948                                 default:
8949                                         log_error_write(srv, __FILE__, __LINE__, "ssd", 
8950                                                         "write failed:", strerror(errno), fd);
8951                                         
8952 -                                       return -1;
8953 +                                       return NETWORK_STATUS_FATAL_ERROR;
8954                                 }
8955                         }
8956                         
8957 @@ -325,7 +339,7 @@
8958                         
8959                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
8960                         
8961 -                       return -1;
8962 +                       return NETWORK_STATUS_FATAL_ERROR;
8963                 }
8964                 
8965                 if (!chunk_finished) {
8966 @@ -337,7 +351,7 @@
8967                 chunks_written++;
8968         }
8969  
8970 -       return chunks_written;
8971 +       return NETWORK_STATUS_SUCCESS;
8972  }
8973  
8974  #endif
8975 --- lighttpd-1.4.11/src/plugin.c        2006-02-08 14:00:54.000000000 +0200
8976 +++ lighttpd/src/plugin.c       2006-07-11 21:23:40.067853974 +0300
8977 @@ -13,7 +13,7 @@
8978  #include <valgrind/valgrind.h>
8979  #endif
8980  
8981 -#ifndef __WIN32
8982 +#ifndef _WIN32
8983  #include <dlfcn.h>
8984  #endif
8985  /*
8986 @@ -56,19 +56,23 @@
8987         
8988         p = calloc(1, sizeof(*p));
8989         
8990 +       p->required_plugins = array_init();
8991 +
8992         return p;
8993  }
8994  
8995  static void plugin_free(plugin *p) {
8996         int use_dlclose = 1;
8997         if (p->name) buffer_free(p->name);
8998 +
8999 +       array_free(p->required_plugins);
9000  #ifdef HAVE_VALGRIND_VALGRIND_H
9001         /*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/
9002  #endif
9003  
9004  #ifndef LIGHTTPD_STATIC
9005         if (use_dlclose && p->lib) {    
9006 -#ifdef __WIN32
9007 +#ifdef _WIN32
9008                 FreeLibrary(p->lib);
9009  #else
9010                 dlclose(p->lib);
9011 @@ -121,9 +125,14 @@
9012  #else
9013  int plugins_load(server *srv) {
9014         plugin *p;
9015 +#ifdef _WIN32
9016 +    FARPROC init;
9017 +#else
9018         int (*init)(plugin *pl);
9019 +#endif
9020 +
9021         const char *error;
9022 -       size_t i;
9023 +       size_t i, j, k;
9024         
9025         for (i = 0; i < srv->srvconf.modules->used; i++) {
9026                 data_string *d = (data_string *)srv->srvconf.modules->data[i];
9027 @@ -133,14 +142,14 @@
9028  
9029                 buffer_append_string(srv->tmp_buf, "/");
9030                 buffer_append_string(srv->tmp_buf, modules);
9031 -#if defined(__WIN32) || defined(__CYGWIN__)
9032 +#if defined(_WIN32) || defined(__CYGWIN__)
9033                 buffer_append_string(srv->tmp_buf, ".dll");
9034  #else
9035                 buffer_append_string(srv->tmp_buf, ".so");
9036  #endif
9037         
9038                 p = plugin_init();
9039 -#ifdef __WIN32
9040 +#ifdef _WIN32
9041                 if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) {
9042                         LPVOID lpMsgBuf;
9043                         FormatMessage(
9044 @@ -175,7 +184,7 @@
9045                 buffer_copy_string(srv->tmp_buf, modules);
9046                 buffer_append_string(srv->tmp_buf, "_plugin_init");
9047  
9048 -#ifdef __WIN32
9049 +#ifdef _WIN32
9050                 init = GetProcAddress(p->lib, srv->tmp_buf->ptr);
9051  
9052                 if (init == NULL)  {
9053 @@ -218,6 +227,25 @@
9054  #if 0
9055                 log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin loaded" );
9056  #endif
9057 +               /* check if the required plugin is loaded */
9058 +               for (k = 0; k < p->required_plugins->used; k++) {
9059 +                       data_string *req = (data_string *)p->required_plugins->data[k];
9060 +
9061 +                       for (j = 0; j < i; j++) {
9062 +                               data_string *mod = (data_string *)srv->srvconf.modules->data[j];
9063 +
9064 +                               if (buffer_is_equal(req->value, mod->value)) break;
9065 +                       }
9066 +
9067 +                       if (j == i) {
9068 +                               /* not found */
9069 +                               log_error_write(srv, __FILE__, __LINE__, "ssbs", modules, "failed to load. required plugin", req->value, "was not loaded" );
9070 +
9071 +                               plugin_free(p);
9072 +                       
9073 +                               return -1;
9074 +                       }
9075 +               }
9076                 plugins_register(srv, p);
9077         }
9078         
9079 @@ -426,6 +454,23 @@
9080         return HANDLER_GO_ON;
9081  }
9082  
9083 +/**
9084 + * get the config-storage of the named plugin 
9085 + */
9086 +void *plugin_get_config(server *srv, const char *name) {
9087 +       size_t i;
9088 +
9089 +       for (i = 0; i < srv->plugins.used; i++) {
9090 +               plugin *p = ((plugin **)srv->plugins.ptr)[i];
9091 +
9092 +               if (buffer_is_equal_string(p->name, name, strlen(name))) {
9093 +                       return p->data;
9094 +               }
9095 +       }
9096 +
9097 +       return NULL;
9098 +}
9099 +
9100  void plugins_free(server *srv) {
9101         size_t i;
9102         plugins_call_cleanup(srv);
9103 --- lighttpd-1.4.11/src/plugin.h        2005-08-15 12:28:56.000000000 +0300
9104 +++ lighttpd/src/plugin.h       2006-07-11 21:23:40.075854475 +0300
9105 @@ -12,6 +12,12 @@
9106  
9107  #define INIT_FUNC(x) \
9108                 static void *x()
9109 +/*
9110 + * The PATCH_OPTION() macro is used in the patch_connection() functions
9111 + * of the modules to update the config object for the current request.
9112 + */
9113 +#define PATCH_OPTION(x) \
9114 +               p->conf.x = s->x
9115  
9116  #define FREE_FUNC          SERVER_FUNC
9117  #define TRIGGER_FUNC       SERVER_FUNC
9118 @@ -59,6 +65,8 @@
9119         
9120         /* dlopen handle */
9121         void *lib;
9122 +
9123 +       array *required_plugins;
9124  } plugin;
9125  
9126  int plugins_load(server *srv);
9127 @@ -88,5 +96,8 @@
9128  int config_patch_connection(server *srv, connection *con, comp_key_t comp);
9129  int config_check_cond(server *srv, connection *con, data_config *dc);
9130  int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n);
9131 +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result);
9132 +
9133 +void *plugin_get_config(server *srv, const char *name);
9134  
9135  #endif
9136 --- lighttpd-1.4.11/src/proc_open.c     2005-08-11 01:26:39.000000000 +0300
9137 +++ lighttpd/src/proc_open.c    2006-07-11 21:23:40.283867504 +0300
9138 @@ -13,13 +13,13 @@
9139  #endif
9140  
9141  
9142 -#ifdef WIN32
9143 +#ifdef _WIN32
9144  /* {{{ win32 stuff */
9145  # define SHELLENV "ComSpec"
9146  # define SECURITY_DC , SECURITY_ATTRIBUTES *security
9147  # define SECURITY_CC , security
9148  # define pipe(pair) (CreatePipe(&pair[0], &pair[1], security, 2048L) ? 0 : -1)
9149 -static inline HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig)
9150 +static HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig)
9151  {
9152         HANDLE copy, self = GetCurrentProcess();
9153  
9154 @@ -148,11 +148,14 @@
9155         STARTUPINFO si;
9156         BOOL procok;
9157         SECURITY_ATTRIBUTES security;
9158 -       const char *shell;
9159 +       const char *shell = NULL;
9160 +       const char *windir = NULL;
9161         buffer *cmdline;
9162  
9163 -       if (NULL == (shell = getenv(SHELLENV))) {
9164 -               fprintf(stderr, "env %s is required", SHELLENV);
9165 +       if (NULL == (shell = getenv(SHELLENV)) &&
9166 +                       NULL == (windir = getenv("SystemRoot")) &&
9167 +                       NULL == (windir = getenv("windir"))) {
9168 +               fprintf(stderr, "One of %s,%%SystemRoot,%%windir is required", SHELLENV);
9169                 return -1;
9170         }
9171  
9172 @@ -177,17 +180,23 @@
9173         memset(&pi, 0, sizeof(pi));
9174  
9175         cmdline = buffer_init();
9176 +       if (shell) {
9177         buffer_append_string(cmdline, shell);
9178 +       } else {
9179 +               buffer_append_string(cmdline, windir);
9180 +               buffer_append_string(cmdline, "\\system32\\cmd.exe");
9181 +       }
9182         buffer_append_string_len(cmdline, CONST_STR_LEN(" /c "));
9183         buffer_append_string(cmdline, command);
9184         procok = CreateProcess(NULL, cmdline->ptr, &security, &security, TRUE,
9185                         NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
9186 -       buffer_free(cmdline);
9187  
9188         if (FALSE == procok) {
9189 -               fprintf(stderr, "failed to CreateProcess");
9190 +               fprintf(stderr, "failed to CreateProcess: %s", cmdline->ptr);
9191 +               buffer_free(cmdline);
9192                 return -1;
9193         }
9194 +       buffer_free(cmdline);
9195  
9196         proc->child = pi.hProcess;
9197         CloseHandle(pi.hThread);
9198 @@ -226,8 +235,7 @@
9199         const char *shell;
9200  
9201         if (NULL == (shell = getenv(SHELLENV))) {
9202 -               fprintf(stderr, "env %s is required", SHELLENV);
9203 -               return -1;
9204 +               shell = "/bin/sh";
9205         }
9206  
9207         if (proc_open_pipes(proc) != 0) {
9208 @@ -262,11 +270,11 @@
9209         }
9210  }
9211  /* }}} */
9212 -#endif /* WIN32 */
9213 +#endif /* _WIN32 */
9214  
9215  /* {{{ proc_read_fd_to_buffer */
9216  static void proc_read_fd_to_buffer(int fd, buffer *b) {
9217 -       ssize_t s;
9218 +       int s; /* win32 has not ssize_t */
9219  
9220         for (;;) {
9221                 buffer_prepare_append(b, 512);
9222 --- lighttpd-1.4.11/src/proc_open.h     2005-08-11 01:26:39.000000000 +0300
9223 +++ lighttpd/src/proc_open.h    2006-07-11 21:23:40.287867754 +0300
9224 @@ -1,7 +1,7 @@
9225  
9226  #include "buffer.h"
9227  
9228 -#ifdef WIN32
9229 +#ifdef _WIN32
9230  #include <windows.h>
9231  typedef HANDLE descriptor_t;
9232  typedef HANDLE proc_pid_t;
9233 --- lighttpd-1.4.11/src/request.c       2006-03-05 11:58:09.000000000 +0200
9234 +++ lighttpd/src/request.c      2006-07-11 21:23:40.035851970 +0300
9235 @@ -10,6 +10,8 @@
9236  #include "keyvalue.h"
9237  #include "log.h"
9238  
9239 +#include "sys-strings.h"
9240 +
9241  static int request_check_hostname(server *srv, connection *con, buffer *host) {
9242         enum { DOMAINLABEL, TOPLABEL } stage = TOPLABEL;
9243         size_t i;
9244 @@ -413,7 +415,7 @@
9245                                         }
9246  
9247                                         if (major_num == 1 && minor_num == 1) {
9248 -                                               con->request.http_version = con->conf.allow_http11 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0;
9249 +                                               con->request.http_version = HTTP_VERSION_1_1;
9250                                         } else if (major_num == 1 && minor_num == 0) {
9251                                                 con->request.http_version = HTTP_VERSION_1_0;
9252                                         } else { 
9253 @@ -797,6 +799,7 @@
9254                                                                                                 "request-header:\n",
9255                                                                                                 con->request.request);
9256                                                                         }
9257 +                                                                       ds->free((data_unset *) ds);
9258                                                                         return 0;
9259                                                                 }
9260                                                                 
9261 @@ -846,6 +849,7 @@
9262                                                                                                 "request-header:\n",
9263                                                                                                 con->request.request);
9264                                                                         }
9265 +                                                                       ds->free((data_unset *) ds);
9266                                                                         return 0;
9267                                                                 }
9268                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) {
9269 @@ -883,6 +887,7 @@
9270                                                                                                 "request-header:\n",
9271                                                                                                 con->request.request);
9272                                                                         }
9273 +                                                                       ds->free((data_unset *) ds);
9274                                                                         return 0;
9275                                                                 }
9276                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
9277 @@ -905,6 +910,7 @@
9278                                                                                                 "request-header:\n",
9279                                                                                                 con->request.request);
9280                                                                         }
9281 +                                                                       ds->free((data_unset *) ds);
9282                                                                         return 0;
9283                                                                 }
9284                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
9285 @@ -922,6 +928,7 @@
9286                                                                                                 "request-header:\n",
9287                                                                                                 con->request.request);
9288                                                                         }
9289 +                                                                       ds->free((data_unset *) ds);
9290                                                                         return 0;
9291                                                                 }
9292                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
9293 @@ -945,6 +952,7 @@
9294                                                                                                 "request-header:\n",
9295                                                                                                 con->request.request);
9296                                                                         }
9297 +                                                                       ds->free((data_unset *) ds);
9298                                                                         return 0;
9299                                                                 }
9300                                                         }
9301 --- lighttpd-1.4.11/src/response.c      2006-03-04 16:41:39.000000000 +0200
9302 +++ lighttpd/src/response.c     2006-07-11 21:23:40.067853974 +0300
9303 @@ -7,7 +7,6 @@
9304  #include <stdlib.h>
9305  #include <string.h>
9306  #include <time.h>
9307 -#include <unistd.h>
9308  #include <ctype.h>
9309  #include <assert.h>
9310  
9311 @@ -24,6 +23,8 @@
9312  #include "plugin.h"
9313  
9314  #include "sys-socket.h"
9315 +#include "sys-files.h"
9316 +#include "sys-strings.h"
9317  
9318  int http_response_write_header(server *srv, connection *con) {
9319         buffer *b;
9320 @@ -59,7 +60,8 @@
9321                 ds = (data_string *)con->response.headers->data[i];
9322                 
9323                 if (ds->value->used && ds->key->used &&
9324 -                   0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1)) {
9325 +                   0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1) &&
9326 +                   0 != strcasecmp(ds->key->ptr, "X-Sendfile")) {
9327                         if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Date"))) have_date = 1;
9328                         if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Server"))) have_server = 1;
9329  
9330 @@ -119,7 +121,7 @@
9331  handler_t http_response_prepare(server *srv, connection *con) {
9332         handler_t r;
9333         
9334 -       /* looks like someone has already done a decision */
9335 +       /* looks like someone has already made a decision */
9336         if (con->mode == DIRECT && 
9337             (con->http_status != 0 && con->http_status != 200)) {
9338                 /* remove a packets in the queue */
9339 @@ -134,7 +136,7 @@
9340         if (con->mode == DIRECT && con->physical.path->used == 0) {
9341                 char *qstr;
9342  
9343 -               /* we only come here when we have the parse the full request again
9344 +               /* we only come here when we have to parse the full request again
9345                  * 
9346                  * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a 
9347                  * problem here as mod_setenv might get called multiple times
9348 @@ -262,6 +264,11 @@
9349                 
9350                 config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */
9351                 
9352 +               /* do we have to downgrade to 1.0 ? */
9353 +               if (!con->conf.allow_http11) {
9354 +                       con->request.http_version = HTTP_VERSION_1_0;
9355 +               }
9356 +
9357                 switch(r = plugins_call_handle_uri_clean(srv, con)) {
9358                 case HANDLER_GO_ON:
9359                         break;
9360 @@ -277,7 +284,7 @@
9361                 
9362                 if (con->request.http_method == HTTP_METHOD_OPTIONS &&
9363                     con->uri.path->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
9364 -                       /* option requests are handled directly without checking of the path */
9365 +                       /* option requests are handled directly without checking the path */
9366                 
9367                         response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
9368  
9369 @@ -320,14 +327,15 @@
9370                 buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root);
9371                 buffer_copy_string_buffer(con->physical.rel_path, con->uri.path);
9372                 
9373 -#if defined(__WIN32) || defined(__CYGWIN__)
9374 -               /* strip dots from the end and spaces
9375 +               filename_unix2local(con->physical.rel_path);
9376 +#if defined(_WIN32) || defined(__CYGWIN__)
9377 +               /* strip dots and spaces from the end
9378                  *
9379                  * windows/dos handle those filenames as the same file
9380                  *
9381                  * foo == foo. == foo..... == "foo...   " == "foo..  ./"
9382                  *
9383 -                * This will affect in some cases PATHINFO
9384 +                * This will affect PATHINFO in some cases
9385                  *
9386                  * on native windows we could prepend the filename with \\?\ to circumvent
9387                  * this behaviour. I have no idea how to push this through cygwin
9388 @@ -378,15 +386,14 @@
9389                         break;
9390                 }
9391                 
9392 -               /* MacOS X and Windows can't distiguish between upper and lower-case 
9393 -                * 
9394 -                * convert to lower-case
9395 +               /* The default Mac OS X and Windows filesystems can't distiguish between
9396 +                * upper- and lowercase, so convert to lowercase
9397                  */
9398                 if (con->conf.force_lowercase_filenames) {
9399                         buffer_to_lower(con->physical.rel_path);
9400                 }
9401  
9402 -               /* the docroot plugins might set the servername, if they don't we take http-host */
9403 +               /* the docroot plugins might set the servername; if they don't we take http-host */
9404                 if (buffer_is_empty(con->server_name)) {
9405                         buffer_copy_string_buffer(con->server_name, con->uri.authority);
9406                 }
9407 @@ -398,15 +405,21 @@
9408                  */
9409                 
9410                 buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
9411 -               BUFFER_APPEND_SLASH(con->physical.path);
9412 +               PATHNAME_APPEND_SLASH(con->physical.path);
9413                 buffer_copy_string_buffer(con->physical.basedir, con->physical.path);
9414                 if (con->physical.rel_path->used &&
9415 -                   con->physical.rel_path->ptr[0] == '/') {
9416 +                   con->physical.rel_path->ptr[0] == DIR_SEPERATOR) {
9417                         buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
9418                 } else {
9419                         buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
9420                 }
9421  
9422 +        /* win32: directories can't have a trailing slash */
9423 +        if (con->physical.path->ptr[con->physical.path->used - 2] == DIR_SEPERATOR) {
9424 +            con->physical.path->ptr[con->physical.path->used - 2] = '\0';
9425 +            con->physical.path->used--;
9426 +        }
9427 +
9428                 if (con->conf.log_request_handling) {
9429                         log_error_write(srv, __FILE__, __LINE__,  "s",  "-- after doc_root");
9430                         log_error_write(srv, __FILE__, __LINE__,  "sb", "Doc-Root     :", con->physical.doc_root);
9431 @@ -436,7 +449,7 @@
9432         }
9433         
9434         /* 
9435 -        * Noone catched away the file from normal path of execution yet (like mod_access)
9436 +        * No one took the file away from the normal path of execution yet (like mod_access)
9437          * 
9438          * Go on and check of the file exists at all
9439          */
9440 @@ -461,7 +474,7 @@
9441                         }
9442                         
9443                         if (S_ISDIR(sce->st.st_mode)) {
9444 -                               if (con->physical.path->ptr[con->physical.path->used - 2] != '/') {
9445 +                               if (con->uri.path->ptr[con->uri.path->used - 2] != '/') {
9446                                         /* redirect to .../ */
9447                                         
9448                                         http_response_redirect_to_directory(srv, con);
9449 @@ -499,7 +512,7 @@
9450                                 /* PATH_INFO ! :) */
9451                                 break;
9452                         default:
9453 -                               /* we have no idea what happend. let's tell the user so. */
9454 +                               /* we have no idea what happened, so tell the user. */
9455                                 con->http_status = 500;
9456                                 buffer_reset(con->physical.path);
9457                                 
9458 @@ -544,7 +557,7 @@
9459                         } while ((found == 0) && (slash != NULL) && (slash - srv->tmp_buf->ptr > con->physical.basedir->used - 2));
9460                         
9461                         if (found == 0) {
9462 -                               /* no it really doesn't exists */
9463 +                               /* no, it really doesn't exists */
9464                                 con->http_status = 404;
9465                                 
9466                                 if (con->conf.log_file_not_found) {
9467 @@ -594,11 +607,11 @@
9468                                 log_error_write(srv, __FILE__, __LINE__,  "s",  "-- subrequest finished");
9469                         }
9470                         
9471 -                       /* something strange happend */
9472 +                       /* something strange happened */
9473                         return r;
9474                 }
9475                 
9476 -               /* if we are still here, no one wanted the file, status 403 is ok I think */
9477 +               /* if we are still here, no one wanted the file; status 403 is ok I think */
9478                 
9479                 if (con->mode == DIRECT) {
9480                         con->http_status = 403;
9481 @@ -610,12 +623,12 @@
9482         
9483         switch(r = plugins_call_handle_subrequest(srv, con)) {
9484         case HANDLER_GO_ON:
9485 -               /* request was not handled, looks like we are done */
9486 +               /* request was not handled; looks like we are done */
9487                 return HANDLER_FINISHED;
9488         case HANDLER_FINISHED:
9489                 /* request is finished */
9490         default:
9491 -               /* something strange happend */
9492 +               /* something strange happened */
9493                 return r;
9494         }
9495         
9496 --- lighttpd-1.4.11/src/server.c        2006-03-04 19:12:17.000000000 +0200
9497 +++ lighttpd/src/server.c       2006-07-11 21:23:40.247865249 +0300
9498 @@ -1,11 +1,9 @@
9499  #include <sys/types.h>
9500 -#include <sys/time.h>
9501  #include <sys/stat.h>
9502  
9503  #include <string.h>
9504  #include <errno.h>
9505  #include <fcntl.h>
9506 -#include <unistd.h>
9507  #include <stdlib.h>
9508  #include <time.h>
9509  #include <signal.h>
9510 @@ -29,9 +27,14 @@
9511  #include "plugin.h"
9512  #include "joblist.h"
9513  #include "network_backends.h"
9514 -
9515 +#ifdef _WIN32
9516 +/* use local getopt implementation */
9517 +# undef HAVE_GETOPT_H
9518 +#endif
9519  #ifdef HAVE_GETOPT_H
9520  #include <getopt.h>
9521 +#else
9522 +#include "getopt.h"
9523  #endif
9524  
9525  #ifdef HAVE_VALGRIND_VALGRIND_H
9526 @@ -60,8 +63,16 @@
9527  /* #define USE_ALARM */
9528  #endif
9529  
9530 +#ifdef _WIN32
9531 +#undef HAVE_SIGNAL
9532 +#endif
9533 +
9534 +#include "sys-files.h"
9535 +#include "sys-process.h"
9536 +
9537  static volatile sig_atomic_t srv_shutdown = 0;
9538  static volatile sig_atomic_t graceful_shutdown = 0;
9539 +static volatile sig_atomic_t graceful_restart = 0;
9540  static volatile sig_atomic_t handle_sig_alarm = 1;
9541  static volatile sig_atomic_t handle_sig_hup = 0;
9542  
9543 @@ -126,6 +137,7 @@
9544         
9545         server *srv = calloc(1, sizeof(*srv));
9546         assert(srv);
9547 +    srv->max_fds = 1024;
9548  #define CLEAN(x) \
9549         srv->x = buffer_init();
9550         
9551 @@ -286,9 +298,7 @@
9552  }
9553  
9554  static void show_features (void) {
9555 -  show_version();
9556 -  printf("\nEvent Handlers:\n\n%s",
9557 -
9558 +  const char *s = ""
9559  #ifdef USE_SELECT
9560        "\t+ select (generic)\n"
9561  #else
9562 @@ -355,11 +365,6 @@
9563  #else
9564        "\t- crypt support\n"
9565  #endif
9566 -#ifdef USE_PAM
9567 -      "\t+ PAM support\n"
9568 -#else
9569 -      "\t- PAM support\n"
9570 -#endif
9571  #ifdef USE_OPENSSL
9572        "\t+ SSL Support\n"
9573  #else
9574 @@ -371,9 +376,9 @@
9575        "\t- PCRE support\n"
9576  #endif
9577  #ifdef HAVE_MYSQL
9578 -      "\t+ mySQL support\n"
9579 +      "\t+ MySQL support\n"
9580  #else
9581 -      "\t- mySQL support\n"
9582 +      "\t- MySQL support\n"
9583  #endif
9584  #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
9585        "\t+ LDAP support\n"
9586 @@ -410,8 +415,11 @@
9587  #else
9588        "\t- GDBM support\n"
9589  #endif
9590 -      "\n"
9591 -      );
9592 +      "\n";
9593 +
9594 +  show_version();
9595 +
9596 +  printf("\nEvent Handlers:\n\n%s", s);
9597  }
9598  
9599  static void show_help (void) {
9600 @@ -438,7 +446,7 @@
9601         write(STDOUT_FILENO, b, strlen(b));
9602  }
9603  
9604 -int main (int argc, char **argv) {
9605 +int main (int argc, char **argv, char **envp) {
9606         server *srv = NULL;
9607         int print_config = 0;
9608         int test_config = 0;
9609 @@ -447,6 +455,10 @@
9610         int num_childs = 0;
9611         int pid_fd = -1, fd;
9612         size_t i;
9613 +#ifdef _WIN32
9614 +       char *optarg = NULL;
9615 +#endif
9616 +
9617  #ifdef HAVE_SIGACTION
9618         struct sigaction act;
9619  #endif
9620 @@ -485,10 +497,15 @@
9621         while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
9622                 switch(o) {
9623                 case 'f': 
9624 +#ifdef _WIN32
9625 +                       /* evil HACK for windows, optarg is not set */
9626 +                       optarg = argv[optind-1];
9627 +#endif
9628                         if (config_read(srv, optarg)) { 
9629                                 server_free(srv);
9630                                 return -1;
9631                         }
9632 +
9633                         break;
9634                 case 'm':
9635                         buffer_copy_string(srv->srvconf.modules_dir, optarg);
9636 @@ -589,6 +606,7 @@
9637                 return -1;
9638         }
9639         
9640 +#ifndef _WIN32
9641         /* open pid file BEFORE chroot */
9642         if (srv->srvconf.pid_file->used) {
9643                 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))) {
9644 @@ -617,13 +635,14 @@
9645                         }
9646                 }
9647         }
9648 -
9649 +#endif
9650         if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
9651                 /* select limits itself
9652                  *
9653                  * as it is a hard limit and will lead to a segfault we add some safety
9654                  * */
9655 -               srv->max_fds = FD_SETSIZE - 200;
9656 +        fprintf(stderr, "%s.%d: max parallel connections: %d\r\n", __FILE__, __LINE__, FD_SETSIZE);
9657 +               srv->max_fds = FD_SETSIZE - 4;
9658         } else {
9659                 srv->max_fds = 4096;
9660         }
9661 @@ -761,7 +780,7 @@
9662                 }
9663  
9664                 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
9665 -                       srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
9666 +                       srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 4 ? rlim.rlim_cur : FD_SETSIZE - 4;
9667                 } else {
9668                         srv->max_fds = rlim.rlim_cur;
9669                 }
9670 @@ -775,9 +794,9 @@
9671  #endif
9672                 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
9673                         /* don't raise the limit above FD_SET_SIZE */
9674 -                       if (srv->max_fds > FD_SETSIZE - 200) {
9675 +                       if (srv->max_fds > FD_SETSIZE - 4) {
9676                                 log_error_write(srv, __FILE__, __LINE__, "sd", 
9677 -                                               "can't raise max filedescriptors above",  FD_SETSIZE - 200,
9678 +                                               "can't raise max filedescriptors above",  FD_SETSIZE - 4,
9679                                                 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
9680                                 return -1;
9681                         }
9682 @@ -818,8 +837,10 @@
9683         if (srv->srvconf.dont_daemonize == 0) daemonize();
9684  #endif
9685  
9686 +#ifdef HAVE_PWD_H
9687         srv->gid = getgid();
9688         srv->uid = getuid();
9689 +#endif
9690         
9691         /* write pid file */
9692         if (pid_fd != -1) {
9693 @@ -883,7 +904,6 @@
9694                 return -1;
9695         }
9696         
9697 -       
9698  #ifdef HAVE_SIGACTION
9699         memset(&act, 0, sizeof(act));
9700         act.sa_handler = SIG_IGN;
9701 @@ -957,7 +977,7 @@
9702         }
9703  #endif
9704  
9705 -       if (NULL == (srv->ev = fdevent_init(srv->max_fds + 1, srv->event_handler))) {
9706 +       if (NULL == (srv->ev = fdevent_init(/*srv->max_fds + 1*/ 4096, srv->event_handler))) {
9707                 log_error_write(srv, __FILE__, __LINE__,
9708                                 "s", "fdevent_init failed");
9709                 return -1;
9710 @@ -1025,7 +1045,31 @@
9711                         /* reset notification */
9712                         handle_sig_hup = 0;
9713                         
9714 +#if 0
9715 +                               pid_t pid;
9716                         
9717 +                       /* send the old process into a graceful-shutdown and start a
9718 +                        * new process right away
9719 +                        *
9720 +                        * BUGS:
9721 +                        * - if webserver is running on port < 1024 (e.g. 80, 433)
9722 +                        *   we don't have the permissions to bind to that port anymore
9723 +                        *
9724 +                        *
9725 +                        *  */
9726 +                       if (0 == (pid = fork())) {
9727 +                               execve(argv[0], argv, envp);
9728 +
9729 +                               exit(-1);
9730 +                       } else if (pid == -1) {
9731 +
9732 +                       } else {
9733 +                               /* parent */
9734 +
9735 +                               graceful_shutdown = 1; /* shutdown without killing running connections */
9736 +                               graceful_restart = 1;  /* don't delete pid file */
9737 +                       }
9738 +#else
9739                         /* cycle logfiles */
9740                         
9741                         switch(r = plugins_call_handle_sighup(srv)) {
9742 @@ -1041,6 +1085,7 @@
9743                                 
9744                                 return -1;
9745                         }
9746 +#endif
9747                 }
9748                 
9749                 if (handle_sig_alarm) {
9750 @@ -1312,7 +1357,8 @@
9751                 srv->joblist->used = 0;
9752         }
9753         
9754 -       if (srv->srvconf.pid_file->used &&
9755 +       if (0 == graceful_restart &&
9756 +           srv->srvconf.pid_file->used &&
9757             srv->srvconf.changeroot->used == 0) {
9758                 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
9759                         if (errno != EACCES && errno != EPERM) {
9760 --- lighttpd-1.4.11/src/spawn-fcgi.c    2006-03-07 14:18:10.000000000 +0200
9761 +++ lighttpd/src/spawn-fcgi.c   2006-07-11 21:23:40.167860238 +0300
9762 @@ -1,19 +1,16 @@
9763  #include <sys/types.h>
9764 -#include <sys/time.h>
9765  #include <sys/stat.h>
9766  
9767  #include <stdlib.h>
9768  #include <string.h>
9769  #include <errno.h>
9770  #include <stdio.h>
9771 -#include <unistd.h>
9772  #include <fcntl.h>
9773 -
9774 +#include <time.h>
9775  #ifdef HAVE_CONFIG_H
9776  #include "config.h"
9777  #endif
9778  
9779 -
9780  #ifdef HAVE_PWD_H
9781  #include <grp.h>
9782  #include <pwd.h>
9783 @@ -30,6 +27,7 @@
9784  #endif
9785  
9786  #include "sys-socket.h"
9787 +#include "sys-files.h"
9788  
9789  #ifdef HAVE_SYS_WAIT_H
9790  #include <sys/wait.h>
9791 @@ -145,6 +143,9 @@
9792                         
9793                         int i = 0;
9794                         
9795 +                       /* loose control terminal */
9796 +                       setsid();
9797 +
9798                         /* is save as we limit to 256 childs */
9799                         sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count);
9800                         
9801 --- lighttpd-1.4.11/src/stat_cache.c    2005-11-22 15:23:51.000000000 +0200
9802 +++ lighttpd/src/stat_cache.c   2006-07-11 21:23:40.067853974 +0300
9803 @@ -6,7 +6,6 @@
9804  #include <stdlib.h>
9805  #include <string.h>
9806  #include <errno.h>
9807 -#include <unistd.h>
9808  #include <stdio.h>
9809  #include <fcntl.h>
9810  #include <assert.h>
9811 @@ -25,19 +24,8 @@
9812  #endif
9813  
9814  #include "sys-mmap.h"
9815 -
9816 -/* NetBSD 1.3.x needs it */
9817 -#ifndef MAP_FAILED
9818 -# define MAP_FAILED -1
9819 -#endif
9820 -
9821 -#ifndef O_LARGEFILE
9822 -# define O_LARGEFILE 0
9823 -#endif
9824 -
9825 -#ifndef HAVE_LSTAT
9826 -#define lstat stat
9827 -#endif
9828 +#include "sys-files.h"
9829 +#include "sys-strings.h"
9830  
9831  #if 0
9832  /* enables debug code for testing if all nodes in the stat-cache as accessable */
9833 --- lighttpd-1.4.11/src/stream.c        2005-09-23 21:50:15.000000000 +0300
9834 +++ lighttpd/src/stream.c       2006-07-11 21:23:40.215863244 +0300
9835 @@ -1,7 +1,6 @@
9836  #include <sys/types.h>
9837  #include <sys/stat.h>
9838  
9839 -#include <unistd.h> 
9840  #include <fcntl.h>
9841  
9842  #include "stream.h"
9843 @@ -10,6 +9,7 @@
9844  #endif
9845  
9846  #include "sys-mmap.h"
9847 +#include "sys-files.h"
9848  
9849  #ifndef O_BINARY
9850  # define O_BINARY 0
9851 @@ -19,7 +19,7 @@
9852         struct stat st;
9853  #ifdef HAVE_MMAP
9854         int fd;
9855 -#elif defined __WIN32
9856 +#elif defined _WIN32
9857         HANDLE *fh, *mh;
9858         void *p;
9859  #endif
9860 @@ -45,7 +45,7 @@
9861                 return -1;
9862         }
9863  
9864 -#elif defined __WIN32
9865 +#elif defined _WIN32
9866         fh = CreateFile(fn->ptr, 
9867                         GENERIC_READ, 
9868                         FILE_SHARE_READ, 
9869 --- lighttpd-1.4.11/src/sys-mmap.h      2005-08-11 01:26:34.000000000 +0300
9870 +++ lighttpd/src/sys-mmap.h     2006-07-11 21:23:40.051852972 +0300
9871 @@ -1,7 +1,7 @@
9872  #ifndef WIN32_MMAP_H
9873  #define WIN32_MMAP_H
9874  
9875 -#ifdef __WIN32
9876 +#ifdef _WIN32
9877  
9878  #define MAP_FAILED -1
9879  #define PROT_SHARED 0
9880 --- lighttpd-1.4.11/src/sys-socket.h    2005-08-11 01:26:39.000000000 +0300
9881 +++ lighttpd/src/sys-socket.h   2006-07-11 21:23:40.051852972 +0300
9882 @@ -1,15 +1,26 @@
9883  #ifndef WIN32_SOCKET_H
9884  #define WIN32_SOCKET_H
9885  
9886 -#ifdef __WIN32
9887 +#ifdef _WIN32
9888  
9889  #include <winsock2.h>
9890  
9891  #define ECONNRESET WSAECONNRESET
9892  #define EINPROGRESS WSAEINPROGRESS
9893  #define EALREADY WSAEALREADY
9894 +#define ENOTCONN WSAENOTCONN
9895 +#define EWOULDBLOCK WSAEWOULDBLOCK
9896  #define ioctl ioctlsocket
9897  #define hstrerror(x) ""
9898 +#define STDIN_FILENO 0
9899 +#define STDOUT_FILENO 1
9900 +#define STDERR_FILENO 2
9901 +#define ssize_t int
9902 +
9903 +int inet_aton(const char *cp, struct in_addr *inp);
9904 +#define HAVE_INET_ADDR
9905 +#undef HAVE_INET_ATON
9906 +
9907  #else
9908  #include <sys/socket.h>
9909  #include <sys/ioctl.h>
9910 @@ -18,6 +29,11 @@
9911  #include <sys/un.h>
9912  #include <arpa/inet.h>
9913  
9914 +#ifndef SUN_LEN
9915 +#define SUN_LEN(su) \
9916 +        (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
9917 +#endif
9918 +
9919  #include <netdb.h>
9920  #endif
9921  
9922 --- lighttpd-1.4.11/tests/LightyTest.pm 2006-01-14 20:32:31.000000000 +0200
9923 +++ lighttpd/tests/LightyTest.pm        2006-07-11 21:23:42.047977994 +0300
9924 @@ -87,14 +87,14 @@
9925         # pre-process configfile if necessary
9926         #
9927  
9928 -       unlink($self->{TESTDIR}."/tmp/cfg.file");
9929 -       system("cat ".$self->{SRCDIR}."/".$self->{CONFIGFILE}.' | perl -pe "s#\@SRCDIR\@#'.$self->{BASEDIR}.'/tests/#" > '.$self->{TESTDIR}.'/tmp/cfg.file');
9930 +       $ENV{'SRCDIR'} = $self->{BASEDIR}.'/tests';
9931 +       $ENV{'PORT'} = $self->{PORT};
9932  
9933         unlink($self->{LIGHTTPD_PIDFILE});
9934         if (1) {
9935 -               system($self->{LIGHTTPD_PATH}." -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH});
9936 +               system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH});
9937         } else {
9938 -               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}." &");
9939 +               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}." &");
9940         }
9941  
9942         select(undef, undef, undef, 0.1);
9943 @@ -184,7 +184,7 @@
9944                                         (my $h = $1) =~ tr/[A-Z]/[a-z]/;
9945  
9946                                         if (defined $resp_hdr{$h}) {
9947 -                                               diag(sprintf("header %s is duplicated: %s and %s\n",
9948 +                                               diag(sprintf("header '%s' is duplicated: '%s' and '%s'\n",
9949                                                              $h, $resp_hdr{$h}, $2));
9950                                         } else {
9951                                                 $resp_hdr{$h} = $2;
9952 @@ -196,6 +196,9 @@
9953                         }
9954                 }
9955  
9956 +               $t->{etag} = $resp_hdr{'etag'};
9957 +               $t->{date} = $resp_hdr{'date'};
9958 +
9959                 # check length
9960                 if (defined $resp_hdr{"content-length"}) {
9961                         $resp_body = substr($lines, 0, $resp_hdr{"content-length"});
9962 --- lighttpd-1.4.11/tests/Makefile.am   2005-09-16 15:48:40.000000000 +0300
9963 +++ lighttpd/tests/Makefile.am  2006-07-11 21:23:42.039977492 +0300
9964 @@ -39,10 +39,15 @@
9965        mod-redirect.t \
9966        mod-userdir.t \
9967        mod-rewrite.t \
9968 +      mod-proxy.t \
9969        request.t \
9970        mod-ssi.t \
9971        LightyTest.pm \
9972 -      mod-setenv.t 
9973 +      mod-setenv.t \
9974 +      lowercase.t \
9975 +      lowercase.conf \
9976 +      proxy.conf \
9977 +      cachable.t
9978  
9979  
9980  TESTS_ENVIRONMENT=$(srcdir)/wrapper.sh $(srcdir) $(top_builddir) 
9981 --- lighttpd-1.4.11/tests/bug-06.conf   2005-08-27 17:44:19.000000000 +0300
9982 +++ lighttpd/tests/bug-06.conf  2006-07-11 21:23:41.915969726 +0300
9983 @@ -1,5 +1,5 @@
9984 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
9985 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
9986 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
9987 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
9988  
9989  ## bind to port (default: 80)
9990  server.port                 = 2048
9991 @@ -8,7 +8,7 @@
9992  
9993  ## bind to localhost (default: all interfaces)
9994  server.bind                = "localhost"
9995 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
9996 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
9997  server.name                = "www.example.org"
9998  server.tag                 = "Apache 1.3.29"
9999  
10000 @@ -59,7 +59,7 @@
10001  ######################## MODULE CONFIG ############################
10002  
10003  
10004 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10005 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
10006  
10007  mimetype.assign             = ( ".png"  => "image/png", 
10008                                  ".jpg"  => "image/jpeg",
10009 @@ -77,7 +77,7 @@
10010                                 ".c"    => "text/plain",
10011                                 ".conf" => "text/plain" )
10012  
10013 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
10014 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
10015  compress.filetype           = ("text/plain", "text/html")
10016  
10017  setenv.add-environment      = ( "TRAC_ENV" => "foo")
10018 @@ -90,7 +90,7 @@
10019                                     "host" => "127.0.0.1",
10020                                     "port" => 1026,
10021  #                                  "mode" => "authorizer",
10022 -#                                  "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
10023 +#                                  "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
10024                                   )
10025                                 )
10026                               )
10027 @@ -106,7 +106,7 @@
10028  ssl.pemfile                 = "server.pem"
10029  
10030  auth.backend                = "plain"
10031 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
10032 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
10033  auth.backend.plain.groupfile = "lighttpd.group"
10034  
10035  auth.backend.ldap.hostname  = "localhost"
10036 @@ -149,15 +149,15 @@
10037  status.config-url           = "/server-config"
10038  
10039  simple-vhost.document-root  = "pages"
10040 -simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
10041 +simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
10042  simple-vhost.default-host   = "www.example.org"
10043  
10044  $HTTP["host"] == "vvv.example.org" {
10045 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10046 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10047  }
10048  
10049  $HTTP["host"] == "zzz.example.org" {
10050 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10051 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10052    server.name = "zzz.example.org"
10053  }
10054  
10055 --- lighttpd-1.4.11/tests/bug-12.conf   2005-08-27 17:44:19.000000000 +0300
10056 +++ lighttpd/tests/bug-12.conf  2006-07-11 21:23:41.907969224 +0300
10057 @@ -1,5 +1,5 @@
10058 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10059 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
10060 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10061 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
10062  
10063  ## bind to port (default: 80)
10064  server.port                 = 2048
10065 @@ -8,7 +8,7 @@
10066  
10067  ## bind to localhost (default: all interfaces)
10068  server.bind                = "localhost"
10069 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
10070 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
10071  server.name                = "www.example.org"
10072  server.tag                 = "Apache 1.3.29"
10073  
10074 @@ -61,7 +61,7 @@
10075  ######################## MODULE CONFIG ############################
10076  
10077  
10078 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10079 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
10080  
10081  mimetype.assign             = ( ".png"  => "image/png", 
10082                                  ".jpg"  => "image/jpeg",
10083 @@ -79,7 +79,7 @@
10084                                 ".c"    => "text/plain",
10085                                 ".conf" => "text/plain" )
10086  
10087 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
10088 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
10089  compress.filetype           = ("text/plain", "text/html")
10090  
10091  setenv.add-environment      = ( "TRAC_ENV" => "foo")
10092 @@ -92,7 +92,7 @@
10093                                     "host" => "127.0.0.1",
10094                                     "port" => 1026,
10095  #                                  "mode" => "authorizer",
10096 -#                                  "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
10097 +#                                  "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
10098                                   )
10099                                 )
10100                               )
10101 @@ -108,7 +108,7 @@
10102  ssl.pemfile                 = "server.pem"
10103  
10104  auth.backend                = "plain"
10105 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
10106 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
10107  auth.backend.plain.groupfile = "lighttpd.group"
10108  
10109  auth.backend.ldap.hostname  = "localhost"
10110 @@ -151,15 +151,15 @@
10111  status.config-url           = "/server-config"
10112  
10113  simple-vhost.document-root  = "pages"
10114 -simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
10115 +simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
10116  simple-vhost.default-host   = "www.example.org"
10117  
10118  $HTTP["host"] == "vvv.example.org" {
10119 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10120 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10121  }
10122  
10123  $HTTP["host"] == "zzz.example.org" {
10124 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10125 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10126    server.name = "zzz.example.org"
10127  }
10128  
10129 --- lighttpd-1.4.11/tests/condition.conf        2005-08-27 17:44:19.000000000 +0300
10130 +++ lighttpd/tests/condition.conf       2006-07-11 21:23:41.951971980 +0300
10131 @@ -2,15 +2,15 @@
10132  debug.log-request-handling = "enable"
10133  debug.log-condition-handling = "enable"
10134  
10135 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10136 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
10137 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10138 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
10139  
10140  ## bind to port (default: 80)
10141  server.port                 = 2048
10142  
10143  ## bind to localhost (default: all interfaces)
10144  server.bind                = "localhost"
10145 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
10146 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
10147  server.name                = "www.example.org"
10148  server.tag                 = "Apache 1.3.29"
10149  
10150 @@ -22,25 +22,25 @@
10151  ######################## MODULE CONFIG ############################
10152  
10153  
10154 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10155 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
10156  
10157  mimetype.assign             = ( ".html" => "text/html" )
10158  
10159  url.redirect = ("^" => "/default")
10160  
10161  $HTTP["host"] == "www.example.org" {
10162 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10163 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10164    server.name = "www.example.org"
10165    url.redirect = ("^" => "/match_1")
10166  }
10167  else $HTTP["host"] == "test1.example.org" {
10168 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10169 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10170    server.name = "test1.example.org"
10171    url.redirect = ("^" => "/match_2")
10172  }
10173  # comments
10174  else $HTTP["host"] == "test2.example.org" {
10175 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10176 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10177    server.name = "test2.example.org"
10178    url.redirect = ("^" => "/match_3")
10179  }
10180 @@ -48,7 +48,7 @@
10181          # comments
10182  
10183  else $HTTP["host"] == "test3.example.org" {
10184 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10185 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10186    server.name = "test3.example.org"
10187    url.redirect = ("^" => "/match_4")
10188  
10189 --- lighttpd-1.4.11/tests/core-keepalive.t      2005-11-17 15:54:19.000000000 +0200
10190 +++ lighttpd/tests/core-keepalive.t     2006-07-11 21:23:41.939971229 +0300
10191 @@ -40,7 +40,7 @@
10192  
10193  GET /12345.txt HTTP/1.0
10194  Host: 123.example.org
10195 -Connection: keep-alive
10196 +Connection: close
10197  EOF
10198   );
10199  $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
10200 --- lighttpd-1.4.11/tests/docroot/www/dummydir/.svn/entries     2006-03-09 19:21:49.000000000 +0200
10201 +++ lighttpd/tests/docroot/www/dummydir/.svn/entries    2006-07-11 21:23:41.575948429 +0300
10202 @@ -9,5 +9,6 @@
10203     last-author="jan"
10204     kind="dir"
10205     uuid="152afb58-edef-0310-8abb-c4023f1b3aa9"
10206 -   revision="1040"/>
10207 +   repos="svn://svn.lighttpd.net/lighttpd"
10208 +   revision="1159"/>
10209  </wc-entries>
10210 --- lighttpd-1.4.11/tests/fastcgi-10.conf       2005-08-31 23:36:34.000000000 +0300
10211 +++ lighttpd/tests/fastcgi-10.conf      2006-07-11 21:23:41.911969475 +0300
10212 @@ -1,12 +1,12 @@
10213 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10214 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
10215 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10216 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
10217  
10218  ## bind to port (default: 80)
10219  server.port                 = 2048
10220  
10221  ## bind to localhost (default: all interfaces)
10222  server.bind                = "localhost"
10223 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
10224 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
10225  server.name                = "www.example.org"
10226  server.tag                 = "Apache 1.3.29"
10227  
10228 @@ -44,7 +44,7 @@
10229  ######################## MODULE CONFIG ############################
10230  
10231  
10232 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10233 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
10234  
10235  mimetype.assign             = ( ".png"  => "image/png", 
10236                                  ".jpg"  => "image/jpeg",
10237 @@ -62,7 +62,7 @@
10238                                 ".c"    => "text/plain",
10239                                 ".conf" => "text/plain" )
10240  
10241 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
10242 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
10243  compress.filetype           = ("text/plain", "text/html")
10244  
10245  fastcgi.debug               = 0
10246 @@ -85,7 +85,7 @@
10247  ssl.pemfile                 = "server.pem"
10248  
10249  auth.backend                = "plain"
10250 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
10251 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
10252  auth.backend.plain.groupfile = "lighttpd.group"
10253  
10254  auth.backend.ldap.hostname  = "localhost"
10255 @@ -128,11 +128,11 @@
10256  status.config-url           = "/server-config"
10257  
10258  $HTTP["host"] == "vvv.example.org" {
10259 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10260 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10261  }
10262  
10263  $HTTP["host"] == "zzz.example.org" {
10264 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10265 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10266    server.name = "zzz.example.org"
10267  }
10268  
10269 --- lighttpd-1.4.11/tests/fastcgi-13.conf       2006-01-03 12:38:17.000000000 +0200
10270 +++ lighttpd/tests/fastcgi-13.conf      2006-07-11 21:23:41.971973233 +0300
10271 @@ -1,5 +1,5 @@
10272 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10273 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
10274 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10275 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
10276  
10277  debug.log-request-header   = "enable"
10278  debug.log-response-header  = "enable"
10279 @@ -10,7 +10,7 @@
10280  
10281  ## bind to localhost (default: all interfaces)
10282  server.bind                = "localhost"
10283 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
10284 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
10285  server.name                = "www.example.org"
10286  server.tag                 = "Apache 1.3.29"
10287  
10288 @@ -59,7 +59,7 @@
10289  ######################## MODULE CONFIG ############################
10290  
10291  
10292 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10293 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
10294  
10295  mimetype.assign             = ( ".png"  => "image/png", 
10296                                  ".jpg"  => "image/jpeg",
10297 @@ -77,7 +77,7 @@
10298                                 ".c"    => "text/plain",
10299                                 ".conf" => "text/plain" )
10300  
10301 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
10302 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
10303  compress.filetype           = ("text/plain", "text/html")
10304  
10305  fastcgi.debug               = 0
10306 @@ -102,7 +102,7 @@
10307  ssl.pemfile                 = "server.pem"
10308  
10309  auth.backend                = "plain"
10310 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
10311 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
10312  auth.backend.plain.groupfile = "lighttpd.group"
10313  
10314  auth.backend.ldap.hostname  = "localhost"
10315 @@ -145,11 +145,11 @@
10316  status.config-url           = "/server-config"
10317  
10318  $HTTP["host"] == "vvv.example.org" {
10319 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10320 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10321  }
10322  
10323  $HTTP["host"] == "zzz.example.org" {
10324 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10325 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10326    server.name = "zzz.example.org"
10327  }
10328  
10329 --- lighttpd-1.4.11/tests/fastcgi-auth.conf     2005-08-27 17:44:19.000000000 +0300
10330 +++ lighttpd/tests/fastcgi-auth.conf    2006-07-11 21:23:42.003975238 +0300
10331 @@ -1,5 +1,5 @@
10332 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10333 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
10334 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10335 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
10336  
10337  debug.log-request-header   = "enable"
10338  debug.log-response-header  = "enable"
10339 @@ -12,7 +12,7 @@
10340  
10341  ## bind to localhost (default: all interfaces)
10342  server.bind                = "localhost"
10343 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
10344 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
10345  server.name                = "www.example.org"
10346  server.tag                 = "Apache 1.3.29"
10347  
10348 @@ -61,7 +61,7 @@
10349  ######################## MODULE CONFIG ############################
10350  
10351  
10352 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10353 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
10354  
10355  mimetype.assign             = ( ".png"  => "image/png", 
10356                                  ".jpg"  => "image/jpeg",
10357 @@ -79,7 +79,7 @@
10358                                 ".c"    => "text/plain",
10359                                 ".conf" => "text/plain" )
10360  
10361 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
10362 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
10363  compress.filetype           = ("text/plain", "text/html")
10364  
10365  fastcgi.debug               = 0
10366 @@ -87,9 +87,9 @@
10367                                    "grisu" => ( 
10368                                     "host" => "127.0.0.1",
10369                                     "port" => 20000,
10370 -                                   "bin-path" => "@SRCDIR@/fcgi-auth",
10371 +                                   "bin-path" => env.SRCDIR + "/fcgi-auth",
10372                                      "mode" => "authorizer",
10373 -                                    "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
10374 +                                    "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
10375                                     
10376                                   )
10377                                 )
10378 @@ -106,7 +106,7 @@
10379  ssl.pemfile                 = "server.pem"
10380  
10381  auth.backend                = "plain"
10382 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
10383 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
10384  auth.backend.plain.groupfile = "lighttpd.group"
10385  
10386  auth.backend.ldap.hostname  = "localhost"
10387 @@ -149,11 +149,11 @@
10388  status.config-url           = "/server-config"
10389  
10390  $HTTP["host"] == "vvv.example.org" {
10391 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10392 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10393  }
10394  
10395  $HTTP["host"] == "zzz.example.org" {
10396 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10397 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10398    server.name = "zzz.example.org"
10399  }
10400  
10401 --- lighttpd-1.4.11/tests/fastcgi-responder.conf        2005-08-27 17:44:19.000000000 +0300
10402 +++ lighttpd/tests/fastcgi-responder.conf       2006-07-11 21:23:41.999974987 +0300
10403 @@ -1,5 +1,5 @@
10404 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10405 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
10406 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10407 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
10408  
10409  #debug.log-request-header   = "enable"
10410  #debug.log-response-header  = "enable"
10411 @@ -15,7 +15,7 @@
10412  
10413  ## bind to localhost (default: all interfaces)
10414  server.bind                = "localhost"
10415 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
10416 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
10417  server.name                = "www.example.org"
10418  server.tag                 = "Apache 1.3.29"
10419  
10420 @@ -64,7 +64,7 @@
10421  ######################## MODULE CONFIG ############################
10422  
10423  
10424 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10425 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
10426  
10427  mimetype.assign             = ( ".png"  => "image/png", 
10428                                  ".jpg"  => "image/jpeg",
10429 @@ -82,7 +82,7 @@
10430                                 ".c"    => "text/plain",
10431                                 ".conf" => "text/plain" )
10432  
10433 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
10434 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
10435  compress.filetype           = ("text/plain", "text/html")
10436  
10437  fastcgi.debug               = 0
10438 @@ -90,10 +90,11 @@
10439                                    "grisu" => ( 
10440                                     "host" => "127.0.0.1",
10441                                     "port" => 10000,
10442 -                                   "bin-path" => "@SRCDIR@/fcgi-responder",
10443 +                                   "bin-path" => env.SRCDIR + "/fcgi-responder",
10444                                     "check-local" => "disable",
10445                                     "max-procs" => 1,
10446 -                                   "min-procs" => 1
10447 +                                   "min-procs" => 1,
10448 +                                   "allow-x-send-file" => "enable",
10449                                   )
10450                                 )
10451                               )
10452 @@ -109,7 +110,7 @@
10453  ssl.pemfile                 = "server.pem"
10454  
10455  auth.backend                = "plain"
10456 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
10457 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
10458  auth.backend.plain.groupfile = "lighttpd.group"
10459  
10460  auth.backend.ldap.hostname  = "localhost"
10461 @@ -152,11 +153,11 @@
10462  status.config-url           = "/server-config"
10463  
10464  $HTTP["host"] == "vvv.example.org" {
10465 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10466 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10467  }
10468  
10469  $HTTP["host"] == "zzz.example.org" {
10470 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10471 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10472    server.name = "zzz.example.org"
10473  }
10474  
10475 --- lighttpd-1.4.11/tests/fcgi-responder.c      2005-08-11 01:26:55.000000000 +0300
10476 +++ lighttpd/tests/fcgi-responder.c     2006-07-11 21:23:41.979973734 +0300
10477 @@ -6,11 +6,17 @@
10478  int main () {
10479         int num_requests = 2;
10480         
10481 -       while (num_requests > 0 &&
10482 -              FCGI_Accept() >= 0) {
10483 -               char* p;
10484 +       while (num_requests > 0 && FCGI_Accept() >= 0) {
10485 +               char* p = NULL;
10486 +               char* doc_root = NULL;
10487 +               char fname[4096];
10488 +               char* pfname = (char *)fname;
10489                 
10490 -               if (NULL != (p = getenv("QUERY_STRING"))) {
10491 +               doc_root = getenv("DOCUMENT_ROOT");
10492 +               p = getenv("QUERY_STRING");
10493 +
10494 +               if (NULL != p && NULL != doc_root) {
10495 +                       snprintf(pfname, sizeof(fname), "%s/phpinfo.php", doc_root);
10496                         if (0 == strcmp(p, "lf")) {
10497                                 printf("Status: 200 OK\n\n");
10498                         } else if (0 == strcmp(p, "crlf")) {
10499 @@ -23,6 +29,18 @@
10500                                 printf("Status: 200 OK\r\n");
10501                                 fflush(stdout);
10502                                 printf("\r\n");
10503 +                       } else if (0 == strcmp(p,"x-lighttpd-send-file")) {
10504 +                               printf("Status: 200 OK\r\n");
10505 +                               printf("X-LIGHTTPD-send-file: %s\r\n", pfname);
10506 +                               printf("\r\n");
10507 +                       } else if (0 == strcmp(p,"xsendfile")) {
10508 +                               printf("Status: 200 OK\r\n");
10509 +                               printf("X-Sendfile: %s\r\n", pfname);
10510 +                               printf("\r\n");
10511 +                       } else if (0 == strcmp(p,"xsendfile-mixed-case")) {
10512 +                               printf("Status: 200 OK\r\n");
10513 +                               printf("X-SeNdFiLe: %s\r\n", pfname);
10514 +                               printf("\r\n");
10515                         } else if (0 == strcmp(p, "die-at-end")) {
10516                                 printf("Status: 200 OK\r\n\r\n");
10517                                 num_requests--;
10518 --- lighttpd-1.4.11/tests/lighttpd.conf 2006-03-09 15:26:58.000000000 +0200
10519 +++ lighttpd/tests/lighttpd.conf        2006-07-11 21:23:41.999974987 +0300
10520 @@ -1,80 +1,18 @@
10521 -debug.log-request-handling = "enable"
10522 -debug.log-condition-handling = "enable"
10523 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10524 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
10525 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10526 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
10527 +server.tag = "Apache 1.3.29"
10528  
10529  ## 64 Mbyte ... nice limit
10530  server.max-request-size = 65000
10531  
10532 -## bind to port (default: 80)
10533 -server.port                 = 2048
10534 -
10535 -## bind to localhost (default: all interfaces)
10536 -server.bind                = "localhost"
10537 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
10538 -server.name                = "www.example.org"
10539 -server.tag                 = "Apache 1.3.29"
10540 -
10541 -server.dir-listing          = "enable"
10542 +include "default.conf"
10543  
10544 -#server.event-handler        = "linux-sysepoll"
10545 -#server.event-handler        = "linux-rtsig"
10546 -
10547 -#server.modules.path         = ""
10548 -server.modules              = ( 
10549 -                               "mod_rewrite",
10550 -                               "mod_setenv",
10551 -                               "mod_secdownload",
10552 -                               "mod_access", 
10553 -                               "mod_auth",
10554 -#                              "mod_httptls",
10555 -                               "mod_status", 
10556 -                               "mod_expire",
10557 -                               "mod_simple_vhost",
10558 -                               "mod_redirect", 
10559 -#                              "mod_evhost",
10560 -#                              "mod_localizer",
10561 -                               "mod_fastcgi",
10562 -                               "mod_cgi",
10563 -                               "mod_compress",
10564 -                               "mod_userdir",
10565 -                               "mod_ssi",
10566 -                               "mod_accesslog" ) 
10567 -
10568 -server.indexfiles           = ( "index.php", "index.html", 
10569 -                                "index.htm", "default.htm" )
10570 -
10571 -
10572 -######################## MODULE CONFIG ############################
10573 -
10574 -ssi.extension = ( ".shtml" )
10575 -
10576 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10577 -
10578 -mimetype.assign             = ( ".png"  => "image/png", 
10579 -                                ".jpg"  => "image/jpeg",
10580 -                                ".jpeg" => "image/jpeg",
10581 -                                ".gif"  => "image/gif",
10582 -                                ".html" => "text/html",
10583 -                                ".htm"  => "text/html",
10584 -                                ".pdf"  => "application/pdf",
10585 -                                ".swf"  => "application/x-shockwave-flash",
10586 -                                ".spl"  => "application/futuresplash",
10587 -                                ".txt"  => "text/plain",
10588 -                                ".tar.gz" =>   "application/x-tgz",
10589 -                                ".tgz"  => "application/x-tgz",
10590 -                                ".gz"   => "application/x-gzip",
10591 -                               ".c"    => "text/plain",
10592 -                               ".conf" => "text/plain" )
10593 +setenv.add-request-header   = ( "FOO" => "foo")
10594 +setenv.add-response-header  = ( "BAR" => "foo")
10595  
10596  $HTTP["host"] == "cache.example.org" {
10597 -  compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
10598 +  compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
10599  }
10600 -compress.filetype           = ("text/plain", "text/html")
10601 -
10602 -setenv.add-environment      = ( "TRAC_ENV" => "tracenv", "SETENV" => "setenv")
10603 -setenv.add-request-header   = ( "FOO" => "foo")
10604 -setenv.add-response-header  = ( "BAR" => "foo")
10605  
10606  $HTTP["url"] =~ "\.pdf$" {
10607    server.range-requests = "disable"
10608 @@ -85,76 +23,31 @@
10609                                 "/prefix.fcgi" => ( ( "host" => "127.0.0.1", "port" => 1026, "check-local" => "disable", "broken-scriptfilename" => "enable" ) )
10610                               )
10611                 
10612 -
10613 -cgi.assign                  = ( ".pl"  => "/usr/bin/perl",
10614 -                                ".cgi" => "/usr/bin/perl",
10615 -                               ".py"  => "/usr/bin/python" )
10616 -                       
10617 -userdir.include-user = ( "jan" )
10618 -userdir.path = "/"
10619 -
10620 -ssl.engine                  = "disable"
10621 -ssl.pemfile                 = "server.pem"
10622 -
10623  $HTTP["host"] == "auth-htpasswd.example.org" {
10624         auth.backend                = "htpasswd"
10625  }
10626  
10627 -auth.backend                = "plain"
10628 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
10629 -
10630 -auth.backend.htpasswd.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.htpasswd"
10631 -
10632 -
10633 -auth.require                = ( "/server-status" => 
10634 -                                ( 
10635 -                                 "method"  => "digest",
10636 -                                 "realm"   => "download archiv",
10637 -                                 "require" => "group=www|user=jan|host=192.168.2.10"
10638 -                               ),
10639 -                               "/server-config" => 
10640 -                                ( 
10641 -                                 "method"  => "basic",
10642 -                                 "realm"   => "download archiv",
10643 -                                 "require" => "valid-user"
10644 -                               )
10645 -                              )
10646 -
10647 -url.access-deny             = ( "~", ".inc")
10648 -
10649 -url.rewrite                = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1",
10650 -                               "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" )
10651 -
10652 -expire.url                  = ( "/expire/access" => "access 2 hours", 
10653 -                               "/expire/modification" => "access plus 1 seconds 2 minutes")
10654 -
10655 -#cache.cache-dir             = "/home/weigon/wwwroot/cache/"
10656 -
10657 -#### status module
10658 -status.status-url           = "/server-status"
10659 -status.config-url           = "/server-config"
10660 -
10661  $HTTP["host"] == "vvv.example.org" {
10662 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10663 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10664    secdownload.secret          = "verysecret"
10665 -  secdownload.document-root   = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10666 +  secdownload.document-root   = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10667    secdownload.uri-prefix      = "/sec/"
10668    secdownload.timeout         = 120
10669  }
10670  
10671  $HTTP["host"] == "zzz.example.org" {
10672 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10673 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10674    server.name = "zzz.example.org"
10675  }
10676  
10677  $HTTP["host"] == "no-simple.example.org" {
10678 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/123.example.org/pages/"
10679 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/123.example.org/pages/"
10680    server.name = "zzz.example.org"
10681  }
10682  
10683  $HTTP["host"] !~ "(no-simple\.example\.org)" {
10684    simple-vhost.document-root  = "pages"
10685 -  simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
10686 +  simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
10687    simple-vhost.default-host   = "www.example.org"
10688  }
10689  
10690 --- lighttpd-1.4.11/tests/mod-fastcgi.t 2006-03-09 15:30:45.000000000 +0200
10691 +++ lighttpd/tests/mod-fastcgi.t        2006-07-11 21:23:41.995974736 +0300
10692 @@ -7,7 +7,7 @@
10693  }
10694  
10695  use strict;
10696 -use Test::More tests => 47;
10697 +use Test::More tests => 49;
10698  use LightyTest;
10699  
10700  my $tf = LightyTest->new();
10701 @@ -15,7 +15,7 @@
10702  my $t;
10703  
10704  SKIP: {
10705 -       skip "no PHP running on port 1026", 30 unless $tf->listening_on(1026);
10706 +       skip "no PHP running on port 1026", 29 unless $tf->listening_on(1026);
10707  
10708         ok($tf->start_proc == 0, "Starting lighttpd") or die();
10709  
10710 @@ -285,6 +285,34 @@
10711         $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'test123' } ];
10712         ok($tf->handle_http($t) == 0, 'line-ending \r\n + \r\n');
10713  
10714 +    # X-LIGHTTPD-send-file
10715 +       $t->{REQUEST}  = ( <<EOF
10716 +GET /index.fcgi?x-lighttpd-send-file HTTP/1.0
10717 +Host: www.example.org
10718 +EOF
10719 + );
10720 +       $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
10721 +' } ];
10722 +       ok($tf->handle_http($t) == 0, 'X-LIGHTTPD-send-file');
10723 +    # X-Sendfile
10724 +       $t->{REQUEST}  = ( <<EOF
10725 +GET /index.fcgi?xsendfile HTTP/1.0
10726 +Host: www.example.org
10727 +EOF
10728 + );
10729 +       $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
10730 +' } ];
10731 +       ok($tf->handle_http($t) == 0, 'X-Sendfile');
10732 +
10733 +       $t->{REQUEST}  = ( <<EOF
10734 +GET /index.fcgi?xsendfile-mixed-case HTTP/1.0
10735 +Host: www.example.org
10736 +EOF
10737 + );
10738 +       $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
10739 +' } ];
10740 +       ok($tf->handle_http($t) == 0, 'X-SeNdFiLe in mixed case');
10741 +
10742         $t->{REQUEST}  = ( <<EOF
10743  GET /index.fcgi?die-at-end HTTP/1.0
10744  Host: www.example.org
10745 --- lighttpd-1.4.11/tests/var-include.conf      2005-08-27 17:44:19.000000000 +0300
10746 +++ lighttpd/tests/var-include.conf     2006-07-11 21:23:41.943971479 +0300
10747 @@ -2,15 +2,15 @@
10748  debug.log-request-handling = "enable"
10749  debug.log-condition-handling = "enable"
10750  
10751 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10752 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
10753 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10754 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
10755  
10756  ## bind to port (default: 80)
10757  server.port                 = 2048
10758  
10759  ## bind to localhost (default: all interfaces)
10760  server.bind                = "localhost"
10761 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
10762 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
10763  server.name                = "www.example.org"
10764  server.tag                 = "Apache 1.3.29"
10765  
10766 @@ -21,19 +21,19 @@
10767  ######################## MODULE CONFIG ############################
10768  
10769  
10770 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
10771 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
10772  
10773  mimetype.assign             = ( ".html" => "text/html" )
10774  
10775  url.redirect = ("^" => "/default")
10776  
10777  $HTTP["host"] == "www.example.org" {
10778 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10779 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10780    server.name = "www.example.org"
10781    url.redirect = ("^" => "/redirect")
10782  }
10783  $HTTP["host"] == "test.example.org" {
10784 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
10785 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
10786    server.name = "test.example.org"
10787    var.myvar = "good"
10788    var.one = 1
This page took 1.271465 seconds and 4 git commands to generate.